webrtc/modules/audio_device/audio_device_impl.cc
Artem Titov 2cf8eb9f78 Reland "Migrate TestAudioDeviceModule on AudioDeviceModuleImpl"
This CL will add AudioDeviceBuffer into the SUT increasing test coverage
for audio quality regression detection.

This reverts commit b035dcc0a2.

Reason for revert: reland with a fix

Original change's description:
> Revert "Reland "Migrate TestAudioDeviceModule on AudioDeviceModuleImpl""
>
> This reverts commit eeae962997.
>
> Reason for revert: breaks WebRTC Chromium FYI ios-device
> https://ci.chromium.org/ui/p/chromium/builders/webrtc.fyi/WebRTC%20Chromium%20FYI%20ios-device/14896/overview
>
> Original change's description:
> > Reland "Migrate TestAudioDeviceModule on AudioDeviceModuleImpl"
> >
> > This reverts commit 69c8d3c843.
> >
> > Reason for revert: Reland with a fix
> >
> > Original change's description:
> > > Revert "Migrate TestAudioDeviceModule on AudioDeviceModuleImpl"
> > >
> > > This reverts commit e42bf81486.
> > >
> > > Reason for revert: Breaks iOS simulator bots and thus blocks chromium roll, https://chromium-review.googlesource.com/c/chromium/src/+/4433814
> > >
> > > Original change's description:
> > > > Migrate TestAudioDeviceModule on AudioDeviceModuleImpl
> > > >
> > > > Bug: b/272350185
> > > > Change-Id: Ia3d85d6fa3b0d4809e987a39d60d3eb022687132
> > > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/300363
> > > > Commit-Queue: Artem Titov <titovartem@webrtc.org>
> > > > Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
> > > > Cr-Commit-Position: refs/heads/main@{#39877}
> > >
> > > Bug: b/272350185
> > > Change-Id: I1e3b542fc1278797f283afedeae01cbb7412d353
> > > No-Presubmit: true
> > > No-Tree-Checks: true
> > > No-Try: true
> > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/301701
> > > Commit-Queue: Jeremy Leconte <jleconte@google.com>
> > > Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
> > > Reviewed-by: Jeremy Leconte <jleconte@google.com>
> > > Auto-Submit: Christoffer Jansson <jansson@google.com>
> > > Owners-Override: Christoffer Jansson <jansson@google.com>
> > > Cr-Commit-Position: refs/heads/main@{#39881}
> >
> > Bug: b/272350185
> > Change-Id: I809466306b2e1fd54c44b90311059c98a53ef8ee
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/301704
> > Reviewed-by: Henrik Andreassson <henrika@webrtc.org>
> > Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
> > Commit-Queue: Artem Titov <titovartem@webrtc.org>
> > Cr-Commit-Position: refs/heads/main@{#39936}
>
> Bug: b/272350185
> Change-Id: If0a10717bf14a0a618e52728fc3a61b9c55f3bd2
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/303460
> Commit-Queue: Jeremy Leconte <jleconte@google.com>
> Owners-Override: Jeremy Leconte <jleconte@google.com>
> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
> Cr-Commit-Position: refs/heads/main@{#39947}

Bug: b/272350185
Change-Id: I7cf7c6bc25561f4eb722957f318c2af9ce20726d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/311101
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40387}
2023-06-30 16:15:06 +00:00

915 lines
27 KiB
C++

/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_device/audio_device_impl.h"
#include <stddef.h>
#include "api/make_ref_counted.h"
#include "api/scoped_refptr.h"
#include "modules/audio_device/audio_device_config.h" // IWYU pragma: keep
#include "modules/audio_device/audio_device_generic.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "system_wrappers/include/metrics.h"
#if defined(_WIN32)
#if defined(WEBRTC_WINDOWS_CORE_AUDIO_BUILD)
#include "modules/audio_device/win/audio_device_core_win.h"
#endif
#elif defined(WEBRTC_ANDROID)
#include <stdlib.h>
#include "sdk/android/native_api/audio_device_module/audio_device_android.h"
#elif defined(WEBRTC_LINUX)
#if defined(WEBRTC_ENABLE_LINUX_ALSA)
#include "modules/audio_device/linux/audio_device_alsa_linux.h"
#endif
#if defined(WEBRTC_ENABLE_LINUX_PULSE)
#include "modules/audio_device/linux/audio_device_pulse_linux.h"
#endif
#elif defined(WEBRTC_IOS)
#include "sdk/objc/native/src/audio/audio_device_ios.h"
#elif defined(WEBRTC_MAC)
#include "modules/audio_device/mac/audio_device_mac.h"
#endif
#if defined(WEBRTC_DUMMY_FILE_DEVICES)
#include "modules/audio_device/dummy/file_audio_device.h"
#include "modules/audio_device/dummy/file_audio_device_factory.h"
#endif
#include "modules/audio_device/dummy/audio_device_dummy.h"
#define CHECKinitialized_() \
{ \
if (!initialized_) { \
return -1; \
} \
}
#define CHECKinitialized__BOOL() \
{ \
if (!initialized_) { \
return false; \
} \
}
namespace webrtc {
rtc::scoped_refptr<AudioDeviceModule> AudioDeviceModule::Create(
AudioLayer audio_layer,
TaskQueueFactory* task_queue_factory) {
RTC_DLOG(LS_INFO) << __FUNCTION__;
#if defined(WEBRTC_ANDROID)
return CreateAndroidAudioDeviceModule(audio_layer);
#else
return AudioDeviceModule::CreateForTest(audio_layer, task_queue_factory);
#endif
}
// static
rtc::scoped_refptr<AudioDeviceModuleForTest> AudioDeviceModule::CreateForTest(
AudioLayer audio_layer,
TaskQueueFactory* task_queue_factory) {
RTC_DLOG(LS_INFO) << __FUNCTION__;
// The "AudioDeviceModule::kWindowsCoreAudio2" audio layer has its own
// dedicated factory method which should be used instead.
if (audio_layer == AudioDeviceModule::kWindowsCoreAudio2) {
RTC_LOG(LS_ERROR) << "Use the CreateWindowsCoreAudioAudioDeviceModule() "
"factory method instead for this option.";
return nullptr;
} else if (audio_layer == AudioDeviceModule::kAndroidJavaAudio ||
audio_layer == AudioDeviceModule::kAndroidOpenSLESAudio ||
audio_layer == AudioDeviceModule::kAndroidJavaInputAndOpenSLESOutputAudio ||
audio_layer == kAndroidAAudioAudio ||
audio_layer == kAndroidJavaInputAndAAudioOutputAudio) {
RTC_LOG(LS_ERROR) << "Use the CreateAndroidAudioDeviceModule() "
"factory method instead for this option.";
return nullptr;
}
// Create the generic reference counted (platform independent) implementation.
auto audio_device = rtc::make_ref_counted<AudioDeviceModuleImpl>(
audio_layer, task_queue_factory);
// Ensure that the current platform is supported.
if (audio_device->CheckPlatform() == -1) {
return nullptr;
}
// Create the platform-dependent implementation.
if (audio_device->CreatePlatformSpecificObjects() == -1) {
return nullptr;
}
// Ensure that the generic audio buffer can communicate with the platform
// specific parts.
if (audio_device->AttachAudioBuffer() == -1) {
return nullptr;
}
return audio_device;
}
AudioDeviceModuleImpl::AudioDeviceModuleImpl(
AudioLayer audio_layer,
TaskQueueFactory* task_queue_factory)
: audio_layer_(audio_layer), audio_device_buffer_(task_queue_factory) {
RTC_DLOG(LS_INFO) << __FUNCTION__;
}
AudioDeviceModuleImpl::AudioDeviceModuleImpl(
AudioLayer audio_layer,
std::unique_ptr<AudioDeviceGeneric> audio_device,
TaskQueueFactory* task_queue_factory,
bool create_detached)
: audio_layer_(audio_layer),
audio_device_buffer_(task_queue_factory, create_detached),
audio_device_(std::move(audio_device)) {
RTC_DLOG(LS_INFO) << __FUNCTION__;
}
int32_t AudioDeviceModuleImpl::CheckPlatform() {
RTC_DLOG(LS_INFO) << __FUNCTION__;
// Ensure that the current platform is supported
PlatformType platform(kPlatformNotSupported);
#if defined(_WIN32)
platform = kPlatformWin32;
RTC_LOG(LS_INFO) << "current platform is Win32";
#elif defined(WEBRTC_ANDROID)
platform = kPlatformAndroid;
RTC_LOG(LS_INFO) << "current platform is Android";
#elif defined(WEBRTC_LINUX)
platform = kPlatformLinux;
RTC_LOG(LS_INFO) << "current platform is Linux";
#elif defined(WEBRTC_IOS)
platform = kPlatformIOS;
RTC_LOG(LS_INFO) << "current platform is IOS";
#elif defined(WEBRTC_MAC)
platform = kPlatformMac;
RTC_LOG(LS_INFO) << "current platform is Mac";
#elif defined(WEBRTC_FUCHSIA)
platform = kPlatformFuchsia;
RTC_LOG(LS_INFO) << "current platform is Fuchsia";
#endif
if (platform == kPlatformNotSupported) {
RTC_LOG(LS_ERROR)
<< "current platform is not supported => this module will self "
"destruct!";
return -1;
}
platform_type_ = platform;
return 0;
}
int32_t AudioDeviceModuleImpl::CreatePlatformSpecificObjects() {
RTC_LOG(LS_INFO) << __FUNCTION__;
if (audio_device_ != nullptr) {
RTC_LOG(LS_INFO) << "Reusing provided audio device";
return 0;
}
// Dummy ADM implementations if build flags are set.
#if defined(WEBRTC_DUMMY_AUDIO_BUILD)
audio_device_.reset(new AudioDeviceDummy());
RTC_LOG(LS_INFO) << "Dummy Audio APIs will be utilized";
#elif defined(WEBRTC_DUMMY_FILE_DEVICES)
audio_device_.reset(FileAudioDeviceFactory::CreateFileAudioDevice());
if (audio_device_) {
RTC_LOG(LS_INFO) << "Will use file-playing dummy device.";
} else {
// Create a dummy device instead.
audio_device_.reset(new AudioDeviceDummy());
RTC_LOG(LS_INFO) << "Dummy Audio APIs will be utilized";
}
// Real (non-dummy) ADM implementations.
#else
AudioLayer audio_layer(PlatformAudioLayer());
// Windows ADM implementation.
#if defined(WEBRTC_WINDOWS_CORE_AUDIO_BUILD)
if ((audio_layer == kWindowsCoreAudio) ||
(audio_layer == kPlatformDefaultAudio)) {
RTC_LOG(LS_INFO) << "Attempting to use the Windows Core Audio APIs...";
if (AudioDeviceWindowsCore::CoreAudioIsSupported()) {
audio_device_.reset(new AudioDeviceWindowsCore());
RTC_LOG(LS_INFO) << "Windows Core Audio APIs will be utilized";
}
}
#endif // defined(WEBRTC_WINDOWS_CORE_AUDIO_BUILD)
// Linux ADM implementation.
// Note that, WEBRTC_ENABLE_LINUX_ALSA is always defined by default when
// WEBRTC_LINUX is defined. WEBRTC_ENABLE_LINUX_PULSE depends on the
// 'rtc_include_pulse_audio' build flag.
// TODO(bugs.webrtc.org/9127): improve support and make it more clear that
// PulseAudio is the default selection.
#if !defined(WEBRTC_ANDROID) && defined(WEBRTC_LINUX)
#if !defined(WEBRTC_ENABLE_LINUX_PULSE)
// Build flag 'rtc_include_pulse_audio' is set to false. In this mode:
// - kPlatformDefaultAudio => ALSA, and
// - kLinuxAlsaAudio => ALSA, and
// - kLinuxPulseAudio => Invalid selection.
RTC_LOG(LS_WARNING) << "PulseAudio is disabled using build flag.";
if ((audio_layer == kLinuxAlsaAudio) ||
(audio_layer == kPlatformDefaultAudio)) {
audio_device_.reset(new AudioDeviceLinuxALSA());
RTC_LOG(LS_INFO) << "Linux ALSA APIs will be utilized.";
}
#else
// Build flag 'rtc_include_pulse_audio' is set to true (default). In this
// mode:
// - kPlatformDefaultAudio => PulseAudio, and
// - kLinuxPulseAudio => PulseAudio, and
// - kLinuxAlsaAudio => ALSA (supported but not default).
RTC_LOG(LS_INFO) << "PulseAudio support is enabled.";
if ((audio_layer == kLinuxPulseAudio) ||
(audio_layer == kPlatformDefaultAudio)) {
// Linux PulseAudio implementation is default.
audio_device_.reset(new AudioDeviceLinuxPulse());
RTC_LOG(LS_INFO) << "Linux PulseAudio APIs will be utilized";
} else if (audio_layer == kLinuxAlsaAudio) {
audio_device_.reset(new AudioDeviceLinuxALSA());
RTC_LOG(LS_WARNING) << "Linux ALSA APIs will be utilized.";
}
#endif // #if !defined(WEBRTC_ENABLE_LINUX_PULSE)
#endif // #if defined(WEBRTC_LINUX)
// iOS ADM implementation.
#if defined(WEBRTC_IOS)
if (audio_layer == kPlatformDefaultAudio) {
audio_device_.reset(
new ios_adm::AudioDeviceIOS(/*bypass_voice_processing=*/false));
RTC_LOG(LS_INFO) << "iPhone Audio APIs will be utilized.";
}
// END #if defined(WEBRTC_IOS)
// Mac OS X ADM implementation.
#elif defined(WEBRTC_MAC)
if (audio_layer == kPlatformDefaultAudio) {
audio_device_.reset(new AudioDeviceMac());
RTC_LOG(LS_INFO) << "Mac OS X Audio APIs will be utilized.";
}
#endif // WEBRTC_MAC
// Dummy ADM implementation.
if (audio_layer == kDummyAudio) {
audio_device_.reset(new AudioDeviceDummy());
RTC_LOG(LS_INFO) << "Dummy Audio APIs will be utilized.";
}
#endif // if defined(WEBRTC_DUMMY_AUDIO_BUILD)
if (!audio_device_) {
RTC_LOG(LS_ERROR)
<< "Failed to create the platform specific ADM implementation.";
return -1;
}
return 0;
}
int32_t AudioDeviceModuleImpl::AttachAudioBuffer() {
RTC_LOG(LS_INFO) << __FUNCTION__;
audio_device_->AttachAudioBuffer(&audio_device_buffer_);
return 0;
}
AudioDeviceModuleImpl::~AudioDeviceModuleImpl() {
RTC_LOG(LS_INFO) << __FUNCTION__;
}
int32_t AudioDeviceModuleImpl::ActiveAudioLayer(AudioLayer* audioLayer) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
AudioLayer activeAudio;
if (audio_device_->ActiveAudioLayer(activeAudio) == -1) {
return -1;
}
*audioLayer = activeAudio;
return 0;
}
int32_t AudioDeviceModuleImpl::Init() {
RTC_LOG(LS_INFO) << __FUNCTION__;
if (initialized_)
return 0;
RTC_CHECK(audio_device_);
AudioDeviceGeneric::InitStatus status = audio_device_->Init();
RTC_HISTOGRAM_ENUMERATION(
"WebRTC.Audio.InitializationResult", static_cast<int>(status),
static_cast<int>(AudioDeviceGeneric::InitStatus::NUM_STATUSES));
if (status != AudioDeviceGeneric::InitStatus::OK) {
RTC_LOG(LS_ERROR) << "Audio device initialization failed.";
return -1;
}
initialized_ = true;
return 0;
}
int32_t AudioDeviceModuleImpl::Terminate() {
RTC_LOG(LS_INFO) << __FUNCTION__;
if (!initialized_)
return 0;
if (audio_device_->Terminate() == -1) {
return -1;
}
initialized_ = false;
return 0;
}
bool AudioDeviceModuleImpl::Initialized() const {
RTC_LOG(LS_INFO) << __FUNCTION__ << ": " << initialized_;
return initialized_;
}
int32_t AudioDeviceModuleImpl::InitSpeaker() {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
return audio_device_->InitSpeaker();
}
int32_t AudioDeviceModuleImpl::InitMicrophone() {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
return audio_device_->InitMicrophone();
}
int32_t AudioDeviceModuleImpl::SpeakerVolumeIsAvailable(bool* available) {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool isAvailable = false;
if (audio_device_->SpeakerVolumeIsAvailable(isAvailable) == -1) {
return -1;
}
*available = isAvailable;
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return 0;
}
int32_t AudioDeviceModuleImpl::SetSpeakerVolume(uint32_t volume) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << volume << ")";
CHECKinitialized_();
return audio_device_->SetSpeakerVolume(volume);
}
int32_t AudioDeviceModuleImpl::SpeakerVolume(uint32_t* volume) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
uint32_t level = 0;
if (audio_device_->SpeakerVolume(level) == -1) {
return -1;
}
*volume = level;
RTC_LOG(LS_INFO) << "output: " << *volume;
return 0;
}
bool AudioDeviceModuleImpl::SpeakerIsInitialized() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized__BOOL();
bool isInitialized = audio_device_->SpeakerIsInitialized();
RTC_LOG(LS_INFO) << "output: " << isInitialized;
return isInitialized;
}
bool AudioDeviceModuleImpl::MicrophoneIsInitialized() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized__BOOL();
bool isInitialized = audio_device_->MicrophoneIsInitialized();
RTC_LOG(LS_INFO) << "output: " << isInitialized;
return isInitialized;
}
int32_t AudioDeviceModuleImpl::MaxSpeakerVolume(uint32_t* maxVolume) const {
CHECKinitialized_();
uint32_t maxVol = 0;
if (audio_device_->MaxSpeakerVolume(maxVol) == -1) {
return -1;
}
*maxVolume = maxVol;
return 0;
}
int32_t AudioDeviceModuleImpl::MinSpeakerVolume(uint32_t* minVolume) const {
CHECKinitialized_();
uint32_t minVol = 0;
if (audio_device_->MinSpeakerVolume(minVol) == -1) {
return -1;
}
*minVolume = minVol;
return 0;
}
int32_t AudioDeviceModuleImpl::SpeakerMuteIsAvailable(bool* available) {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool isAvailable = false;
if (audio_device_->SpeakerMuteIsAvailable(isAvailable) == -1) {
return -1;
}
*available = isAvailable;
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return 0;
}
int32_t AudioDeviceModuleImpl::SetSpeakerMute(bool enable) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")";
CHECKinitialized_();
return audio_device_->SetSpeakerMute(enable);
}
int32_t AudioDeviceModuleImpl::SpeakerMute(bool* enabled) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool muted = false;
if (audio_device_->SpeakerMute(muted) == -1) {
return -1;
}
*enabled = muted;
RTC_LOG(LS_INFO) << "output: " << muted;
return 0;
}
int32_t AudioDeviceModuleImpl::MicrophoneMuteIsAvailable(bool* available) {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool isAvailable = false;
if (audio_device_->MicrophoneMuteIsAvailable(isAvailable) == -1) {
return -1;
}
*available = isAvailable;
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return 0;
}
int32_t AudioDeviceModuleImpl::SetMicrophoneMute(bool enable) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")";
CHECKinitialized_();
return (audio_device_->SetMicrophoneMute(enable));
}
int32_t AudioDeviceModuleImpl::MicrophoneMute(bool* enabled) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool muted = false;
if (audio_device_->MicrophoneMute(muted) == -1) {
return -1;
}
*enabled = muted;
RTC_LOG(LS_INFO) << "output: " << muted;
return 0;
}
int32_t AudioDeviceModuleImpl::MicrophoneVolumeIsAvailable(bool* available) {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool isAvailable = false;
if (audio_device_->MicrophoneVolumeIsAvailable(isAvailable) == -1) {
return -1;
}
*available = isAvailable;
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return 0;
}
int32_t AudioDeviceModuleImpl::SetMicrophoneVolume(uint32_t volume) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << volume << ")";
CHECKinitialized_();
return (audio_device_->SetMicrophoneVolume(volume));
}
int32_t AudioDeviceModuleImpl::MicrophoneVolume(uint32_t* volume) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
uint32_t level = 0;
if (audio_device_->MicrophoneVolume(level) == -1) {
return -1;
}
*volume = level;
RTC_LOG(LS_INFO) << "output: " << *volume;
return 0;
}
int32_t AudioDeviceModuleImpl::StereoRecordingIsAvailable(
bool* available) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool isAvailable = false;
if (audio_device_->StereoRecordingIsAvailable(isAvailable) == -1) {
return -1;
}
*available = isAvailable;
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return 0;
}
int32_t AudioDeviceModuleImpl::SetStereoRecording(bool enable) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")";
CHECKinitialized_();
if (audio_device_->RecordingIsInitialized()) {
RTC_LOG(LS_ERROR)
<< "unable to set stereo mode after recording is initialized";
return -1;
}
if (audio_device_->SetStereoRecording(enable) == -1) {
if (enable) {
RTC_LOG(LS_WARNING) << "failed to enable stereo recording";
}
return -1;
}
int8_t nChannels(1);
if (enable) {
nChannels = 2;
}
audio_device_buffer_.SetRecordingChannels(nChannels);
return 0;
}
int32_t AudioDeviceModuleImpl::StereoRecording(bool* enabled) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool stereo = false;
if (audio_device_->StereoRecording(stereo) == -1) {
return -1;
}
*enabled = stereo;
RTC_LOG(LS_INFO) << "output: " << stereo;
return 0;
}
int32_t AudioDeviceModuleImpl::StereoPlayoutIsAvailable(bool* available) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool isAvailable = false;
if (audio_device_->StereoPlayoutIsAvailable(isAvailable) == -1) {
return -1;
}
*available = isAvailable;
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return 0;
}
int32_t AudioDeviceModuleImpl::SetStereoPlayout(bool enable) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")";
CHECKinitialized_();
if (audio_device_->PlayoutIsInitialized()) {
RTC_LOG(LS_ERROR)
<< "unable to set stereo mode while playing side is initialized";
return -1;
}
if (audio_device_->SetStereoPlayout(enable)) {
RTC_LOG(LS_WARNING) << "stereo playout is not supported";
return -1;
}
int8_t nChannels(1);
if (enable) {
nChannels = 2;
}
audio_device_buffer_.SetPlayoutChannels(nChannels);
return 0;
}
int32_t AudioDeviceModuleImpl::StereoPlayout(bool* enabled) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool stereo = false;
if (audio_device_->StereoPlayout(stereo) == -1) {
return -1;
}
*enabled = stereo;
RTC_LOG(LS_INFO) << "output: " << stereo;
return 0;
}
int32_t AudioDeviceModuleImpl::PlayoutIsAvailable(bool* available) {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool isAvailable = false;
if (audio_device_->PlayoutIsAvailable(isAvailable) == -1) {
return -1;
}
*available = isAvailable;
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return 0;
}
int32_t AudioDeviceModuleImpl::RecordingIsAvailable(bool* available) {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
bool isAvailable = false;
if (audio_device_->RecordingIsAvailable(isAvailable) == -1) {
return -1;
}
*available = isAvailable;
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return 0;
}
int32_t AudioDeviceModuleImpl::MaxMicrophoneVolume(uint32_t* maxVolume) const {
CHECKinitialized_();
uint32_t maxVol(0);
if (audio_device_->MaxMicrophoneVolume(maxVol) == -1) {
return -1;
}
*maxVolume = maxVol;
return 0;
}
int32_t AudioDeviceModuleImpl::MinMicrophoneVolume(uint32_t* minVolume) const {
CHECKinitialized_();
uint32_t minVol(0);
if (audio_device_->MinMicrophoneVolume(minVol) == -1) {
return -1;
}
*minVolume = minVol;
return 0;
}
int16_t AudioDeviceModuleImpl::PlayoutDevices() {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
uint16_t nPlayoutDevices = audio_device_->PlayoutDevices();
RTC_LOG(LS_INFO) << "output: " << nPlayoutDevices;
return (int16_t)(nPlayoutDevices);
}
int32_t AudioDeviceModuleImpl::SetPlayoutDevice(uint16_t index) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << index << ")";
CHECKinitialized_();
return audio_device_->SetPlayoutDevice(index);
}
int32_t AudioDeviceModuleImpl::SetPlayoutDevice(WindowsDeviceType device) {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
return audio_device_->SetPlayoutDevice(device);
}
int32_t AudioDeviceModuleImpl::PlayoutDeviceName(
uint16_t index,
char name[kAdmMaxDeviceNameSize],
char guid[kAdmMaxGuidSize]) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << index << ", ...)";
CHECKinitialized_();
if (name == NULL) {
return -1;
}
if (audio_device_->PlayoutDeviceName(index, name, guid) == -1) {
return -1;
}
if (name != NULL) {
RTC_LOG(LS_INFO) << "output: name = " << name;
}
if (guid != NULL) {
RTC_LOG(LS_INFO) << "output: guid = " << guid;
}
return 0;
}
int32_t AudioDeviceModuleImpl::RecordingDeviceName(
uint16_t index,
char name[kAdmMaxDeviceNameSize],
char guid[kAdmMaxGuidSize]) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << index << ", ...)";
CHECKinitialized_();
if (name == NULL) {
return -1;
}
if (audio_device_->RecordingDeviceName(index, name, guid) == -1) {
return -1;
}
if (name != NULL) {
RTC_LOG(LS_INFO) << "output: name = " << name;
}
if (guid != NULL) {
RTC_LOG(LS_INFO) << "output: guid = " << guid;
}
return 0;
}
int16_t AudioDeviceModuleImpl::RecordingDevices() {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
uint16_t nRecordingDevices = audio_device_->RecordingDevices();
RTC_LOG(LS_INFO) << "output: " << nRecordingDevices;
return (int16_t)nRecordingDevices;
}
int32_t AudioDeviceModuleImpl::SetRecordingDevice(uint16_t index) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << index << ")";
CHECKinitialized_();
return audio_device_->SetRecordingDevice(index);
}
int32_t AudioDeviceModuleImpl::SetRecordingDevice(WindowsDeviceType device) {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
return audio_device_->SetRecordingDevice(device);
}
int32_t AudioDeviceModuleImpl::InitPlayout() {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
if (PlayoutIsInitialized()) {
return 0;
}
int32_t result = audio_device_->InitPlayout();
RTC_LOG(LS_INFO) << "output: " << result;
RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitPlayoutSuccess",
static_cast<int>(result == 0));
return result;
}
int32_t AudioDeviceModuleImpl::InitRecording() {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
if (RecordingIsInitialized()) {
return 0;
}
int32_t result = audio_device_->InitRecording();
RTC_LOG(LS_INFO) << "output: " << result;
RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitRecordingSuccess",
static_cast<int>(result == 0));
return result;
}
bool AudioDeviceModuleImpl::PlayoutIsInitialized() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized__BOOL();
return audio_device_->PlayoutIsInitialized();
}
bool AudioDeviceModuleImpl::RecordingIsInitialized() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized__BOOL();
return audio_device_->RecordingIsInitialized();
}
int32_t AudioDeviceModuleImpl::StartPlayout() {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
if (Playing()) {
return 0;
}
audio_device_buffer_.StartPlayout();
int32_t result = audio_device_->StartPlayout();
RTC_LOG(LS_INFO) << "output: " << result;
RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartPlayoutSuccess",
static_cast<int>(result == 0));
return result;
}
int32_t AudioDeviceModuleImpl::StopPlayout() {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
int32_t result = audio_device_->StopPlayout();
audio_device_buffer_.StopPlayout();
RTC_LOG(LS_INFO) << "output: " << result;
RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopPlayoutSuccess",
static_cast<int>(result == 0));
return result;
}
bool AudioDeviceModuleImpl::Playing() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized__BOOL();
return audio_device_->Playing();
}
int32_t AudioDeviceModuleImpl::StartRecording() {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
if (Recording()) {
return 0;
}
audio_device_buffer_.StartRecording();
int32_t result = audio_device_->StartRecording();
RTC_LOG(LS_INFO) << "output: " << result;
RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StartRecordingSuccess",
static_cast<int>(result == 0));
return result;
}
int32_t AudioDeviceModuleImpl::StopRecording() {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
int32_t result = audio_device_->StopRecording();
audio_device_buffer_.StopRecording();
RTC_LOG(LS_INFO) << "output: " << result;
RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.StopRecordingSuccess",
static_cast<int>(result == 0));
return result;
}
bool AudioDeviceModuleImpl::Recording() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized__BOOL();
return audio_device_->Recording();
}
int32_t AudioDeviceModuleImpl::RegisterAudioCallback(
AudioTransport* audioCallback) {
RTC_LOG(LS_INFO) << __FUNCTION__;
return audio_device_buffer_.RegisterAudioCallback(audioCallback);
}
int32_t AudioDeviceModuleImpl::PlayoutDelay(uint16_t* delayMS) const {
CHECKinitialized_();
uint16_t delay = 0;
if (audio_device_->PlayoutDelay(delay) == -1) {
RTC_LOG(LS_ERROR) << "failed to retrieve the playout delay";
return -1;
}
*delayMS = delay;
return 0;
}
bool AudioDeviceModuleImpl::BuiltInAECIsAvailable() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized__BOOL();
bool isAvailable = audio_device_->BuiltInAECIsAvailable();
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return isAvailable;
}
int32_t AudioDeviceModuleImpl::EnableBuiltInAEC(bool enable) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")";
CHECKinitialized_();
int32_t ok = audio_device_->EnableBuiltInAEC(enable);
RTC_LOG(LS_INFO) << "output: " << ok;
return ok;
}
bool AudioDeviceModuleImpl::BuiltInAGCIsAvailable() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized__BOOL();
bool isAvailable = audio_device_->BuiltInAGCIsAvailable();
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return isAvailable;
}
int32_t AudioDeviceModuleImpl::EnableBuiltInAGC(bool enable) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")";
CHECKinitialized_();
int32_t ok = audio_device_->EnableBuiltInAGC(enable);
RTC_LOG(LS_INFO) << "output: " << ok;
return ok;
}
bool AudioDeviceModuleImpl::BuiltInNSIsAvailable() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized__BOOL();
bool isAvailable = audio_device_->BuiltInNSIsAvailable();
RTC_LOG(LS_INFO) << "output: " << isAvailable;
return isAvailable;
}
int32_t AudioDeviceModuleImpl::EnableBuiltInNS(bool enable) {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << enable << ")";
CHECKinitialized_();
int32_t ok = audio_device_->EnableBuiltInNS(enable);
RTC_LOG(LS_INFO) << "output: " << ok;
return ok;
}
int32_t AudioDeviceModuleImpl::GetPlayoutUnderrunCount() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
CHECKinitialized_();
int32_t underrunCount = audio_device_->GetPlayoutUnderrunCount();
RTC_LOG(LS_INFO) << "output: " << underrunCount;
return underrunCount;
}
#if defined(WEBRTC_IOS)
int AudioDeviceModuleImpl::GetPlayoutAudioParameters(
AudioParameters* params) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
int r = audio_device_->GetPlayoutAudioParameters(params);
RTC_LOG(LS_INFO) << "output: " << r;
return r;
}
int AudioDeviceModuleImpl::GetRecordAudioParameters(
AudioParameters* params) const {
RTC_LOG(LS_INFO) << __FUNCTION__;
int r = audio_device_->GetRecordAudioParameters(params);
RTC_LOG(LS_INFO) << "output: " << r;
return r;
}
#endif // WEBRTC_IOS
AudioDeviceModuleImpl::PlatformType AudioDeviceModuleImpl::Platform() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
return platform_type_;
}
AudioDeviceModule::AudioLayer AudioDeviceModuleImpl::PlatformAudioLayer()
const {
RTC_LOG(LS_INFO) << __FUNCTION__;
return audio_layer_;
}
} // namespace webrtc