tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio_device_module.md (12638B)


<!-- go/cmark --> <!--* freshness: {owner: 'henrika' reviewed: '2024-09-02'} *-->

Audio Device Module (ADM)

Overview

The ADM(AudioDeviceModule) is responsible for driving input (microphone) and output (speaker) audio in WebRTC and the API is defined in [audio_device.h][19].

Main functions of the ADM are:

for audio in both directions.

* Recording audio from the selected microphone, and * playing out audio on the selected speaker.

Control (AGC) and Noise Suppression (NS)) for Android and iOS.

ADM implementations reside at two different locations in the WebRTC repository: /modules/audio_device/ and /sdk/. The latest implementations for [iOS][20] and [Android][21] can be found under /sdk/. /modules/audio_device/ contains older versions for mobile platforms and also implementations for desktop platforms such as [Linux][22], [Windows][23] and [Mac OSX][24]. This document is focusing on the parts in /modules/audio_device/ but implementation specific details such as threading models are omitted to keep the descriptions as simple as possible.

By default, the ADM in WebRTC is created in [WebRtcVoiceEngine::Init][1] but an external implementation can also be injected using [webrtc::CreatePeerConnectionFactory][25]. An example of where an external ADM is injected can be found in [PeerConnectionInterfaceTest][26] where a so-called [fake ADM][29] is utilized to avoid hardware dependency in a gtest. Clients can also inject their own ADMs in situations where functionality is needed that is not provided by the default implementations.

Background

This section contains a historical background of the ADM API.

The ADM interface is old and has undergone many changes over the years. It used to be much more granular but it still contains more than 50 methods and is implemented on several different hardware platforms.

Some APIs are not implemented on all platforms, and functionality can be spread out differently between the methods.

The most up-to-date implementations of the ADM interface are for [iOS][27] and for [Android][28].

Desktop version are not updated to comply with the latest C++ style guide and more work is also needed to improve the performance and stability of these versions.

WebRtcVoiceEngine

[WebRtcVoiceEngine][2] does not utilize all methods of the ADM but it still serves as the best example of its architecture and how to use it. For a more detailed view of all methods in the ADM interface, see [ADM unit tests][3].

Assuming that an external ADM implementation is not injected, a default - or internal - ADM is created in [WebRtcVoiceEngine::Init][1] using [AudioDeviceModule::Create][4].

Basic initialization is done using a utility method called [adm_helpers::Init][5] which calls fundamental ADM APIs like:

for each platform.

for playing out audio using an index retrieved by the corresponding enumeration method [AudiDeviceModule::PlayoutDeviceName][8].

use for recording audio using an index retrieved by the corresponding enumeration method which is [AudiDeviceModule::RecordingDeviceName][10].

to use the selected output device.

needed to use the selected input device.

the selected audio device supports it.

if the selected audio device supports it.

[WebRtcVoiceEngine::Init][1] also calls [AudiDeviceModule::RegisterAudioTransport][15] to register an existing [AudioTransport][16] implementation which handles audio callbacks in both directions and therefore serves as the bridge between the native ADM and the upper WebRTC layers.

Recorded audio samples are delivered from the ADM to the WebRtcVoiceEngine (who owns the AudioTransport object) via [AudioTransport::RecordedDataIsAvailable][17]:

int32_t RecordedDataIsAvailable(const void* audioSamples, size_t nSamples, size_t nBytesPerSample,
                                size_t nChannels, uint32_t samplesPerSec, uint32_t totalDelayMS,
                                int32_t clockDrift, uint32_t currentMicLevel, bool keyPressed,
                                uint32_t& newMicLevel)

Decoded audio samples ready to be played out are are delivered by the WebRtcVoiceEngine to the ADM, via [AudioTransport::NeedMorePlayoutData][18]:

int32_t NeedMorePlayData(size_t nSamples, size_t nBytesPerSample, size_t nChannels, int32_t samplesPerSec,
                         void* audioSamples, size_t& nSamplesOut,
                         int64_t* elapsed_time_ms, int64_t* ntp_time_ms)

