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