summaryrefslogtreecommitdiffstats
path: root/media/audio
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-21 02:50:38 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-21 02:50:38 +0000
commit938ecf4550bd9011cf006a1f0239b3c786304bac (patch)
tree423a1f648dd14f734705ea76a2f908a5ea00f289 /media/audio
parentc137292f1790329b838e857135dac7fe80f504cf (diff)
downloadchromium_src-938ecf4550bd9011cf006a1f0239b3c786304bac.zip
chromium_src-938ecf4550bd9011cf006a1f0239b3c786304bac.tar.gz
chromium_src-938ecf4550bd9011cf006a1f0239b3c786304bac.tar.bz2
Revert r21137 to fix Chromium mac valgrind
TBR=scherkus Review URL: http://codereview.chromium.org/159122 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21154 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio')
-rw-r--r--media/audio/audio_output.h14
-rw-r--r--media/audio/fake_audio_output_stream.cc72
-rw-r--r--media/audio/fake_audio_output_stream.h50
-rw-r--r--media/audio/linux/alsa_output.cc4
-rw-r--r--media/audio/linux/alsa_output.h1
-rw-r--r--media/audio/linux/audio_manager_linux.cc21
-rw-r--r--media/audio/linux/audio_manager_linux.h1
-rw-r--r--media/audio/mac/audio_manager_mac.cc16
-rw-r--r--media/audio/mac/audio_manager_mac.h1
-rw-r--r--media/audio/mac/audio_output_mac.cc4
-rw-r--r--media/audio/mac/audio_output_mac.h1
-rw-r--r--media/audio/simple_sources_unittest.cc46
-rw-r--r--media/audio/win/audio_manager_win.h3
-rw-r--r--media/audio/win/audio_output_win.cc94
-rw-r--r--media/audio/win/audio_output_win_unittest.cc45
-rw-r--r--media/audio/win/waveout_output_win.cc4
-rw-r--r--media/audio/win/waveout_output_win.h1
17 files changed, 190 insertions, 188 deletions
diff --git a/media/audio/audio_output.h b/media/audio/audio_output.h
index a12742e..4793e71 100644
--- a/media/audio/audio_output.h
+++ b/media/audio/audio_output.h
@@ -91,7 +91,9 @@ class AudioOutputStream {
// Starts playing audio and generating AudioSourceCallback::OnMoreData().
// Since implementor of AudioOutputStream may have internal buffers, right
- // after calling this method initial buffers are fetched.
+ // after calling this method initial buffers are fetched. User of this
+ // object should prepare |AudioOutputStream::GetNumBuffers()| before calling
+ // AudioOutputStream::Start().
//
// The output stream does not take ownership of this callback.
virtual void Start(AudioSourceCallback* callback) = 0;
@@ -112,6 +114,11 @@ class AudioOutputStream {
// After calling this method, the object should not be used anymore.
virtual void Close() = 0;
+ // Gets the number of internal buffers used in this output stream. This
+ // method is useful for providing information about how user of this object
+ // should prepare initial buffers before calling AudioOutputStream::Start().
+ virtual size_t GetNumBuffers() = 0;
+
protected:
virtual ~AudioOutputStream() {}
};
@@ -157,6 +164,11 @@ class AudioManager {
virtual void MuteAll() = 0;
virtual void UnMuteAll() = 0;
+ // For testing purposes only. Returns the internal buffer of the last
+ // AUDIO_MOCK AudioOutputStream closed. Returns NULL if none closed yet.
+ // The buffer size is the same as passed to AudioOutputStream::Open().
+ virtual const void* GetLastMockBuffer() = 0;
+
// Get AudioManager singleton.
// TODO(cpu): Define threading requirements for interacting with AudioManager.
static AudioManager* GetAudioManager();
diff --git a/media/audio/fake_audio_output_stream.cc b/media/audio/fake_audio_output_stream.cc
index 6eb5417..e69de29 100644
--- a/media/audio/fake_audio_output_stream.cc
+++ b/media/audio/fake_audio_output_stream.cc
@@ -1,72 +0,0 @@
-// Copyright (c) 2009 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.
-
-#include "base/at_exit.h"
-#include "media/audio/fake_audio_output_stream.h"
-
-bool FakeAudioOutputStream::has_created_fake_stream_ = false;
-FakeAudioOutputStream* FakeAudioOutputStream::last_fake_stream_ = NULL;
-
-// static
-AudioOutputStream* FakeAudioOutputStream::MakeFakeStream() {
- if (!has_created_fake_stream_)
- base::AtExitManager::RegisterCallback(&DestroyLastFakeStream, NULL);
- has_created_fake_stream_ = true;
-
- return new FakeAudioOutputStream();
-}
-
-// static
-FakeAudioOutputStream* FakeAudioOutputStream::GetLastFakeStream() {
- return last_fake_stream_;
-}
-
-bool FakeAudioOutputStream::Open(size_t packet_size) {
- if (packet_size < sizeof(int16))
- return false;
- packet_size_ = packet_size;
- buffer_.reset(new char[packet_size_]);
- return true;
-}
-
-void FakeAudioOutputStream::Start(AudioSourceCallback* callback) {
- callback_ = callback;
- memset(buffer_.get(), 0, packet_size_);
- callback_->OnMoreData(this, buffer_.get(), packet_size_);
-}
-
-void FakeAudioOutputStream::Stop() {
-}
-
-void FakeAudioOutputStream::SetVolume(double left_level, double right_level) {
- left_volume_ = left_level;
- right_volume_ = right_level;
-}
-
-void FakeAudioOutputStream::GetVolume(double* left_level, double* right_level) {
- *left_level = left_volume_;
- *right_level = right_volume_;
-}
-
-void FakeAudioOutputStream::Close() {
- callback_->OnClose(this);
- callback_ = NULL;
-
- if (last_fake_stream_)
- delete last_fake_stream_;
- last_fake_stream_ = this;
-}
-
-FakeAudioOutputStream::FakeAudioOutputStream()
- : left_volume_(0),
- right_volume_(0),
- callback_(NULL),
- packet_size_(0) {
-}
-
-// static
-void FakeAudioOutputStream::DestroyLastFakeStream(void* param) {
- if (last_fake_stream_)
- delete last_fake_stream_;
-}
diff --git a/media/audio/fake_audio_output_stream.h b/media/audio/fake_audio_output_stream.h
index 189a7ad..e69de29 100644
--- a/media/audio/fake_audio_output_stream.h
+++ b/media/audio/fake_audio_output_stream.h
@@ -1,50 +0,0 @@
-// Copyright (c) 2009 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.
-//
-// A fake implementation of AudioOutputStream. It is used for testing purpose.
-// TODO(hclam): Implement a thread in this fake output stream to simulate an
-// audio output stream reading from AudioSourceCallback.
-
-#ifndef MEDIA_AUDIO_FAKE_AUDIO_OUTPUT_STREAM_H_
-#define MEDIA_AUDIO_FAKE_AUDIO_OUTOUT_STREAM_H_
-
-#include <vector>
-
-#include "base/scoped_ptr.h"
-#include "media/audio/audio_output.h"
-
-class FakeAudioOutputStream : public AudioOutputStream {
- public:
- static AudioOutputStream* MakeFakeStream();
- static FakeAudioOutputStream* GetLastFakeStream();
-
- virtual bool Open(size_t packet_size);
- virtual void Start(AudioSourceCallback* callback);
- virtual void Stop();
- virtual void SetVolume(double left_level, double right_level);
- virtual void GetVolume(double* left_level, double* right_level);
- virtual void Close();
-
- char* buffer() { return buffer_.get(); }
- double left_volume() { return left_volume_; }
- double right_volume() { return right_volume_; }
-
- private:
- FakeAudioOutputStream();
- virtual ~FakeAudioOutputStream() {}
-
- static void DestroyLastFakeStream(void* param);
- static bool has_created_fake_stream_;
- static FakeAudioOutputStream* last_fake_stream_;
-
- double left_volume_;
- double right_volume_;
- AudioSourceCallback* callback_;
- scoped_ptr_malloc<char> buffer_;
- size_t packet_size_;
-
- DISALLOW_COPY_AND_ASSIGN(FakeAudioOutputStream);
-};
-
-#endif // MEDIA_AUDIO_FAKE_AUDIO_OUTPUT_STREAM_H_
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc
index 08075de..e7dab51 100644
--- a/media/audio/linux/alsa_output.cc
+++ b/media/audio/linux/alsa_output.cc
@@ -527,3 +527,7 @@ void AlsaPCMOutputStream::SetVolume(double left_level, double right_level) {
void AlsaPCMOutputStream::GetVolume(double* left_level, double* right_level) {
NOTIMPLEMENTED();
}
+
+size_t AlsaPCMOutputStream::GetNumBuffers() {
+ return 0;
+}
diff --git a/media/audio/linux/alsa_output.h b/media/audio/linux/alsa_output.h
index 850ab7f..42cd3c8 100644
--- a/media/audio/linux/alsa_output.h
+++ b/media/audio/linux/alsa_output.h
@@ -65,6 +65,7 @@ class AlsaPCMOutputStream :
virtual void Stop();
virtual void SetVolume(double left_level, double right_level);
virtual void GetVolume(double* left_level, double* right_level);
+ virtual size_t GetNumBuffers();
private:
// Closes the playback handle, reporting errors if any occur. Returns true
diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc
index a9d299f..69e8b9b 100644
--- a/media/audio/linux/audio_manager_linux.cc
+++ b/media/audio/linux/audio_manager_linux.cc
@@ -6,7 +6,6 @@
#include "base/at_exit.h"
#include "base/logging.h"
-#include "media/audio/fake_audio_output_stream.h"
#include "media/audio/linux/alsa_output.h"
namespace {
@@ -28,15 +27,11 @@ AudioOutputStream* AudioManagerLinux::MakeAudioStream(Format format,
// surround40, surround51, etc.
//
// http://0pointer.de/blog/projects/guide-to-sound-apis.html
- if (format == AudioManager::AUDIO_MOCK) {
- return FakeAudioOutputStream::MakeFakeStream();
- } else {
- AlsaPCMOutputStream* stream =
- new AlsaPCMOutputStream(AlsaPCMOutputStream::kDefaultDevice,
- 100 /* 100ms minimal buffer */,
- format, channels, sample_rate, bits_per_sample);
- return stream;
- }
+ AlsaPCMOutputStream* stream =
+ new AlsaPCMOutputStream(AlsaPCMOutputStream::kDefaultDevice,
+ 100 /* 100ms minimal buffer */,
+ format, channels, sample_rate, bits_per_sample);
+ return stream;
}
AudioManagerLinux::AudioManagerLinux() {
@@ -55,6 +50,12 @@ void AudioManagerLinux::UnMuteAll() {
NOTIMPLEMENTED();
}
+const void* AudioManagerLinux::GetLastMockBuffer() {
+ // TODO(ajwong): Implement.
+ NOTIMPLEMENTED();
+ return NULL;
+}
+
// TODO(ajwong): Collapse this with the windows version.
void DestroyAudioManagerLinux(void* not_used) {
delete g_audio_manager;
diff --git a/media/audio/linux/audio_manager_linux.h b/media/audio/linux/audio_manager_linux.h
index 191e687..5b369a1 100644
--- a/media/audio/linux/audio_manager_linux.h
+++ b/media/audio/linux/audio_manager_linux.h
@@ -19,6 +19,7 @@ class AudioManagerLinux : public AudioManager {
char bits_per_sample);
virtual void MuteAll();
virtual void UnMuteAll();
+ virtual const void* GetLastMockBuffer();
private:
// Friend function for invoking the private destructor at exit.
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
index a921dfb..7a8e15b 100644
--- a/media/audio/mac/audio_manager_mac.cc
+++ b/media/audio/mac/audio_manager_mac.cc
@@ -5,7 +5,6 @@
#include <CoreAudio/AudioHardware.h>
#include "base/at_exit.h"
-#include "media/audio/fake_audio_output_stream.h"
#include "media/audio/mac/audio_manager_mac.h"
#include "media/audio/mac/audio_output_mac.h"
@@ -20,9 +19,8 @@ bool AudioManagerMac::HasAudioDevices() {
AudioOutputStream* AudioManagerMac::MakeAudioStream(Format format, int channels,
int sample_rate,
char bits_per_sample) {
- if (format == AUDIO_MOCK)
- return FakeAudioOutputStream::MakeFakeStream();
- else if (format != AUDIO_PCM_LINEAR)
+ // TODO(cpu): add mock format.
+ if (format != AUDIO_PCM_LINEAR)
return NULL;
return new PCMQueueOutAudioOutputStream(this, channels, sample_rate,
bits_per_sample);
@@ -36,15 +34,19 @@ void AudioManagerMac::UnMuteAll() {
// TODO(cpu): implement.
}
+const void* AudioManagerMac::GetLastMockBuffer() {
+ // TODO(cpu): implement.
+ return NULL;
+}
+
// Called by the stream when it has been released by calling Close().
void AudioManagerMac::ReleaseStream(PCMQueueOutAudioOutputStream* stream) {
delete stream;
}
namespace {
-
-AudioManagerMac* g_audio_manager = NULL;
-
+ AudioManagerMac* g_audio_manager = NULL;
+
} // namespace.
void DestroyAudioManagerMac(void* param) {
diff --git a/media/audio/mac/audio_manager_mac.h b/media/audio/mac/audio_manager_mac.h
index 51ee58a..46cb2a5 100644
--- a/media/audio/mac/audio_manager_mac.h
+++ b/media/audio/mac/audio_manager_mac.h
@@ -24,6 +24,7 @@ class AudioManagerMac : public AudioManager {
char bits_per_sample);
virtual void MuteAll();
virtual void UnMuteAll();
+ virtual const void* GetLastMockBuffer();
// Mac-only method to free a stream created in MakeAudioStream.
// It is called internally by the audio stream when it has been closed.
diff --git a/media/audio/mac/audio_output_mac.cc b/media/audio/mac/audio_output_mac.cc
index 657e91a..4d7c6bb 100644
--- a/media/audio/mac/audio_output_mac.cc
+++ b/media/audio/mac/audio_output_mac.cc
@@ -145,6 +145,10 @@ void PCMQueueOutAudioOutputStream::GetVolume(double* left_level,
// TODO(cpu): Implement.
}
+size_t PCMQueueOutAudioOutputStream::GetNumBuffers() {
+ return kNumBuffers;
+}
+
// Note to future hackers of this function: Do not add locks here because we
// call out to third party source that might do crazy things including adquire
// external locks or somehow re-enter here because its legal for them to call
diff --git a/media/audio/mac/audio_output_mac.h b/media/audio/mac/audio_output_mac.h
index 340e1eb..d1129b3 100644
--- a/media/audio/mac/audio_output_mac.h
+++ b/media/audio/mac/audio_output_mac.h
@@ -35,6 +35,7 @@ class PCMQueueOutAudioOutputStream : public AudioOutputStream {
virtual void Stop();
virtual void SetVolume(double left_level, double right_level);
virtual void GetVolume(double* left_level, double* right_level);
+ virtual size_t GetNumBuffers();
private:
// The audio is double buffered.
diff --git a/media/audio/simple_sources_unittest.cc b/media/audio/simple_sources_unittest.cc
index ef6a5a7..32176b7 100644
--- a/media/audio/simple_sources_unittest.cc
+++ b/media/audio/simple_sources_unittest.cc
@@ -6,7 +6,6 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "base/time.h"
-#include "media/audio/fake_audio_output_stream.h"
#include "media/audio/simple_sources.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -61,48 +60,3 @@ TEST(SimpleSourcesTest, PushSourceSmallerWrite) {
push_source.OnClose(NULL);
}
-
-// Validate that the SineWaveAudioSource writes the expected values for
-// the FORMAT_16BIT_MONO. The values are carefully selected so rounding issues
-// do not affect the result. We also test that AudioManager::GetLastMockBuffer
-// works.
-TEST(SimpleSources, SineWaveAudio16MonoTest) {
- const size_t samples = 1024;
- const size_t bytes_per_sample = 2;
- const int freq = 200;
-
- SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
- freq, AudioManager::kTelephoneSampleRate);
-
- AudioManager* audio_man = AudioManager::GetAudioManager();
- ASSERT_TRUE(NULL != audio_man);
- AudioOutputStream* oas =
- audio_man->MakeAudioStream(AudioManager::AUDIO_MOCK, 1,
- AudioManager::kTelephoneSampleRate,
- bytes_per_sample * 2);
- ASSERT_TRUE(NULL != oas);
- EXPECT_TRUE(oas->Open(samples * bytes_per_sample));
-
- oas->Start(&source);
- oas->Stop();
- oas->Close();
-
- ASSERT_TRUE(FakeAudioOutputStream::GetLastFakeStream());
- const int16* last_buffer =
- reinterpret_cast<int16*>(
- FakeAudioOutputStream::GetLastFakeStream()->buffer());
- ASSERT_TRUE(NULL != last_buffer);
-
- size_t half_period = AudioManager::kTelephoneSampleRate / (freq * 2);
-
- // Spot test positive incursion of sine wave.
- EXPECT_EQ(0, last_buffer[0]);
- EXPECT_EQ(5126, last_buffer[1]);
- EXPECT_TRUE(last_buffer[1] < last_buffer[2]);
- EXPECT_TRUE(last_buffer[2] < last_buffer[3]);
- // Spot test negative incursion of sine wave.
- EXPECT_EQ(0, last_buffer[half_period]);
- EXPECT_EQ(-5126, last_buffer[half_period + 1]);
- EXPECT_TRUE(last_buffer[half_period + 1] > last_buffer[half_period + 2]);
- EXPECT_TRUE(last_buffer[half_period + 2] > last_buffer[half_period + 3]);
-}
diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h
index f060fc4..12a4c06 100644
--- a/media/audio/win/audio_manager_win.h
+++ b/media/audio/win/audio_manager_win.h
@@ -11,6 +11,7 @@
#include "media/audio/audio_output.h"
class PCMWaveOutAudioOutputStream;
+class AudioOutputStreamMockWin;
// Windows implementation of the AudioManager singleton. This class is internal
// to the audio output and only internal users can call methods not exposed by
@@ -25,10 +26,12 @@ class AudioManagerWin : public AudioManager {
char bits_per_sample);
virtual void MuteAll();
virtual void UnMuteAll();
+ virtual const void* GetLastMockBuffer();
// Windows-only methods to free a stream created in MakeAudioStream. These
// are called internally by the audio stream when it has been closed.
void ReleaseStream(PCMWaveOutAudioOutputStream* stream);
+ void ReleaseStream(AudioOutputStreamMockWin* stream);
private:
friend void DestroyAudioManagerWin(void *);
diff --git a/media/audio/win/audio_output_win.cc b/media/audio/win/audio_output_win.cc
index f7eac01..bc8c712 100644
--- a/media/audio/win/audio_output_win.cc
+++ b/media/audio/win/audio_output_win.cc
@@ -9,10 +9,81 @@
#include "base/at_exit.h"
#include "base/basictypes.h"
-#include "media/audio/fake_audio_output_stream.h"
#include "media/audio/win/audio_manager_win.h"
#include "media/audio/win/waveout_output_win.h"
+// A do-nothing audio stream. It behaves like a regular audio stream but does
+// not have any side effect, except possibly the creation and tear-down of
+// of a thread. It is useful to test code that uses audio streams such as
+// audio sources.
+class AudioOutputStreamMockWin : public AudioOutputStream {
+ public:
+ explicit AudioOutputStreamMockWin(AudioManagerWin* manager)
+ : manager_(manager),
+ callback_(NULL),
+ buffer_(NULL),
+ packet_size_(0),
+ left_volume_(1.0),
+ right_volume_(1.0) {
+ }
+
+ virtual ~AudioOutputStreamMockWin() {
+ delete[] buffer_;
+ packet_size_ = 0;
+ }
+
+ virtual bool Open(size_t packet_size) {
+ if (packet_size < sizeof(int16))
+ return false;
+ packet_size_ = packet_size;
+ buffer_ = new char[packet_size_];
+ return true;
+ }
+
+ virtual void Start(AudioSourceCallback* callback) {
+ callback_ = callback;
+ memset(buffer_, 0, packet_size_);
+ callback_->OnMoreData(this, buffer_, packet_size_);
+ }
+
+ // TODO(cpu): flesh out Start and Stop methods. We need a thread to
+ // perform periodic callbacks.
+ virtual void Stop() {
+ }
+
+ virtual void SetVolume(double left_level, double right_level) {
+ left_volume_ = left_level;
+ right_volume_ = right_level;
+ }
+
+ virtual void GetVolume(double* left_level, double* right_level) {
+ *left_level = left_volume_;
+ *right_level = right_volume_;
+ }
+
+ virtual size_t GetNumBuffers() {
+ return 1;
+ }
+
+ virtual void Close() {
+ callback_->OnClose(this);
+ callback_ = NULL;
+ manager_->ReleaseStream(this);
+ }
+
+ char* buffer() {
+ return buffer_;
+ }
+
+ private:
+ AudioManagerWin* manager_;
+ AudioSourceCallback* callback_;
+ char* buffer_;
+ size_t packet_size_;
+ double left_volume_;
+ double right_volume_;
+};
+
namespace {
// The next 3 constants are some sensible limits to prevent integer overflow
@@ -31,10 +102,18 @@ const int kMaxChannels = 6;
const int kMaxSampleRate = 192000;
const int kMaxBitsPerSample = 64;
+AudioOutputStreamMockWin* g_last_mock_stream = NULL;
AudioManagerWin* g_audio_manager = NULL;
+void ReplaceLastMockStream(AudioOutputStreamMockWin* newer) {
+ if (g_last_mock_stream)
+ delete g_last_mock_stream;
+ g_last_mock_stream = newer;
+}
+
} // namespace.
+
bool AudioManagerWin::HasAudioDevices() {
return (::waveOutGetNumDevs() != 0);
}
@@ -43,6 +122,7 @@ bool AudioManagerWin::HasAudioDevices() {
// should suffice most windows user's needs.
// - PCMWaveOutAudioOutputStream: Based on the waveOutWrite API (in progress)
// - PCMDXSoundAudioOutputStream: Based on DirectSound or XAudio (future work).
+
AudioOutputStream* AudioManagerWin::MakeAudioStream(Format format, int channels,
int sample_rate,
char bits_per_sample) {
@@ -52,7 +132,7 @@ AudioOutputStream* AudioManagerWin::MakeAudioStream(Format format, int channels,
return NULL;
if (format == AUDIO_MOCK) {
- return FakeAudioOutputStream::MakeFakeStream();
+ return new AudioOutputStreamMockWin(this);
} else if (format == AUDIO_PCM_LINEAR) {
return new PCMWaveOutAudioOutputStream(this, channels, sample_rate,
bits_per_sample, WAVE_MAPPER);
@@ -65,6 +145,15 @@ void AudioManagerWin::ReleaseStream(PCMWaveOutAudioOutputStream* stream) {
delete stream;
}
+void AudioManagerWin::ReleaseStream(AudioOutputStreamMockWin *stream) {
+ // Note that we keep the last mock stream so GetLastMockBuffer() works.
+ ReplaceLastMockStream(stream);
+}
+
+const void* AudioManagerWin::GetLastMockBuffer() {
+ return (g_last_mock_stream) ? g_last_mock_stream->buffer() : NULL;
+}
+
void AudioManagerWin::MuteAll() {
}
@@ -72,6 +161,7 @@ void AudioManagerWin::UnMuteAll() {
}
AudioManagerWin::~AudioManagerWin() {
+ ReplaceLastMockStream(NULL);
}
void DestroyAudioManagerWin(void* param) {
diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc
index f47bd9c..fae74ac 100644
--- a/media/audio/win/audio_output_win_unittest.cc
+++ b/media/audio/win/audio_output_win_unittest.cc
@@ -193,6 +193,51 @@ TEST(WinAudioTest, MockStreamBasicCallbacks) {
EXPECT_EQ(1, source.was_closed());
}
+// Validate that the SineWaveAudioSource writes the expected values for
+// the FORMAT_16BIT_MONO. The values are carefully selected so rounding issues
+// do not affect the result. We also test that AudioManager::GetLastMockBuffer
+// works.
+// TODO(hclam): move this test to SimpleSourcesTest once mock audio stream is
+// implemented on other platform.
+TEST(WinAudioTest, SineWaveAudio16MonoTest) {
+ const size_t samples = 1024;
+ const size_t bytes_per_sample = 2;
+ const int freq = 200;
+
+ SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
+ freq, AudioManager::kTelephoneSampleRate);
+
+ AudioManager* audio_man = AudioManager::GetAudioManager();
+ ASSERT_TRUE(NULL != audio_man);
+ AudioOutputStream* oas =
+ audio_man->MakeAudioStream(AudioManager::AUDIO_MOCK, 1,
+ AudioManager::kTelephoneSampleRate,
+ bytes_per_sample * 2);
+ ASSERT_TRUE(NULL != oas);
+ EXPECT_TRUE(oas->Open(samples * bytes_per_sample));
+
+ oas->Start(&source);
+ oas->Stop();
+ oas->Close();
+
+ const int16* last_buffer =
+ reinterpret_cast<const int16*>(audio_man->GetLastMockBuffer());
+ ASSERT_TRUE(NULL != last_buffer);
+
+ size_t half_period = AudioManager::kTelephoneSampleRate / (freq * 2);
+
+ // Spot test positive incursion of sine wave.
+ EXPECT_EQ(0, last_buffer[0]);
+ EXPECT_EQ(5126, last_buffer[1]);
+ EXPECT_TRUE(last_buffer[1] < last_buffer[2]);
+ EXPECT_TRUE(last_buffer[2] < last_buffer[3]);
+ // Spot test negative incursion of sine wave.
+ EXPECT_EQ(0, last_buffer[half_period]);
+ EXPECT_EQ(-5126, last_buffer[half_period + 1]);
+ EXPECT_TRUE(last_buffer[half_period + 1] > last_buffer[half_period + 2]);
+ EXPECT_TRUE(last_buffer[half_period + 2] > last_buffer[half_period + 3]);
+}
+
// ===========================================================================
// Validation of AudioManager::AUDIO_PCM_LINEAR
//
diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc
index 124d8e7..d8d2ebdd 100644
--- a/media/audio/win/waveout_output_win.cc
+++ b/media/audio/win/waveout_output_win.cc
@@ -215,6 +215,10 @@ void PCMWaveOutAudioOutputStream::GetVolume(double* left_level,
*right_level = volume_;
}
+size_t PCMWaveOutAudioOutputStream::GetNumBuffers() {
+ return kNumBuffers;
+}
+
void PCMWaveOutAudioOutputStream::HandleError(MMRESULT error) {
DLOG(WARNING) << "PCMWaveOutAudio error " << error;
callback_->OnError(this, error);
diff --git a/media/audio/win/waveout_output_win.h b/media/audio/win/waveout_output_win.h
index 3f822e9..ea9bdef 100644
--- a/media/audio/win/waveout_output_win.h
+++ b/media/audio/win/waveout_output_win.h
@@ -40,6 +40,7 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream {
virtual void Stop();
virtual void SetVolume(double left_level, double right_level);
virtual void GetVolume(double* left_level, double* right_level);
+ virtual size_t GetNumBuffers();
// Sends a buffer to the audio driver for playback.
void QueueNextPacket(WAVEHDR* buffer);