ADM and audio device selection

1,760 views
Skip to first unread message

Alexandre GOUAILLARD

unread,
Oct 24, 2017, 11:49:48 PM10/24/17
to discuss...@googlegroups.com
dear all,

we're trying to implement audio device selection in C++ code.
While implementing video capture device / app / window / desktop is relatively easy, we are struggling with audio and the intricacies of the audio device module, Voice Engine, etc.

We've tried to create an ADM outside of the peerconnection factory and pass it in, which allows us to list the input and output devices, but it looks like we would have to fix the input device once and for all for the Perrconnectionfactory, and hence all the peer connections created thereafter. 
ADM => PCF => PC => CreateAudioSource => MSTrack => AddTrack()

We were expecting to be able to actually create an ADM, and an audio source / track separately from the peerconnection object, and only involve the peerconnection when calling addTrack().
capturer => Source => Track => PC->AddTrack( Track )

We have looked into the chrome side of things and got even more confused, even though the agc_audio_stream seems to be the right capturer class. How it ends up in a peerconnection and how to use it is not clear to us.

Has anybody done something like that, or could any googler give us hint(s) about the expected flow?

Regards,

Dr. Alex.

--
Alex. Gouaillard, PhD, PhD, MBA
------------------------------------------------------------------------------------
President - CoSMo Software Consulting, Singapore
------------------------------------------------------------------------------------

Henrik Andreasson

unread,
Oct 25, 2017, 4:37:55 AM10/25/17
to discuss-webrtc
We've tried to create an ADM outside of the peerconnection factory and pass it in, which allows us to list the input and output devices, but it looks like we would have to fix the input device once and for all for the Perrconnectionfactory, and hence all the peer connections created thereafter. 
ADM => PCF => PC => CreateAudioSource => MSTrack => AddTrack()

It is not clear to me what the actual problem is with this approach. Does it work but you would prefer an alternative (more clean or more inline with Chrome) solution or are there still
issues that you can't resolve? 

Sergio Garcia Murillo

unread,
Oct 25, 2017, 5:05:39 AM10/25/17
to discuss...@googlegroups.com
Hi Henrik,

IMHO using an external ADM allows little flexibility, from my investigation (please, correct me if I am wrong) if you want to implement a track/device based audio processing you need to provide a dummy external ADM and override the AudioSourceInterface and track sinks to be able to get/fetch the audio data anyway.

Also, (again please correct if I am wrong) it seems there are two different ways of delivering data to the voe channel that work simultaneously, one via the adm RegisterAudioCallback(webrtc::AudioTransport*) and the other via AudioSourceInterfae::AddSink(webrtc::AudioTrackSinkInterface * sink).

Overall it is quite difficult (at least it has been for me) to understand the whole audio processing and IMHO it should be more similar to what chrome currently implements (which would allow device selection by default on the AudioSource), allowing to plug new input/output devices without needing to overwrite quite a lot of code. I also acknowledge that this change would require quite a huge refactor and is far from trivial, so just my 2 cents ;)

Best regards
Sergio

Henrik Andreasson

unread,
Oct 25, 2017, 7:01:56 AM10/25/17
to discuss-webrtc
I understand your viewpoint Sergio, but given title of this thread "ADM and device selection"; are there any real issues with the
"external ADM" approach there? The transport mechanism/API is imho another (broader and more difficult) topic.
Also, please note that on most mobile platforms, device handling can be done completely outside the native WebRTC stack.

--

---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrtc+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/1c366089-126f-2d41-e4a8-0497958f2440%40gmail.com.

For more options, visit https://groups.google.com/d/optout.

Alexandre GOUAILLARD

unread,
Oct 25, 2017, 7:35:00 AM10/25/17
to discuss...@googlegroups.com
hi henrik,

Thanks for answering.

sergio and I are working together on this issue, so our comments are not independent.

As noted in the first e-mail our goal is to "implement audio device selection in C++ code".

We originally thought ADM was the way to go, but we have come to realise that different webrtc consumer would implement different APIs in different design pattern to achieve it. To answer specifically your question, in the ADM => PCF => PC => CreateAudioSource => MSTrack => AddTrack() case, I dislike the fact that I have to decide what device to use once and for all at peerconnection factory time, and won't be able to change it from one peerconnection to the other (without creating a new adm and a new peerconnection). What I dislike about the chrome approach are the dependencies to other chrome internal packages, and the fact that I would have to reimplement OS dependent classes that, I believe, ADM is dealing with already,

Here is the user story version: as a C++ developper I would like to be able to capture/record the audio frames  from my webcam, my system audio (on windows), and one acquisition device and add them three as different audio tracks to a peerconnection, like i can do in a web application. 

Given the multiple ways to do it out there, Our question is what is the *recommended way* to do it. Of course the recommended way could be different depending on the scope: from libwebrtc stand alone vs chrome, or depending on the OS/platform: on desktop OSes vs mobile OSes. So let's say I'm interested in windows only as describe in the above user story, and that I would like to stay as close to standalone webrtc as possible.

I hope this clarifies.

thanks again.

Dr. Alex.




On Wed, Oct 25, 2017 at 7:01 PM, Henrik Andreasson <hen...@webrtc.org> wrote:
I understand your viewpoint Sergio, but given title of this thread "ADM and device selection"; are there any real issues with the
"external ADM" approach there? The transport mechanism/API is imho another (broader and more difficult) topic.
Also, please note that on most mobile platforms, device handling can be done completely outside the native WebRTC stack.

