summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-11 03:07:19 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-11 03:07:19 +0000
commit9ade381f46175dead00a1cc9ffc3328230e8c982 (patch)
tree64c6caf04643408b2e25bce192f03c9b7b93eaa2 /media
parentadc19c0eeac9f3caaae4e35bd64e79e6b6e72a0f (diff)
downloadchromium_src-9ade381f46175dead00a1cc9ffc3328230e8c982.zip
chromium_src-9ade381f46175dead00a1cc9ffc3328230e8c982.tar.gz
chromium_src-9ade381f46175dead00a1cc9ffc3328230e8c982.tar.bz2
Simplified AudioOutputStream interface.
1. Removed packet_size parameter from Open(). 2. Removed OnClose() from the callback. Now the callback is guaranteed to be called only between Start() and Stop(). 3. Added samples_per_packet in the AudioParameters struct. BUG=39825 TEST=Unittests Review URL: http://codereview.chromium.org/4661001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65766 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/audio/audio_input_controller.cc18
-rw-r--r--media/audio/audio_input_controller.h9
-rw-r--r--media/audio/audio_input_controller_unittest.cc16
-rw-r--r--media/audio/audio_input_unittest.cc20
-rw-r--r--media/audio/audio_io.h33
-rw-r--r--media/audio/audio_manager.h21
-rw-r--r--media/audio/audio_output_controller.cc39
-rw-r--r--media/audio/audio_output_controller.h7
-rw-r--r--media/audio/audio_output_controller_unittest.cc34
-rw-r--r--media/audio/audio_parameters.cc17
-rw-r--r--media/audio/audio_parameters.h18
-rw-r--r--media/audio/fake_audio_input_stream.cc13
-rw-r--r--media/audio/fake_audio_input_stream.h5
-rw-r--r--media/audio/fake_audio_input_stream_unittest.cc2
-rw-r--r--media/audio/fake_audio_output_stream.cc21
-rw-r--r--media/audio/fake_audio_output_stream.h7
-rw-r--r--media/audio/linux/alsa_input.cc17
-rw-r--r--media/audio/linux/alsa_input.h2
-rw-r--r--media/audio/linux/alsa_output.cc41
-rw-r--r--media/audio/linux/alsa_output.h14
-rw-r--r--media/audio/linux/alsa_output_unittest.cc55
-rw-r--r--media/audio/linux/audio_manager_linux.cc12
-rw-r--r--media/audio/linux/audio_manager_linux.h3
-rw-r--r--media/audio/mac/audio_input_mac.cc6
-rw-r--r--media/audio/mac/audio_input_mac.h3
-rw-r--r--media/audio/mac/audio_manager_mac.cc12
-rw-r--r--media/audio/mac/audio_manager_mac.h3
-rw-r--r--media/audio/mac/audio_output_mac.cc26
-rw-r--r--media/audio/mac/audio_output_mac.h4
-rw-r--r--media/audio/mac/audio_output_mac_unittest.cc32
-rw-r--r--media/audio/openbsd/audio_manager_openbsd.cc3
-rw-r--r--media/audio/openbsd/audio_manager_openbsd.h3
-rw-r--r--media/audio/simple_sources.cc7
-rw-r--r--media/audio/simple_sources.h2
-rw-r--r--media/audio/simple_sources_unittest.cc6
-rw-r--r--media/audio/test_audio_input_controller_factory.cc3
-rw-r--r--media/audio/test_audio_input_controller_factory.h3
-rw-r--r--media/audio/win/audio_manager_win.cc12
-rw-r--r--media/audio/win/audio_manager_win.h3
-rw-r--r--media/audio/win/audio_output_win_unittest.cc127
-rw-r--r--media/audio/win/wavein_input_win.cc4
-rw-r--r--media/audio/win/wavein_input_win.h3
-rw-r--r--media/audio/win/waveout_output_win.cc28
-rw-r--r--media/audio/win/waveout_output_win.h5
-rw-r--r--media/base/limits.h1
-rw-r--r--media/filters/audio_renderer_impl.cc8
46 files changed, 324 insertions, 404 deletions
diff --git a/media/audio/audio_input_controller.cc b/media/audio/audio_input_controller.cc
index 45ab2c4..b5c9df2b 100644
--- a/media/audio/audio_input_controller.cc
+++ b/media/audio/audio_input_controller.cc
@@ -8,7 +8,6 @@
namespace {
const int kMaxInputChannels = 2;
-const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate;
} // namespace
@@ -31,15 +30,12 @@ AudioInputController::~AudioInputController() {
// static
scoped_refptr<AudioInputController> AudioInputController::Create(
EventHandler* event_handler,
- AudioParameters params,
- int samples_per_packet) {
- if (!params.IsValid() ||
- (params.channels > kMaxInputChannels) ||
- (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0))
+ AudioParameters params) {
+ if (!params.IsValid() || (params.channels > kMaxInputChannels))
return NULL;
if (factory_) {
- return factory_->Create(event_handler, params, samples_per_packet);
+ return factory_->Create(event_handler, params);
}
scoped_refptr<AudioInputController> controller(new AudioInputController(
@@ -50,7 +46,7 @@ scoped_refptr<AudioInputController> AudioInputController::Create(
controller->thread_.message_loop()->PostTask(
FROM_HERE,
NewRunnableMethod(controller.get(), &AudioInputController::DoCreate,
- params, samples_per_packet));
+ params));
return controller;
}
@@ -75,10 +71,8 @@ void AudioInputController::Close() {
thread_.Stop();
}
-void AudioInputController::DoCreate(AudioParameters params,
- uint32 samples_per_packet) {
- stream_ = AudioManager::GetAudioManager()->MakeAudioInputStream(
- params, samples_per_packet);
+void AudioInputController::DoCreate(AudioParameters params) {
+ stream_ = AudioManager::GetAudioManager()->MakeAudioInputStream(params);
if (!stream_) {
// TODO(satish): Define error types.
diff --git a/media/audio/audio_input_controller.h b/media/audio/audio_input_controller.h
index f6e8d1e..cfba450b3 100644
--- a/media/audio/audio_input_controller.h
+++ b/media/audio/audio_input_controller.h
@@ -55,8 +55,7 @@ class AudioInputController :
class Factory {
public:
virtual AudioInputController* Create(EventHandler* event_handler,
- AudioParameters params,
- int samples_per_packet) = 0;
+ AudioParameters params) = 0;
protected:
virtual ~Factory() {}
@@ -70,8 +69,7 @@ class AudioInputController :
// handler will receive a OnCreated() call.
static scoped_refptr<AudioInputController> Create(
EventHandler* event_handler,
- AudioParameters params,
- int samples_per_packet); // Size of the hardware buffer.
+ AudioParameters params);
// Sets the factory used by the static method Create. AudioInputController
// does not take ownership of |factory|. A value of NULL results in an
@@ -110,8 +108,7 @@ class AudioInputController :
AudioInputController(EventHandler* handler);
// The following methods are executed on the audio controller thread.
- void DoCreate(AudioParameters params,
- uint32 samples_per_packet);
+ void DoCreate(AudioParameters params);
void DoRecord();
void DoClose();
void DoReportError(int code);
diff --git a/media/audio/audio_input_controller_unittest.cc b/media/audio/audio_input_controller_unittest.cc
index 03219f8..ac57d2a 100644
--- a/media/audio/audio_input_controller_unittest.cc
+++ b/media/audio/audio_input_controller_unittest.cc
@@ -55,9 +55,9 @@ TEST(AudioInputControllerTest, CreateAndClose) {
.WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));
AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels,
- kSampleRate, kBitsPerSample);
+ kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioInputController> controller =
- AudioInputController::Create(&event_handler, params, kSamplesPerPacket);
+ AudioInputController::Create(&event_handler, params);
ASSERT_TRUE(controller.get());
// Wait for OnCreated() to be called.
@@ -86,9 +86,9 @@ TEST(AudioInputControllerTest, RecordAndClose) {
.WillRepeatedly(CheckCountAndSignalEvent(&count, 10, &event));
AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels,
- kSampleRate, kBitsPerSample);
+ kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioInputController> controller =
- AudioInputController::Create(&event_handler, params, kSamplesPerPacket);
+ AudioInputController::Create(&event_handler, params);
ASSERT_TRUE(controller.get());
// Wait for OnCreated() to be called.
@@ -108,9 +108,9 @@ TEST(AudioInputControllerTest, SamplesPerPacketTooLarge) {
MockAudioInputControllerEventHandler event_handler;
AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels,
- kSampleRate, kBitsPerSample);
+ kSampleRate, kBitsPerSample, kSamplesPerPacket * 1000);
scoped_refptr<AudioInputController> controller = AudioInputController::Create(
- &event_handler, params, kSamplesPerPacket * 1000);
+ &event_handler, params);
ASSERT_FALSE(controller);
}
@@ -119,9 +119,9 @@ TEST(AudioInputControllerTest, CloseTwice) {
MockAudioInputControllerEventHandler event_handler;
EXPECT_CALL(event_handler, OnCreated(NotNull()));
AudioParameters params(AudioParameters::AUDIO_MOCK, kChannels,
- kSampleRate, kBitsPerSample);
+ kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioInputController> controller =
- AudioInputController::Create(&event_handler, params, kSamplesPerPacket);
+ AudioInputController::Create(&event_handler, params);
ASSERT_TRUE(controller.get());
controller->Close();
diff --git a/media/audio/audio_input_unittest.cc b/media/audio/audio_input_unittest.cc
index 6a67f0c..82cb887 100644
--- a/media/audio/audio_input_unittest.cc
+++ b/media/audio/audio_input_unittest.cc
@@ -104,8 +104,8 @@ bool CanRunAudioTests() {
AudioInputStream* CreateTestAudioInputStream() {
AudioManager* audio_man = AudioManager::GetAudioManager();
AudioInputStream* ais = audio_man->MakeAudioInputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16),
- kSamplesPerPacket);
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate,
+ 16, kSamplesPerPacket));
EXPECT_TRUE(NULL != ais);
return ais;
}
@@ -119,21 +119,21 @@ TEST(AudioInputTest, SanityOnMakeParams) {
AudioManager* audio_man = AudioManager::GetAudioManager();
AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR;
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
- AudioParameters(fmt, 8, 8000, 16), 0));
+ AudioParameters(fmt, 8, 8000, 16, kSamplesPerPacket)));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
- AudioParameters(fmt, 1, 1024 * 1024, 16), 0));
+ AudioParameters(fmt, 1, 1024 * 1024, 16, kSamplesPerPacket)));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
- AudioParameters(fmt, 2, 8000, 80), 0));
+ AudioParameters(fmt, 2, 8000, 80, kSamplesPerPacket)));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
- AudioParameters(fmt, 2, 8000, 80), 1024 * 4096));
+ AudioParameters(fmt, 2, 8000, 80, 1000 * kSamplesPerPacket)));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
- AudioParameters(fmt, -2, 8000, 16), 0));
+ AudioParameters(fmt, -2, 8000, 16, kSamplesPerPacket)));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
- AudioParameters(fmt, 2, -8000, 16), 0));
+ AudioParameters(fmt, 2, -8000, 16, kSamplesPerPacket)));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
- AudioParameters(fmt, 2, 8000, -16), 0));
+ AudioParameters(fmt, 2, 8000, -16, kSamplesPerPacket)));
EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(
- AudioParameters(fmt, 2, 8000, 16), -1024));
+ AudioParameters(fmt, 2, 8000, 16, -1024)));
}
// Test create and close of an AudioInputStream without recording audio.
diff --git a/media/audio/audio_io.h b/media/audio/audio_io.h
index 3aa22cf..cadc5d3 100644
--- a/media/audio/audio_io.h
+++ b/media/audio/audio_io.h
@@ -40,6 +40,11 @@
// Models an audio stream that gets rendered to the audio hardware output.
// Because we support more audio streams than physically available channels
// a given AudioOutputStream might or might not talk directly to hardware.
+// An audio stream allocates several buffers for audio data and calls
+// AudioSourceCallback::OnModeData() periodically to fill these buffers,
+// as the data is written to the audio device. Size of each packet is determined
+// by |samples_per_packet| specified in AudioParameters when the stream is
+// created.
class AudioOutputStream {
public:
// Audio sources must implement AudioSourceCallback. This interface will be
@@ -51,19 +56,16 @@ class AudioOutputStream {
virtual ~AudioSourceCallback() {}
// Provide more data by filling |dest| up to |max_size| bytes. The provided
- // buffer size is usually what is specified in Open(). The source
- // will return the number of bytes it filled. The expected structure of
- // |dest| is platform and format specific.
- // |pending_bytes| is the number of bytes will be played before the
- // requested data is played.
+ // buffer size is determined by the |samples_per_packet| specified in
+ // AudioParameters when the stream is created. The source will return
+ // the number of bytes it filled. The expected structure of |dest| is
+ // platform and format specific.
+ // |buffers_state| contains current state of the buffers, and can be used
+ // by the source to calculate delay.
virtual uint32 OnMoreData(
AudioOutputStream* stream, uint8* dest, uint32 max_size,
AudioBuffersState buffers_state) = 0;
- // The stream is done with this callback. After this call the audio source
- // can go away or be destroyed.
- virtual void OnClose(AudioOutputStream* stream) = 0;
-
// There was an error while playing a buffer. Audio source cannot be
// destroyed yet. No direct action needed by the AudioStream, but it is
// a good place to stop accumulating sound data since is is likely that
@@ -72,17 +74,8 @@ class AudioOutputStream {
virtual void OnError(AudioOutputStream* stream, int code) = 0;
};
- // Open the stream. |packet_size| is the requested buffer allocation which
- // the audio source thinks it can usually fill without blocking. Internally
- // two or three buffers of |packet_size| size are created, one will be
- // locked for playback and one will be ready to be filled in the call to
- // AudioSourceCallback::OnMoreData().
- // The number of buffers is controlled by AUDIO_PCM_LOW_LATENCY. See more
- // information below.
- //
- // TODO(ajwong): Streams are not reusable, so try to move packet_size into the
- // constructor.
- virtual bool Open(uint32 packet_size) = 0;
+ // Open the stream. false is returned if the stream cannot be opened.
+ virtual bool Open() = 0;
// Starts playing audio and generating AudioSourceCallback::OnMoreData().
// Since implementor of AudioOutputStream may have internal buffers, right
diff --git a/media/audio/audio_manager.h b/media/audio/audio_manager.h
index 805db89..26f0acf 100644
--- a/media/audio/audio_manager.h
+++ b/media/audio/audio_manager.h
@@ -12,6 +12,9 @@ class AudioInputStream;
class AudioOutputStream;
class MessageLoop;
+// TODO(sergeyu): In this interface and some other places AudioParameters struct
+// is passed by value. It is better to change it to const reference.
+
// Manages all audio resources. In particular it owns the AudioOutputStream
// objects. Provides some convenience functions that avoid the need to provide
// iterators over the existing streams.
@@ -26,14 +29,19 @@ class AudioManager {
// sample rates.
virtual bool HasAudioInputDevices() = 0;
- // Factory for all the supported stream formats. The |channels| can be 1 to 5.
- // The |sample_rate| is in hertz and can be any value supported by the
- // platform. For some future formats the |sample_rate| and |bits_per_sample|
- // can take special values.
+ // Factory for all the supported stream formats. |params| defines parameters
+ // of the audio stream to be created.
+ //
+ // |params.sample_per_packet| is the requested buffer allocation which the
+ // audio source thinks it can usually fill without blocking. Internally two
+ // or three buffers are created, one will be locked for playback and one will
+ // be ready to be filled in the call to AudioSourceCallback::OnMoreData().
+ //
// Returns NULL if the combination of the parameters is not supported, or if
// we have reached some other platform specific limit.
//
- // AUDIO_PCM_LOW_LATENCY can be passed to this method and it has two effects:
+ // |params.format| can be set to AUDIO_PCM_LOW_LATENCY and that has two
+ // effects:
// 1- Instead of triple buffered the audio will be double buffered.
// 2- A low latency driver or alternative audio subsystem will be used when
// available.
@@ -53,8 +61,7 @@ class AudioManager {
//
// Do not free the returned AudioInputStream. It is owned by AudioManager.
// When you are done with it, call |Stop()| and |Close()| to release it.
- virtual AudioInputStream* MakeAudioInputStream(AudioParameters params,
- int samples_per_packet) = 0;
+ virtual AudioInputStream* MakeAudioInputStream(AudioParameters params) = 0;
// Muting continues playback but effectively the volume is set to zero.
// Un-muting returns the volume to the previous level.
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc
index 4ba0f3e..033d4c5 100644
--- a/media/audio/audio_output_controller.cc
+++ b/media/audio/audio_output_controller.cc
@@ -6,23 +6,15 @@
#include "base/message_loop.h"
-// The following parameters limit the request buffer and packet size from the
-// renderer to avoid renderer from requesting too much memory.
-static const uint32 kMegabytes = 1024 * 1024;
-static const uint32 kMaxHardwareBufferSize = 2 * kMegabytes;
// Signal a pause in low-latency mode.
static const int kPauseMark = -1;
namespace {
// Return true if the parameters for creating an audio stream is valid.
// Return false otherwise.
-static bool CheckParameters(AudioParameters params,
- uint32 hardware_buffer_size) {
+static bool CheckParameters(AudioParameters params) {
if (!params.IsValid())
return false;
- if (hardware_buffer_size <= 0 ||
- hardware_buffer_size > kMaxHardwareBufferSize)
- return false;
return true;
}
@@ -51,10 +43,9 @@ AudioOutputController::~AudioOutputController() {
scoped_refptr<AudioOutputController> AudioOutputController::Create(
EventHandler* event_handler,
AudioParameters params,
- uint32 hardware_buffer_size,
uint32 buffer_capacity) {
- if (!CheckParameters(params, hardware_buffer_size))
+ if (!CheckParameters(params))
return NULL;
// Starts the audio controller thread.
@@ -66,7 +57,7 @@ scoped_refptr<AudioOutputController> AudioOutputController::Create(
controller->message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate,
- params, hardware_buffer_size));
+ params));
return controller;
}
@@ -74,12 +65,11 @@ scoped_refptr<AudioOutputController> AudioOutputController::Create(
scoped_refptr<AudioOutputController> AudioOutputController::CreateLowLatency(
EventHandler* event_handler,
AudioParameters params,
- uint32 hardware_buffer_size,
SyncReader* sync_reader) {
DCHECK(sync_reader);
- if (!CheckParameters(params, hardware_buffer_size))
+ if (!CheckParameters(params))
return NULL;
// Starts the audio controller thread.
@@ -91,7 +81,7 @@ scoped_refptr<AudioOutputController> AudioOutputController::CreateLowLatency(
controller->message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate,
- params, hardware_buffer_size));
+ params));
return controller;
}
@@ -144,8 +134,7 @@ void AudioOutputController::EnqueueData(const uint8* data, uint32 size) {
}
}
-void AudioOutputController::DoCreate(AudioParameters params,
- uint32 hardware_buffer_size) {
+void AudioOutputController::DoCreate(AudioParameters params) {
DCHECK_EQ(message_loop_, MessageLoop::current());
// Close() can be called before DoCreate() is executed.
@@ -160,7 +149,7 @@ void AudioOutputController::DoCreate(AudioParameters params,
return;
}
- if (!stream_->Open(hardware_buffer_size)) {
+ if (!stream_->Open()) {
stream_->Close();
stream_ = NULL;
@@ -168,6 +157,7 @@ void AudioOutputController::DoCreate(AudioParameters params,
handler_->OnError(this, 0);
return;
}
+
// We have successfully opened the stream. Set the initial volume.
stream_->SetVolume(volume_);
@@ -246,6 +236,10 @@ void AudioOutputController::DoClose(Task* closed_task) {
stream_ = NULL;
}
+ if (LowLatencyMode()) {
+ sync_reader_->Close();
+ }
+
state_ = kClosed;
}
@@ -299,15 +293,6 @@ uint32 AudioOutputController::OnMoreData(
return size;
}
-void AudioOutputController::OnClose(AudioOutputStream* stream) {
- DCHECK_EQ(message_loop_, MessageLoop::current());
-
- // Push source doesn't need to know the stream so just pass in NULL.
- if (LowLatencyMode()) {
- sync_reader_->Close();
- }
-}
-
void AudioOutputController::OnError(AudioOutputStream* stream, int code) {
// Handle error on the audio controller thread.
message_loop_->PostTask(
diff --git a/media/audio/audio_output_controller.h b/media/audio/audio_output_controller.h
index 6c1ba89..0a191e3 100644
--- a/media/audio/audio_output_controller.h
+++ b/media/audio/audio_output_controller.h
@@ -108,8 +108,6 @@ class AudioOutputController
static scoped_refptr<AudioOutputController> Create(
EventHandler* event_handler,
AudioParameters params,
- uint32 hardware_buffer_size, // Size of the hardware buffer.
-
// Soft limit for buffer capacity in this controller. This parameter
// is used only in regular latency mode.
uint32 buffer_capacity);
@@ -118,8 +116,6 @@ class AudioOutputController
static scoped_refptr<AudioOutputController> CreateLowLatency(
EventHandler* event_handler,
AudioParameters params,
- uint32 hardware_buffer_size, // Size of the hardware buffer.
-
// External synchronous reader for audio controller.
SyncReader* sync_reader);
@@ -158,7 +154,6 @@ class AudioOutputController
// AudioSourceCallback methods.
virtual uint32 OnMoreData(AudioOutputStream* stream, uint8* dest,
uint32 max_size, AudioBuffersState buffers_state);
- virtual void OnClose(AudioOutputStream* stream);
virtual void OnError(AudioOutputStream* stream, int code);
private:
@@ -166,7 +161,7 @@ class AudioOutputController
uint32 capacity, SyncReader* sync_reader);
// The following methods are executed on the audio controller thread.
- void DoCreate(AudioParameters params, uint32 hardware_buffer_size);
+ void DoCreate(AudioParameters params);
void DoPlay();
void DoPause();
void DoFlush();
diff --git a/media/audio/audio_output_controller_unittest.cc b/media/audio/audio_output_controller_unittest.cc
index 6997016..d70aed1 100644
--- a/media/audio/audio_output_controller_unittest.cc
+++ b/media/audio/audio_output_controller_unittest.cc
@@ -21,8 +21,9 @@ using ::testing::Return;
static const int kSampleRate = AudioParameters::kAudioCDSampleRate;
static const int kBitsPerSample = 16;
static const int kChannels = 2;
-static const int kHardwareBufferSize = kSampleRate * kBitsPerSample *
- kChannels / 8;
+static const int kSamplesPerPacket = kSampleRate / 10;
+static const int kHardwareBufferSize = kSamplesPerPacket * kChannels *
+ kBitsPerSample / 8;
static const int kBufferCapacity = 3 * kHardwareBufferSize;
namespace media {
@@ -97,10 +98,9 @@ TEST(AudioOutputControllerTest, CreateAndClose) {
EXPECT_CALL(event_handler, OnMoreData(NotNull(), _));
AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
- kSampleRate, kBitsPerSample);
+ kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioOutputController> controller =
- AudioOutputController::Create(&event_handler, params,
- kHardwareBufferSize, kBufferCapacity);
+ AudioOutputController::Create(&event_handler, params, kBufferCapacity);
ASSERT_TRUE(controller.get());
// Close the controller immediately.
@@ -128,10 +128,9 @@ TEST(AudioOutputControllerTest, PlayAndClose) {
.WillRepeatedly(SignalEvent(&event));
AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
- kSampleRate, kBitsPerSample);
+ kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioOutputController> controller =
- AudioOutputController::Create(&event_handler, params,
- kHardwareBufferSize, kBufferCapacity);
+ AudioOutputController::Create(&event_handler, params, kBufferCapacity);
ASSERT_TRUE(controller.get());
// Wait for OnCreated() to be called.
@@ -178,10 +177,9 @@ TEST(AudioOutputControllerTest, PlayPauseClose) {
.WillOnce(InvokeWithoutArgs(&pause_event, &base::WaitableEvent::Signal));
AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
- kSampleRate, kBitsPerSample);
+ kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioOutputController> controller =
- AudioOutputController::Create(&event_handler, params,
- kHardwareBufferSize, kBufferCapacity);
+ AudioOutputController::Create(&event_handler, params, kBufferCapacity);
ASSERT_TRUE(controller.get());
// Wait for OnCreated() to be called.
@@ -239,10 +237,9 @@ TEST(AudioOutputControllerTest, PlayPausePlay) {
.RetiresOnSaturation();
AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
- kSampleRate, kBitsPerSample);
+ kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioOutputController> controller =
- AudioOutputController::Create(&event_handler, params,
- kHardwareBufferSize, kBufferCapacity);
+ AudioOutputController::Create(&event_handler, params, kBufferCapacity);
ASSERT_TRUE(controller.get());
// Wait for OnCreated() to be called.
@@ -283,10 +280,10 @@ TEST(AudioOutputControllerTest, HardwareBufferTooLarge) {
// Create an audio device with a very large hardware buffer size.
MockAudioOutputControllerEventHandler event_handler;
AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
- kSampleRate, kBitsPerSample);
+ kSampleRate, kBitsPerSample,
+ kSamplesPerPacket * 1000);
scoped_refptr<AudioOutputController> controller =
AudioOutputController::Create(&event_handler, params,
- kHardwareBufferSize * 1000,
kBufferCapacity);
// Use assert because we don't stop the device and assume we can't
@@ -311,10 +308,9 @@ TEST(AudioOutputControllerTest, CloseTwice) {
.WillRepeatedly(SignalEvent(&event));
AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannels,
- kSampleRate, kBitsPerSample);
+ kSampleRate, kBitsPerSample, kSamplesPerPacket);
scoped_refptr<AudioOutputController> controller =
- AudioOutputController::Create(&event_handler, params,
- kHardwareBufferSize, kBufferCapacity);
+ AudioOutputController::Create(&event_handler, params, kBufferCapacity);
ASSERT_TRUE(controller.get());
// Wait for OnCreated() to be called.
diff --git a/media/audio/audio_parameters.cc b/media/audio/audio_parameters.cc
index ca12452..b0a691b 100644
--- a/media/audio/audio_parameters.cc
+++ b/media/audio/audio_parameters.cc
@@ -10,15 +10,18 @@ AudioParameters::AudioParameters()
: format(AUDIO_PCM_LINEAR),
channels(0),
sample_rate(0),
- bits_per_sample(0) {
+ bits_per_sample(0),
+ samples_per_packet(0) {
}
AudioParameters::AudioParameters(Format format, int channels,
- int sample_rate, int bits_per_sample)
+ int sample_rate, int bits_per_sample,
+ int samples_per_packet)
: format(format),
channels(channels),
sample_rate(sample_rate),
- bits_per_sample(bits_per_sample) {
+ bits_per_sample(bits_per_sample),
+ samples_per_packet(samples_per_packet) {
}
bool AudioParameters::IsValid() const {
@@ -26,5 +29,11 @@ bool AudioParameters::IsValid() const {
(channels > 0) && (channels <= media::Limits::kMaxChannels) &&
(sample_rate > 0) && (sample_rate <= media::Limits::kMaxSampleRate) &&
(bits_per_sample > 0) &&
- (bits_per_sample <= media::Limits::kMaxBitsPerSample);
+ (bits_per_sample <= media::Limits::kMaxBitsPerSample) &&
+ (samples_per_packet > 0) &&
+ (samples_per_packet <= media::Limits::kMaxSamplesPerPacket);
+}
+
+int AudioParameters::GetPacketSize() const {
+ return samples_per_packet * channels * bits_per_sample / 8;
}
diff --git a/media/audio/audio_parameters.h b/media/audio/audio_parameters.h
index b7b8ae5..9172d74 100644
--- a/media/audio/audio_parameters.h
+++ b/media/audio/audio_parameters.h
@@ -24,15 +24,21 @@ struct AudioParameters {
AudioParameters();
- AudioParameters(Format format, int channels,
- int sample_rate, int bits_per_sample);
+ AudioParameters(Format format, int channels, int sample_rate,
+ int bits_per_sample, int samples_per_packet);
+ // Checks that all values are in the expected range. All limits are specified
+ // in media::Limits.
bool IsValid() const;
- Format format; // Format of the stream.
- int channels; // Number of channels.
- int sample_rate; // Sampling frequency/rate.
- int bits_per_sample; // Number of bits per sample.
+ // Returns size of audio packets in bytes.
+ int GetPacketSize() const;
+
+ Format format; // Format of the stream.
+ int channels; // Number of channels.
+ int sample_rate; // Sampling frequency/rate.
+ int bits_per_sample; // Number of bits per sample.
+ int samples_per_packet; // Size of a packet in frames.
};
#endif // MEDIA_AUDIO_AUDIO_PARAMETERS_H_
diff --git a/media/audio/fake_audio_input_stream.cc b/media/audio/fake_audio_input_stream.cc
index a60446a..dacea2f 100644
--- a/media/audio/fake_audio_input_stream.cc
+++ b/media/audio/fake_audio_input_stream.cc
@@ -7,18 +7,17 @@
using base::Time;
using base::TimeDelta;
-AudioInputStream* FakeAudioInputStream::MakeFakeStream(AudioParameters params,
- int samples_per_packet) {
- return new FakeAudioInputStream(params, samples_per_packet);
+AudioInputStream* FakeAudioInputStream::MakeFakeStream(AudioParameters params) {
+ return new FakeAudioInputStream(params);
}
-FakeAudioInputStream::FakeAudioInputStream(AudioParameters params,
- int samples_per_packet)
+FakeAudioInputStream::FakeAudioInputStream(AudioParameters params)
: callback_(NULL),
buffer_size_((params.channels * params.bits_per_sample *
- samples_per_packet) / 8),
+ params.samples_per_packet) / 8),
thread_("FakeAudioRecordingThread"),
- callback_interval_ms_((samples_per_packet * 1000) / params.sample_rate) {
+ callback_interval_ms_((params.samples_per_packet * 1000) /
+ params.sample_rate) {
// This object is ref counted (so that it can be used with Thread, PostTask)
// but the caller expects a plain pointer. So we take a reference here and
// will Release() ourselves in Close().
diff --git a/media/audio/fake_audio_input_stream.h b/media/audio/fake_audio_input_stream.h
index d1e3260..62ab504 100644
--- a/media/audio/fake_audio_input_stream.h
+++ b/media/audio/fake_audio_input_stream.h
@@ -20,8 +20,7 @@ class FakeAudioInputStream :
public AudioInputStream,
public base::RefCountedThreadSafe<FakeAudioInputStream> {
public:
- static AudioInputStream* MakeFakeStream(AudioParameters params,
- int samples_per_packet);
+ static AudioInputStream* MakeFakeStream(AudioParameters params);
virtual bool Open();
virtual void Start(AudioInputCallback* callback);
@@ -32,7 +31,7 @@ class FakeAudioInputStream :
// Give RefCountedThreadSafe access our destructor.
friend class base::RefCountedThreadSafe<FakeAudioInputStream>;
- FakeAudioInputStream(AudioParameters params, int samples_per_packet);
+ FakeAudioInputStream(AudioParameters params);
virtual ~FakeAudioInputStream();
void DoCallback();
diff --git a/media/audio/fake_audio_input_stream_unittest.cc b/media/audio/fake_audio_input_stream_unittest.cc
index eee8c92..1e37359 100644
--- a/media/audio/fake_audio_input_stream_unittest.cc
+++ b/media/audio/fake_audio_input_stream_unittest.cc
@@ -41,7 +41,7 @@ TEST(FakeAudioInputTest, BasicCallbacks) {
ASSERT_TRUE(NULL != audio_man);
// Ask for one recorded packet every 50ms.
AudioInputStream* stream = audio_man->MakeAudioInputStream(
- AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8), 400);
+ AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8, 400));
ASSERT_TRUE(NULL != stream);
EXPECT_TRUE(stream->Open());
stream->Start(&callback);
diff --git a/media/audio/fake_audio_output_stream.cc b/media/audio/fake_audio_output_stream.cc
index d69e80a..1530227 100644
--- a/media/audio/fake_audio_output_stream.cc
+++ b/media/audio/fake_audio_output_stream.cc
@@ -11,12 +11,13 @@ bool FakeAudioOutputStream::has_created_fake_stream_ = false;
FakeAudioOutputStream* FakeAudioOutputStream::last_fake_stream_ = NULL;
// static
-AudioOutputStream* FakeAudioOutputStream::MakeFakeStream() {
+AudioOutputStream* FakeAudioOutputStream::MakeFakeStream(
+ AudioParameters params) {
if (!has_created_fake_stream_)
base::AtExitManager::RegisterCallback(&DestroyLastFakeStream, NULL);
has_created_fake_stream_ = true;
- FakeAudioOutputStream* new_stream = new FakeAudioOutputStream();
+ FakeAudioOutputStream* new_stream = new FakeAudioOutputStream(params);
if (last_fake_stream_) {
DCHECK(last_fake_stream_->closed_);
@@ -32,10 +33,9 @@ FakeAudioOutputStream* FakeAudioOutputStream::GetLastFakeStream() {
return last_fake_stream_;
}
-bool FakeAudioOutputStream::Open(uint32 packet_size) {
- if (packet_size < sizeof(int16))
+bool FakeAudioOutputStream::Open() {
+ if (packet_size_ < sizeof(int16))
return false;
- packet_size_ = packet_size;
buffer_.reset(new uint8[packet_size_]);
return true;
}
@@ -48,6 +48,7 @@ void FakeAudioOutputStream::Start(AudioSourceCallback* callback) {
}
void FakeAudioOutputStream::Stop() {
+ callback_ = NULL;
}
void FakeAudioOutputStream::SetVolume(double volume) {
@@ -59,19 +60,13 @@ void FakeAudioOutputStream::GetVolume(double* volume) {
}
void FakeAudioOutputStream::Close() {
- // Calls |callback_| only if it is valid. We don't have |callback_| if
- // we have not yet started.
- if (callback_) {
- callback_->OnClose(this);
- callback_ = NULL;
- }
closed_ = true;
}
-FakeAudioOutputStream::FakeAudioOutputStream()
+FakeAudioOutputStream::FakeAudioOutputStream(AudioParameters params)
: volume_(0),
callback_(NULL),
- packet_size_(0),
+ packet_size_(params.GetPacketSize()),
closed_(false) {
}
diff --git a/media/audio/fake_audio_output_stream.h b/media/audio/fake_audio_output_stream.h
index 35aed2a..5d80a8e 100644
--- a/media/audio/fake_audio_output_stream.h
+++ b/media/audio/fake_audio_output_stream.h
@@ -13,13 +13,14 @@
#include "base/scoped_ptr.h"
#include "media/audio/audio_io.h"
+#include "media/audio/audio_parameters.h"
class FakeAudioOutputStream : public AudioOutputStream {
public:
- static AudioOutputStream* MakeFakeStream();
+ static AudioOutputStream* MakeFakeStream(AudioParameters params);
static FakeAudioOutputStream* GetLastFakeStream();
- virtual bool Open(uint32 packet_size);
+ virtual bool Open();
virtual void Start(AudioSourceCallback* callback);
virtual void Stop();
virtual void SetVolume(double volume);
@@ -30,7 +31,7 @@ class FakeAudioOutputStream : public AudioOutputStream {
double volume() { return volume_; }
private:
- FakeAudioOutputStream();
+ explicit FakeAudioOutputStream(AudioParameters params);
virtual ~FakeAudioOutputStream();
static void DestroyLastFakeStream(void* param);
diff --git a/media/audio/linux/alsa_input.cc b/media/audio/linux/alsa_input.cc
index 800be6f..13aea5b4 100644
--- a/media/audio/linux/alsa_input.cc
+++ b/media/audio/linux/alsa_input.cc
@@ -28,16 +28,14 @@ const char* AlsaPcmInputStream::kAutoSelectDevice = "";
AlsaPcmInputStream::AlsaPcmInputStream(const std::string& device_name,
const AudioParameters& params,
- int samples_per_packet,
AlsaWrapper* wrapper)
: device_name_(device_name),
params_(params),
- samples_per_packet_(samples_per_packet),
- bytes_per_packet_(samples_per_packet_ *
+ bytes_per_packet_(params.samples_per_packet *
(params.channels * params.bits_per_sample) / 8),
wrapper_(wrapper),
packet_duration_ms_(
- (samples_per_packet_ * base::Time::kMillisecondsPerSecond) /
+ (params.samples_per_packet * base::Time::kMillisecondsPerSecond) /
params.sample_rate),
callback_(NULL),
device_handle_(NULL),
@@ -147,7 +145,7 @@ void AlsaPcmInputStream::ReadAudio() {
Recover(frames);
}
- if (frames < samples_per_packet_) {
+ if (frames < params_.samples_per_packet) {
// Not enough data yet or error happened. In both cases wait for a very
// small duration before checking again.
MessageLoop::current()->PostDelayedTask(
@@ -157,15 +155,15 @@ void AlsaPcmInputStream::ReadAudio() {
return;
}
- int num_packets = frames / samples_per_packet_;
+ int num_packets = frames / params_.samples_per_packet;
while (num_packets--) {
int frames_read = wrapper_->PcmReadi(device_handle_, audio_packet_.get(),
- samples_per_packet_);
- if (frames_read == samples_per_packet_) {
+ params_.samples_per_packet);
+ if (frames_read == params_.samples_per_packet) {
callback_->OnData(this, audio_packet_.get(), bytes_per_packet_);
} else {
LOG(WARNING) << "PcmReadi returning less than expected frames: "
- << frames_read << " vs. " << samples_per_packet_
+ << frames_read << " vs. " << params_.samples_per_packet
<< ". Dropping this packet.";
}
}
@@ -213,4 +211,3 @@ void AlsaPcmInputStream::HandleError(const char* method, int error) {
LOG(WARNING) << method << ": " << wrapper_->StrError(error);
callback_->OnError(this, error);
}
-
diff --git a/media/audio/linux/alsa_input.h b/media/audio/linux/alsa_input.h
index d0ed07d..94af7df 100644
--- a/media/audio/linux/alsa_input.h
+++ b/media/audio/linux/alsa_input.h
@@ -30,7 +30,6 @@ class AlsaPcmInputStream : public AudioInputStream {
// |kAutoSelectDevice|.
AlsaPcmInputStream(const std::string& device_name,
const AudioParameters& params,
- int samples_per_packet,
AlsaWrapper* wrapper);
virtual ~AlsaPcmInputStream();
@@ -53,7 +52,6 @@ class AlsaPcmInputStream : public AudioInputStream {
std::string device_name_;
AudioParameters params_;
- int samples_per_packet_;
int bytes_per_packet_;
AlsaWrapper* wrapper_;
int packet_duration_ms_; // Length of each recorded packet in milliseconds.
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc
index 410ed15f..6df30b4 100644
--- a/media/audio/linux/alsa_output.cc
+++ b/media/audio/linux/alsa_output.cc
@@ -232,15 +232,18 @@ AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name,
bytes_per_sample_(params.bits_per_sample / 8),
bytes_per_frame_(channels_ * params.bits_per_sample / 8),
should_downmix_(false),
- latency_micros_(0),
- micros_per_packet_(0),
+ packet_size_(params.GetPacketSize()),
+ micros_per_packet_(FramesToMicros(
+ params.samples_per_packet, sample_rate_)),
+ latency_micros_(std::max(AlsaPcmOutputStream::kMinLatencyMicros,
+ micros_per_packet_ * 2)),
bytes_per_output_frame_(bytes_per_frame_),
alsa_buffer_frames_(0),
stop_stream_(false),
wrapper_(wrapper),
manager_(manager),
playback_handle_(NULL),
- frames_per_packet_(0),
+ frames_per_packet_(packet_size_ / bytes_per_frame_),
client_thread_loop_(MessageLoop::current()),
message_loop_(message_loop) {
@@ -271,13 +274,9 @@ AlsaPcmOutputStream::~AlsaPcmOutputStream() {
// where the stream is not always stopped and closed, causing this to fail.
}
-bool AlsaPcmOutputStream::Open(uint32 packet_size) {
+bool AlsaPcmOutputStream::Open() {
DCHECK_EQ(MessageLoop::current(), client_thread_loop_);
- DCHECK_EQ(0U, packet_size % bytes_per_frame_)
- << "Buffers should end on a frame boundary. Frame size: "
- << bytes_per_frame_;
-
if (shared_data_.state() == kInError) {
return false;
}
@@ -294,7 +293,7 @@ bool AlsaPcmOutputStream::Open(uint32 packet_size) {
shared_data_.TransitionTo(kIsOpened);
message_loop_->PostTask(
FROM_HERE,
- NewRunnableMethod(this, &AlsaPcmOutputStream::OpenTask, packet_size));
+ NewRunnableMethod(this, &AlsaPcmOutputStream::OpenTask));
return true;
}
@@ -308,10 +307,6 @@ void AlsaPcmOutputStream::Close() {
NOTREACHED() << "Unable to transition Closed.";
}
- // Signal our successful close, and disassociate the source callback.
- shared_data_.OnClose(this);
- shared_data_.set_source_callback(NULL);
-
message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(this, &AlsaPcmOutputStream::CloseTask));
@@ -340,6 +335,9 @@ void AlsaPcmOutputStream::Start(AudioSourceCallback* callback) {
void AlsaPcmOutputStream::Stop() {
DCHECK_EQ(MessageLoop::current(), client_thread_loop_);
+ // Reset the callback, so that it is not called anymore.
+ shared_data_.set_source_callback(NULL);
+
shared_data_.TransitionTo(kIsStopped);
}
@@ -355,18 +353,10 @@ void AlsaPcmOutputStream::GetVolume(double* volume) {
*volume = shared_data_.volume();
}
-void AlsaPcmOutputStream::OpenTask(uint32 packet_size) {
+void AlsaPcmOutputStream::OpenTask() {
DCHECK_EQ(message_loop_, MessageLoop::current());
- // Initialize the configuration variables.
- packet_size_ = packet_size;
- frames_per_packet_ = packet_size_ / bytes_per_frame_;
-
// Try to open the device.
- micros_per_packet_ =
- FramesToMicros(packet_size / bytes_per_frame_, sample_rate_);
- latency_micros_ = std::max(AlsaPcmOutputStream::kMinLatencyMicros,
- micros_per_packet_ * 2);
if (requested_device_name_ == kAutoSelectDevice) {
playback_handle_ = AutoSelectDevice(latency_micros_);
if (playback_handle_)
@@ -920,13 +910,6 @@ uint32 AlsaPcmOutputStream::SharedData::OnMoreData(
return 0;
}
-void AlsaPcmOutputStream::SharedData::OnClose(AudioOutputStream* stream) {
- AutoLock l(lock_);
- if (source_callback_) {
- source_callback_->OnClose(stream);
- }
-}
-
void AlsaPcmOutputStream::SharedData::OnError(AudioOutputStream* stream,
int code) {
AutoLock l(lock_);
diff --git a/media/audio/linux/alsa_output.h b/media/audio/linux/alsa_output.h
index bd1ecb9..25ff055 100644
--- a/media/audio/linux/alsa_output.h
+++ b/media/audio/linux/alsa_output.h
@@ -24,6 +24,13 @@
// threading assumptions at the top of the implementation file to avoid
// introducing race conditions between tasks posted to the internal
// message_loop, and the thread calling the public APIs.
+//
+// TODO(sergeyu): AlsaPcmOutputStream is always created and used from the
+// audio thread (i.e. |client_thread_loop_| and |message_loop_| always point
+// to the same thread), so it doesn't need to be thread-safe anymore.
+//
+// TODO(sergeyu): Remove refcounter from AlsaPcmOutputStream and use
+// ScopedRunnableMethodFactory to create tasks.
#ifndef MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_
#define MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_
@@ -79,7 +86,7 @@ class AlsaPcmOutputStream :
MessageLoop* message_loop);
// Implementation of AudioOutputStream.
- virtual bool Open(uint32 packet_size);
+ virtual bool Open();
virtual void Close();
virtual void Start(AudioSourceCallback* callback);
virtual void Stop();
@@ -127,7 +134,7 @@ class AlsaPcmOutputStream :
friend std::ostream& operator<<(std::ostream& os, InternalState);
// Various tasks that complete actions started in the public API.
- void OpenTask(uint32 packet_size);
+ void OpenTask();
void StartTask();
void CloseTask();
@@ -179,7 +186,6 @@ class AlsaPcmOutputStream :
// using a deleted callback.
uint32 OnMoreData(AudioOutputStream* stream, uint8* dest,
uint32 max_size, AudioBuffersState buffers_state);
- void OnClose(AudioOutputStream* stream);
void OnError(AudioOutputStream* stream, int code);
// Changes the AudioSourceCallback to proxy calls to. Pass in NULL to
@@ -211,9 +217,9 @@ class AlsaPcmOutputStream :
// Device configuration data. Populated after OpenTask() completes.
std::string device_name_;
bool should_downmix_;
- uint32 latency_micros_;
uint32 packet_size_;
uint32 micros_per_packet_;
+ uint32 latency_micros_;
uint32 bytes_per_output_frame_;
uint32 alsa_buffer_frames_;
diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc
index cd50919..83c0eff 100644
--- a/media/audio/linux/alsa_output_unittest.cc
+++ b/media/audio/linux/alsa_output_unittest.cc
@@ -70,7 +70,6 @@ class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream,
uint8* dest, uint32 max_size,
AudioBuffersState buffers_state));
- MOCK_METHOD1(OnClose, void(AudioOutputStream* stream));
MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code));
};
@@ -96,16 +95,20 @@ class MockAudioManagerLinux : public AudioManagerLinux {
class AlsaPcmOutputStreamTest : public testing::Test {
protected:
AlsaPcmOutputStreamTest() {
- test_stream_ = CreateStreamWithChannels(kTestChannels);
+ test_stream_ = CreateStream(kTestChannels);
}
virtual ~AlsaPcmOutputStreamTest() {
test_stream_ = NULL;
}
- AlsaPcmOutputStream* CreateStreamWithChannels(int channels) {
+ AlsaPcmOutputStream* CreateStream(int channels) {
+ return CreateStream(channels, kTestFramesPerPacket);
+ }
+
+ AlsaPcmOutputStream* CreateStream(int channels, int32 samples_per_packet) {
AudioParameters params(kTestFormat, channels, kTestSampleRate,
- kTestBitsPerSample);
+ kTestBitsPerSample, samples_per_packet);
return new AlsaPcmOutputStream(kTestDeviceName,
params,
&mock_alsa_wrapper_,
@@ -197,18 +200,19 @@ TEST_F(AlsaPcmOutputStreamTest, ConstructedState) {
test_stream_->shared_data_.state());
// Should support mono.
- test_stream_ = CreateStreamWithChannels(1);
+ test_stream_ = CreateStream(1);
EXPECT_EQ(AlsaPcmOutputStream::kCreated,
test_stream_->shared_data_.state());
// Should support multi-channel.
- test_stream_ = CreateStreamWithChannels(3);
+ test_stream_ = CreateStream(3);
EXPECT_EQ(AlsaPcmOutputStream::kCreated,
test_stream_->shared_data_.state());
// Bad bits per sample.
AudioParameters bad_bps_params(kTestFormat, kTestChannels,
- kTestSampleRate, kTestBitsPerSample - 1);
+ kTestSampleRate, kTestBitsPerSample - 1,
+ kTestFramesPerPacket);
test_stream_ = new AlsaPcmOutputStream(kTestDeviceName,
bad_bps_params,
&mock_alsa_wrapper_,
@@ -220,7 +224,7 @@ TEST_F(AlsaPcmOutputStreamTest, ConstructedState) {
// Bad format.
AudioParameters bad_format_params(
AudioParameters::AUDIO_LAST_FORMAT, kTestChannels,
- kTestSampleRate, kTestBitsPerSample);
+ kTestSampleRate, kTestBitsPerSample, kTestFramesPerPacket);
test_stream_ = new AlsaPcmOutputStream(kTestDeviceName,
bad_format_params,
&mock_alsa_wrapper_,
@@ -235,8 +239,6 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) {
static_cast<double>(1000000) / kTestSampleRate;
const double kPacketFramesInMinLatency =
AlsaPcmOutputStream::kMinLatencyMicros / kMicrosPerFrame / 2.0;
- const int kMinLatencyPacketSize =
- static_cast<int>(kPacketFramesInMinLatency * kTestBytesPerFrame);
// Test that packets which would cause a latency under less than
// AlsaPcmOutputStream::kMinLatencyMicros will get clipped to
@@ -253,7 +255,8 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) {
SetArgumentPointee<2>(kTestFramesPerPacket / 2),
Return(0)));
- ASSERT_TRUE(test_stream_->Open(kMinLatencyPacketSize));
+ test_stream_ = CreateStream(kTestChannels, kPacketFramesInMinLatency);
+ ASSERT_TRUE(test_stream_->Open());
message_loop_.RunAllPending();
// Now close it and test that everything was released.
@@ -268,15 +271,9 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) {
Mock::VerifyAndClear(&mock_manager_);
// Test that having more packets ends up with a latency based on packet size.
- const int kOverMinLatencyPacketSize =
- (kPacketFramesInMinLatency + 1) * kTestBytesPerFrame;
- int64 expected_micros = 2 *
- AlsaPcmOutputStream::FramesToMicros(
- kOverMinLatencyPacketSize / kTestBytesPerFrame,
- kTestSampleRate);
-
- // Recreate the stream to reset the state.
- test_stream_ = CreateStreamWithChannels(kTestChannels);
+ const int kOverMinLatencyPacketSize = kPacketFramesInMinLatency + 1;
+ int64 expected_micros = 2 * AlsaPcmOutputStream::FramesToMicros(
+ kOverMinLatencyPacketSize, kTestSampleRate);
EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, _, _, _))
.WillOnce(DoAll(SetArgumentPointee<0>(kFakeHandle), Return(0)));
@@ -288,7 +285,8 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) {
SetArgumentPointee<2>(kTestFramesPerPacket / 2),
Return(0)));
- ASSERT_TRUE(test_stream_->Open(kOverMinLatencyPacketSize));
+ test_stream_ = CreateStream(kTestChannels, kOverMinLatencyPacketSize);
+ ASSERT_TRUE(test_stream_->Open());
message_loop_.RunAllPending();
// Now close it and test that everything was released.
@@ -332,7 +330,7 @@ TEST_F(AlsaPcmOutputStreamTest, OpenClose) {
Return(0)));
// Open the stream.
- ASSERT_TRUE(test_stream_->Open(kTestPacketSize));
+ ASSERT_TRUE(test_stream_->Open());
message_loop_.RunAllPending();
EXPECT_EQ(AlsaPcmOutputStream::kIsOpened,
@@ -363,7 +361,7 @@ TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) {
.WillOnce(Return(kDummyMessage));
// Open still succeeds since PcmOpen is delegated to another thread.
- ASSERT_TRUE(test_stream_->Open(kTestPacketSize));
+ ASSERT_TRUE(test_stream_->Open());
ASSERT_EQ(AlsaPcmOutputStream::kIsOpened,
test_stream_->shared_data_.state());
ASSERT_FALSE(test_stream_->stop_stream_);
@@ -397,7 +395,7 @@ TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) {
// If open fails, the stream stays in kCreated because it has effectively had
// no changes.
- ASSERT_TRUE(test_stream_->Open(kTestPacketSize));
+ ASSERT_TRUE(test_stream_->Open());
EXPECT_EQ(AlsaPcmOutputStream::kIsOpened,
test_stream_->shared_data_.state());
ASSERT_FALSE(test_stream_->stop_stream_);
@@ -431,7 +429,7 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
Return(0)));
// Open the stream.
- ASSERT_TRUE(test_stream_->Open(kTestPacketSize));
+ ASSERT_TRUE(test_stream_->Open());
message_loop_.RunAllPending();
// Expect Device setup.
@@ -469,7 +467,6 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
message_loop_.RunAllPending();
EXPECT_CALL(mock_manager_, ReleaseOutputStream(test_stream_.get()));
- EXPECT_CALL(mock_callback, OnClose(test_stream_.get()));
EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle))
.WillOnce(Return(0));
EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle))
@@ -684,7 +681,7 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) {
.WillRepeatedly(Invoke(EchoHint));
- test_stream_ = CreateStreamWithChannels(i);
+ test_stream_ = CreateStream(i);
EXPECT_TRUE(test_stream_->AutoSelectDevice(i));
EXPECT_EQ(kExpectedDownmix[i], test_stream_->should_downmix_);
@@ -734,7 +731,7 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_FallbackDevices) {
EXPECT_CALL(mock_alsa_wrapper_, PcmOpen(_, StrEq(fourth_try.c_str()), _, _))
.WillOnce(Return(kTestFailedErrno));
- test_stream_ = CreateStreamWithChannels(5);
+ test_stream_ = CreateStream(5);
EXPECT_FALSE(test_stream_->AutoSelectDevice(5));
}
@@ -752,7 +749,7 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) {
EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno))
.WillOnce(Return(kDummyMessage));
- test_stream_ = CreateStreamWithChannels(5);
+ test_stream_ = CreateStream(5);
EXPECT_TRUE(test_stream_->AutoSelectDevice(5));
EXPECT_TRUE(test_stream_->should_downmix_);
}
diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc
index b22ec44..fdf8044 100644
--- a/media/audio/linux/audio_manager_linux.cc
+++ b/media/audio/linux/audio_manager_linux.cc
@@ -17,7 +17,6 @@
namespace {
const int kMaxInputChannels = 2;
-const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate;
} // namespace
@@ -37,7 +36,7 @@ AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream(
// Early return for testing hook. Do this before checking for
// |initialized_|.
if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioOutputStream::MakeFakeStream();
+ return FakeAudioOutputStream::MakeFakeStream(params);
}
if (!initialized()) {
@@ -60,13 +59,12 @@ AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream(
}
AudioInputStream* AudioManagerLinux::MakeAudioInputStream(
- AudioParameters params, int samples_per_packet) {
- if (!params.IsValid() || params.channels > kMaxInputChannels ||
- samples_per_packet < 0 || samples_per_packet > kMaxSamplesPerPacket)
+ AudioParameters params) {
+ if (!params.IsValid() || params.channels > kMaxInputChannels)
return NULL;
if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet);
+ return FakeAudioInputStream::MakeFakeStream(params);
} else if (params.format != AudioParameters::AUDIO_PCM_LINEAR) {
return NULL;
}
@@ -81,7 +79,7 @@ AudioInputStream* AudioManagerLinux::MakeAudioInputStream(
}
AlsaPcmInputStream* stream = new AlsaPcmInputStream(
- device_name, params, samples_per_packet, wrapper_.get());
+ device_name, params, wrapper_.get());
return stream;
}
diff --git a/media/audio/linux/audio_manager_linux.h b/media/audio/linux/audio_manager_linux.h
index afa60af..a5ba17cf 100644
--- a/media/audio/linux/audio_manager_linux.h
+++ b/media/audio/linux/audio_manager_linux.h
@@ -27,8 +27,7 @@ class AudioManagerLinux : public AudioManagerBase {
virtual bool HasAudioOutputDevices();
virtual bool HasAudioInputDevices();
virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params);
- virtual AudioInputStream* MakeAudioInputStream(
- AudioParameters params, int samples_per_packet);
+ virtual AudioInputStream* MakeAudioInputStream(AudioParameters params);
virtual void MuteAll();
virtual void UnMuteAll();
diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc
index 88db2db..7e0c933 100644
--- a/media/audio/mac/audio_input_mac.cc
+++ b/media/audio/mac/audio_input_mac.cc
@@ -17,9 +17,7 @@ enum {
#endif
PCMQueueInAudioInputStream::PCMQueueInAudioInputStream(
- AudioManagerMac* manager,
- AudioParameters params,
- int samples_per_buffer)
+ AudioManagerMac* manager, AudioParameters params)
: manager_(manager),
callback_(NULL),
audio_queue_(NULL),
@@ -39,7 +37,7 @@ PCMQueueInAudioInputStream::PCMQueueInAudioInputStream(
format_.mBytesPerPacket = (params.bits_per_sample * params.channels) / 8;
format_.mBytesPerFrame = format_.mBytesPerPacket;
- buffer_size_bytes_ = format_.mBytesPerFrame * samples_per_buffer;
+ buffer_size_bytes_ = params.GetPacketSize();
}
PCMQueueInAudioInputStream::~PCMQueueInAudioInputStream() {
diff --git a/media/audio/mac/audio_input_mac.h b/media/audio/mac/audio_input_mac.h
index 8b049f7..078d4da 100644
--- a/media/audio/mac/audio_input_mac.h
+++ b/media/audio/mac/audio_input_mac.h
@@ -19,8 +19,7 @@ class PCMQueueInAudioInputStream : public AudioInputStream {
public:
// Parameters as per AudioManager::MakeAudioInputStream.
PCMQueueInAudioInputStream(AudioManagerMac* manager,
- AudioParameters params,
- int samples_per_packet);
+ AudioParameters params);
virtual ~PCMQueueInAudioInputStream();
// Implementation of AudioInputStream.
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
index 1eb9398..4565bba 100644
--- a/media/audio/mac/audio_manager_mac.cc
+++ b/media/audio/mac/audio_manager_mac.cc
@@ -13,7 +13,6 @@
namespace {
const int kMaxInputChannels = 2;
-const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate;
bool HasAudioHardware(AudioObjectPropertySelector selector) {
AudioDeviceID output_device_id = kAudioObjectUnknown;
@@ -45,22 +44,21 @@ bool AudioManagerMac::HasAudioInputDevices() {
AudioOutputStream* AudioManagerMac::MakeAudioOutputStream(
AudioParameters params) {
if (params.format == AudioParameters::AUDIO_MOCK)
- return FakeAudioOutputStream::MakeFakeStream();
+ return FakeAudioOutputStream::MakeFakeStream(params);
else if (params.format != AudioParameters::AUDIO_PCM_LINEAR)
return NULL;
return new PCMQueueOutAudioOutputStream(this, params);
}
AudioInputStream* AudioManagerMac::MakeAudioInputStream(
- AudioParameters params, int samples_per_packet) {
- if (!params.IsValid() || (params.channels > kMaxInputChannels) ||
- (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0))
+ AudioParameters params) {
+ if (!params.IsValid() || (params.channels > kMaxInputChannels))
return NULL;
if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet);
+ return FakeAudioInputStream::MakeFakeStream(params);
} else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
- return new PCMQueueInAudioInputStream(this, params, samples_per_packet);
+ return new PCMQueueInAudioInputStream(this, params);
}
return NULL;
}
diff --git a/media/audio/mac/audio_manager_mac.h b/media/audio/mac/audio_manager_mac.h
index 3abfab1..31f6de2 100644
--- a/media/audio/mac/audio_manager_mac.h
+++ b/media/audio/mac/audio_manager_mac.h
@@ -22,8 +22,7 @@ class AudioManagerMac : public AudioManagerBase {
virtual bool HasAudioOutputDevices();
virtual bool HasAudioInputDevices();
virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params);
- virtual AudioInputStream* MakeAudioInputStream(AudioParameters params,
- int samples_per_packet);
+ virtual AudioInputStream* MakeAudioInputStream(AudioParameters params);
virtual void MuteAll();
virtual void UnMuteAll();
diff --git a/media/audio/mac/audio_output_mac.cc b/media/audio/mac/audio_output_mac.cc
index 8d68b27..615fa5e 100644
--- a/media/audio/mac/audio_output_mac.cc
+++ b/media/audio/mac/audio_output_mac.cc
@@ -45,14 +45,14 @@ enum {
PCMQueueOutAudioOutputStream::PCMQueueOutAudioOutputStream(
AudioManagerMac* manager, AudioParameters params)
- : format_(),
- audio_queue_(NULL),
- buffer_(),
- source_(NULL),
- manager_(manager),
- silence_bytes_(0),
- volume_(1),
- pending_bytes_(0) {
+ : format_(),
+ audio_queue_(NULL),
+ buffer_(),
+ source_(NULL),
+ manager_(manager),
+ silence_bytes_(0),
+ volume_(1),
+ pending_bytes_(0) {
// We must have a manager.
DCHECK(manager_);
// A frame is one sample across all channels. In interleaved audio the per
@@ -68,6 +68,8 @@ PCMQueueOutAudioOutputStream::PCMQueueOutAudioOutputStream(
format_.mBytesPerPacket = (format_.mBitsPerChannel * params.channels) / 8;
format_.mBytesPerFrame = format_.mBytesPerPacket;
+ packet_size_ = params.GetPacketSize();
+
// Silence buffer has a duration of 6ms to simulate the behavior of Windows.
// This value is choosen by experiments and macs cannot keep up with
// anything less than 6ms.
@@ -87,11 +89,7 @@ void PCMQueueOutAudioOutputStream::HandleError(OSStatus err) {
NOTREACHED() << "error code " << err;
}
-bool PCMQueueOutAudioOutputStream::Open(uint32 packet_size) {
- if (0 == packet_size) {
- // TODO(cpu) : Impelement default buffer computation.
- return false;
- }
+bool PCMQueueOutAudioOutputStream::Open() {
// Create the actual queue object and let the OS use its own thread to
// run its CFRunLoop.
OSStatus err = AudioQueueNewOutput(&format_, RenderCallback, this, NULL,
@@ -102,7 +100,7 @@ bool PCMQueueOutAudioOutputStream::Open(uint32 packet_size) {
}
// Allocate the hardware-managed buffers.
for (uint32 ix = 0; ix != kNumBuffers; ++ix) {
- err = AudioQueueAllocateBuffer(audio_queue_, packet_size, &buffer_[ix]);
+ err = AudioQueueAllocateBuffer(audio_queue_, packet_size_, &buffer_[ix]);
if (err != noErr) {
HandleError(err);
return false;
diff --git a/media/audio/mac/audio_output_mac.h b/media/audio/mac/audio_output_mac.h
index 60cf2b6..31128bc 100644
--- a/media/audio/mac/audio_output_mac.h
+++ b/media/audio/mac/audio_output_mac.h
@@ -27,7 +27,7 @@ class PCMQueueOutAudioOutputStream : public AudioOutputStream {
virtual ~PCMQueueOutAudioOutputStream();
// Implementation of AudioOutputStream.
- virtual bool Open(uint32 packet_size);
+ virtual bool Open();
virtual void Close();
virtual void Start(AudioSourceCallback* callback);
virtual void Stop();
@@ -54,6 +54,8 @@ class PCMQueueOutAudioOutputStream : public AudioOutputStream {
AudioSourceCallback* source_;
// Our creator, the audio manager needs to be notified when we close.
AudioManagerMac* manager_;
+ // Packet size in bytes.
+ uint32 packet_size_;
// Number of bytes for making a silence buffer.
int silence_bytes_;
// Volume level from 0 to 1.
diff --git a/media/audio/mac/audio_output_mac_unittest.cc b/media/audio/mac/audio_output_mac_unittest.cc
index 061316f..e330e2b 100644
--- a/media/audio/mac/audio_output_mac_unittest.cc
+++ b/media/audio/mac/audio_output_mac_unittest.cc
@@ -24,7 +24,6 @@ class MockAudioSource : public AudioOutputStream::AudioSourceCallback {
MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, uint8* dest,
uint32 max_size,
AudioBuffersState buffers_state));
- MOCK_METHOD1(OnClose, void(AudioOutputStream* stream));
MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code));
};
@@ -58,7 +57,7 @@ TEST(MacAudioTest, PCMWaveStreamGetAndClose) {
if (!audio_man->HasAudioOutputDevices())
return;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16));
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16, 1024));
ASSERT_TRUE(NULL != oas);
oas->Close();
}
@@ -70,9 +69,9 @@ TEST(MacAudioTest, PCMWaveStreamOpenAndClose) {
if (!audio_man->HasAudioOutputDevices())
return;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16));
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16, 1024));
ASSERT_TRUE(NULL != oas);
- EXPECT_TRUE(oas->Open(1024));
+ EXPECT_TRUE(oas->Open());
oas->Close();
}
@@ -85,17 +84,15 @@ TEST(MacAudioTest, PCMWaveStreamPlay200HzTone44KssMono) {
ASSERT_TRUE(NULL != audio_man);
if (!audio_man->HasAudioOutputDevices())
return;
+ uint32 frames_100_ms = AudioParameters::kAudioCDSampleRate / 10;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1,
- AudioParameters::kAudioCDSampleRate, 16));
+ AudioParameters::kAudioCDSampleRate, 16, frames_100_ms));
ASSERT_TRUE(NULL != oas);
+ EXPECT_TRUE(oas->Open());
SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
200.0, AudioParameters::kAudioCDSampleRate);
- uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2;
-
- EXPECT_TRUE(oas->Open(bytes_100_ms));
-
oas->SetVolume(0.5);
oas->Start(&source);
usleep(500000);
@@ -118,16 +115,16 @@ TEST(MacAudioTest, PCMWaveStreamPlay200HzTone22KssMono) {
ASSERT_TRUE(NULL != audio_man);
if (!audio_man->HasAudioOutputDevices())
return;
+ uint32 frames_100_ms = AudioParameters::kAudioCDSampleRate / 10;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1,
- AudioParameters::kAudioCDSampleRate / 2, 16));
+ AudioParameters::kAudioCDSampleRate / 2, 16,
+ frames_100_ms));
ASSERT_TRUE(NULL != oas);
SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
200.0, AudioParameters::kAudioCDSampleRate/2);
- uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 20) * 2;
-
- EXPECT_TRUE(oas->Open(bytes_100_ms));
+ EXPECT_TRUE(oas->Open());
oas->Start(&source);
usleep(1500000);
oas->Stop();
@@ -145,14 +142,17 @@ TEST(MacAudioTest, PCMWaveStreamPendingBytes) {
ASSERT_TRUE(NULL != audio_man);
if (!audio_man->HasAudioOutputDevices())
return;
+
+ uint32 frames_100_ms = AudioParameters::kAudioCDSampleRate / 10;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1,
- AudioParameters::kAudioCDSampleRate, 16));
+ AudioParameters::kAudioCDSampleRate, 16, frames_100_ms));
ASSERT_TRUE(NULL != oas);
NiceMock<MockAudioSource> source;
- uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2;
- EXPECT_TRUE(oas->Open(bytes_100_ms));
+ EXPECT_TRUE(oas->Open());
+
+ uint32 bytes_100_ms = frames_100_ms * 2;
// We expect the amount of pending bytes will reaching |bytes_100_ms|
// because the audio output stream has a double buffer scheme.
diff --git a/media/audio/openbsd/audio_manager_openbsd.cc b/media/audio/openbsd/audio_manager_openbsd.cc
index 251a085..b200309 100644
--- a/media/audio/openbsd/audio_manager_openbsd.cc
+++ b/media/audio/openbsd/audio_manager_openbsd.cc
@@ -28,8 +28,7 @@ AudioOutputStream* AudioManagerOpenBSD::MakeAudioOutputStream(
}
AudioInputStream* AudioManagerOpenBSD::MakeAudioInputStream(
- AudioParameters params,
- uint32 samples_per_packet) {
+ AudioParameters params) {
NOTIMPLEMENTED();
return NULL;
}
diff --git a/media/audio/openbsd/audio_manager_openbsd.h b/media/audio/openbsd/audio_manager_openbsd.h
index c643cdd..281ac79 100644
--- a/media/audio/openbsd/audio_manager_openbsd.h
+++ b/media/audio/openbsd/audio_manager_openbsd.h
@@ -18,8 +18,7 @@ class AudioManagerOpenBSD : public AudioManagerBase {
virtual bool HasAudioOutputDevices();
virtual bool HasAudioInputDevices();
virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params);
- virtual AudioInputStream* MakeAudioInputStream(AudioParameters params,
- uint32 samples_per_packet);
+ virtual AudioInputStream* MakeAudioInputStream(AudioParameters params);
virtual void MuteAll();
virtual void UnMuteAll();
diff --git a/media/audio/simple_sources.cc b/media/audio/simple_sources.cc
index 5445600..df0a730 100644
--- a/media/audio/simple_sources.cc
+++ b/media/audio/simple_sources.cc
@@ -43,9 +43,6 @@ uint32 SineWaveAudioSource::OnMoreData(
return max_size;
}
-void SineWaveAudioSource::OnClose(AudioOutputStream* stream) {
-}
-
void SineWaveAudioSource::OnError(AudioOutputStream* stream, int code) {
NOTREACHED();
}
@@ -65,10 +62,6 @@ uint32 PushSource::OnMoreData(
return buffer_.Read(dest, max_size);
}
-void PushSource::OnClose(AudioOutputStream* stream) {
- CleanUp();
-}
-
void PushSource::OnError(AudioOutputStream* stream, int code) {
NOTREACHED();
}
diff --git a/media/audio/simple_sources.h b/media/audio/simple_sources.h
index 4f4dc07..dec839d 100644
--- a/media/audio/simple_sources.h
+++ b/media/audio/simple_sources.h
@@ -29,7 +29,6 @@ class SineWaveAudioSource : public AudioOutputStream::AudioSourceCallback {
virtual uint32 OnMoreData(
AudioOutputStream* stream, uint8* dest, uint32 max_size,
AudioBuffersState audio_buffers);
- virtual void OnClose(AudioOutputStream* stream);
virtual void OnError(AudioOutputStream* stream, int code);
protected:
@@ -73,7 +72,6 @@ class PushSource : public AudioOutputStream::AudioSourceCallback,
// Implementation of AudioSourceCallback.
virtual uint32 OnMoreData(AudioOutputStream* stream, uint8* dest,
uint32 max_size, AudioBuffersState buffers_state);
- virtual void OnClose(AudioOutputStream* stream);
virtual void OnError(AudioOutputStream* stream, int code);
// Discard all buffered data and reset to initial state.
diff --git a/media/audio/simple_sources_unittest.cc b/media/audio/simple_sources_unittest.cc
index bbcbff2..f96ffad 100644
--- a/media/audio/simple_sources_unittest.cc
+++ b/media/audio/simple_sources_unittest.cc
@@ -58,8 +58,6 @@ TEST(SimpleSourcesTest, PushSourceSmallerWrite) {
EXPECT_EQ(0, memcmp(data.get() + i, read_data.get(), size));
}
EXPECT_EQ(0u, push_source.UnProcessedBytes());
-
- push_source.OnClose(NULL);
}
// Validate that the SineWaveAudioSource writes the expected values for
@@ -78,10 +76,10 @@ TEST(SimpleSources, SineWaveAudio16MonoTest) {
ASSERT_TRUE(NULL != audio_man);
AudioParameters params(
AudioParameters::AUDIO_MOCK, 1, AudioParameters::kTelephoneSampleRate,
- bytes_per_sample * 2);
+ bytes_per_sample * 2, samples);
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(params);
ASSERT_TRUE(NULL != oas);
- EXPECT_TRUE(oas->Open(samples * bytes_per_sample));
+ EXPECT_TRUE(oas->Open());
oas->Start(&source);
oas->Stop();
diff --git a/media/audio/test_audio_input_controller_factory.cc b/media/audio/test_audio_input_controller_factory.cc
index 99980bf..2a2f402 100644
--- a/media/audio/test_audio_input_controller_factory.cc
+++ b/media/audio/test_audio_input_controller_factory.cc
@@ -25,8 +25,7 @@ TestAudioInputControllerFactory::TestAudioInputControllerFactory()
AudioInputController* TestAudioInputControllerFactory::Create(
AudioInputController::EventHandler* event_handler,
- AudioParameters params,
- int samples_per_packet) {
+ AudioParameters params) {
DCHECK(!controller_); // Only one test instance managed at a time.
controller_ = new TestAudioInputController(this, event_handler);
return controller_;
diff --git a/media/audio/test_audio_input_controller_factory.h b/media/audio/test_audio_input_controller_factory.h
index 0d14828..382626d 100644
--- a/media/audio/test_audio_input_controller_factory.h
+++ b/media/audio/test_audio_input_controller_factory.h
@@ -74,8 +74,7 @@ class TestAudioInputControllerFactory : public AudioInputController::Factory {
// AudioInputController::Factory methods.
AudioInputController* Create(
AudioInputController::EventHandler* event_handler,
- AudioParameters params,
- int samples_per_packet);
+ AudioParameters params);
TestAudioInputController* controller() const { return controller_; }
diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc
index 3d5c137..a2fbd92 100644
--- a/media/audio/win/audio_manager_win.cc
+++ b/media/audio/win/audio_manager_win.cc
@@ -23,7 +23,6 @@ namespace {
const int kWinMaxChannels = 8;
const int kWinMaxInputChannels = 2;
-const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate;
// We use 3 buffers for recording audio so that if a recording callback takes
// some time to return we won't lose audio. More buffers while recording are
// ok because they don't introduce any delay in recording, unlike in playback
@@ -51,7 +50,7 @@ AudioOutputStream* AudioManagerWin::MakeAudioOutputStream(
return NULL;
if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioOutputStream::MakeFakeStream();
+ return FakeAudioOutputStream::MakeFakeStream(params);
} else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
return new PCMWaveOutAudioOutputStream(this, params, 3, WAVE_MAPPER);
} else if (params.format == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
@@ -63,16 +62,15 @@ AudioOutputStream* AudioManagerWin::MakeAudioOutputStream(
// Factory for the implementations of AudioInputStream.
AudioInputStream* AudioManagerWin::MakeAudioInputStream(
- AudioParameters params, int samples_per_packet) {
- if (!params.IsValid() || (params.channels > kWinMaxInputChannels) ||
- (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0))
+ AudioParameters params) {
+ if (!params.IsValid() || (params.channels > kWinMaxInputChannels))
return NULL;
if (params.format == AudioParameters::AUDIO_MOCK) {
- return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet);
+ return FakeAudioInputStream::MakeFakeStream(params);
} else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) {
return new PCMWaveInAudioInputStream(this, params, kNumInputBuffers,
- samples_per_packet, WAVE_MAPPER);
+ WAVE_MAPPER);
}
return NULL;
}
diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h
index 09f0019..2ea4c8f 100644
--- a/media/audio/win/audio_manager_win.h
+++ b/media/audio/win/audio_manager_win.h
@@ -23,8 +23,7 @@ class AudioManagerWin : public AudioManagerBase {
virtual bool HasAudioOutputDevices();
virtual bool HasAudioInputDevices();
virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params);
- virtual AudioInputStream* MakeAudioInputStream(AudioParameters params,
- int samples_per_packet);
+ virtual AudioInputStream* MakeAudioInputStream(AudioParameters params);
virtual void MuteAll();
virtual void UnMuteAll();
diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc
index 2e86450..7665d08 100644
--- a/media/audio/win/audio_output_win_unittest.cc
+++ b/media/audio/win/audio_output_win_unittest.cc
@@ -36,8 +36,7 @@ class TestSourceBasic : public AudioOutputStream::AudioSourceCallback {
public:
explicit TestSourceBasic()
: callback_count_(0),
- had_error_(0),
- was_closed_(0) {
+ had_error_(0) {
}
// AudioSourceCallback::OnMoreData implementation:
virtual uint32 OnMoreData(AudioOutputStream* stream, uint8* dest,
@@ -48,10 +47,6 @@ class TestSourceBasic : public AudioOutputStream::AudioSourceCallback {
reinterpret_cast<char*>(dest)[0] = 1;
return max_size;
}
- // AudioSourceCallback::OnClose implementation:
- virtual void OnClose(AudioOutputStream* stream) {
- ++was_closed_;
- }
// AudioSourceCallback::OnError implementation:
virtual void OnError(AudioOutputStream* stream, int code) {
++had_error_;
@@ -68,15 +63,10 @@ class TestSourceBasic : public AudioOutputStream::AudioSourceCallback {
void set_error(bool error) {
had_error_ += error ? 1 : 0;
}
- // Returns how many times the OnClose callback was called.
- int was_closed() const {
- return was_closed_;
- }
private:
int callback_count_;
int had_error_;
- int was_closed_;
};
bool IsRunningHeadless() {
@@ -153,7 +143,6 @@ class MockAudioSource : public AudioOutputStream::AudioSourceCallback {
MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, uint8* dest,
uint32 max_size,
AudioBuffersState buffers_state));
- MOCK_METHOD1(OnClose, void(AudioOutputStream* stream));
MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code));
};
@@ -211,16 +200,15 @@ TEST(WinAudioTest, MockStreamBasicCallbacks) {
AudioManager* audio_man = AudioManager::GetAudioManager();
ASSERT_TRUE(NULL != audio_man);
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
- AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8));
+ AudioParameters(AudioParameters::AUDIO_MOCK, 2, 8000, 8, 128));
ASSERT_TRUE(NULL != oas);
- EXPECT_TRUE(oas->Open(256));
+ EXPECT_TRUE(oas->Open());
TestSourceBasic source;
oas->Start(&source);
EXPECT_GT(source.callback_count(), 0);
oas->Stop();
oas->Close();
EXPECT_EQ(0, source.had_error());
- EXPECT_EQ(1, source.was_closed());
}
// ===========================================================================
@@ -240,7 +228,7 @@ TEST(WinAudioTest, PCMWaveStreamGetAndClose) {
if (!audio_man->HasAudioOutputDevices())
return;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16));
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16, 256));
ASSERT_TRUE(NULL != oas);
oas->Close();
}
@@ -255,17 +243,21 @@ TEST(WinAudioTest, SanityOnMakeParams) {
return;
AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR;
EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
- AudioParameters(fmt, 9, 8000, 16)));
+ AudioParameters(fmt, 9, 8000, 16, 256)));
+ EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
+ AudioParameters(fmt, 1, 1024 * 1024, 16, 256)));
+ EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
+ AudioParameters(fmt, 2, 8000, 80, 256)));
EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
- AudioParameters(fmt, 1, 1024 * 1024, 16)));
+ AudioParameters(fmt, -2, 8000, 16, 256)));
EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
- AudioParameters(fmt, 2, 8000, 80)));
+ AudioParameters(fmt, 2, -8000, 16, 256)));
EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
- AudioParameters(fmt, -2, 8000, 16)));
+ AudioParameters(fmt, 1, 8000, 16, -100)));
EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
- AudioParameters(fmt, 2, -8000, 16)));
+ AudioParameters(fmt, 1, 8000, 16, 0)));
EXPECT_TRUE(NULL == audio_man->MakeAudioOutputStream(
- AudioParameters(fmt, 2, -8000, -16)));
+ AudioParameters(fmt, 1, 8000, 16, 100000)));
}
// Test that it can be opened and closed.
@@ -277,9 +269,9 @@ TEST(WinAudioTest, PCMWaveStreamOpenAndClose) {
if (!audio_man->HasAudioOutputDevices())
return;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16));
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16, 256));
ASSERT_TRUE(NULL != oas);
- EXPECT_TRUE(oas->Open(1024));
+ EXPECT_TRUE(oas->Open());
oas->Close();
}
@@ -292,9 +284,9 @@ TEST(WinAudioTest, PCMWaveStreamOpenLimit) {
if (!audio_man->HasAudioOutputDevices())
return;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16));
- ASSERT_TRUE(NULL != oas);
- EXPECT_FALSE(oas->Open(1024 * 1024 * 1024));
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16,
+ 1024 * 1024 * 1024));
+ ASSERT_TRUE(NULL == oas);
oas->Close();
}
@@ -308,10 +300,10 @@ TEST(WinAudioTest, PCMWaveStreamTripleBuffer) {
if (!audio_man->HasAudioOutputDevices())
return;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16));
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16, 256));
ASSERT_TRUE(NULL != oas);
TestSourceTripleBuffer test_triple_buffer;
- EXPECT_TRUE(oas->Open(512));
+ EXPECT_TRUE(oas->Open());
oas->Start(&test_triple_buffer);
::Sleep(300);
EXPECT_GT(test_triple_buffer.callback_count(), kNumBuffers);
@@ -332,10 +324,10 @@ TEST(WinAudioTest, PCMWaveSlowSource) {
if (!audio_man->HasAudioOutputDevices())
return;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16));
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16, 256));
ASSERT_TRUE(NULL != oas);
TestSourceLaggy test_laggy(2, 90);
- EXPECT_TRUE(oas->Open(512));
+ EXPECT_TRUE(oas->Open());
// The test parameters cause a callback every 32 ms and the source is
// sleeping for 90 ms, so it is guaranteed that we run out of ready buffers.
oas->Start(&test_laggy);
@@ -357,16 +349,16 @@ TEST(WinAudioTest, PCMWaveStreamPlaySlowLoop) {
ASSERT_TRUE(NULL != audio_man);
if (!audio_man->HasAudioOutputDevices())
return;
+ uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1,
- AudioParameters::kAudioCDSampleRate, 16));
+ AudioParameters::kAudioCDSampleRate, 16, samples_100_ms));
ASSERT_TRUE(NULL != oas);
SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
200.0, AudioParameters::kAudioCDSampleRate);
- uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2;
- EXPECT_TRUE(oas->Open(bytes_100_ms));
+ EXPECT_TRUE(oas->Open());
oas->SetVolume(1.0);
for (int ix = 0; ix != 5; ++ix) {
@@ -388,16 +380,16 @@ TEST(WinAudioTest, PCMWaveStreamPlay200HzTone44Kss) {
ASSERT_TRUE(NULL != audio_man);
if (!audio_man->HasAudioOutputDevices())
return;
+ uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1,
- AudioParameters::kAudioCDSampleRate, 16));
+ AudioParameters::kAudioCDSampleRate, 16, samples_100_ms));
ASSERT_TRUE(NULL != oas);
SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
200.0, AudioParameters::kAudioCDSampleRate);
- uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2;
- EXPECT_TRUE(oas->Open(bytes_100_ms));
+ EXPECT_TRUE(oas->Open());
oas->SetVolume(1.0);
oas->Start(&source);
::Sleep(500);
@@ -416,16 +408,17 @@ TEST(WinAudioTest, PCMWaveStreamPlay200HzTone22Kss) {
ASSERT_TRUE(NULL != audio_man);
if (!audio_man->HasAudioOutputDevices())
return;
+ uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 20;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1,
- AudioParameters::kAudioCDSampleRate / 2, 16));
+ AudioParameters::kAudioCDSampleRate / 2, 16,
+ samples_100_ms));
ASSERT_TRUE(NULL != oas);
SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
200.0, AudioParameters::kAudioCDSampleRate/2);
- uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 20) * 2;
- EXPECT_TRUE(oas->Open(bytes_100_ms));
+ EXPECT_TRUE(oas->Open());
oas->SetVolume(0.5);
oas->Start(&source);
@@ -462,29 +455,33 @@ TEST(WinAudioTest, PushSourceFile16KHz) {
ASSERT_TRUE(NULL != audio_man);
if (!audio_man->HasAudioOutputDevices())
return;
+
+ // Compute buffer size for 100ms of audio.
+ const uint32 kSamples100ms = (16000 / 1000) * 100;
+ const uint32 kSize100ms = kSamples100ms * 2;
+
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
- AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16));
+ AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1, 16000, 16,
+ kSamples100ms));
ASSERT_TRUE(NULL != oas);
- // compute buffer size for 100ms of audio. Which is 3200 bytes.
- const uint32 kSize50ms = 2 * (16000 / 1000) * 100;
- EXPECT_TRUE(oas->Open(kSize50ms));
+ EXPECT_TRUE(oas->Open());
uint32 offset = 0;
- const uint32 kMaxStartOffset = file_reader.size() - kSize50ms;
+ const uint32 kMaxStartOffset = file_reader.size() - kSize100ms;
// We buffer and play at the same time, buffering happens every ~10ms and the
- // consuming of the buffer happens every ~50ms. We do 100 buffers which
+ // consuming of the buffer happens every ~100ms. We do 100 buffers which
// effectively wrap around the file more than once.
PushSource push_source;
for (uint32 ix = 0; ix != 100; ++ix) {
- push_source.Write(file_reader.GetChunkAt(offset), kSize50ms);
+ push_source.Write(file_reader.GetChunkAt(offset), kSize100ms);
if (ix == 2) {
// For glitch free, start playing after some buffers are in.
oas->Start(&push_source);
}
::Sleep(10);
- offset += kSize50ms;
+ offset += kSize100ms;
if (offset > kMaxStartOffset)
offset = 0;
}
@@ -506,16 +503,16 @@ TEST(WinAudioTest, PCMWaveStreamPlayTwice200HzTone44Kss) {
ASSERT_TRUE(NULL != audio_man);
if (!audio_man->HasAudioOutputDevices())
return;
+
+ uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1,
- AudioParameters::kAudioCDSampleRate, 16));
+ AudioParameters::kAudioCDSampleRate, 16, samples_100_ms));
ASSERT_TRUE(NULL != oas);
SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
200.0, AudioParameters::kAudioCDSampleRate);
- uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2;
-
- EXPECT_TRUE(oas->Open(bytes_100_ms));
+ EXPECT_TRUE(oas->Open());
oas->SetVolume(1.0);
// Play the wave for .5 seconds.
@@ -545,17 +542,17 @@ TEST(WinAudioTest, PCMWaveStreamPlay200HzTone44KssLowLatency) {
ASSERT_TRUE(NULL != audio_man);
if (!audio_man->HasAudioOutputDevices())
return;
+
+ uint32 samples_50_ms = AudioParameters::kAudioCDSampleRate / 20;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, 1,
- AudioParameters::kAudioCDSampleRate, 16));
+ AudioParameters::kAudioCDSampleRate, 16, samples_50_ms));
ASSERT_TRUE(NULL != oas);
SineWaveAudioSource source(SineWaveAudioSource::FORMAT_16BIT_LINEAR_PCM, 1,
200.0, AudioParameters::kAudioCDSampleRate);
- uint32 bytes_50_ms = (AudioParameters::kAudioCDSampleRate / 20) *
- sizeof(uint16);
- EXPECT_TRUE(oas->Open(bytes_50_ms));
+ EXPECT_TRUE(oas->Open());
oas->SetVolume(1.0);
// Play the wave for .8 seconds.
@@ -573,14 +570,17 @@ TEST(WinAudioTest, PCMWaveStreamPendingBytes) {
ASSERT_TRUE(NULL != audio_man);
if (!audio_man->HasAudioOutputDevices())
return;
+
+ uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 1,
- AudioParameters::kAudioCDSampleRate, 16));
+ AudioParameters::kAudioCDSampleRate, 16, samples_100_ms));
ASSERT_TRUE(NULL != oas);
NiceMock<MockAudioSource> source;
- uint32 bytes_100_ms = (AudioParameters::kAudioCDSampleRate / 10) * 2;
- EXPECT_TRUE(oas->Open(bytes_100_ms));
+ EXPECT_TRUE(oas->Open());
+
+ uint32 bytes_100_ms = samples_100_ms * 2;
// We expect the amount of pending bytes will reaching 2 times of
// |bytes_100_ms| because the audio output stream has a triple buffer scheme.
@@ -637,9 +637,6 @@ class SyncSocketSource : public AudioOutputStream::AudioSourceCallback {
uint32 got = socket_->Receive(dest, max_size);
return got;
}
- // AudioSourceCallback::OnClose implementation:
- virtual void OnClose(AudioOutputStream* stream) {
- }
// AudioSourceCallback::OnError implementation:
virtual void OnError(AudioOutputStream* stream, int code) {
}
@@ -703,14 +700,14 @@ TEST(WinAudioTest, SyncSocketBasic) {
return;
int sample_rate = AudioParameters::kAudioCDSampleRate;
+ const uint32 kSamples20ms = sample_rate / 50;
AudioOutputStream* oas = audio_man->MakeAudioOutputStream(
AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, 1,
- sample_rate, 16));
+ sample_rate, 16, kSamples20ms));
ASSERT_TRUE(NULL != oas);
// compute buffer size for 20ms of audio, 882 samples (mono).
- const uint32 kSamples20ms = sample_rate / 50 * sizeof(uint16);
- ASSERT_TRUE(oas->Open(kSamples20ms));
+ ASSERT_TRUE(oas->Open());
base::SyncSocket* sockets[2];
ASSERT_TRUE(base::SyncSocket::CreatePair(sockets));
diff --git a/media/audio/win/wavein_input_win.cc b/media/audio/win/wavein_input_win.cc
index b328dcd..c02fd52 100644
--- a/media/audio/win/wavein_input_win.cc
+++ b/media/audio/win/wavein_input_win.cc
@@ -26,7 +26,7 @@ WAVEHDR* GetNextBuffer(WAVEHDR* current) {
PCMWaveInAudioInputStream::PCMWaveInAudioInputStream(
AudioManagerWin* manager, AudioParameters params, int num_buffers,
- uint32 samples_per_packet, UINT device_id)
+ UINT device_id)
: state_(kStateEmpty),
manager_(manager),
device_id_(device_id),
@@ -42,7 +42,7 @@ PCMWaveInAudioInputStream::PCMWaveInAudioInputStream(
format_.cbSize = 0;
format_.nBlockAlign = (format_.nChannels * format_.wBitsPerSample) / 8;
format_.nAvgBytesPerSec = format_.nBlockAlign * format_.nSamplesPerSec;
- buffer_size_ = samples_per_packet * format_.nBlockAlign;
+ buffer_size_ = params.samples_per_packet * format_.nBlockAlign;
// If we don't have a packet size we use 100ms.
if (!buffer_size_)
buffer_size_ = format_.nAvgBytesPerSec / 10;
diff --git a/media/audio/win/wavein_input_win.h b/media/audio/win/wavein_input_win.h
index 46aa0b6..7dd4781 100644
--- a/media/audio/win/wavein_input_win.h
+++ b/media/audio/win/wavein_input_win.h
@@ -21,8 +21,7 @@ class PCMWaveInAudioInputStream : public AudioInputStream {
// the audio manager who is creating this object and |device_id| which
// is provided by the operating system.
PCMWaveInAudioInputStream(AudioManagerWin* manager, AudioParameters params,
- int num_buffers, uint32 samples_per_packet,
- UINT device_id);
+ int num_buffers, UINT device_id);
virtual ~PCMWaveInAudioInputStream();
// Implementation of AudioInputStream.
diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc
index 2c3d5c4..9c99634 100644
--- a/media/audio/win/waveout_output_win.cc
+++ b/media/audio/win/waveout_output_win.cc
@@ -87,10 +87,11 @@ PCMWaveOutAudioOutputStream::PCMWaveOutAudioOutputStream(
callback_(NULL),
num_buffers_(num_buffers),
buffer_(NULL),
- buffer_size_(0),
+ buffer_size_(params.GetPacketSize()),
volume_(1),
channels_(params.channels),
pending_bytes_(0) {
+
format_.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
format_.Format.nChannels = params.channels;
format_.Format.nSamplesPerSec = params.sample_rate;
@@ -116,11 +117,9 @@ PCMWaveOutAudioOutputStream::~PCMWaveOutAudioOutputStream() {
DCHECK(NULL == waveout_);
}
-bool PCMWaveOutAudioOutputStream::Open(uint32 buffer_size) {
+bool PCMWaveOutAudioOutputStream::Open() {
if (state_ != PCMA_BRAND_NEW)
return false;
- if (buffer_size > kMaxOpenBufferSize)
- return false;
if (num_buffers_ < 2 || num_buffers_ > 5)
return false;
// Open the device. We'll be getting callback in WaveCallback function.
@@ -132,24 +131,20 @@ bool PCMWaveOutAudioOutputStream::Open(uint32 buffer_size) {
CALLBACK_FUNCTION);
if (result != MMSYSERR_NOERROR)
return false;
- // If we don't have a packet size we use 100ms.
- if (!buffer_size)
- buffer_size = format_.Format.nAvgBytesPerSec / 10;
- SetupBuffers(buffer_size);
- buffer_size_ = buffer_size;
+ SetupBuffers();
state_ = PCMA_READY;
return true;
}
-void PCMWaveOutAudioOutputStream::SetupBuffers(uint32 rq_size) {
+void PCMWaveOutAudioOutputStream::SetupBuffers() {
WAVEHDR* last = NULL;
WAVEHDR* first = NULL;
for (int ix = 0; ix != num_buffers_; ++ix) {
- uint32 sz = sizeof(WAVEHDR) + rq_size;
+ uint32 sz = sizeof(WAVEHDR) + buffer_size_;
buffer_ = reinterpret_cast<WAVEHDR*>(new char[sz]);
buffer_->lpData = reinterpret_cast<char*>(buffer_) + sizeof(WAVEHDR);
- buffer_->dwBufferLength = rq_size;
+ buffer_->dwBufferLength = buffer_size_;
buffer_->dwBytesRecorded = 0;
buffer_->dwUser = reinterpret_cast<DWORD_PTR>(last);
buffer_->dwFlags = WHDR_DONE;
@@ -235,6 +230,10 @@ void PCMWaveOutAudioOutputStream::Stop() {
HandleError(res);
return;
}
+
+ // Don't use callback after Stop().
+ callback_ = NULL;
+
state_ = PCMA_READY;
}
@@ -347,10 +346,5 @@ void PCMWaveOutAudioOutputStream::WaveCallback(HWAVEOUT hwo, UINT msg,
obj->pending_bytes_ += buffer->dwBufferLength;
- } else if (msg == WOM_CLOSE) {
- // We can be closed before calling Start, so it is possible to have a
- // null callback at this point.
- if (obj->callback_)
- obj->callback_->OnClose(obj);
}
}
diff --git a/media/audio/win/waveout_output_win.h b/media/audio/win/waveout_output_win.h
index 7437416..651c9d2 100644
--- a/media/audio/win/waveout_output_win.h
+++ b/media/audio/win/waveout_output_win.h
@@ -35,7 +35,7 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream {
virtual ~PCMWaveOutAudioOutputStream();
// Implementation of AudioOutputStream.
- virtual bool Open(uint32 packet_size);
+ virtual bool Open();
virtual void Close();
virtual void Start(AudioSourceCallback* callback);
virtual void Stop();
@@ -65,7 +65,7 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream {
void HandleError(MMRESULT error);
// Allocates and prepares the memory that will be used for playback. Only
// two buffers are created.
- void SetupBuffers(uint32 rq_size);
+ void SetupBuffers();
// Deallocates the memory allocated in SetupBuffers.
void FreeBuffers();
@@ -116,4 +116,3 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream {
};
#endif // MEDIA_AUDIO_WIN_WAVEOUT_OUTPUT_WIN_H_
-
diff --git a/media/base/limits.h b/media/base/limits.h
index b8a139f..cef29ec 100644
--- a/media/base/limits.h
+++ b/media/base/limits.h
@@ -27,6 +27,7 @@ struct Limits {
static const int kMaxSampleRate = 192000;
static const int kMaxChannels = 32;
static const int kMaxBitsPerSample = 64;
+ static const int kMaxSamplesPerPacket = kMaxSampleRate;
// Maximum possible time.
static const int64 kMaxTimeInMicroseconds = kint64max;
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
index 5634ab2..3c7ce91 100644
--- a/media/filters/audio_renderer_impl.cc
+++ b/media/filters/audio_renderer_impl.cc
@@ -79,6 +79,9 @@ bool AudioRendererImpl::OnInitialize(const MediaFormat& media_format) {
return false;
}
+ // Set packet size.
+ params.samples_per_packet = kSamplesPerBuffer;
+
bytes_per_second_ = params.sample_rate * params.channels *
params.bits_per_sample / 8;
@@ -87,10 +90,7 @@ bool AudioRendererImpl::OnInitialize(const MediaFormat& media_format) {
if (!stream_)
return false;
- // Calculate buffer size and open the stream.
- size_t size = kSamplesPerBuffer * params.channels *
- params.bits_per_sample / 8;
- if (!stream_->Open(size)) {
+ if (!stream_->Open()) {
stream_->Close();
stream_ = NULL;
}