summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhenrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-24 14:07:13 +0000
committerhenrika@chromium.org <henrika@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-24 14:07:13 +0000
commit1c578739e55dec9eb140feef7b3dff34ee9cf494 (patch)
tree4e8dc94db42a733215fa7942233534f8ab41b9c3
parent894e8fcc93c010a0558b025d45ce19adddad1108 (diff)
downloadchromium_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.cc64
-rw-r--r--content/renderer/media/webrtc_audio_device_unittest.cc80
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) {