I want the sound to go *here* – Audio routing in Windows Phone 8.1

Windows Phone 8.1 devices have a number of different audio output options. Most of the time the audio is routed to the default or “active” endpoint. The default endpoint is determined by a number of factors. If your phone is connected to a Bluetooth device that supports audio then it will be routed there by default. A common example is the Bluetooth enabled car. When you start your car it talks with your phone and automatically routes the audio to the vehicle speakers.

Sometimes though, you want your app to be able to control where the audio is getting routed. That is where the AudioRoutingManager comes in handy. The AudioRoutingManager allows you to specify one of the supported audio endpoints. There are usually four possible endpoints but not all of them may be available. They are: None, earpiece,  speakerphone and Bluetooth. For more detail on how these are related check out Matthew van Eerde’s blog on the subject.

There are two keys to successfully using the AudioRoutingManger.

Key #1) You need to add the ID_CAP_VOIP capability to your app.

You can do this using the manifest editor for Windows Phone Silverlight apps but it’s not quite as easy to do this for Windows Phone 8.1 Runtime apps.

Here’s what you need to do for your Windows Phone 8.1 Runtime app:

    1. Create a new XML file and name it WindowsPhoneReservedAppInfo.xml

    2. Add the new file to the root of your Windows Phone 8.1 Runtime project in Visual Studio

      Capture

    3. Add the following XML to the file:

  1: <?xml version="1.0" encoding="utf-8"?>
  2: <WindowsPhoneReservedAppInfo xmlns="https://schemas.microsoft.com/phone/2013/windowsphonereservedappinfo">
  3:   <SoftwareCapabilities>
  4:     <SoftwareCapability Id="ID_CAP_VOIP" />
  5:   </SoftwareCapabilities>
  6: </WindowsPhoneReservedAppInfo>

Key #2) You need to make sure the audio is streaming before you change the endpoint.

This means that if you re using an audio technology like WASAPI you need to call:

IAudioClient::Start

Before you call:

AudioRoutingManager.SetAudioEndpoint

If the stream is not started and you call SetAudioEndpoint you will get an error and the endpoint won’t change. Of course this does have the potential for the audio to come out of the wrong endpoint a few milliseconds before the endpoint gets switched. Unfortunately there is no way around this other than to roll silence before switching the endpoint.

Other things to consider:

  • When you specify the ID_CAP_VOIP in your app the default endpoint may change. For most audio apps the external speaker will be the default unless Bluetooth is available. When you have ID_CAP_VOIP set then the earphone becomes the default endpoint unless bluethooth is available.

  • The AudioRoutingManager.SetAudioEndpoint API doesn’t work in the emulator. Basically it is a “no-op” but luckily it doesn’t appear to cause an error.

  • If you are getting the following exception: HRESULT: 0x80070005 (E_ACCESSDENIED) when calling SetAudioEndpoint  you don’t have your WindowsPhoneReservedAppInfo.xml file setup correctly or the file is not getting parsed properly at runtime. Make sure the file is flagged as “Content” with an item type of XML.

    Capture2

I hope this helps,

James

 

Follow the Windows Store Developer Solutions team on Twitter @wsdevsol. Comments are welcome, both below and on twitter.