diff --git a/webrtc/modules/audio_device/android/audio_device_template.h b/webrtc/modules/audio_device/android/audio_device_template.h index dc32feffab..09706595a9 100644 --- a/webrtc/modules/audio_device/android/audio_device_template.h +++ b/webrtc/modules/audio_device/android/audio_device_template.h @@ -331,41 +331,48 @@ class AudioDeviceTemplate : public AudioDeviceGeneric { return -1; } + // Returns true if the audio manager has been configured to support stereo + // and false otherwised. Default is mono. int32_t StereoPlayoutIsAvailable(bool& available) override { LOG(INFO) << __FUNCTION__; - available = false; + available = audio_manager_->IsStereoPlayoutSupported(); return 0; } - // TODO(henrika): add support. int32_t SetStereoPlayout(bool enable) override { LOG(INFO) << __FUNCTION__; - // Allow disabling stereo playout, as that matches returning false(0) from - // StereoPlayoutIsAvailable and is the default case. - return enable ? -1 : 0; + bool available = audio_manager_->IsStereoPlayoutSupported(); + // Android does not support changes between mono and stero on the fly. + // Instead, the native audio layer is configured via the audio manager + // to either support mono or stereo. It is allowed to call this method + // if that same state is not modified. + return (enable == available) ? 0 : -1; } - // TODO(henrika): add support. int32_t StereoPlayout(bool& enabled) const override { - enabled = false; - FATAL() << "Should never be called"; - return -1; + enabled = audio_manager_->IsStereoPlayoutSupported(); + return 0; } int32_t StereoRecordingIsAvailable(bool& available) override { LOG(INFO) << __FUNCTION__; - available = false; + available = audio_manager_->IsStereoRecordSupported(); return 0; } int32_t SetStereoRecording(bool enable) override { LOG(INFO) << __FUNCTION__; - return -1; + bool available = audio_manager_->IsStereoRecordSupported(); + // Android does not support changes between mono and stero on the fly. + // Instead, the native audio layer is configured via the audio manager + // to either support mono or stereo. It is allowed to call this method + // if that same state is not modified. + return (enable == available) ? 0 : -1; } int32_t StereoRecording(bool& enabled) const override { LOG(INFO) << __FUNCTION__; - enabled = false; + enabled = audio_manager_->IsStereoRecordSupported(); return 0; } diff --git a/webrtc/modules/audio_device/android/audio_manager.cc b/webrtc/modules/audio_device/android/audio_manager.cc index da348d2117..60a1d9a9a5 100644 --- a/webrtc/modules/audio_device/android/audio_manager.cc +++ b/webrtc/modules/audio_device/android/audio_manager.cc @@ -220,6 +220,18 @@ bool AudioManager::IsProAudioSupported() const { return pro_audio_; } +bool AudioManager::IsStereoPlayoutSupported() const { + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + ALOGD("IsStereoPlayoutSupported()"); + return (playout_parameters_.channels() == 2); +} + +bool AudioManager::IsStereoRecordSupported() const { + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + ALOGD("IsStereoRecordSupported()"); + return (record_parameters_.channels() == 2); +} + int AudioManager::GetDelayEstimateInMilliseconds() const { return delay_estimate_in_milliseconds_; } diff --git a/webrtc/modules/audio_device/android/audio_manager.h b/webrtc/modules/audio_device/android/audio_manager.h index e15e4aaf77..638b085972 100644 --- a/webrtc/modules/audio_device/android/audio_manager.h +++ b/webrtc/modules/audio_device/android/audio_manager.h @@ -103,6 +103,14 @@ class AudioManager { bool IsLowLatencyPlayoutSupported() const; bool IsLowLatencyRecordSupported() const; + // Returns true if the device supports (and has been configured for) stereo. + // Call the Java API WebRtcAudioManager.setStereoOutput/Input() with true as + // paramter to enable stereo. Default is mono in both directions and the + // setting is set once and for all when the audio manager object is created. + // TODO(henrika): stereo is not supported in combination with OpenSL ES. + bool IsStereoPlayoutSupported() const; + bool IsStereoRecordSupported() const; + // Returns true if the device supports pro-audio features in combination with // OpenSL ES. bool IsProAudioSupported() const; diff --git a/webrtc/modules/audio_device/android/audio_manager_unittest.cc b/webrtc/modules/audio_device/android/audio_manager_unittest.cc index 0ebc66258e..e82376d7ef 100644 --- a/webrtc/modules/audio_device/android/audio_manager_unittest.cc +++ b/webrtc/modules/audio_device/android/audio_manager_unittest.cc @@ -136,6 +136,16 @@ TEST_F(AudioManagerTest, IsProAudioSupported) { audio_manager()->IsProAudioSupported() ? "Yes" : "No"); } +// Verify that playout side is configured for mono by default. +TEST_F(AudioManagerTest, IsStereoPlayoutSupported) { + EXPECT_FALSE(audio_manager()->IsStereoPlayoutSupported()); +} + +// Verify that recording side is configured for mono by default. +TEST_F(AudioManagerTest, IsStereoRecordSupported) { + EXPECT_FALSE(audio_manager()->IsStereoRecordSupported()); +} + TEST_F(AudioManagerTest, ShowAudioParameterInfo) { const bool low_latency_out = audio_manager()->IsLowLatencyPlayoutSupported(); const bool low_latency_in = audio_manager()->IsLowLatencyRecordSupported(); diff --git a/webrtc/modules/audio_device/android/opensles_player.cc b/webrtc/modules/audio_device/android/opensles_player.cc index 513f8233f8..3a40bf4779 100644 --- a/webrtc/modules/audio_device/android/opensles_player.cc +++ b/webrtc/modules/audio_device/android/opensles_player.cc @@ -79,6 +79,11 @@ OpenSLESPlayer::~OpenSLESPlayer() { int OpenSLESPlayer::Init() { ALOGD("Init%s", GetThreadInfo().c_str()); RTC_DCHECK(thread_checker_.CalledOnValidThread()); + if (audio_parameters_.channels() == 2) { + // TODO(henrika): FineAudioBuffer needs more work to support stereo. + ALOGE("OpenSLESPlayer does not support stereo"); + return -1; + } return 0; } diff --git a/webrtc/modules/audio_device/android/opensles_recorder.cc b/webrtc/modules/audio_device/android/opensles_recorder.cc index e3a6e61ab0..df94ba8e15 100644 --- a/webrtc/modules/audio_device/android/opensles_recorder.cc +++ b/webrtc/modules/audio_device/android/opensles_recorder.cc @@ -76,6 +76,11 @@ OpenSLESRecorder::~OpenSLESRecorder() { int OpenSLESRecorder::Init() { ALOGD("Init%s", GetThreadInfo().c_str()); RTC_DCHECK(thread_checker_.CalledOnValidThread()); + if (audio_parameters_.channels() == 2) { + // TODO(henrika): FineAudioBuffer needs more work to support stereo. + ALOGE("OpenSLESRecorder does not support stereo"); + return -1; + } return 0; } diff --git a/webrtc/modules/audio_device/audio_device_buffer.cc b/webrtc/modules/audio_device/audio_device_buffer.cc index 79a0ebc3b6..063c65f4fc 100644 --- a/webrtc/modules/audio_device/audio_device_buffer.cc +++ b/webrtc/modules/audio_device/audio_device_buffer.cc @@ -376,8 +376,8 @@ int32_t AudioDeviceBuffer::RequestPlayoutData(size_t samples_per_channel) { } // Update playout stats which is used as base for periodic logging of the // audio output state. - UpdatePlayStats(max_abs, num_samples_out); - return static_cast(num_samples_out); + UpdatePlayStats(max_abs, num_samples_out / play_channels_); + return static_cast(num_samples_out / play_channels_); } int32_t AudioDeviceBuffer::GetPlayoutData(void* audio_buffer) {