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 #include "media/audio/audio_util.h"
     14 
     15 namespace media {
     16 
     17 //////////////////////////////////////////////////////////////////////////////
     18 // SineWaveAudioSource implementation.
     19 
     20 SineWaveAudioSource::SineWaveAudioSource(int channels,
     21                                          double freq, double sample_freq)
     22     : channels_(channels),
     23       f_(freq / sample_freq),
     24       time_state_(0),
     25       cap_(0),
     26       callbacks_(0),
     27       errors_(0) {
     28 }
     29 
     30 // The implementation could be more efficient if a lookup table is constructed
     31 // but it is efficient enough for our simple needs.
     32 int SineWaveAudioSource::OnMoreData(AudioBus* audio_bus,
     33                                     AudioBuffersState audio_buffers) {
     34   base::AutoLock auto_lock(time_lock_);
     35   callbacks_++;
     36 
     37   // The table is filled with s(t) = kint16max*sin(Theta*t),
     38   // where Theta = 2*PI*fs.
     39   // We store the discrete time value |t| in a member to ensure that the
     40   // next pass starts at a correct state.
     41   int max_frames = cap_ > 0 ?
     42       std::min(audio_bus->frames(), cap_ - time_state_) : audio_bus->frames();
     43   for (int i = 0; i < max_frames; ++i)
     44     audio_bus->channel(0)[i] = sin(2.0 * M_PI * f_ * time_state_++);
     45   for (int i = 1; i < audio_bus->channels(); ++i) {
     46     memcpy(audio_bus->channel(i), audio_bus->channel(0),
     47            max_frames * sizeof(*audio_bus->channel(i)));
     48   }
     49   return max_frames;
     50 }
     51 
     52 int SineWaveAudioSource::OnMoreIOData(AudioBus* source,
     53                                       AudioBus* dest,
     54                                       AudioBuffersState audio_buffers) {
     55   return OnMoreData(dest, audio_buffers);
     56 }
     57 
     58 void SineWaveAudioSource::OnError(AudioOutputStream* stream) {
     59   errors_++;
     60 }
     61 
     62 void SineWaveAudioSource::CapSamples(int cap) {
     63   base::AutoLock auto_lock(time_lock_);
     64   DCHECK_GT(cap, 0);
     65   cap_ = cap;
     66 }
     67 
     68 void SineWaveAudioSource::Reset() {
     69   base::AutoLock auto_lock(time_lock_);
     70   time_state_ = 0;
     71 }
     72 
     73 }  // namespace media
     74