1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org#include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <assert.h>
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdlib.h>
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h>
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
17c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org#include "webrtc/modules/audio_processing/utility/delay_estimator.h"
18c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org#include "webrtc/modules/audio_processing/utility/delay_estimator_internal.h"
19221798a7c4ad83ba7fb8b3ae39b99d44278bbe5aandrew@webrtc.org#include "webrtc/system_wrappers/interface/compile_assert_c.h"
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Only bit |kBandFirst| through bit |kBandLast| are processed and
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// |kBandFirst| - |kBandLast| must be < 32.
23c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.orgenum { kBandFirst = 12 };
24c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.orgenum { kBandLast = 43 };
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic __inline uint32_t SetBit(uint32_t in, int pos) {
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  uint32_t mask = (1 << pos);
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  uint32_t out = (in | mask);
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return out;
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Calculates the mean recursively. Same version as WebRtc_MeanEstimatorFix(),
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// but for float.
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Inputs:
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//    - new_value             : New additional value.
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//    - scale                 : Scale for smoothing (should be less than 1.0).
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Input/Output:
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//    - mean_value            : Pointer to the mean value for updating.
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void MeanEstimatorFloat(float new_value,
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               float scale,
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               float* mean_value) {
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(scale < 1.0f);
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  *mean_value += (new_value - *mean_value) * scale;
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Computes the binary spectrum by comparing the input |spectrum| with a
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// |threshold_spectrum|. Float and fixed point versions.
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Inputs:
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//      - spectrum            : Spectrum of which the binary spectrum should be
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//                              calculated.
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//      - threshold_spectrum  : Threshold spectrum with which the input
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//                              spectrum is compared.
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Return:
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//      - out                 : Binary spectrum.
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic uint32_t BinarySpectrumFix(uint16_t* spectrum,
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                  SpectrumType* threshold_spectrum,
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                  int q_domain,
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                  int* threshold_initialized) {
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int i = kBandFirst;
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  uint32_t out = 0;
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(q_domain < 16);
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!(*threshold_initialized)) {
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Set the |threshold_spectrum| to half the input |spectrum| as starting
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // value. This speeds up the convergence.
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (i = kBandFirst; i <= kBandLast; i++) {
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (spectrum[i] > 0) {
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // Convert input spectrum from Q(|q_domain|) to Q15.
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        threshold_spectrum[i].int32_ = (spectrum_q15 >> 1);
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        *threshold_initialized = 1;
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (i = kBandFirst; i <= kBandLast; i++) {
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Convert input spectrum from Q(|q_domain|) to Q15.
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Update the |threshold_spectrum|.
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WebRtc_MeanEstimatorFix(spectrum_q15, 6, &(threshold_spectrum[i].int32_));
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Convert |spectrum| at current frequency bin to a binary value.
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (spectrum_q15 > threshold_spectrum[i].int32_) {
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      out = SetBit(out, i - kBandFirst);
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return out;
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic uint32_t BinarySpectrumFloat(float* spectrum,
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    SpectrumType* threshold_spectrum,
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    int* threshold_initialized) {
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int i = kBandFirst;
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  uint32_t out = 0;
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const float kScale = 1 / 64.0;
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!(*threshold_initialized)) {
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Set the |threshold_spectrum| to half the input |spectrum| as starting
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // value. This speeds up the convergence.
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (i = kBandFirst; i <= kBandLast; i++) {
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (spectrum[i] > 0.0f) {
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        threshold_spectrum[i].float_ = (spectrum[i] / 2);
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        *threshold_initialized = 1;
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (i = kBandFirst; i <= kBandLast; i++) {
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Update the |threshold_spectrum|.
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    MeanEstimatorFloat(spectrum[i], kScale, &(threshold_spectrum[i].float_));
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Convert |spectrum| at current frequency bin to a binary value.
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (spectrum[i] > threshold_spectrum[i].float_) {
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      out = SetBit(out, i - kBandFirst);
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return out;
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
126c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.orgvoid WebRtc_FreeDelayEstimatorFarend(void* handle) {
127c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (handle == NULL) {
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return;
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  free(self->mean_far_spectrum);
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  self->mean_far_spectrum = NULL;
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
136c02e4cccd5e176a9917193e0f7cb95203e6f7474bjornv@webrtc.org  WebRtc_FreeBinaryDelayEstimatorFarend(self->binary_farend);
137c02e4cccd5e176a9917193e0f7cb95203e6f7474bjornv@webrtc.org  self->binary_farend = NULL;
138c02e4cccd5e176a9917193e0f7cb95203e6f7474bjornv@webrtc.org
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  free(self);
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
142c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.orgvoid* WebRtc_CreateDelayEstimatorFarend(int spectrum_size, int history_size) {
143c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  DelayEstimatorFarend* self = NULL;
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Check if the sub band used in the delay estimation is small enough to fit
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // the binary spectra in a uint32_t.
147c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  COMPILE_ASSERT(kBandLast - kBandFirst < 32);
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
149c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (spectrum_size >= kBandLast) {
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    self = malloc(sizeof(DelayEstimator));
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (self != NULL) {
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int memory_fail = 0;
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
156c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    // Allocate memory for the binary far-end spectrum handling.
157c02e4cccd5e176a9917193e0f7cb95203e6f7474bjornv@webrtc.org    self->binary_farend = WebRtc_CreateBinaryDelayEstimatorFarend(history_size);
158c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    memory_fail |= (self->binary_farend == NULL);
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Allocate memory for spectrum buffers.
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    self->mean_far_spectrum = malloc(spectrum_size * sizeof(SpectrumType));
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memory_fail |= (self->mean_far_spectrum == NULL);
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
164c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    self->spectrum_size = spectrum_size;
165c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
166c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    if (memory_fail) {
167c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org      WebRtc_FreeDelayEstimatorFarend(self);
168c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org      self = NULL;
169c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    }
170c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
171c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
172c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  return self;
173c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org}
174c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
175c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.orgint WebRtc_InitDelayEstimatorFarend(void* handle) {
176c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
177c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
178c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (self == NULL) {
179c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    return -1;
180c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
181c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
182c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  // Initialize far-end part of binary delay estimator.
183c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  WebRtc_InitBinaryDelayEstimatorFarend(self->binary_farend);
184c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
185c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  // Set averaged far and near end spectra to zero.
186c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  memset(self->mean_far_spectrum, 0,
187c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org         sizeof(SpectrumType) * self->spectrum_size);
188c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  // Reset initialization indicators.
189c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  self->far_spectrum_initialized = 0;
190c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
191c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  return 0;
192c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org}
193c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
1941df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.orgvoid WebRtc_SoftResetDelayEstimatorFarend(void* handle, int delay_shift) {
1951df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
1961df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org  assert(self != NULL);
1971df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org  WebRtc_SoftResetBinaryDelayEstimatorFarend(self->binary_farend, delay_shift);
1981df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org}
1991df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org
200c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.orgint WebRtc_AddFarSpectrumFix(void* handle, uint16_t* far_spectrum,
201c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org                             int spectrum_size, int far_q) {
202c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
203c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  uint32_t binary_spectrum = 0;
204c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
205c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (self == NULL) {
206c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    return -1;
207c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
208c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (far_spectrum == NULL) {
209c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    // Empty far end spectrum.
210c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    return -1;
211c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
212c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (spectrum_size != self->spectrum_size) {
213c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    // Data sizes don't match.
214c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    return -1;
215c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
216c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (far_q > 15) {
217c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    // If |far_q| is larger than 15 we cannot guarantee no wrap around.
218c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    return -1;
219c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
220c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
221c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  // Get binary spectrum.
222c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  binary_spectrum = BinarySpectrumFix(far_spectrum, self->mean_far_spectrum,
223c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org                                      far_q, &(self->far_spectrum_initialized));
224c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
225c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
226c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  return 0;
227c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org}
228c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
229c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.orgint WebRtc_AddFarSpectrumFloat(void* handle, float* far_spectrum,
230c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org                               int spectrum_size) {
231c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
232c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  uint32_t binary_spectrum = 0;
233c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
234c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (self == NULL) {
235c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    return -1;
236c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
237c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (far_spectrum == NULL) {
238c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    // Empty far end spectrum.
239c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    return -1;
240c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
241c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (spectrum_size != self->spectrum_size) {
242c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    // Data sizes don't match.
243c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    return -1;
244c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
245c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
246c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  // Get binary spectrum.
247c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  binary_spectrum = BinarySpectrumFloat(far_spectrum, self->mean_far_spectrum,
248c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org                                        &(self->far_spectrum_initialized));
249c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);
250c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
251c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  return 0;
252c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org}
253c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
254c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.orgvoid WebRtc_FreeDelayEstimator(void* handle) {
255c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
256c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
257c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (handle == NULL) {
258c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    return;
259c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
260c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
261c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  free(self->mean_near_spectrum);
262c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  self->mean_near_spectrum = NULL;
263c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
264c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
265c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  self->binary_handle = NULL;
266c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
267c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  free(self);
268c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org}
269c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
270b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.orgvoid* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead) {
271c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  DelayEstimator* self = NULL;
272c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle;
273c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
274c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (farend_handle != NULL) {
275c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    self = malloc(sizeof(DelayEstimator));
276c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  }
277c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
278c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  if (self != NULL) {
279c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    int memory_fail = 0;
280c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
281c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    // Allocate memory for the farend spectrum handling.
282c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    self->binary_handle =
283b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org        WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead);
284c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    memory_fail |= (self->binary_handle == NULL);
285c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
286c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    // Allocate memory for spectrum buffers.
287c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    self->mean_near_spectrum = malloc(farend->spectrum_size *
288c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org                                      sizeof(SpectrumType));
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memory_fail |= (self->mean_near_spectrum == NULL);
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
291c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org    self->spectrum_size = farend->spectrum_size;
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (memory_fail) {
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      WebRtc_FreeDelayEstimator(self);
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      self = NULL;
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return self;
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtc_InitDelayEstimator(void* handle) {
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (self == NULL) {
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Initialize binary delay estimator.
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  WebRtc_InitBinaryDelayEstimator(self->binary_handle);
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Set averaged far and near end spectra to zero.
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  memset(self->mean_near_spectrum, 0,
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org         sizeof(SpectrumType) * self->spectrum_size);
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Reset initialization indicators.
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  self->near_spectrum_initialized = 0;
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3211df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.orgint WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) {
3221df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
3231df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org  assert(self != NULL);
3241df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org  return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift);
3251df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org}
3261df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org
327b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.orgint WebRtc_set_lookahead(void* handle, int lookahead) {
328b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
329b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org  assert(self != NULL);
330b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org  assert(self->binary_handle != NULL);
331b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org  if ((lookahead > self->binary_handle->near_history_size - 1) ||
332b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org      (lookahead < 0)) {
333b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org    return -1;
334b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org  }
335b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org  self->binary_handle->lookahead = lookahead;
336b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org  return self->binary_handle->lookahead;
337b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org}
338b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org
3391df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.orgint WebRtc_lookahead(void* handle) {
3401df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
3411df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org  assert(self != NULL);
342b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org  assert(self->binary_handle != NULL);
3431df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org  return self->binary_handle->lookahead;
3441df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org}
3451df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org
3469b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.orgint WebRtc_set_allowed_offset(void* handle, int allowed_offset) {
3479b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
3489b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org
3499b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org  if ((self == NULL) || (allowed_offset < 0)) {
3509b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org    return -1;
3519b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org  }
3529b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org  self->binary_handle->allowed_offset = allowed_offset;
3539b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org  return 0;
3549b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org}
3559b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org
3569b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.orgint WebRtc_get_allowed_offset(const void* handle) {
3578d4f9cac87bb508f20715024affecce11df070dcbjornv@webrtc.org  const DelayEstimator* self = (const DelayEstimator*) handle;
3589b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org
3599b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org  if (self == NULL) {
3609b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org    return -1;
3619b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org  }
3629b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org  return self->binary_handle->allowed_offset;
3639b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org}
3649b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.org
365cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.orgint WebRtc_enable_robust_validation(void* handle, int enable) {
366cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
367cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org
368cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org  if (self == NULL) {
369cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org    return -1;
370cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org  }
371cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org  if ((enable < 0) || (enable > 1)) {
372cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org    return -1;
373cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org  }
374b5a182a9321ff847a24620c5e991e1749362549abjornv@webrtc.org  assert(self->binary_handle != NULL);
375cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org  self->binary_handle->robust_validation_enabled = enable;
376cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org  return 0;
377cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org}
378cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org
3799b125e1b0d1bf2cc646ab5f42ba650f62250eb4dbjornv@webrtc.orgint WebRtc_is_robust_validation_enabled(const void* handle) {
3808d4f9cac87bb508f20715024affecce11df070dcbjornv@webrtc.org  const DelayEstimator* self = (const DelayEstimator*) handle;
381cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org
382cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org  if (self == NULL) {
383cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org    return -1;
384cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org  }
385cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org  return self->binary_handle->robust_validation_enabled;
386cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org}
387cd8c2b1046b70c4cae288fc548c9787c6875a2d4bjornv@webrtc.org
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtc_DelayEstimatorProcessFix(void* handle,
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    uint16_t* near_spectrum,
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    int spectrum_size,
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    int near_q) {
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
393c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  uint32_t binary_spectrum = 0;
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (self == NULL) {
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (near_spectrum == NULL) {
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Empty near end spectrum.
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (spectrum_size != self->spectrum_size) {
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Data sizes don't match.
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (near_q > 15) {
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // If |near_q| is larger than 15 we cannot guarantee no wrap around.
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Get binary spectra.
412c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  binary_spectrum = BinarySpectrumFix(near_spectrum,
413c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org                                      self->mean_near_spectrum,
414c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org                                      near_q,
415c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org                                      &(self->near_spectrum_initialized));
416c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org
417c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtc_DelayEstimatorProcessFloat(void* handle,
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      float* near_spectrum,
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      int spectrum_size) {
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
424c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  uint32_t binary_spectrum = 0;
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (self == NULL) {
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (near_spectrum == NULL) {
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Empty near end spectrum.
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (spectrum_size != self->spectrum_size) {
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Data sizes don't match.
435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
438c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  // Get binary spectrum.
439c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  binary_spectrum = BinarySpectrumFloat(near_spectrum, self->mean_near_spectrum,
440c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org                                        &(self->near_spectrum_initialized));
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
442c7beae5a7f10192712a5d1a901f41a90f42daaffbjornv@webrtc.org  return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtc_last_delay(void* handle) {
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (self == NULL) {
449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return WebRtc_binary_last_delay(self->binary_handle);
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
454d9e4516726c76e3a570c12cd159527c31ce1b563bjornv@webrtc.org
4551df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.orgfloat WebRtc_last_delay_quality(void* handle) {
456d9e4516726c76e3a570c12cd159527c31ce1b563bjornv@webrtc.org  DelayEstimator* self = (DelayEstimator*) handle;
4571df7a5a60c35863a609155f931580a7367fff900bjornv@webrtc.org  assert(self != NULL);
458d9e4516726c76e3a570c12cd159527c31ce1b563bjornv@webrtc.org  return WebRtc_binary_last_delay_quality(self->binary_handle);
459d9e4516726c76e3a570c12cd159527c31ce1b563bjornv@webrtc.org}
460