Audio samples are 16-bit linear PCM using regular interleaving of channels within each sample.

WebRtcVoiceEngine also owns an [AudioState][30] member and this class is used has helper to start and stop audio to and from the ADM. To initialize and start recording, it calls:

and to initialize and start playout:

Finally, the corresponding stop methods [AudiDeviceModule::StopRecording][35] and [AudiDeviceModule::StopPlayout][36] are called followed by [AudiDeviceModule::Terminate][37].

[1]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/media/engine/webrtcvoice_engine.cc;l=314;drc=f7b1b95f11c74cb5369fdd528b73c70a50f2e206 [2]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/media/engine/webrtcvoice_engine.h;l=48;drc=d15a575ec3528c252419149d35977e55269d8a41 [3]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/audiodeviceunittest.cc;l=1;drc=d15a575ec3528c252419149d35977e55269d8a41 [4]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=46;drc=eb8c4ca608486add9800f6bfb7a8ba3cf23e738e [5]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/media/engine/admhelpers.h;drc=2222a80e79ae1ef5cb9510ec51d3868be75f47a2 [6]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=62;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [7]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=77;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [8]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=69;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [9]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=79;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [10]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=72;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [11]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=99;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [12]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=101;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [13]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=130;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [14]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=133;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [15]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=59;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [16]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audiodevicedefines.h;l=34;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [17]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audiodevicedefines.h;l=36;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [18]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audiodevicedefines.h;l=48;drc=9438fb3fff97c803d1ead34c0e4f223db168526f [19]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;drc=eb8c4ca608486add9800f6bfb7a8ba3cf23e738es [20]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/sdk/objc/native/api/audiodevice_module.h;drc=76443eafa9375374d9f1d23da2b913f2acac6ac2 [21]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/sdk/android/src/jni/audiodevice/audiodevicemodule.h;drc=bbeb10925eb106eeed6143ccf571bc438ec22ce1 [22]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/linux/;drc=d15a575ec3528c252419149d35977e55269d8a41 [23]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/win/;drc=d15a575ec3528c252419149d35977e55269d8a41 [24]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/mac/;drc=3b68aa346a5d3483c3448852d19d91723846825c [25]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/api/createpeerconnection_factory.h;l=45;drc=09ceed2165137c4bea4e02e8d3db31970d0bf273 [26]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/pc/peerconnectioninterfaceunittest.cc;l=692;drc=2efb8a5ec61b1b87475d046c03d20244f53b14b6 [27]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/sdk/objc/native/api/audiodevice_module.h;drc=76443eafa9375374d9f1d23da2b913f2acac6ac2 [28]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/sdk/android/src/jni/audiodevice/audiodevicemodule.h;drc=bbeb10925eb106eeed6143ccf571bc438ec22ce1 [29]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/pc/test/fakeaudiocapturemodule.h;l=42;drc=d15a575ec3528c252419149d35977e55269d8a41 [30]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/audio/audiostate.h;drc=d15a575ec3528c252419149d35977e55269d8a41 [31]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=87;drc=eb8c4ca608486add9800f6bfb7a8ba3cf23e738e [32]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=94;drc=eb8c4ca608486add9800f6bfb7a8ba3cf23e738e [33]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=84;drc=eb8c4ca608486add9800f6bfb7a8ba3cf23e738e [34]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=91;drc=eb8c4ca608486add9800f6bfb7a8ba3cf23e738e [35]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=95;drc=eb8c4ca608486add9800f6bfb7a8ba3cf23e738e [36]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=92;drc=eb8c4ca608486add9800f6bfb7a8ba3cf23e738e [37]: https://source.chromium.org/chromium/chromium/src/+/main:thirdparty/webrtc/modules/audiodevice/include/audio_device.h;l=63;drc=eb8c4ca608486add9800f6bfb7a8ba3cf23e738e