simple_sources.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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
14namespace media {
15
16//////////////////////////////////////////////////////////////////////////////
17// SineWaveAudioSource implementation.
18
19SineWaveAudioSource::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.
31int 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
51void SineWaveAudioSource::OnError(AudioOutputStream* stream) {
52  errors_++;
53}
54
55void SineWaveAudioSource::CapSamples(int cap) {
56  base::AutoLock auto_lock(time_lock_);
57  DCHECK_GT(cap, 0);
58  cap_ = cap;
59}
60
61void SineWaveAudioSource::Reset() {
62  base::AutoLock auto_lock(time_lock_);
63  time_state_ = 0;
64}
65
66}  // namespace media
67