On Wed, Oct 25, 2017 at 11:05 AM, Sergio Garcia Murillo <sergio.garcia.murillo@gmail.com> wrote:
On 25/10/2017 10:33, Henrik Andreasson wrote:
We've tried to create an ADM outside of the peerconnection factory and pass it in, which allows us to list the input and output devices, but it looks like we would have to fix the input device once and for all for the Perrconnectionfactory, and hence all the peer connections created thereafter. 
ADM => PCF => PC => CreateAudioSource => MSTrack => AddTrack()

It is not clear to me what the actual problem is with this approach. Does it work but you would prefer an alternative (more clean or more inline with Chrome) solution or are there still
issues that you can't resolve? 

Hi Henrik,

IMHO using an external ADM allows little flexibility, from my investigation (please, correct me if I am wrong) if you want to implement a track/device based audio processing you need to provide a dummy external ADM and override the AudioSourceInterface and track sinks to be able to get/fetch the audio data anyway.

Also, (again please correct if I am wrong) it seems there are two different ways of delivering data to the voe channel that work simultaneously, one via the adm RegisterAudioCallback(webrtc::AudioTransport*) and the other via AudioSourceInterfae::AddSink(webrtc::AudioTrackSinkInterface * sink).

Overall it is quite difficult (at least it has been for me) to understand the whole audio processing and IMHO it should be more similar to what chrome currently implements (which would allow device selection by default on the AudioSource), allowing to plug new input/output devices without needing to overwrite quite a lot of code. I also acknowledge that this change would require quite a huge refactor and is far from trivial, so just my 2 cents ;)

Best regards
Sergio

--

---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrtc+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/1c366089-126f-2d41-e4a8-0497958f2440%40gmail.com.

For more options, visit https://groups.google.com/d/optout.

--

---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrtc+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Henrik Andreasson

unread,
Oct 25, 2017, 8:00:03 AM10/25/17
to discuss-webrtc
My own personal reply is Chrome has been the main driver for implementing the standard adding the support that you need.
Hence, a more natural and flexible implementation can be found in using the web based APIs focusing on desktop platforms.
For native WebRTC, these parts are not on pair with the web standard, and other means are needed instead. Also, the native
stack is more used on mobile platforms where device handling can be done independently and where a user normally has less
devices to choose from.

Hence, my current recommendation for native WebRTC is to use the external ADM path and accept that device handling will be less
flexible that way. Or alternatively, focus on web based APIs instead.

PS it is not clear to me what type of use case requires support for more than one active recording device.

Alexandre GOUAILLARD

unread,
Oct 25, 2017, 11:04:24 AM10/25/17
to discuss...@googlegroups.com
hi henrik,

Thank you again for your answer.

Here is the use case as presented before: "as a C++ developper I would like to be able to capture/record the audio frames  from my webcam/mike, my system audio (on windows), and one acquisition device (e.g. a digital input card from audio equipment) and add them three as different audio tracks to a peerConnection, like I can do in a web application".

[henrik] My own personal reply is Chrome has been the main driver for implementing the standard adding the support that you need. Hence, a more natural and flexible implementation can be found in using the web based APIs focusing on desktop platforms.

[alex] Fair enough. Can you just point us to the part that connects the audio_source in chrome to the VoE in webrtc? Now that the two webrtc trees (chrome and standalone) are in sync, life is good. We could not figure out how the actual audio frames were being pushed through.

[henrik] For native WebRTC, these parts are not on pair with the web standard, and other means are needed instead. Also, the native stack is more used on mobile platforms where device handling can be done independently and where a user normally has less devices to choose from. Hence, my current recommendation for native WebRTC is to use the external ADM path and accept that device handling will be less flexible that way.

[alex] Thank you for confirming that going through the adm is the preferred way for libwebrtc stand alone. Now, is there a way (we would have missed) to change the deviceId after the creation of an ADM (1), respectively a peerconnectifonfactory (2), respectively a peerconnection (3) instance.

thanks again.

best regards,

Dr. Alex.




For more options, visit https://groups.google.com/d/optout.

Kaiduan Xie

unread,
Oct 25, 2017, 3:25:39 PM10/25/17
to discuss...@googlegroups.com

Sergio Garcia Murillo

unread,
Oct 25, 2017, 4:08:28 PM10/25/17
to discuss...@googlegroups.com
Yes, basically Chrome passes an empty/dummy audio device module to the peerconnection, and then override the LocalAudioSource to push data to the audio source sink set by the audio track.

BR
Sergio
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/CACKRbQdpxGeq3RArSGPK%2BLoN5TUA2oDcPuyTj9vO7nnnFh0AhA%40mail.gmail.com.

Kaiduan Xie

unread,
Oct 25, 2017, 4:44:25 PM10/25/17
to discuss...@googlegroups.com

--

---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrtc+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Henrik Andreasson

unread,
Oct 26, 2017, 4:53:49 AM10/26/17
to discuss-webrtc
I don't have all the answers and the topic is complex. Using an external ADM in native WebRTC for desktop is not a complete replacement for the existing web-based implementation
parts. Instead, it makes it possible to get more control of the audio streams but in a non standardized way.

An injected ADM is connected and used by VoE here. Today, only default devices are utilized but it should be possible to switch device if the external ADM supports dynamic device switching.
The existing ADM implementation in native WebRTC for desktop serves mainly as an example. The audio parts in Chrome are better maintained and tested.

On Wed, Oct 25, 2017 at 10:44 PM, Kaiduan Xie <kaid...@gmail.com> wrote:
Reply all
Reply to author
Forward
0 new messages