Home | History | Annotate | Download | only in audio
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 // MSVC++ requires this to be set before any other includes to get M_PI.
      5 #define _USE_MATH_DEFINES
      6 #include <cmath>
      7 
      8 #include "media/audio/simple_sources.h"
      9 
     10 #include <algorithm>
     11 
     12 #include "base/logging.h"
     13 
     14 namespace media {
     15 
     16 //////////////////////////////////////////////////////////////////////////////
     17 // SineWaveAudioSource implementation.
     18 
     19 SineWaveAudioSource::SineWaveAudioSource(int channels,
     20                                          double freq, double sample_freq)
     21     : channels_(channels),
     22       f_(freq / sample_freq),
     23       time_state_(0),
     24       cap_(0),
     25       callbacks_(0),
     26       errors_(0) {
     27 }
     28 
     29 // The implementation could be more efficient if a lookup table is constructed
     30 // but it is efficient enough for our simple needs.
     31 int SineWaveAudioSource::OnMoreData(AudioBus* audio_bus,
     32                                     AudioBuffersState audio_buffers) {
     33   base::AutoLock auto_lock(time_lock_);
     34   callbacks_++;
     35 
     36   // The table is filled with s(t) = kint16max*sin(Theta*t),
     37   // where Theta = 2*PI*fs.
     38   // We store the discrete time value |t| in a member to ensure that the
     39   // next pass starts at a correct state.
     40   int max_frames = cap_ > 0 ?
     41       std::min(audio_bus->frames(), cap_ - time_state_) : audio_bus->frames();
     42   for (int i = 0; i < max_frames; ++i)
     43     audio_bus->channel(0)[i] = sin(2.0 * M_PI * f_ * time_state_++);
     44   for (int i = 1; i < audio_bus->channels(); ++i) {
     45     memcpy(audio_bus->channel(i), audio_bus->channel(0),
     46            max_frames * sizeof(*audio_bus->channel(i)));
     47   }
     48   return max_frames;
     49 }
     50 
     51 void SineWaveAudioSource::OnError(AudioOutputStream* stream) {
     52   errors_++;
     53 }
     54 
     55 void SineWaveAudioSource::CapSamples(int cap) {
     56   base::AutoLock auto_lock(time_lock_);
     57   DCHECK_GT(cap, 0);
     58   cap_ = cap;
     59 }
     60 
     61 void SineWaveAudioSource::Reset() {
     62   base::AutoLock auto_lock(time_lock_);
     63   time_state_ = 0;
     64 }
     65 
     66 }  // namespace media
     67