Chromium Code Reviews| Index: media/audio/win/audio_manager_win.cc |
| diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc |
| index 1d5538fa6ce5d7619fd5279a6bbfd67ba19283cf..5ce84fc0868517c138806b8a7489f5700951f50c 100644 |
| --- a/media/audio/win/audio_manager_win.cc |
| +++ b/media/audio/win/audio_manager_win.cc |
| @@ -281,6 +281,11 @@ AudioParameters AudioManagerWin::GetInputStreamParameters( |
| sample_rate, 16, kFallbackBufferSize); |
| } |
| +std::string AudioManagerWin::GetAssociatedOutputDeviceID( |
| + const std::string& input_device_id) { |
| + return CoreAudioUtil::GetMatchingOutputDeviceID(input_device_id); |
| +} |
| + |
| // Factory for the implementations of AudioOutputStream for AUDIO_PCM_LINEAR |
| // mode. |
| // - PCMWaveOutAudioOutputStream: Based on the waveOut API. |
| @@ -351,58 +356,69 @@ AudioInputStream* AudioManagerWin::MakeLowLatencyInputStream( |
| return stream; |
| } |
| +std::string AudioManagerWin::GetDefaultOutputDeviceID() { |
| + if (!CoreAudioUtil::IsSupported()) |
| + return std::string(); |
| + return CoreAudioUtil::GetDefaultOutputDeviceID(); |
| +} |
| + |
| AudioParameters AudioManagerWin::GetPreferredOutputStreamParameters( |
| const std::string& output_device_id, |
| const AudioParameters& input_params) { |
| // TODO(tommi): Support |output_device_id|. |
| DLOG_IF(ERROR, !output_device_id.empty()) << "Not implemented!"; |
| + |
| + const bool core_audio_supported = CoreAudioUtil::IsSupported(); |
|
henrika (OOO until Aug 14)
2013/09/04 11:11:40
nice!
|
| + DLOG_IF(ERROR, !core_audio_supported && !output_device_id.empty()) |
| + << "CoreAudio is required to open non-default devices."; |
| + |
| const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
| ChannelLayout channel_layout = CHANNEL_LAYOUT_STEREO; |
| int sample_rate = 48000; |
| int buffer_size = kFallbackBufferSize; |
| int bits_per_sample = 16; |
| int input_channels = 0; |
| - bool use_input_params = !CoreAudioUtil::IsSupported(); |
| - if (cmd_line->HasSwitch(switches::kEnableExclusiveAudio)) { |
| - // TODO(crogers): tune these values for best possible WebAudio performance. |
| - // WebRTC works well at 48kHz and a buffer size of 480 samples will be used |
| - // for this case. Note that exclusive mode is experimental. |
| - // This sample rate will be combined with a buffer size of 256 samples, |
| - // which corresponds to an output delay of ~5.33ms. |
| - sample_rate = 48000; |
| - buffer_size = 256; |
| - if (input_params.IsValid()) |
| - channel_layout = input_params.channel_layout(); |
| - } else if (!use_input_params) { |
| - // Hardware sample-rate on Windows can be configured, so we must query. |
| - // TODO(henrika): improve possibility to specify an audio endpoint. |
| - // Use the default device (same as for Wave) for now to be compatible. |
| - int hw_sample_rate = WASAPIAudioOutputStream::HardwareSampleRate(); |
| - |
| - AudioParameters params; |
| - HRESULT hr = CoreAudioUtil::GetPreferredAudioParameters(eRender, eConsole, |
| - ¶ms); |
| - int hw_buffer_size = |
| - FAILED(hr) ? kFallbackBufferSize : params.frames_per_buffer(); |
| - channel_layout = WASAPIAudioOutputStream::HardwareChannelLayout(); |
| - |
| - // TODO(henrika): Figure out the right thing to do here. |
| - if (hw_sample_rate && hw_buffer_size) { |
| - sample_rate = hw_sample_rate; |
| - buffer_size = hw_buffer_size; |
| + bool use_input_params = !core_audio_supported; |
| + if (core_audio_supported) { |
| + if (cmd_line->HasSwitch(switches::kEnableExclusiveAudio)) { |
| + // TODO(crogers): tune these values for best possible WebAudio |
|
henrika (OOO until Aug 14)
2013/09/04 11:11:40
rtoy instead of crogers?
tommi (sloooow) - chröme
2013/09/04 13:06:55
Done.
|
| + // performance. WebRTC works well at 48kHz and a buffer size of 480 |
| + // samples will be used for this case. Note that exclusive mode is |
| + // experimental. This sample rate will be combined with a buffer size of |
| + // 256 samples, which corresponds to an output delay of ~5.33ms. |
| + sample_rate = 48000; |
| + buffer_size = 256; |
| + if (input_params.IsValid()) |
| + channel_layout = input_params.channel_layout(); |
| } else { |
| - use_input_params = true; |
| + AudioParameters params; |
| + HRESULT hr = CoreAudioUtil::GetPreferredAudioParameters(output_device_id, |
| + ¶ms); |
| + if (SUCCEEDED(hr)) { |
| + bits_per_sample = params.bits_per_sample(); |
| + buffer_size = params.frames_per_buffer(); |
| + channel_layout = params.channel_layout(); |
| + sample_rate = params.sample_rate(); |
| + } else { |
| + use_input_params = true; |
| + } |
| } |
| } |
| if (input_params.IsValid()) { |
| - if (cmd_line->HasSwitch(switches::kTrySupportedChannelLayouts) && |
| - CoreAudioUtil::IsSupported()) { |
| + if (core_audio_supported && |
| + cmd_line->HasSwitch(switches::kTrySupportedChannelLayouts)) { |
| // Check if it is possible to open up at the specified input channel |
| // layout but avoid checking if the specified layout is the same as the |
| // hardware (preferred) layout. We do this extra check to avoid the |
| // CoreAudioUtil::IsChannelLayoutSupported() overhead in most cases. |
| if (input_params.channel_layout() != channel_layout) { |
| + // TODO(henrika): Use |output_device_id| here. |
| + // Internally, IsChannelLayoutSupported does many of the operations |
| + // that have already been done such as opening up a client and fetching |
| + // the WAVEFORMATPCMEX format. Ideally we should only do that once and |
| + // do it for the requested device. Then here, we can check the layout |
| + // from the data we already hold. |
| if (CoreAudioUtil::IsChannelLayoutSupported( |
| eRender, eConsole, input_params.channel_layout())) { |
| // Open up using the same channel layout as the source if it is |
| @@ -420,10 +436,10 @@ AudioParameters AudioManagerWin::GetPreferredOutputStreamParameters( |
| // equal to the input values, AudioOutputResampler will skip resampling |
| // and bit per sample differences (since the input parameters will match |
| // the output parameters). |
| - sample_rate = input_params.sample_rate(); |
| bits_per_sample = input_params.bits_per_sample(); |
| - channel_layout = input_params.channel_layout(); |
| buffer_size = input_params.frames_per_buffer(); |
| + channel_layout = input_params.channel_layout(); |
| + sample_rate = input_params.sample_rate(); |
| } |
| } |