diff options
| author | henrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-24 14:07:13 +0000 |
|---|---|---|
| committer | henrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-24 14:07:13 +0000 |
| commit | 1c578739e55dec9eb140feef7b3dff34ee9cf494 (patch) | |
| tree | 4e8dc94db42a733215fa7942233534f8ab41b9c3 | |
| parent | 894e8fcc93c010a0558b025d45ce19adddad1108 (diff) | |
| download | chromium_src-1c578739e55dec9eb140feef7b3dff34ee9cf494.zip chromium_src-1c578739e55dec9eb140feef7b3dff34ee9cf494.tar.gz chromium_src-1c578739e55dec9eb140feef7b3dff34ee9cf494.tar.bz2 | |
Added support for 96kHz capture rate on Windows 7 and Mac OS X for WebRTC.
I also took the opportunity to add support for 96kHz output rate for Mac OS X as well in this CL. Forgot that when I did modifications for Windows 7 earlier.
BUG=115270
TEST=content_unittest
Review URL: http://codereview.chromium.org/9416101
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123474 0039d316-1c4b-4281-b951-d872f2087c98
| -rw-r--r-- | content/renderer/media/webrtc_audio_device_impl.cc | 64 | ||||
| -rw-r--r-- | content/renderer/media/webrtc_audio_device_unittest.cc | 80 |
2 files changed, 110 insertions, 34 deletions
diff --git a/content/renderer/media/webrtc_audio_device_impl.cc b/content/renderer/media/webrtc_audio_device_impl.cc index 38a558c..1293674 100644 --- a/content/renderer/media/webrtc_audio_device_impl.cc +++ b/content/renderer/media/webrtc_audio_device_impl.cc @@ -13,6 +13,21 @@ static const int64 kMillisecondsBetweenProcessCalls = 5000; +// Supported hardware sample rates for input and output sides. +#if defined(OS_WIN) || defined(OS_MACOSX) +// media::GetAudioInput[Output]HardwareSampleRate() asks the audio layer +// for its current sample rate (set by the user) on Windows and Mac OS X. +// The listed rates below adds restrictions and WebRtcAudioDeviceImpl::Init() +// will fail if the user selects any rate outside these ranges. +static int kValidInputRates[] = {96000, 48000, 44100, 32000, 16000}; +static int kValidOutputRates[] = {96000, 48000, 44100}; +#elif defined(OS_LINUX) || defined(OS_OPENBSD) +// media::GetAudioInput[Output]HardwareSampleRate() is hardcoded to return +// 48000 in both directions on Linux. +static int kValidInputRates[] = {48000}; +static int kValidOutputRates[] = {48000}; +#endif + WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl() : ref_count_(0), render_loop_(base::MessageLoopProxy::current()), @@ -280,18 +295,42 @@ int32_t WebRtcAudioDeviceImpl::Init() { DCHECK(!input_buffer_.get()); DCHECK(!output_buffer_.get()); + // TODO(henrika): it could be possible to allow one of the directions (input + // or output) to use a non-supported rate. As an example: if only the + // output rate is OK, we could finalize Init() and only set up an AudioDevice. + // Ask the browser for the default audio output hardware sample-rate. // This request is based on a synchronous IPC message. int output_sample_rate = static_cast<int>(audio_hardware::GetOutputSampleRate()); DVLOG(1) << "Audio output hardware sample rate: " << output_sample_rate; + // Verify that the reported output hardware sample rate is supported + // on the current platform. + if (std::find(&kValidOutputRates[0], + &kValidOutputRates[0] + arraysize(kValidOutputRates), + output_sample_rate) == + &kValidOutputRates[arraysize(kValidOutputRates)]) { + DLOG(ERROR) << output_sample_rate << " is not a supported output rate."; + return -1; + } + // Ask the browser for the default audio input hardware sample-rate. // This request is based on a synchronous IPC message. int input_sample_rate = static_cast<int>(audio_hardware::GetInputSampleRate()); DVLOG(1) << "Audio input hardware sample rate: " << input_sample_rate; + // Verify that the reported input hardware sample rate is supported + // on the current platform. + if (std::find(&kValidInputRates[0], + &kValidInputRates[0] + arraysize(kValidInputRates), + input_sample_rate) == + &kValidInputRates[arraysize(kValidInputRates)]) { + DLOG(ERROR) << input_sample_rate << " is not a supported input rate."; + return -1; + } + // Ask the browser for the default number of audio input channels. // This request is based on a synchronous IPC message. int input_channels = audio_hardware::GetInputChannelCount(); @@ -307,17 +346,6 @@ int32_t WebRtcAudioDeviceImpl::Init() { // Windows #if defined(OS_WIN) - if (input_sample_rate != 48000 && input_sample_rate != 44100 && - input_sample_rate != 32000 && input_sample_rate != 16000) { - DLOG(ERROR) << "Only 48, 44.1, 32 and 16kHz input rates are supported."; - return -1; - } - if (output_sample_rate != 96000 && output_sample_rate != 48000 && - output_sample_rate != 44100) { - DLOG(ERROR) << "Only 96, 48 and 44.1kHz output rates are supported."; - return -1; - } - // Always use stereo rendering on Windows. output_channels = 2; @@ -361,16 +389,6 @@ int32_t WebRtcAudioDeviceImpl::Init() { // Mac OS X #elif defined(OS_MACOSX) - if (input_sample_rate != 48000 && input_sample_rate != 44100 && - input_sample_rate != 32000 && input_sample_rate != 16000) { - DLOG(ERROR) << "Only 48, 44.1, 32 and 16kHz input rates are supported."; - return -1; - } - if (output_sample_rate != 48000 && output_sample_rate != 44100) { - DLOG(ERROR) << "Only 48 and 44.1kHz output rates are supported on Mac OSX."; - return -1; - } - output_channels = 1; // Capture side: AUDIO_PCM_LOW_LATENCY on Mac OS X is based on a callback- @@ -400,10 +418,6 @@ int32_t WebRtcAudioDeviceImpl::Init() { } // Linux #elif defined(OS_LINUX) || defined(OS_OPENBSD) - if (output_sample_rate != 48000) { - DLOG(ERROR) << "Only 48kHz sample rate is supported on Linux."; - return -1; - } input_channels = 2; output_channels = 1; diff --git a/content/renderer/media/webrtc_audio_device_unittest.cc b/content/renderer/media/webrtc_audio_device_unittest.cc index 35c2a22..577302b 100644 --- a/content/renderer/media/webrtc_audio_device_unittest.cc +++ b/content/renderer/media/webrtc_audio_device_unittest.cc @@ -78,6 +78,11 @@ bool IsRunningHeadless() { return false; } +// Return true if at least one element in the array matches |value|. +bool FindElementInArray(int* array, int size, int value) { + return (std::find(&array[0], &array[0] + size, value) != &array[size]); +} + // This method returns false if a non-supported rate is detected on the // input or output side. // TODO(henrika): add support for automatic fallback to Windows Wave audio @@ -85,17 +90,32 @@ bool IsRunningHeadless() { // invalid audio settings by actually trying to open the audio streams instead // of relying on hard coded conditions. bool HardwareSampleRatesAreValid() { - int output_sample_rate = - static_cast<int>(audio_hardware::GetOutputSampleRate()); + // These are the currently supported hardware sample rates in both directions. + // The actual WebRTC client can limit these ranges further depending on + // platform but this is the maximum range we support today. + int valid_input_rates[] = {16000, 32000, 44100, 48000, 96000}; + int valid_output_rates[] = {44100, 48000, 96000}; + + // Verify the input sample rate. int input_sample_rate = static_cast<int>(audio_hardware::GetInputSampleRate()); - bool rates_are_valid = - ((output_sample_rate == 96000 || output_sample_rate == 48000 || - output_sample_rate == 44100) && - (input_sample_rate == 48000 || input_sample_rate == 44100 || - input_sample_rate == 32000 || input_sample_rate == 16000)); - DLOG_IF(WARNING, !rates_are_valid) << "Non-supported sample rate detected."; - return rates_are_valid; + + if (!FindElementInArray(valid_input_rates, arraysize(valid_input_rates), + input_sample_rate)) { + DLOG(WARNING) << "Non-supported input sample rate detected."; + return false; + } + + // Given that the input rate was OK, verify the output rate as well. + int output_sample_rate = + static_cast<int>(audio_hardware::GetOutputSampleRate()); + if (!FindElementInArray(valid_output_rates, arraysize(valid_output_rates), + output_sample_rate)) { + DLOG(WARNING) << "Non-supported output sample rate detected."; + return false; + } + + return true; } @@ -168,6 +188,48 @@ class WebRTCMediaProcessImpl : public webrtc::VoEMediaProcess { } // end namespace +// Trivial test which verifies that one part of the test harness +// (HardwareSampleRatesAreValid()) works as intended for all supported +// hardware input sample rates. +TEST_F(WebRTCAudioDeviceTest, TestValidInputRates) { + int valid_rates[] = {16000, 32000, 44100, 48000, 96000}; + + // Verify that we will approve all rates listed in |valid_rates|. + for (size_t i = 0; i < arraysize(valid_rates); ++i) { + EXPECT_TRUE(FindElementInArray(valid_rates, arraysize(valid_rates), + valid_rates[i])); + } + + // Verify that any value outside the valid range results in negative + // find results. + int invalid_rates[] = {-1, 0, 8000, 11025, 22050, 192000}; + for (size_t i = 0; i < arraysize(invalid_rates); ++i) { + EXPECT_FALSE(FindElementInArray(valid_rates, arraysize(valid_rates), + invalid_rates[i])); + } +} + +// Trivial test which verifies that one part of the test harness +// (HardwareSampleRatesAreValid()) works as intended for all supported +// hardware output sample rates. +TEST_F(WebRTCAudioDeviceTest, TestValidOutputRates) { + int valid_rates[] = {44100, 48000, 96000}; + + // Verify that we will approve all rates listed in |valid_rates|. + for (size_t i = 0; i < arraysize(valid_rates); ++i) { + EXPECT_TRUE(FindElementInArray(valid_rates, arraysize(valid_rates), + valid_rates[i])); + } + + // Verify that any value outside the valid range results in negative + // find results. + int invalid_rates[] = {-1, 0, 8000, 11025, 22050, 32000, 192000}; + for (size_t i = 0; i < arraysize(invalid_rates); ++i) { + EXPECT_FALSE(FindElementInArray(valid_rates, arraysize(valid_rates), + invalid_rates[i])); + } +} + // Basic test that instantiates and initializes an instance of // WebRtcAudioDeviceImpl. TEST_F(WebRTCAudioDeviceTest, Construct) { |
