// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // MSVC++ requires this to be set before any other includes to get M_PI. #define _USE_MATH_DEFINES #include #include "media/audio/simple_sources.h" #include #include "base/logging.h" namespace media { ////////////////////////////////////////////////////////////////////////////// // SineWaveAudioSource implementation. SineWaveAudioSource::SineWaveAudioSource(int channels, double freq, double sample_freq) : channels_(channels), f_(freq / sample_freq), time_state_(0), cap_(0), callbacks_(0), errors_(0) { } // The implementation could be more efficient if a lookup table is constructed // but it is efficient enough for our simple needs. int SineWaveAudioSource::OnMoreData(AudioBus* audio_bus, AudioBuffersState audio_buffers) { base::AutoLock auto_lock(time_lock_); callbacks_++; // The table is filled with s(t) = kint16max*sin(Theta*t), // where Theta = 2*PI*fs. // We store the discrete time value |t| in a member to ensure that the // next pass starts at a correct state. int max_frames = cap_ > 0 ? std::min(audio_bus->frames(), cap_ - time_state_) : audio_bus->frames(); for (int i = 0; i < max_frames; ++i) audio_bus->channel(0)[i] = sin(2.0 * M_PI * f_ * time_state_++); for (int i = 1; i < audio_bus->channels(); ++i) { memcpy(audio_bus->channel(i), audio_bus->channel(0), max_frames * sizeof(*audio_bus->channel(i))); } return max_frames; } int SineWaveAudioSource::OnMoreIOData(AudioBus* source, AudioBus* dest, AudioBuffersState audio_buffers) { return OnMoreData(dest, audio_buffers); } void SineWaveAudioSource::OnError(AudioOutputStream* stream) { errors_++; } void SineWaveAudioSource::CapSamples(int cap) { base::AutoLock auto_lock(time_lock_); DCHECK_GT(cap, 0); cap_ = cap; } void SineWaveAudioSource::Reset() { base::AutoLock auto_lock(time_lock_); time_state_ = 0; } } // namespace media