diff --git a/ringrtc/rffi/BUILD.gn b/ringrtc/rffi/BUILD.gn index 8052b39c18..341535b0fc 100644 --- a/ringrtc/rffi/BUILD.gn +++ b/ringrtc/rffi/BUILD.gn @@ -7,6 +7,7 @@ import("//webrtc.gni") # C++ source files common to all platforms common_sources = [ + "src/audio_device.cc", "src/field_trial.cc", "src/injectable_network.cc", "src/logging.cc", diff --git a/ringrtc/rffi/api/peer_connection_factory.h b/ringrtc/rffi/api/peer_connection_factory.h index 9f48d151fa..5057b84585 100644 --- a/ringrtc/rffi/api/peer_connection_factory.h +++ b/ringrtc/rffi/api/peer_connection_factory.h @@ -81,6 +81,7 @@ enum class RffiPeerConnectionKind: uint8_t { enum RffiAudioDeviceModuleType { kRffiAudioDeviceModuleDefault = 0, kRffiAudioDeviceModuleFile = 1, + kRffiAudioDeviceModuleRingRtc = 2, }; typedef struct { diff --git a/ringrtc/rffi/src/audio_device.cc b/ringrtc/rffi/src/audio_device.cc new file mode 100644 index 0000000000..bb1dab87e5 --- /dev/null +++ b/ringrtc/rffi/src/audio_device.cc @@ -0,0 +1,300 @@ +/* + * Copyright 2024 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +#include "rffi/src/audio_device.h" + +#include "api/make_ref_counted.h" +#include "api/scoped_refptr.h" +#include "rtc_base/logging.h" + +#define TRACE_LOG \ + RTC_LOG(LS_VERBOSE) << "RingRTCAudioDeviceModule::" << __func__ + +namespace webrtc { +namespace rffi { + +RingRTCAudioDeviceModule::RingRTCAudioDeviceModule() = default; +RingRTCAudioDeviceModule::~RingRTCAudioDeviceModule() = default; + +// static +rtc::scoped_refptr RingRTCAudioDeviceModule::Create() { + TRACE_LOG; + return rtc::make_ref_counted(); +} + +int32_t RingRTCAudioDeviceModule::ActiveAudioLayer( + AudioLayer* audioLayer) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::RegisterAudioCallback( + AudioTransport* audioCallback) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::Init() { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::Terminate() { + TRACE_LOG; + return -1; +} + +bool RingRTCAudioDeviceModule::Initialized() const { + TRACE_LOG; + return false; +} + +int16_t RingRTCAudioDeviceModule::PlayoutDevices() { + TRACE_LOG; + return -1; +} + +int16_t RingRTCAudioDeviceModule::RecordingDevices() { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::PlayoutDeviceName( + uint16_t index, + char name[kAdmMaxDeviceNameSize], + char guid[kAdmMaxGuidSize]) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::RecordingDeviceName( + uint16_t index, + char name[kAdmMaxDeviceNameSize], + char guid[kAdmMaxGuidSize]) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SetPlayoutDevice(uint16_t index) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SetPlayoutDevice(WindowsDeviceType device) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SetRecordingDevice(uint16_t index) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SetRecordingDevice(WindowsDeviceType device) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::PlayoutIsAvailable(bool* available) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::InitPlayout() { + TRACE_LOG; + return -1; +} + +bool RingRTCAudioDeviceModule::PlayoutIsInitialized() const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::RecordingIsAvailable(bool* available) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::InitRecording() { + TRACE_LOG; + return -1; +} + +bool RingRTCAudioDeviceModule::RecordingIsInitialized() const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::StartPlayout() { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::StopPlayout() { + TRACE_LOG; + return -1; +} + +bool RingRTCAudioDeviceModule::Playing() const { + TRACE_LOG; + return false; +} + +int32_t RingRTCAudioDeviceModule::StartRecording() { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::StopRecording() { + TRACE_LOG; + return -1; +} + +bool RingRTCAudioDeviceModule::Recording() const { + TRACE_LOG; + return false; +} + +int32_t RingRTCAudioDeviceModule::InitSpeaker() { + TRACE_LOG; + return -1; +} + +bool RingRTCAudioDeviceModule::SpeakerIsInitialized() const { + TRACE_LOG; + return false; +} + +int32_t RingRTCAudioDeviceModule::InitMicrophone() { + TRACE_LOG; + return -1; +} + +bool RingRTCAudioDeviceModule::MicrophoneIsInitialized() const { + TRACE_LOG; + return false; +} + +int32_t RingRTCAudioDeviceModule::SpeakerVolumeIsAvailable(bool* available) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SetSpeakerVolume(uint32_t volume) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SpeakerVolume(uint32_t* volume) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::MaxSpeakerVolume(uint32_t* maxVolume) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::MinSpeakerVolume(uint32_t* minVolume) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::MicrophoneVolumeIsAvailable(bool* available) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SetMicrophoneVolume(uint32_t volume) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::MicrophoneVolume(uint32_t* volume) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::MaxMicrophoneVolume( + uint32_t* maxVolume) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::MinMicrophoneVolume( + uint32_t* minVolume) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SpeakerMuteIsAvailable(bool* available) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SetSpeakerMute(bool enable) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SpeakerMute(bool* enabled) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::MicrophoneMuteIsAvailable(bool* available) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SetMicrophoneMute(bool enable) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::MicrophoneMute(bool* enabled) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::StereoPlayoutIsAvailable( + bool* available) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SetStereoPlayout(bool enable) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::StereoPlayout(bool* enabled) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::StereoRecordingIsAvailable( + bool* available) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::SetStereoRecording(bool enable) { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::StereoRecording(bool* enabled) const { + TRACE_LOG; + return -1; +} + +int32_t RingRTCAudioDeviceModule::PlayoutDelay(uint16_t* delayMS) const { + TRACE_LOG; + return -1; +} + +} // namespace rffi +} // namespace webrtc diff --git a/ringrtc/rffi/src/audio_device.h b/ringrtc/rffi/src/audio_device.h new file mode 100644 index 0000000000..ee4d7ce5db --- /dev/null +++ b/ringrtc/rffi/src/audio_device.h @@ -0,0 +1,144 @@ +/* + * Copyright 2024 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +#ifndef RFFI_AUDIO_DEVICE_H__ +#define RFFI_AUDIO_DEVICE_H__ + +#include + +#include "api/audio/audio_device.h" + +namespace webrtc { +namespace rffi { + +/** + * RingRTC-specific ADM implementation, which forwards to Rust layer. + */ +class RingRTCAudioDeviceModule: public AudioDeviceModule { + public: + RingRTCAudioDeviceModule(); + ~RingRTCAudioDeviceModule() override; + + // Creates a default ADM for usage in production code. + static rtc::scoped_refptr Create(); + + // Retrieve the currently utilized audio layer + int32_t ActiveAudioLayer(AudioLayer* audioLayer) const override; + + // Full-duplex transportation of PCM audio + int32_t RegisterAudioCallback(AudioTransport* audioCallback) override; + + // Main initialization and termination + int32_t Init() override; + int32_t Terminate() override; + bool Initialized() const override; + + // Device enumeration + int16_t PlayoutDevices() override; + int16_t RecordingDevices() override; + int32_t PlayoutDeviceName(uint16_t index, + char name[kAdmMaxDeviceNameSize], + char guid[kAdmMaxGuidSize]) override; + int32_t RecordingDeviceName(uint16_t index, + char name[kAdmMaxDeviceNameSize], + char guid[kAdmMaxGuidSize]) override; + + // Device selection + int32_t SetPlayoutDevice(uint16_t index) override; + int32_t SetPlayoutDevice(WindowsDeviceType device) override; + int32_t SetRecordingDevice(uint16_t index) override; + int32_t SetRecordingDevice(WindowsDeviceType device) override; + + // Audio transport initialization + int32_t PlayoutIsAvailable(bool* available) override; + int32_t InitPlayout() override; + bool PlayoutIsInitialized() const override; + int32_t RecordingIsAvailable(bool* available) override; + int32_t InitRecording() override; + bool RecordingIsInitialized() const override; + + // Audio transport control + int32_t StartPlayout() override; + int32_t StopPlayout() override; + bool Playing() const override; + int32_t StartRecording() override; + int32_t StopRecording() override; + bool Recording() const override; + + // Audio mixer initialization + int32_t InitSpeaker() override; + bool SpeakerIsInitialized() const override; + int32_t InitMicrophone() override; + bool MicrophoneIsInitialized() const override; + + // Speaker volume controls + int32_t SpeakerVolumeIsAvailable(bool* available) override; + int32_t SetSpeakerVolume(uint32_t volume) override; + int32_t SpeakerVolume(uint32_t* volume) const override; + int32_t MaxSpeakerVolume(uint32_t* maxVolume) const override; + int32_t MinSpeakerVolume(uint32_t* minVolume) const override; + + // Microphone volume controls + int32_t MicrophoneVolumeIsAvailable(bool* available) override; + int32_t SetMicrophoneVolume(uint32_t volume) override; + int32_t MicrophoneVolume(uint32_t* volume) const override; + int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override; + int32_t MinMicrophoneVolume(uint32_t* minVolume) const override; + + // Speaker mute control + int32_t SpeakerMuteIsAvailable(bool* available) override; + int32_t SetSpeakerMute(bool enable) override; + int32_t SpeakerMute(bool* enabled) const override; + + // Microphone mute control + int32_t MicrophoneMuteIsAvailable(bool* available) override; + int32_t SetMicrophoneMute(bool enable) override; + int32_t MicrophoneMute(bool* enabled) const override; + + // Stereo support + int32_t StereoPlayoutIsAvailable(bool* available) const override; + int32_t SetStereoPlayout(bool enable) override; + int32_t StereoPlayout(bool* enabled) const override; + int32_t StereoRecordingIsAvailable(bool* available) const override; + int32_t SetStereoRecording(bool enable) override; + int32_t StereoRecording(bool* enabled) const override; + + // Playout delay + int32_t PlayoutDelay(uint16_t* delayMS) const override; + + // Only supported on Android. + bool BuiltInAECIsAvailable() const override { return false; } + bool BuiltInAGCIsAvailable() const override { return false; } + bool BuiltInNSIsAvailable() const override { return false; } + // When using software AEC, use AECM instead of AEC3. + bool UseAecm() const override { return false; } + + // Enables the built-in audio effects. Only supported on Android. + int32_t EnableBuiltInAEC(bool enable) override { return -1; } + int32_t EnableBuiltInAGC(bool enable) override { return -1; } + int32_t EnableBuiltInNS(bool enable) override { return -1; } + + // Play underrun count. Only supported on Android. + int32_t GetPlayoutUnderrunCount() const override { return -1; } + + // Used to generate RTC stats. If not implemented, RTCAudioPlayoutStats will + // not be present in the stats. + absl::optional GetStats() const override { return absl::nullopt; } + +// Only supported on iOS. +#if defined(WEBRTC_IOS) + int GetPlayoutAudioParameters(AudioParameters* params) const override { + return -1; + } + int GetRecordAudioParameters(AudioParameters* params) const override { + return -1; + } +#endif // WEBRTC_IOS +}; + +} // namespace rffi +} // namespace webrtc + +#endif // RFFI_AUDIO_DEVICE_H__ diff --git a/ringrtc/rffi/src/peer_connection_factory.cc b/ringrtc/rffi/src/peer_connection_factory.cc index 1a8032b505..fcfc46a3b6 100644 --- a/ringrtc/rffi/src/peer_connection_factory.cc +++ b/ringrtc/rffi/src/peer_connection_factory.cc @@ -25,6 +25,7 @@ #include "rffi/api/peer_connection_factory.h" #include "rffi/api/peer_connection_observer_intf.h" #include "rffi/api/injectable_network.h" +#include "rffi/src/audio_device.h" #include "rffi/src/peer_connection_observer.h" #include "rffi/src/ptr.h" #include "rtc_base/logging.h" @@ -146,6 +147,8 @@ class PeerConnectionFactoryWithOwnedThreads #endif return AudioDeviceModule::Create( AudioDeviceModule::kPlatformDefaultAudio, dependencies.task_queue_factory.get()); + case kRffiAudioDeviceModuleRingRtc: + return RingRTCAudioDeviceModule::Create(); } });