1c55a96383497a772a307b346368133960b02ad03Eric Laurent/*
2c55a96383497a772a307b346368133960b02ad03Eric Laurent *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3c55a96383497a772a307b346368133960b02ad03Eric Laurent *
4c55a96383497a772a307b346368133960b02ad03Eric Laurent *  Use of this source code is governed by a BSD-style license
5c55a96383497a772a307b346368133960b02ad03Eric Laurent *  that can be found in the LICENSE file in the root of the source
6c55a96383497a772a307b346368133960b02ad03Eric Laurent *  tree. An additional intellectual property rights grant can be found
7c55a96383497a772a307b346368133960b02ad03Eric Laurent *  in the file PATENTS.  All contributing project authors may
8c55a96383497a772a307b346368133960b02ad03Eric Laurent *  be found in the AUTHORS file in the root of the source tree.
9c55a96383497a772a307b346368133960b02ad03Eric Laurent */
10c55a96383497a772a307b346368133960b02ad03Eric Laurent
11c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "delay_estimator_wrapper.h"
12c55a96383497a772a307b346368133960b02ad03Eric Laurent
13c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <assert.h>
14c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <stdlib.h>
15c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <string.h>
16c55a96383497a772a307b346368133960b02ad03Eric Laurent
17c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "delay_estimator.h"
18c55a96383497a772a307b346368133960b02ad03Eric Laurent
19c55a96383497a772a307b346368133960b02ad03Eric Laurenttypedef union {
20c55a96383497a772a307b346368133960b02ad03Eric Laurent  float float_;
21c55a96383497a772a307b346368133960b02ad03Eric Laurent  int32_t int32_;
22c55a96383497a772a307b346368133960b02ad03Eric Laurent} SpectrumType;
23c55a96383497a772a307b346368133960b02ad03Eric Laurent
24c55a96383497a772a307b346368133960b02ad03Eric Laurenttypedef struct {
25c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Pointers to mean values of spectrum.
26c55a96383497a772a307b346368133960b02ad03Eric Laurent  SpectrumType* mean_far_spectrum;
27c55a96383497a772a307b346368133960b02ad03Eric Laurent  SpectrumType* mean_near_spectrum;
28c55a96383497a772a307b346368133960b02ad03Eric Laurent  // |mean_*_spectrum| initialization indicator.
29c55a96383497a772a307b346368133960b02ad03Eric Laurent  int far_spectrum_initialized;
30c55a96383497a772a307b346368133960b02ad03Eric Laurent  int near_spectrum_initialized;
31c55a96383497a772a307b346368133960b02ad03Eric Laurent
32c55a96383497a772a307b346368133960b02ad03Eric Laurent  int spectrum_size;
33c55a96383497a772a307b346368133960b02ad03Eric Laurent
34c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Binary spectrum based delay estimator
35c55a96383497a772a307b346368133960b02ad03Eric Laurent  BinaryDelayEstimator* binary_handle;
36c55a96383497a772a307b346368133960b02ad03Eric Laurent} DelayEstimator;
37c55a96383497a772a307b346368133960b02ad03Eric Laurent
38c55a96383497a772a307b346368133960b02ad03Eric Laurent// Only bit |kBandFirst| through bit |kBandLast| are processed and
39c55a96383497a772a307b346368133960b02ad03Eric Laurent// |kBandFirst| - |kBandLast| must be < 32.
40c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic const int kBandFirst = 12;
41c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic const int kBandLast = 43;
42c55a96383497a772a307b346368133960b02ad03Eric Laurent
43c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic __inline uint32_t SetBit(uint32_t in, int pos) {
44c55a96383497a772a307b346368133960b02ad03Eric Laurent  uint32_t mask = (1 << pos);
45c55a96383497a772a307b346368133960b02ad03Eric Laurent  uint32_t out = (in | mask);
46c55a96383497a772a307b346368133960b02ad03Eric Laurent
47c55a96383497a772a307b346368133960b02ad03Eric Laurent  return out;
48c55a96383497a772a307b346368133960b02ad03Eric Laurent}
49c55a96383497a772a307b346368133960b02ad03Eric Laurent
50c55a96383497a772a307b346368133960b02ad03Eric Laurent// Calculates the mean recursively. Same version as WebRtc_MeanEstimatorFix(),
51c55a96383497a772a307b346368133960b02ad03Eric Laurent// but for float.
52c55a96383497a772a307b346368133960b02ad03Eric Laurent//
53c55a96383497a772a307b346368133960b02ad03Eric Laurent// Inputs:
54c55a96383497a772a307b346368133960b02ad03Eric Laurent//    - new_value             : New additional value.
55c55a96383497a772a307b346368133960b02ad03Eric Laurent//    - scale                 : Scale for smoothing (should be less than 1.0).
56c55a96383497a772a307b346368133960b02ad03Eric Laurent//
57c55a96383497a772a307b346368133960b02ad03Eric Laurent// Input/Output:
58c55a96383497a772a307b346368133960b02ad03Eric Laurent//    - mean_value            : Pointer to the mean value for updating.
59c55a96383497a772a307b346368133960b02ad03Eric Laurent//
60c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic void MeanEstimatorFloat(float new_value,
61c55a96383497a772a307b346368133960b02ad03Eric Laurent                               float scale,
62c55a96383497a772a307b346368133960b02ad03Eric Laurent                               float* mean_value) {
63c55a96383497a772a307b346368133960b02ad03Eric Laurent  assert(scale < 1.0f);
64c55a96383497a772a307b346368133960b02ad03Eric Laurent  *mean_value += (new_value - *mean_value) * scale;
65c55a96383497a772a307b346368133960b02ad03Eric Laurent}
66c55a96383497a772a307b346368133960b02ad03Eric Laurent
67c55a96383497a772a307b346368133960b02ad03Eric Laurent// Computes the binary spectrum by comparing the input |spectrum| with a
68c55a96383497a772a307b346368133960b02ad03Eric Laurent// |threshold_spectrum|. Float and fixed point versions.
69c55a96383497a772a307b346368133960b02ad03Eric Laurent//
70c55a96383497a772a307b346368133960b02ad03Eric Laurent// Inputs:
71c55a96383497a772a307b346368133960b02ad03Eric Laurent//      - spectrum            : Spectrum of which the binary spectrum should be
72c55a96383497a772a307b346368133960b02ad03Eric Laurent//                              calculated.
73c55a96383497a772a307b346368133960b02ad03Eric Laurent//      - threshold_spectrum  : Threshold spectrum with which the input
74c55a96383497a772a307b346368133960b02ad03Eric Laurent//                              spectrum is compared.
75c55a96383497a772a307b346368133960b02ad03Eric Laurent// Return:
76c55a96383497a772a307b346368133960b02ad03Eric Laurent//      - out                 : Binary spectrum.
77c55a96383497a772a307b346368133960b02ad03Eric Laurent//
78c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic uint32_t BinarySpectrumFix(uint16_t* spectrum,
79c55a96383497a772a307b346368133960b02ad03Eric Laurent                                  SpectrumType* threshold_spectrum,
80c55a96383497a772a307b346368133960b02ad03Eric Laurent                                  int q_domain,
81c55a96383497a772a307b346368133960b02ad03Eric Laurent                                  int* threshold_initialized) {
82c55a96383497a772a307b346368133960b02ad03Eric Laurent  int i = kBandFirst;
83c55a96383497a772a307b346368133960b02ad03Eric Laurent  uint32_t out = 0;
84c55a96383497a772a307b346368133960b02ad03Eric Laurent
85c55a96383497a772a307b346368133960b02ad03Eric Laurent  assert(q_domain < 16);
86c55a96383497a772a307b346368133960b02ad03Eric Laurent
87c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(*threshold_initialized)) {
88c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Set the |threshold_spectrum| to half the input |spectrum| as starting
89c55a96383497a772a307b346368133960b02ad03Eric Laurent    // value. This speeds up the convergence.
90c55a96383497a772a307b346368133960b02ad03Eric Laurent    for (i = kBandFirst; i <= kBandLast; i++) {
91c55a96383497a772a307b346368133960b02ad03Eric Laurent      if (spectrum[i] > 0) {
92c55a96383497a772a307b346368133960b02ad03Eric Laurent        // Convert input spectrum from Q(|q_domain|) to Q15.
93c55a96383497a772a307b346368133960b02ad03Eric Laurent        int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
94c55a96383497a772a307b346368133960b02ad03Eric Laurent        threshold_spectrum[i].int32_ = (spectrum_q15 >> 1);
95c55a96383497a772a307b346368133960b02ad03Eric Laurent        *threshold_initialized = 1;
96c55a96383497a772a307b346368133960b02ad03Eric Laurent      }
97c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
98c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
99c55a96383497a772a307b346368133960b02ad03Eric Laurent  for (i = kBandFirst; i <= kBandLast; i++) {
100c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Convert input spectrum from Q(|q_domain|) to Q15.
101c55a96383497a772a307b346368133960b02ad03Eric Laurent    int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
102c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Update the |threshold_spectrum|.
103c55a96383497a772a307b346368133960b02ad03Eric Laurent    WebRtc_MeanEstimatorFix(spectrum_q15, 6, &(threshold_spectrum[i].int32_));
104c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Convert |spectrum| at current frequency bin to a binary value.
105c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (spectrum_q15 > threshold_spectrum[i].int32_) {
106c55a96383497a772a307b346368133960b02ad03Eric Laurent      out = SetBit(out, i - kBandFirst);
107c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
108c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
109c55a96383497a772a307b346368133960b02ad03Eric Laurent
110c55a96383497a772a307b346368133960b02ad03Eric Laurent  return out;
111c55a96383497a772a307b346368133960b02ad03Eric Laurent}
112c55a96383497a772a307b346368133960b02ad03Eric Laurent
113c55a96383497a772a307b346368133960b02ad03Eric Laurentstatic uint32_t BinarySpectrumFloat(float* spectrum,
114c55a96383497a772a307b346368133960b02ad03Eric Laurent                                    SpectrumType* threshold_spectrum,
115c55a96383497a772a307b346368133960b02ad03Eric Laurent                                    int* threshold_initialized) {
116c55a96383497a772a307b346368133960b02ad03Eric Laurent  int i = kBandFirst;
117c55a96383497a772a307b346368133960b02ad03Eric Laurent  uint32_t out = 0;
118c55a96383497a772a307b346368133960b02ad03Eric Laurent  const float kScale = 1 / 64.0;
119c55a96383497a772a307b346368133960b02ad03Eric Laurent
120c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (!(*threshold_initialized)) {
121c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Set the |threshold_spectrum| to half the input |spectrum| as starting
122c55a96383497a772a307b346368133960b02ad03Eric Laurent    // value. This speeds up the convergence.
123c55a96383497a772a307b346368133960b02ad03Eric Laurent    for (i = kBandFirst; i <= kBandLast; i++) {
124c55a96383497a772a307b346368133960b02ad03Eric Laurent      if (spectrum[i] > 0.0f) {
125c55a96383497a772a307b346368133960b02ad03Eric Laurent        threshold_spectrum[i].float_ = (spectrum[i] / 2);
126c55a96383497a772a307b346368133960b02ad03Eric Laurent        *threshold_initialized = 1;
127c55a96383497a772a307b346368133960b02ad03Eric Laurent      }
128c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
129c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
130c55a96383497a772a307b346368133960b02ad03Eric Laurent
131c55a96383497a772a307b346368133960b02ad03Eric Laurent  for (i = kBandFirst; i <= kBandLast; i++) {
132c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Update the |threshold_spectrum|.
133c55a96383497a772a307b346368133960b02ad03Eric Laurent    MeanEstimatorFloat(spectrum[i], kScale, &(threshold_spectrum[i].float_));
134c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Convert |spectrum| at current frequency bin to a binary value.
135c55a96383497a772a307b346368133960b02ad03Eric Laurent    if (spectrum[i] > threshold_spectrum[i].float_) {
136c55a96383497a772a307b346368133960b02ad03Eric Laurent      out = SetBit(out, i - kBandFirst);
137c55a96383497a772a307b346368133960b02ad03Eric Laurent    }
138c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
139c55a96383497a772a307b346368133960b02ad03Eric Laurent
140c55a96383497a772a307b346368133960b02ad03Eric Laurent  return out;
141c55a96383497a772a307b346368133960b02ad03Eric Laurent}
142c55a96383497a772a307b346368133960b02ad03Eric Laurent
143c55a96383497a772a307b346368133960b02ad03Eric Laurentint WebRtc_FreeDelayEstimator(void* handle) {
144c55a96383497a772a307b346368133960b02ad03Eric Laurent  DelayEstimator* self = (DelayEstimator*) handle;
145c55a96383497a772a307b346368133960b02ad03Eric Laurent
146c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self == NULL) {
147c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
148c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
149c55a96383497a772a307b346368133960b02ad03Eric Laurent
150c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self->mean_far_spectrum != NULL) {
151c55a96383497a772a307b346368133960b02ad03Eric Laurent    free(self->mean_far_spectrum);
152c55a96383497a772a307b346368133960b02ad03Eric Laurent    self->mean_far_spectrum = NULL;
153c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
154c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self->mean_near_spectrum != NULL) {
155c55a96383497a772a307b346368133960b02ad03Eric Laurent    free(self->mean_near_spectrum);
156c55a96383497a772a307b346368133960b02ad03Eric Laurent    self->mean_near_spectrum = NULL;
157c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
158c55a96383497a772a307b346368133960b02ad03Eric Laurent
159c55a96383497a772a307b346368133960b02ad03Eric Laurent  WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
160c55a96383497a772a307b346368133960b02ad03Eric Laurent
161c55a96383497a772a307b346368133960b02ad03Eric Laurent  free(self);
162c55a96383497a772a307b346368133960b02ad03Eric Laurent
163c55a96383497a772a307b346368133960b02ad03Eric Laurent  return 0;
164c55a96383497a772a307b346368133960b02ad03Eric Laurent}
165c55a96383497a772a307b346368133960b02ad03Eric Laurent
166c55a96383497a772a307b346368133960b02ad03Eric Laurentint WebRtc_CreateDelayEstimator(void** handle,
167c55a96383497a772a307b346368133960b02ad03Eric Laurent                                int spectrum_size,
168c55a96383497a772a307b346368133960b02ad03Eric Laurent                                int max_delay,
169c55a96383497a772a307b346368133960b02ad03Eric Laurent                                int lookahead) {
170c55a96383497a772a307b346368133960b02ad03Eric Laurent  DelayEstimator* self = NULL;
171c55a96383497a772a307b346368133960b02ad03Eric Laurent
172c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Check if the sub band used in the delay estimation is small enough to fit
173c55a96383497a772a307b346368133960b02ad03Eric Laurent  // the binary spectra in a uint32_t.
174c55a96383497a772a307b346368133960b02ad03Eric Laurent  assert(kBandLast - kBandFirst < 32);
175c55a96383497a772a307b346368133960b02ad03Eric Laurent
176c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (handle == NULL) {
177c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
178c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
179c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (spectrum_size < kBandLast) {
180c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
181c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
182c55a96383497a772a307b346368133960b02ad03Eric Laurent
183c55a96383497a772a307b346368133960b02ad03Eric Laurent  self = malloc(sizeof(DelayEstimator));
184c55a96383497a772a307b346368133960b02ad03Eric Laurent  *handle = self;
185c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self == NULL) {
186c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
187c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
188c55a96383497a772a307b346368133960b02ad03Eric Laurent
189c55a96383497a772a307b346368133960b02ad03Eric Laurent  self->mean_far_spectrum = NULL;
190c55a96383497a772a307b346368133960b02ad03Eric Laurent  self->mean_near_spectrum = NULL;
191c55a96383497a772a307b346368133960b02ad03Eric Laurent
192c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Create binary delay estimator.
193c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (WebRtc_CreateBinaryDelayEstimator(&self->binary_handle,
194c55a96383497a772a307b346368133960b02ad03Eric Laurent                                        max_delay,
195c55a96383497a772a307b346368133960b02ad03Eric Laurent                                        lookahead) != 0) {
196c55a96383497a772a307b346368133960b02ad03Eric Laurent    WebRtc_FreeDelayEstimator(self);
197c55a96383497a772a307b346368133960b02ad03Eric Laurent    self = NULL;
198c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
199c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
200c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Allocate memory for spectrum buffers.
201c55a96383497a772a307b346368133960b02ad03Eric Laurent  self->mean_far_spectrum = malloc(spectrum_size * sizeof(SpectrumType));
202c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self->mean_far_spectrum == NULL) {
203c55a96383497a772a307b346368133960b02ad03Eric Laurent    WebRtc_FreeDelayEstimator(self);
204c55a96383497a772a307b346368133960b02ad03Eric Laurent    self = NULL;
205c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
206c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
207c55a96383497a772a307b346368133960b02ad03Eric Laurent  self->mean_near_spectrum = malloc(spectrum_size * sizeof(SpectrumType));
208c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self->mean_near_spectrum == NULL) {
209c55a96383497a772a307b346368133960b02ad03Eric Laurent    WebRtc_FreeDelayEstimator(self);
210c55a96383497a772a307b346368133960b02ad03Eric Laurent    self = NULL;
211c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
212c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
213c55a96383497a772a307b346368133960b02ad03Eric Laurent
214c55a96383497a772a307b346368133960b02ad03Eric Laurent  self->spectrum_size = spectrum_size;
215c55a96383497a772a307b346368133960b02ad03Eric Laurent
216c55a96383497a772a307b346368133960b02ad03Eric Laurent  return 0;
217c55a96383497a772a307b346368133960b02ad03Eric Laurent}
218c55a96383497a772a307b346368133960b02ad03Eric Laurent
219c55a96383497a772a307b346368133960b02ad03Eric Laurentint WebRtc_InitDelayEstimator(void* handle) {
220c55a96383497a772a307b346368133960b02ad03Eric Laurent  DelayEstimator* self = (DelayEstimator*) handle;
221c55a96383497a772a307b346368133960b02ad03Eric Laurent
222c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self == NULL) {
223c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
224c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
225c55a96383497a772a307b346368133960b02ad03Eric Laurent
226c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Initialize binary delay estimator.
227c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (WebRtc_InitBinaryDelayEstimator(self->binary_handle) != 0) {
228c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
229c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
230c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Set averaged far and near end spectra to zero.
231c55a96383497a772a307b346368133960b02ad03Eric Laurent  memset(self->mean_far_spectrum, 0,
232c55a96383497a772a307b346368133960b02ad03Eric Laurent         sizeof(SpectrumType) * self->spectrum_size);
233c55a96383497a772a307b346368133960b02ad03Eric Laurent  memset(self->mean_near_spectrum, 0,
234c55a96383497a772a307b346368133960b02ad03Eric Laurent         sizeof(SpectrumType) * self->spectrum_size);
235c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Reset initialization indicators.
236c55a96383497a772a307b346368133960b02ad03Eric Laurent  self->far_spectrum_initialized = 0;
237c55a96383497a772a307b346368133960b02ad03Eric Laurent  self->near_spectrum_initialized = 0;
238c55a96383497a772a307b346368133960b02ad03Eric Laurent
239c55a96383497a772a307b346368133960b02ad03Eric Laurent  return 0;
240c55a96383497a772a307b346368133960b02ad03Eric Laurent}
241c55a96383497a772a307b346368133960b02ad03Eric Laurent
242c55a96383497a772a307b346368133960b02ad03Eric Laurentint WebRtc_DelayEstimatorProcessFix(void* handle,
243c55a96383497a772a307b346368133960b02ad03Eric Laurent                                    uint16_t* far_spectrum,
244c55a96383497a772a307b346368133960b02ad03Eric Laurent                                    uint16_t* near_spectrum,
245c55a96383497a772a307b346368133960b02ad03Eric Laurent                                    int spectrum_size,
246c55a96383497a772a307b346368133960b02ad03Eric Laurent                                    int far_q,
247c55a96383497a772a307b346368133960b02ad03Eric Laurent                                    int near_q) {
248c55a96383497a772a307b346368133960b02ad03Eric Laurent  DelayEstimator* self = (DelayEstimator*) handle;
249c55a96383497a772a307b346368133960b02ad03Eric Laurent  uint32_t binary_far_spectrum = 0;
250c55a96383497a772a307b346368133960b02ad03Eric Laurent  uint32_t binary_near_spectrum = 0;
251c55a96383497a772a307b346368133960b02ad03Eric Laurent
252c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self == NULL) {
253c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
254c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
255c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (far_spectrum == NULL) {
256c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Empty far end spectrum.
257c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
258c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
259c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (near_spectrum == NULL) {
260c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Empty near end spectrum.
261c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
262c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
263c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (spectrum_size != self->spectrum_size) {
264c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Data sizes don't match.
265c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
266c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
267c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (far_q > 15) {
268c55a96383497a772a307b346368133960b02ad03Eric Laurent    // If |far_q| is larger than 15 we cannot guarantee no wrap around.
269c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
270c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
271c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (near_q > 15) {
272c55a96383497a772a307b346368133960b02ad03Eric Laurent    // If |near_q| is larger than 15 we cannot guarantee no wrap around.
273c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
274c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
275c55a96383497a772a307b346368133960b02ad03Eric Laurent
276c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Get binary spectra.
277c55a96383497a772a307b346368133960b02ad03Eric Laurent  binary_far_spectrum = BinarySpectrumFix(far_spectrum,
278c55a96383497a772a307b346368133960b02ad03Eric Laurent                                          self->mean_far_spectrum,
279c55a96383497a772a307b346368133960b02ad03Eric Laurent                                          far_q,
280c55a96383497a772a307b346368133960b02ad03Eric Laurent                                          &(self->far_spectrum_initialized));
281c55a96383497a772a307b346368133960b02ad03Eric Laurent  binary_near_spectrum = BinarySpectrumFix(near_spectrum,
282c55a96383497a772a307b346368133960b02ad03Eric Laurent                                           self->mean_near_spectrum,
283c55a96383497a772a307b346368133960b02ad03Eric Laurent                                           near_q,
284c55a96383497a772a307b346368133960b02ad03Eric Laurent                                           &(self->near_spectrum_initialized));
285c55a96383497a772a307b346368133960b02ad03Eric Laurent
286c55a96383497a772a307b346368133960b02ad03Eric Laurent  return WebRtc_ProcessBinarySpectrum(self->binary_handle,
287c55a96383497a772a307b346368133960b02ad03Eric Laurent                                      binary_far_spectrum,
288c55a96383497a772a307b346368133960b02ad03Eric Laurent                                      binary_near_spectrum);
289c55a96383497a772a307b346368133960b02ad03Eric Laurent}
290c55a96383497a772a307b346368133960b02ad03Eric Laurent
291c55a96383497a772a307b346368133960b02ad03Eric Laurentint WebRtc_DelayEstimatorProcessFloat(void* handle,
292c55a96383497a772a307b346368133960b02ad03Eric Laurent                                      float* far_spectrum,
293c55a96383497a772a307b346368133960b02ad03Eric Laurent                                      float* near_spectrum,
294c55a96383497a772a307b346368133960b02ad03Eric Laurent                                      int spectrum_size) {
295c55a96383497a772a307b346368133960b02ad03Eric Laurent  DelayEstimator* self = (DelayEstimator*) handle;
296c55a96383497a772a307b346368133960b02ad03Eric Laurent  uint32_t binary_far_spectrum = 0;
297c55a96383497a772a307b346368133960b02ad03Eric Laurent  uint32_t binary_near_spectrum = 0;
298c55a96383497a772a307b346368133960b02ad03Eric Laurent
299c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self == NULL) {
300c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
301c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
302c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (far_spectrum == NULL) {
303c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Empty far end spectrum.
304c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
305c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
306c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (near_spectrum == NULL) {
307c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Empty near end spectrum.
308c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
309c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
310c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (spectrum_size != self->spectrum_size) {
311c55a96383497a772a307b346368133960b02ad03Eric Laurent    // Data sizes don't match.
312c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
313c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
314c55a96383497a772a307b346368133960b02ad03Eric Laurent
315c55a96383497a772a307b346368133960b02ad03Eric Laurent  // Get binary spectra.
316c55a96383497a772a307b346368133960b02ad03Eric Laurent  binary_far_spectrum = BinarySpectrumFloat(far_spectrum,
317c55a96383497a772a307b346368133960b02ad03Eric Laurent                                            self->mean_far_spectrum,
318c55a96383497a772a307b346368133960b02ad03Eric Laurent                                            &(self->far_spectrum_initialized));
319c55a96383497a772a307b346368133960b02ad03Eric Laurent  binary_near_spectrum = BinarySpectrumFloat(near_spectrum,
320c55a96383497a772a307b346368133960b02ad03Eric Laurent                                             self->mean_near_spectrum,
321c55a96383497a772a307b346368133960b02ad03Eric Laurent                                             &(self->near_spectrum_initialized));
322c55a96383497a772a307b346368133960b02ad03Eric Laurent
323c55a96383497a772a307b346368133960b02ad03Eric Laurent  return WebRtc_ProcessBinarySpectrum(self->binary_handle,
324c55a96383497a772a307b346368133960b02ad03Eric Laurent                                      binary_far_spectrum,
325c55a96383497a772a307b346368133960b02ad03Eric Laurent                                      binary_near_spectrum);
326c55a96383497a772a307b346368133960b02ad03Eric Laurent}
327c55a96383497a772a307b346368133960b02ad03Eric Laurent
328c55a96383497a772a307b346368133960b02ad03Eric Laurentint WebRtc_last_delay(void* handle) {
329c55a96383497a772a307b346368133960b02ad03Eric Laurent  DelayEstimator* self = (DelayEstimator*) handle;
330c55a96383497a772a307b346368133960b02ad03Eric Laurent
331c55a96383497a772a307b346368133960b02ad03Eric Laurent  if (self == NULL) {
332c55a96383497a772a307b346368133960b02ad03Eric Laurent    return -1;
333c55a96383497a772a307b346368133960b02ad03Eric Laurent  }
334c55a96383497a772a307b346368133960b02ad03Eric Laurent
335c55a96383497a772a307b346368133960b02ad03Eric Laurent  return WebRtc_binary_last_delay(self->binary_handle);
336c55a96383497a772a307b346368133960b02ad03Eric Laurent}
337