How do manual audio routes work?

It's been a while since I last wrote about manual audio routes, and I thought it might be helpful to describe how they work from a SIP signaling perspective. There are essentially two media handling modes that participants in an audio conference can be in. The first is the default, where audio from each participant is sent to every other participant. The second is a sort of "create your own audio routing" mode. When you switch a participant into this mode, using the BeginRemoveFromDefaultRouting method on AudioVideoMcuSession, two things happen:

  1. Audio from the affected participant is no longer sent to other participants, and
  2. Audio from other participants is no longer sent to the affected participant.

At this point, you can wire up your own custom audio routes to and from the participant, using the methods on the AudioVideoMcuRouting class.

Even though you are calling methods on the Conversation and Call classes, the work in both cases is being done by the A/V MCU. (If you're not familiar with this term, the MCU is the Lync component that mixes the media from all the conference participants.) When you call BeginRemoveFromDefaultRouting, your application sends a SIP INFO message to the conference focus. This INFO message contains a C3P request (a command for the conference formatted as an XML document) with a modifyEndpointMedia element. If you look inside this C3P request, you''ll see that it identifies the user who is being removed from default routing, along with the following:

[xml] <msci:conf-media-filter filter="block" duration="60000" /> [/xml]

This <msci:conf-media-filter> element indicates that the specified user is being removed from the default audio mix, in this case for 60 seconds. On receiving this message, the conference focus will tell the MCU to exclude this user from the audio mix.

Now you can set up manual audio routes using the OutgoingAudioRoute and IncomingAudioRoute classes along with the AudioVideoMcuRouting.BeginUpdateAudioRoutes method. When you call BeginUpdateAudioRoutes, your application sends another INFO message to the focus, with another modifyEndpointMedia command. This one contains something like the following:

[xml] <msci:to-mixer> <controls xmlns=""> <route> <wire userEntity="sip:adamb@domain.local" endpointEntity="{6B42CF22-83E6-4C70-930D-569976DE901F}" mediaId="1" /> </route> </controls> </msci:to-mixer> <msci:from-mixer> <controls xmlns=""> <route> <wire userEntity="sip:adamb@domain.local" endpointEntity="{6B42CF22-83E6-4C70-930D-569976DE901F}" mediaId="1" /> /route> </controls> </msci:from-mixer> [/xml]

The userEntity in each of these is another conference participant whom we want to send to or receive from. In this specific example, the application will start sending media to Adam B. and receiving media from Adam B. as well. Any other participants in the conference won''t be affected.

Removing custom audio routes looks similar:

[xml] <msci:to-mixer> <controls xmlns=""> <route> <unwire userEntity="" endpointEntity="{6B42CF22-83E6-4C70-930D-569976DE901F}" mediaId="1" /> </route> </controls> </msci:to-mixer> <msci:from-mixer> <controls xmlns=""> <route> <unwire userEntity="" endpointEntity="{6B42CF22-83E6-4C70-930D-569976DE901F}" mediaId="1" /> </route> </controls> </msci:from-mixer> [/xml]

In UCMA, you can only create custom audio routes for a local participant: i.e., an endpoint that is managed by the application. Interestingly, there seems to be nothing in the actual SIP INFO messages that are sent to the conference focus that makes this limitation necessary. My next experiment is going to be figuring out whether it's possible to get around this limitation in UCMA by building modified INFO messages in the application and sending them directly.