summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorcrogers@google.com <crogers@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-07 00:54:10 +0000
committercrogers@google.com <crogers@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-07 00:54:10 +0000
commitc158a30079b86c411ff72e0925755b1c6873fbbd (patch)
treedcd9aad135b0bb18926a57066e3efe6ba6a8d895 /media
parente876248ed8d704fc22a58e0b77fb96e01467558b (diff)
downloadchromium_src-c158a30079b86c411ff72e0925755b1c6873fbbd.zip
chromium_src-c158a30079b86c411ff72e0925755b1c6873fbbd.tar.gz
chromium_src-c158a30079b86c411ff72e0925755b1c6873fbbd.tar.bz2
Plumb |input_channels| all the way to AudioManager
to support synchronized audio I/O without requiring use of the "Web Audio Input" enable flag. The approach taken is to include |input_channels| as part of the AudioParameters class so that we can represent synchronized I/O streams directly without needing to separately pass |input_channels| through-out the callstack. Please note that we're still not yet removing the "Web Audio Input" flag until we more properly verify the input device selection from getUserMedia(). BUG=none TEST=manual test: http://chromium.googlecode.com/svn/trunk/samples/audio/visualizer-live.html Review URL: https://codereview.chromium.org/11878032 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@181126 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/audio/audio_device_thread.cc2
-rw-r--r--media/audio/audio_device_thread.h2
-rw-r--r--media/audio/audio_input_device.cc2
-rw-r--r--media/audio/audio_manager_base.cc3
-rw-r--r--media/audio/audio_output_device.cc33
-rw-r--r--media/audio/audio_output_device.h10
-rw-r--r--media/audio/audio_output_device_unittest.cc29
-rw-r--r--media/audio/audio_output_ipc.h5
-rw-r--r--media/audio/audio_parameters.cc23
-rw-r--r--media/audio/audio_parameters.h11
-rw-r--r--media/audio/mac/audio_manager_mac.cc11
-rw-r--r--media/audio/win/audio_manager_win.cc7
-rw-r--r--media/base/audio_renderer_sink.h18
13 files changed, 81 insertions, 75 deletions
diff --git a/media/audio/audio_device_thread.cc b/media/audio/audio_device_thread.cc
index 51d5ecd..c592acc 100644
--- a/media/audio/audio_device_thread.cc
+++ b/media/audio/audio_device_thread.cc
@@ -177,10 +177,8 @@ void AudioDeviceThread::Thread::Run() {
AudioDeviceThread::Callback::Callback(
const AudioParameters& audio_parameters,
- int input_channels,
base::SharedMemoryHandle memory, int memory_length)
: audio_parameters_(audio_parameters),
- input_channels_(input_channels),
samples_per_ms_(audio_parameters.sample_rate() / 1000),
bytes_per_ms_(audio_parameters.channels() *
(audio_parameters_.bits_per_sample() / 8) *
diff --git a/media/audio/audio_device_thread.h b/media/audio/audio_device_thread.h
index 44dbc3a..c43a01b 100644
--- a/media/audio/audio_device_thread.h
+++ b/media/audio/audio_device_thread.h
@@ -37,7 +37,6 @@ class MEDIA_EXPORT AudioDeviceThread {
class Callback {
public:
Callback(const AudioParameters& audio_parameters,
- int input_channels,
base::SharedMemoryHandle memory,
int memory_length);
virtual ~Callback();
@@ -57,7 +56,6 @@ class MEDIA_EXPORT AudioDeviceThread {
// The variables are 'const' since values are calculated/set in the
// constructor and must never change.
const AudioParameters audio_parameters_;
- const int input_channels_;
const int samples_per_ms_;
const int bytes_per_ms_;
diff --git a/media/audio/audio_input_device.cc b/media/audio/audio_input_device.cc
index a60d60d..5c5bcf7 100644
--- a/media/audio/audio_input_device.cc
+++ b/media/audio/audio_input_device.cc
@@ -303,7 +303,7 @@ AudioInputDevice::AudioThreadCallback::AudioThreadCallback(
base::SharedMemoryHandle memory,
int memory_length,
CaptureCallback* capture_callback)
- : AudioDeviceThread::Callback(audio_parameters, 0, memory, memory_length),
+ : AudioDeviceThread::Callback(audio_parameters, memory, memory_length),
capture_callback_(capture_callback) {
audio_bus_ = AudioBus::Create(audio_parameters_);
}
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc
index 67e03c0..b453877 100644
--- a/media/audio/audio_manager_base.cc
+++ b/media/audio/audio_manager_base.cc
@@ -396,7 +396,8 @@ AudioParameters AudioManagerBase::GetPreferredLowLatencyOutputStreamParameters(
// TODO(dalecurtis): This should include bits per channel and channel layout
// eventually.
return AudioParameters(
- AudioParameters::AUDIO_PCM_LOW_LATENCY, input_params.channel_layout(),
+ AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ input_params.channel_layout(), input_params.input_channels(),
GetAudioHardwareSampleRate(), 16, GetAudioHardwareBufferSize());
#endif // defined(OS_IOS)
}
diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc
index cf4ebff..e95d21b 100644
--- a/media/audio/audio_output_device.cc
+++ b/media/audio/audio_output_device.cc
@@ -22,7 +22,6 @@ class AudioOutputDevice::AudioThreadCallback
: public AudioDeviceThread::Callback {
public:
AudioThreadCallback(const AudioParameters& audio_parameters,
- int input_channels,
base::SharedMemoryHandle memory,
int memory_length,
AudioRendererSink::RenderCallback* render_callback);
@@ -44,7 +43,6 @@ AudioOutputDevice::AudioOutputDevice(
AudioOutputIPC* ipc,
const scoped_refptr<base::MessageLoopProxy>& io_loop)
: ScopedLoopObserver(io_loop),
- input_channels_(0),
callback_(NULL),
ipc_(ipc),
state_(IDLE),
@@ -57,19 +55,11 @@ AudioOutputDevice::AudioOutputDevice(
void AudioOutputDevice::Initialize(const AudioParameters& params,
RenderCallback* callback) {
DCHECK(!callback_) << "Calling Initialize() twice?";
+ DCHECK(params.IsValid());
audio_parameters_ = params;
callback_ = callback;
}
-void AudioOutputDevice::InitializeIO(const AudioParameters& params,
- int input_channels,
- RenderCallback* callback) {
- DCHECK_GE(input_channels, 0);
- DCHECK_LT(input_channels, limits::kMaxChannels);
- input_channels_ = input_channels;
- Initialize(params, callback);
-}
-
AudioOutputDevice::~AudioOutputDevice() {
// The current design requires that the user calls Stop() before deleting
// this class.
@@ -83,7 +73,7 @@ void AudioOutputDevice::Start() {
DCHECK(callback_) << "Initialize hasn't been called";
message_loop()->PostTask(FROM_HERE,
base::Bind(&AudioOutputDevice::CreateStreamOnIOThread, this,
- audio_parameters_, input_channels_));
+ audio_parameters_));
}
void AudioOutputDevice::Stop() {
@@ -119,12 +109,11 @@ bool AudioOutputDevice::SetVolume(double volume) {
return true;
}
-void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params,
- int input_channels) {
+void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params) {
DCHECK(message_loop()->BelongsToCurrentThread());
if (state_ == IDLE) {
state_ = CREATING_STREAM;
- ipc_->CreateStream(stream_id_, params, input_channels);
+ ipc_->CreateStream(stream_id_, params);
}
}
@@ -237,7 +226,7 @@ void AudioOutputDevice::OnStreamCreated(
DCHECK(audio_thread_.IsStopped());
audio_callback_.reset(new AudioOutputDevice::AudioThreadCallback(
- audio_parameters_, input_channels_, handle, length, callback_));
+ audio_parameters_, handle, length, callback_));
audio_thread_.Start(audio_callback_.get(), socket_handle,
"AudioOutputDevice");
state_ = PAUSED;
@@ -263,12 +252,10 @@ void AudioOutputDevice::WillDestroyCurrentMessageLoop() {
AudioOutputDevice::AudioThreadCallback::AudioThreadCallback(
const AudioParameters& audio_parameters,
- int input_channels,
base::SharedMemoryHandle memory,
int memory_length,
AudioRendererSink::RenderCallback* render_callback)
: AudioDeviceThread::Callback(audio_parameters,
- input_channels,
memory,
memory_length),
render_callback_(render_callback) {
@@ -282,9 +269,10 @@ void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() {
// Calculate output and input memory size.
int output_memory_size = AudioBus::CalculateMemorySize(audio_parameters_);
+ int input_channels = audio_parameters_.input_channels();
int frames = audio_parameters_.frames_per_buffer();
int input_memory_size =
- AudioBus::CalculateMemorySize(input_channels_, frames);
+ AudioBus::CalculateMemorySize(input_channels, frames);
int io_size = output_memory_size + input_memory_size;
@@ -293,12 +281,12 @@ void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() {
output_bus_ =
AudioBus::WrapMemory(audio_parameters_, shared_memory_.memory());
- if (input_channels_ > 0) {
+ if (input_channels > 0) {
// The input data is after the output data.
char* input_data =
static_cast<char*>(shared_memory_.memory()) + output_memory_size;
input_bus_ =
- AudioBus::WrapMemory(input_channels_, frames, input_data);
+ AudioBus::WrapMemory(input_channels, frames, input_data);
}
}
@@ -319,9 +307,10 @@ void AudioOutputDevice::AudioThreadCallback::Process(int pending_data) {
// Update the audio-delay measurement then ask client to render audio. Since
// |output_bus_| is wrapping the shared memory the Render() call is writing
// directly into the shared memory.
+ int input_channels = audio_parameters_.input_channels();
size_t num_frames = audio_parameters_.frames_per_buffer();
- if (input_bus_.get() && input_channels_ > 0) {
+ if (input_bus_.get() && input_channels > 0) {
render_callback_->RenderIO(input_bus_.get(),
output_bus_.get(),
audio_delay_milliseconds);
diff --git a/media/audio/audio_output_device.h b/media/audio/audio_output_device.h
index 6650028..28a7098 100644
--- a/media/audio/audio_output_device.h
+++ b/media/audio/audio_output_device.h
@@ -80,9 +80,6 @@ class MEDIA_EXPORT AudioOutputDevice
// AudioRendererSink implementation.
virtual void Initialize(const AudioParameters& params,
RenderCallback* callback) OVERRIDE;
- virtual void InitializeIO(const AudioParameters& params,
- int input_channels,
- RenderCallback* callback) OVERRIDE;
virtual void Start() OVERRIDE;
virtual void Stop() OVERRIDE;
virtual void Play() OVERRIDE;
@@ -126,8 +123,7 @@ class MEDIA_EXPORT AudioOutputDevice
// The following methods are tasks posted on the IO thread that needs to
// be executed on that thread. They interact with AudioMessageFilter and
// sends IPC messages on that thread.
- void CreateStreamOnIOThread(const AudioParameters& params,
- int input_channels);
+ void CreateStreamOnIOThread(const AudioParameters& params);
void PlayOnIOThread();
void PauseOnIOThread(bool flush);
void ShutDownOnIOThread();
@@ -139,10 +135,6 @@ class MEDIA_EXPORT AudioOutputDevice
AudioParameters audio_parameters_;
- // The number of optional synchronized input channels having the same
- // sample-rate and buffer-size as specified in audio_parameters_.
- int input_channels_;
-
RenderCallback* callback_;
// A pointer to the IPC layer that takes care of sending requests over to
diff --git a/media/audio/audio_output_device_unittest.cc b/media/audio/audio_output_device_unittest.cc
index 70e2a49..07a752d 100644
--- a/media/audio/audio_output_device_unittest.cc
+++ b/media/audio/audio_output_device_unittest.cc
@@ -52,8 +52,8 @@ class MockAudioOutputIPC : public AudioOutputIPC {
MOCK_METHOD1(AddDelegate, int(AudioOutputIPCDelegate* delegate));
MOCK_METHOD1(RemoveDelegate, void(int stream_id));
- MOCK_METHOD3(CreateStream,
- void(int stream_id, const AudioParameters& params, int input_channels));
+ MOCK_METHOD2(CreateStream,
+ void(int stream_id, const AudioParameters& params));
MOCK_METHOD1(PlayStream, void(int stream_id));
MOCK_METHOD1(CloseStream, void(int stream_id));
MOCK_METHOD2(SetVolume, void(int stream_id, double volume));
@@ -110,7 +110,7 @@ class AudioOutputDeviceTest
// Must remain the first member of this class.
base::ShadowingAtExitManager at_exit_manager_;
MessageLoopForIO io_loop_;
- const AudioParameters default_audio_parameters_;
+ AudioParameters default_audio_parameters_;
StrictMock<MockRenderCallback> callback_;
StrictMock<MockAudioOutputIPC> audio_output_ipc_;
scoped_refptr<AudioOutputDevice> audio_device_;
@@ -148,25 +148,22 @@ int AudioOutputDeviceTest::CalculateMemorySize() {
}
AudioOutputDeviceTest::AudioOutputDeviceTest()
- : default_audio_parameters_(AudioParameters::AUDIO_PCM_LINEAR,
- CHANNEL_LAYOUT_STEREO,
- 48000, 16, 1024),
- synchronized_io_(GetParam()),
+ : synchronized_io_(GetParam()),
input_channels_(synchronized_io_ ? 2 : 0) {
+ default_audio_parameters_.Reset(
+ AudioParameters::AUDIO_PCM_LINEAR,
+ CHANNEL_LAYOUT_STEREO, input_channels_,
+ 48000, 16, 1024);
+
EXPECT_CALL(audio_output_ipc_, AddDelegate(_))
.WillOnce(Return(kStreamId));
audio_device_ = new AudioOutputDevice(
&audio_output_ipc_, io_loop_.message_loop_proxy());
- if (synchronized_io_) {
- audio_device_->InitializeIO(default_audio_parameters_,
- input_channels_,
- &callback_);
- } else {
- audio_device_->Initialize(default_audio_parameters_,
- &callback_);
- }
+ audio_device_->Initialize(default_audio_parameters_,
+ &callback_);
+
io_loop_.RunUntilIdle();
}
@@ -179,7 +176,7 @@ AudioOutputDeviceTest::~AudioOutputDeviceTest() {
void AudioOutputDeviceTest::StartAudioDevice() {
audio_device_->Start();
- EXPECT_CALL(audio_output_ipc_, CreateStream(kStreamId, _, _));
+ EXPECT_CALL(audio_output_ipc_, CreateStream(kStreamId, _));
io_loop_.RunUntilIdle();
}
diff --git a/media/audio/audio_output_ipc.h b/media/audio/audio_output_ipc.h
index 8543cdc..894ece5 100644
--- a/media/audio/audio_output_ipc.h
+++ b/media/audio/audio_output_ipc.h
@@ -68,13 +68,12 @@ class MEDIA_EXPORT AudioOutputIPC {
// Sends a request to create an AudioOutputController object in the peer
// process, identify it by |stream_id| and configure it to use the specified
- // audio |params| and number of synchronized input channels.
+ // audio |params| including number of synchronized input channels.
// Once the stream has been created, the implementation must
// generate a notification to the AudioOutputIPCDelegate and call
// OnStreamCreated().
virtual void CreateStream(int stream_id,
- const AudioParameters& params,
- int input_channels) = 0;
+ const AudioParameters& params) = 0;
// Starts playing the stream. This should generate a call to
// AudioOutputController::Play().
diff --git a/media/audio/audio_parameters.cc b/media/audio/audio_parameters.cc
index 0d9263ff5..721dea0a 100644
--- a/media/audio/audio_parameters.cc
+++ b/media/audio/audio_parameters.cc
@@ -14,7 +14,8 @@ AudioParameters::AudioParameters()
sample_rate_(0),
bits_per_sample_(0),
frames_per_buffer_(0),
- channels_(0) {
+ channels_(0),
+ input_channels_(0) {
}
AudioParameters::AudioParameters(Format format, ChannelLayout channel_layout,
@@ -25,14 +26,30 @@ AudioParameters::AudioParameters(Format format, ChannelLayout channel_layout,
sample_rate_(sample_rate),
bits_per_sample_(bits_per_sample),
frames_per_buffer_(frames_per_buffer),
- channels_(ChannelLayoutToChannelCount(channel_layout)) {
+ channels_(ChannelLayoutToChannelCount(channel_layout)),
+ input_channels_(0) {
+}
+
+AudioParameters::AudioParameters(Format format, ChannelLayout channel_layout,
+ int input_channels,
+ int sample_rate, int bits_per_sample,
+ int frames_per_buffer)
+ : format_(format),
+ channel_layout_(channel_layout),
+ sample_rate_(sample_rate),
+ bits_per_sample_(bits_per_sample),
+ frames_per_buffer_(frames_per_buffer),
+ channels_(ChannelLayoutToChannelCount(channel_layout)),
+ input_channels_(input_channels) {
}
void AudioParameters::Reset(Format format, ChannelLayout channel_layout,
+ int input_channels,
int sample_rate, int bits_per_sample,
int frames_per_buffer) {
format_ = format;
channel_layout_ = channel_layout;
+ input_channels_ = input_channels;
sample_rate_ = sample_rate;
bits_per_sample_ = bits_per_sample;
frames_per_buffer_ = frames_per_buffer;
@@ -46,6 +63,8 @@ bool AudioParameters::IsValid() const {
(channels_ <= media::limits::kMaxChannels) &&
(channel_layout_ > CHANNEL_LAYOUT_UNSUPPORTED) &&
(channel_layout_ < CHANNEL_LAYOUT_MAX) &&
+ (input_channels_ >= 0) &&
+ (input_channels_ <= media::limits::kMaxChannels) &&
(sample_rate_ >= media::limits::kMinSampleRate) &&
(sample_rate_ <= media::limits::kMaxSampleRate) &&
(bits_per_sample_ > 0) &&
diff --git a/media/audio/audio_parameters.h b/media/audio/audio_parameters.h
index 0225468..6f3c525 100644
--- a/media/audio/audio_parameters.h
+++ b/media/audio/audio_parameters.h
@@ -46,7 +46,12 @@ class MEDIA_EXPORT AudioParameters {
AudioParameters(Format format, ChannelLayout channel_layout,
int sample_rate, int bits_per_sample,
int frames_per_buffer);
+ AudioParameters(Format format, ChannelLayout channel_layout,
+ int input_channels,
+ int sample_rate, int bits_per_sample,
+ int frames_per_buffer);
void Reset(Format format, ChannelLayout channel_layout,
+ int input_channels,
int sample_rate, int bits_per_sample,
int frames_per_buffer);
@@ -69,6 +74,7 @@ class MEDIA_EXPORT AudioParameters {
int bits_per_sample() const { return bits_per_sample_; }
int frames_per_buffer() const { return frames_per_buffer_; }
int channels() const { return channels_; }
+ int input_channels() const { return input_channels_; }
private:
Format format_; // Format of the stream.
@@ -79,6 +85,9 @@ class MEDIA_EXPORT AudioParameters {
int channels_; // Number of channels. Value set based on
// |channel_layout|.
+ int input_channels_; // Optional number of input channels.
+ // Normally 0, but can be set to specify
+ // synchronized I/O.
};
// Comparison is useful when AudioParameters is used with std structures.
@@ -87,6 +96,8 @@ inline bool operator<(const AudioParameters& a, const AudioParameters& b) {
return a.format() < b.format();
if (a.channels() != b.channels())
return a.channels() < b.channels();
+ if (a.input_channels() != b.input_channels())
+ return a.input_channels() < b.input_channels();
if (a.sample_rate() != b.sample_rate())
return a.sample_rate() < b.sample_rate();
if (a.bits_per_sample() != b.bits_per_sample())
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc
index 9b69cb7..4030a23 100644
--- a/media/audio/mac/audio_manager_mac.cc
+++ b/media/audio/mac/audio_manager_mac.cc
@@ -283,10 +283,12 @@ AudioOutputStream* AudioManagerMac::MakeLowLatencyOutputStream(
const AudioParameters& params) {
DCHECK_EQ(AudioParameters::AUDIO_PCM_LOW_LATENCY, params.format());
- // TODO(crogers): remove once we properly handle input device selection.
+ // TODO(crogers): support more than stereo input.
+ // TODO(crogers): remove flag once we handle input device selection.
// https://code.google.com/p/chromium/issues/detail?id=147327
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableWebAudioInput)) {
+ if (params.input_channels() == 2 &&
+ CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableWebAudioInput)) {
if (HasUnifiedDefaultIO())
return new AudioHardwareUnifiedStream(this, params);
@@ -328,7 +330,8 @@ AudioParameters AudioManagerMac::GetPreferredLowLatencyOutputStreamParameters(
// Specifically, this is a limitation of AudioSynchronizedStream which
// can be removed as part of the work to consolidate these back-ends.
return AudioParameters(
- AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_STEREO,
+ AudioParameters::AUDIO_PCM_LOW_LATENCY,
+ CHANNEL_LAYOUT_STEREO, input_params.input_channels(),
GetAudioHardwareSampleRate(), 16, GetAudioHardwareBufferSize());
}
diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc
index e62d951..f8e3ba0 100644
--- a/media/audio/win/audio_manager_win.cc
+++ b/media/audio/win/audio_manager_win.cc
@@ -292,8 +292,11 @@ AudioOutputStream* AudioManagerWin::MakeLowLatencyOutputStream(
this, params, media::NumberOfWaveOutBuffers(), WAVE_MAPPER);
}
- // TODO(henrika): remove once we properly handle input device selection.
- if (CommandLine::ForCurrentProcess()->HasSwitch(
+ // TODO(crogers): support more than stereo input.
+ // TODO(henrika): remove flag once we properly handle input device selection.
+ // https://code.google.com/p/chromium/issues/detail?id=147327
+ if (params.input_channels() == 2 &&
+ CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableWebAudioInput)) {
if (WASAPIUnifiedStream::HasUnifiedDefaultIO()) {
DVLOG(1) << "WASAPIUnifiedStream is created.";
diff --git a/media/base/audio_renderer_sink.h b/media/base/audio_renderer_sink.h
index ad61c4b..51e6c1f 100644
--- a/media/base/audio_renderer_sink.h
+++ b/media/base/audio_renderer_sink.h
@@ -41,19 +41,15 @@ class AudioRendererSink
// Sets important information about the audio stream format.
// It must be called before any of the other methods.
- virtual void Initialize(const AudioParameters& params,
- RenderCallback* callback) = 0;
-
- // InitializeIO() may be called instead of Initialize() for clients who wish
- // to have synchronized input and output. |input_channels| specifies the
+ // For clients wishing to have synchronized input and output,
+ // |params| may specify |input_channels| > 0, representing a
// number of input channels which will be at the same sample-rate
// and buffer-size as the output as specified in |params|.
- // The callback's RenderIO() method will be called instead of Render(),
- // providing the synchronized input data at the same time as when new
- // output data is to be rendered.
- virtual void InitializeIO(const AudioParameters& params,
- int input_channels,
- RenderCallback* callback) {}
+ // In this case, the callback's RenderIO() method will be called instead
+ // of Render(), providing the synchronized input data at the same time as
+ // when new output data is to be rendered.
+ virtual void Initialize(const AudioParameters& params,
+ RenderCallback* callback) = 0;
// Starts audio playback.
virtual void Start() = 0;