Skip to content

Commit

Permalink
Cherry pick audio selection from m97 release (#35)
Browse files Browse the repository at this point in the history
* [Mac] Allow audio device selection (#21)

* first attempt

* remove unused dep

* init playout / recording

* use AudioDeviceID as guid

* switch device method

* equality

* default device

* `isDefault` property

* dont format default device name

* type param

* bypass

* refactor

* fix

* append Audio to thread labels

* ref

* lk headers

* low level apis

* fix thread checks

Some methods of ADM needs to be run on worker thread, otherwise RTC's thread check will fail.

* switch to default device when removed

* close mixerManager if didn't switch to default device

* default audio device switched

* expose devices update handler

* fix ios compile

* fix bug: don't always recreate RTCAudioDeviceModule

* handle guid.

Co-authored-by: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com>
  • Loading branch information
cloudwebrtc and hiroshihorie committed Jun 7, 2023
1 parent bed873d commit 627b2d2
Show file tree
Hide file tree
Showing 30 changed files with 749 additions and 76 deletions.
5 changes: 0 additions & 5 deletions modules/audio_device/android/audio_device_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,6 @@ class AudioDeviceTemplate : public AudioDeviceGeneric {
RTC_CHECK_NOTREACHED();
}

int32_t SetAudioDeviceSink(AudioDeviceSink* sink) override {
RTC_CHECK_NOTREACHED();
return -1;
}

int32_t SetSpeakerMute(bool enable) override { RTC_CHECK_NOTREACHED(); }

int32_t SpeakerMute(bool& enabled) const override { RTC_CHECK_NOTREACHED(); }
Expand Down
4 changes: 4 additions & 0 deletions modules/audio_device/audio_device_data_observer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ class ADMWrapper : public AudioDeviceModule, public AudioTransport {
}
#endif // WEBRTC_IOS

int32_t SetAudioDeviceSink(AudioDeviceSink* sink) const override {
return impl_->SetAudioDeviceSink(sink);
}

protected:
rtc::scoped_refptr<AudioDeviceModule> impl_;
AudioDeviceDataObserver* legacy_observer_ = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion modules/audio_device/audio_device_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ class AudioDeviceGeneric {
virtual int GetRecordAudioParameters(AudioParameters* params) const;
#endif // WEBRTC_IOS

virtual int32_t SetAudioDeviceSink(AudioDeviceSink* sink) = 0;
virtual int32_t SetAudioDeviceSink(AudioDeviceSink* sink) { return -1; }

virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) = 0;

Expand Down
28 changes: 21 additions & 7 deletions modules/audio_device/audio_device_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,17 @@ namespace webrtc {

rtc::scoped_refptr<AudioDeviceModule> AudioDeviceModule::Create(
AudioLayer audio_layer,
TaskQueueFactory* task_queue_factory) {
TaskQueueFactory* task_queue_factory,
bool bypass_voice_processing) {
RTC_DLOG(LS_INFO) << __FUNCTION__;
return AudioDeviceModule::CreateForTest(audio_layer, task_queue_factory);
return AudioDeviceModule::CreateForTest(audio_layer, task_queue_factory, bypass_voice_processing);
}

// static
rtc::scoped_refptr<AudioDeviceModuleForTest> AudioDeviceModule::CreateForTest(
AudioLayer audio_layer,
TaskQueueFactory* task_queue_factory) {
TaskQueueFactory* task_queue_factory,
bool bypass_voice_processing) {
RTC_DLOG(LS_INFO) << __FUNCTION__;

// The "AudioDeviceModule::kWindowsCoreAudio2" audio layer has its own
Expand All @@ -93,7 +95,7 @@ rtc::scoped_refptr<AudioDeviceModuleForTest> AudioDeviceModule::CreateForTest(

// Create the generic reference counted (platform independent) implementation.
auto audio_device = rtc::make_ref_counted<AudioDeviceModuleImpl>(
audio_layer, task_queue_factory);
audio_layer, task_queue_factory, bypass_voice_processing);

// Ensure that the current platform is supported.
if (audio_device->CheckPlatform() == -1) {
Expand All @@ -116,8 +118,13 @@ rtc::scoped_refptr<AudioDeviceModuleForTest> AudioDeviceModule::CreateForTest(

AudioDeviceModuleImpl::AudioDeviceModuleImpl(
AudioLayer audio_layer,
TaskQueueFactory* task_queue_factory)
: audio_layer_(audio_layer), audio_device_buffer_(task_queue_factory) {
TaskQueueFactory* task_queue_factory,
bool bypass_voice_processing)
: audio_layer_(audio_layer),
#if defined(WEBRTC_IOS)
bypass_voice_processing_(bypass_voice_processing),
#endif
audio_device_buffer_(task_queue_factory) {
RTC_DLOG(LS_INFO) << __FUNCTION__;
}

Expand Down Expand Up @@ -280,7 +287,7 @@ int32_t AudioDeviceModuleImpl::CreatePlatformSpecificObjects() {
#if defined(WEBRTC_IOS)
if (audio_layer == kPlatformDefaultAudio) {
audio_device_.reset(
new ios_adm::AudioDeviceIOS(/*bypass_voice_processing=*/false));
new ios_adm::AudioDeviceIOS(/*bypass_voice_processing=*/bypass_voice_processing_));
RTC_LOG(LS_INFO) << "iPhone Audio APIs will be utilized.";
}
// END #if defined(WEBRTC_IOS)
Expand Down Expand Up @@ -937,6 +944,13 @@ int AudioDeviceModuleImpl::GetRecordAudioParameters(
}
#endif // WEBRTC_IOS

int32_t AudioDeviceModuleImpl::SetAudioDeviceSink(AudioDeviceSink* sink) const {
RTC_LOG(LS_INFO) << __FUNCTION__ << "(" << sink << ")";
int32_t ok = audio_device_->SetAudioDeviceSink(sink);
RTC_LOG(LS_INFO) << "output: " << ok;
return ok;
}

AudioDeviceModuleImpl::PlatformType AudioDeviceModuleImpl::Platform() const {
RTC_LOG(LS_INFO) << __FUNCTION__;
return platform_type_;
Expand Down
9 changes: 7 additions & 2 deletions modules/audio_device/audio_device_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class AudioDeviceModuleImpl : public AudioDeviceModuleForTest {
int32_t AttachAudioBuffer();

AudioDeviceModuleImpl(AudioLayer audio_layer,
TaskQueueFactory* task_queue_factory);
TaskQueueFactory* task_queue_factory,
bool bypass_voice_processing = false);
~AudioDeviceModuleImpl() override;

// Retrieve the currently utilized audio layer
Expand Down Expand Up @@ -145,6 +146,8 @@ class AudioDeviceModuleImpl : public AudioDeviceModuleForTest {
int GetRecordAudioParameters(AudioParameters* params) const override;
#endif // WEBRTC_IOS

int32_t SetAudioDeviceSink(AudioDeviceSink* sink) const override;

#if defined(WEBRTC_ANDROID)
// Only use this acccessor for test purposes on Android.
AudioManager* GetAndroidAudioManagerForTest() {
Expand All @@ -165,7 +168,9 @@ class AudioDeviceModuleImpl : public AudioDeviceModuleForTest {
AudioLayer audio_layer_;
PlatformType platform_type_ = kPlatformNotSupported;
bool initialized_ = false;
#if defined(WEBRTC_ANDROID)
#if defined(WEBRTC_IOS)
bool bypass_voice_processing_;
#elif defined(WEBRTC_ANDROID)
// Should be declared first to ensure that it outlives other resources.
std::unique_ptr<AudioManager> audio_manager_android_;
#endif
Expand Down
4 changes: 0 additions & 4 deletions modules/audio_device/dummy/audio_device_dummy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,5 @@ int32_t AudioDeviceDummy::PlayoutDelay(uint16_t& delayMS) const {
return -1;
}

int32_t AudioDeviceDummy::SetAudioDeviceSink(AudioDeviceSink* sink) {
return -1;
}

void AudioDeviceDummy::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {}
} // namespace webrtc
2 changes: 0 additions & 2 deletions modules/audio_device/dummy/audio_device_dummy.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ class AudioDeviceDummy : public AudioDeviceGeneric {
// Delay information and control
int32_t PlayoutDelay(uint16_t& delayMS) const override;

int32_t SetAudioDeviceSink(AudioDeviceSink* sink) override;

void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;

};
Expand Down
4 changes: 0 additions & 4 deletions modules/audio_device/dummy/file_audio_device.cc
Original file line number Diff line number Diff line change
Expand Up @@ -427,10 +427,6 @@ int32_t FileAudioDevice::PlayoutDelay(uint16_t& delayMS) const {
return 0;
}

int32_t FileAudioDevice::SetAudioDeviceSink(AudioDeviceSink* sink) {
return -1;
}

void FileAudioDevice::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
MutexLock lock(&mutex_);

Expand Down
2 changes: 0 additions & 2 deletions modules/audio_device/dummy/file_audio_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@ class FileAudioDevice : public AudioDeviceGeneric {
// Delay information and control
int32_t PlayoutDelay(uint16_t& delayMS) const override;

int32_t SetAudioDeviceSink(AudioDeviceSink* sink) override;

void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;

private:
Expand Down
8 changes: 6 additions & 2 deletions modules/audio_device/include/audio_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ class AudioDeviceModule : public rtc::RefCountInterface {
// Creates a default ADM for usage in production code.
static rtc::scoped_refptr<AudioDeviceModule> Create(
AudioLayer audio_layer,
TaskQueueFactory* task_queue_factory);
TaskQueueFactory* task_queue_factory,
bool bypass_voice_processing = false);
// Creates an ADM with support for extra test methods. Don't use this factory
// in production code.
static rtc::scoped_refptr<AudioDeviceModuleForTest> CreateForTest(
AudioLayer audio_layer,
TaskQueueFactory* task_queue_factory);
TaskQueueFactory* task_queue_factory,
bool bypass_voice_processing = false);

// Retrieve the currently utilized audio layer
virtual int32_t ActiveAudioLayer(AudioLayer* audioLayer) const = 0;
Expand Down Expand Up @@ -180,6 +182,8 @@ class AudioDeviceModule : public rtc::RefCountInterface {
virtual int GetRecordAudioParameters(AudioParameters* params) const = 0;
#endif // WEBRTC_IOS

virtual int32_t SetAudioDeviceSink(AudioDeviceSink* sink) const { return -1; }

protected:
~AudioDeviceModule() override {}
};
Expand Down
2 changes: 0 additions & 2 deletions modules/audio_device/linux/audio_device_alsa_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ class AudioDeviceLinuxALSA : public AudioDeviceGeneric {
void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer)
RTC_LOCKS_EXCLUDED(mutex_) override;

int32_t SetAudioDeviceSink(AudioDeviceSink* sink) override { return -1; }

private:
int32_t InitRecordingLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
int32_t StopRecordingLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
Expand Down
2 changes: 0 additions & 2 deletions modules/audio_device/linux/audio_device_pulse_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,6 @@ class AudioDeviceLinuxPulse : public AudioDeviceGeneric {

void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) override;

int32_t SetAudioDeviceSink(AudioDeviceSink* sink) override { return -1; }

private:
void Lock() RTC_EXCLUSIVE_LOCK_FUNCTION(mutex_) { mutex_.Lock(); }
void UnLock() RTC_UNLOCK_FUNCTION(mutex_) { mutex_.Unlock(); }
Expand Down
Loading

0 comments on commit 627b2d2

Please sign in to comment.