1dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org/*
2dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org *
4dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org */
10dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org
11dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org// MSVC++ requires this to be set before any other includes to get M_PI.
12dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org#define _USE_MATH_DEFINES
13dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org
14dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org#include "webrtc/common_audio/resampler/sinusoidal_linear_chirp_source.h"
15dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org
163f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <math.h>
17dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org
18dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.orgnamespace webrtc {
19dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org
20dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.orgSinusoidalLinearChirpSource::SinusoidalLinearChirpSource(int sample_rate,
21dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org  int samples, double max_frequency, double delay_samples)
22dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org    : sample_rate_(sample_rate),
23dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      total_samples_(samples),
24dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      max_frequency_(max_frequency),
25dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      current_index_(0),
26dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      delay_samples_(delay_samples) {
27dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org  // Chirp rate.
28dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org  double duration = static_cast<double>(total_samples_) / sample_rate_;
29dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org  k_ = (max_frequency_ - kMinFrequency) / duration;
30dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org}
31dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org
3205f213189c0247a6e3ac82e1f39ef1db606cbba3andrew@webrtc.orgvoid SinusoidalLinearChirpSource::Run(int frames, float* destination) {
33dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org  for (int i = 0; i < frames; ++i, ++current_index_) {
34dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org    // Filter out frequencies higher than Nyquist.
35dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org    if (Frequency(current_index_) > 0.5 * sample_rate_) {
36dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      destination[i] = 0;
37dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org    } else {
38dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      // Calculate time in seconds.
39dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      double t = (static_cast<double>(current_index_) - delay_samples_) /
40dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org          sample_rate_;
41dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      if (t < 0) {
42dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org        destination[i] = 0;
43dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      } else {
44dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org        // Sinusoidal linear chirp.
45dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org        destination[i] =
46dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org            sin(2 * M_PI * (kMinFrequency * t + (k_ / 2) * t * t));
47dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      }
48dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org    }
49dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org  }
50dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org}
51dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org
52dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.orgdouble SinusoidalLinearChirpSource::Frequency(int position) {
53dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org  return kMinFrequency + (position - delay_samples_) *
54dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org      (max_frequency_ - kMinFrequency) / total_samples_;
55dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org}
56dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org
57dea537b43c923bd1176d8a9302fedc8ff1dadf7aandrew@webrtc.org}  // namespace webrtc
58