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