# Support USB Audio devices on Android

**URL:** <https://forum.juce.com/t/support-usb-audio-devices-on-android/19616>\
**Category:** Android\
**Created:** [October 25, 2016, 8:02am UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616 "2016-10-25T08:02:35Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![asavio](https://avatars.discourse-cdn.com/v4/letter/a/7c8e57/32.png) [@asavio](https://forum.juce.com/u/asavio)\
**Post date:** [October 25, 2016, 8:02am UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/1 "2016-10-25T08:02:36Z")

</div>

Hi,

I am part of a team developing a music app that uses JUCE for the audio engine.

We would like to add support for USB audio recording and playback on Android for USB OTG-capable devices. Target audio interfaces would be e.g. the iRig UA, Scarlett Focusrite, Steinberg etc. At the moment, it looks like JUCE supports USB audio on Android only halfway: it does route the output to the USB device but ignores the input and keeps using the internal microphone. I have tested this using the “Recording” and “Synthesisers” demos with JUCE 4.2.4 on an iRig UA and Scarlett 2i2.

It would be neat if JUCE could add support for USB audio on Android. Ideally, there would be a callback informing the client when an USB audio-capable device is plugged in, and the client would have the ability to either route the input/output to it, or keep using the internal microphone/speakers.

Do you have any plans to add USB audio support to JUCE on Android in the near future?

Thanks for your reply.

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [October 31, 2016, 10:41am UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/2 "2016-10-31T10:41:02Z")

</div>

OK I’ve added this to our back log along with some other android audio fixes which we have been working on.

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [February 7, 2017, 12:28pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/3 "2017-02-07T12:28:53Z")

</div>

Just an update on this: OpenSL completely abstracts away the different audio devices and routing. Any Android app using OpenSL (including JUCE) will only ever see a single audio output device called the “Default Android Output”.

The only way to control audio routing is by specifying an intent for your audio output. JUCE will always specify the “Media” intent (the default). With this intent, Android will automatically re-route the audio to an external USB audio device when it is plugged in. JUCE won’t even get a callback when this happens. There is also the “Telephony” intent which will always keep the audio on the ear-piece etc.

---

<div class="post-metadata">

**Author:** ![adamwilson](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/adamwilson/32/1387_2.png) [@adamwilson](https://forum.juce.com/u/adamwilson)\
**Post date:** [February 7, 2017, 12:41pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/4 "2017-02-07T12:41:16Z")

</div>

It would be great if Android started properly supporting multichannel audio devices. I’m sure it must be something they’re working on…

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [February 7, 2017, 12:50pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/5 "2017-02-07T12:50:55Z")

</div>

They already support it with HDMI. The problem is that I’m struggling to figure out the number of channels of the current audio routing with OpenSL. Maybe you can help @adamski?

Even in Java (without OpenSL) it’s hard to get the number of output channels of the currently selected output device.

You can get a list of audio device infos with the [`getDevices`](https://developer.android.com/reference/android/media/AudioManager.html#getDevices(int)) method and each info includes detailed information about the audio channels. But I’m failing to find out which device is currently active with the currently routed output.

It seems that in Java, you can only query the currently routed output when the audio output is actually playing audio (see the [`getRoutedDevice`](https://developer.android.com/reference/android/media/AudioTrack.html#getRoutedDevice()) method and the description saying it’s only valid when the AudioTrack is actually playing).

That would be OK for JUCE but JUCE uses OpenSL. And I can’t find a way to somehow determine the routed device in OpenSL. In fact, OpenSL always just says that the “Default Android Output” is selected even after plugging in a USB or HDMI device.

So ultimately my question is: how can I find the [`AudioDeviceInfo`](https://developer.android.com/reference/android/media/AudioDeviceInfo.html) of the audio output device that OpenSL is currently using?

---

<div class="post-metadata">

**Author:** ![donturner1](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/donturner1/32/4411_2.png) [@donturner1](https://forum.juce.com/u/donturner1)\
**Post date:** [February 20, 2017, 4:43pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/6 "2017-02-20T16:43:19Z")

</div>

I’m investigating this but I’m not clear on what the problem is, first it was about audio _input_, then it changes to _output_…

asavio originally stated: “JUCE supports USB audio on Android only halfway: it does route the output to the USB device but ignores the input and keeps using the internal microphone.”

Fabian you then say “how can I find the AudioDeviceInfo of the audio output device that OpenSL is currently using?”

Please could you clarify the problem so I can take a look? 🙂

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [February 20, 2017, 5:50pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/7 "2017-02-20T17:50:05Z")

</div>

Hi @Don_Turner,  
thank you for looking into this. The post is a bit confusing as we have fixed a few bugs in the meantime.

Basically, @asavio’ s first part of his problem should be fixed: we’ve changed the audio intent to `media` and therefore Android should automatically re-route JUCE’s incoming/outgoing audio from/to usb audio devices.

@asavio second request is to have a callback to inform the client when USB audio-capale devices are plugged in. And fixing this problem is similar to @adamski’s problem: how do I query the number of channels of an audio device (for example HDMI may have 7.1).

It’s easy to do both from Java: in Java I can query all the attached audio devices and query their properties (such as number of channels etc.) and register callbacks when devices come and go. But in OpenSL (C++) there is no way to figure out the native number of channels of a device or to register callbacks.

If there would be some way to know which OpenSL device corresponds to which Java audio device then I could work out the number of channels but it seems that OpenSL only ever reports a single device (the “Android OpenSL Default Device” - this is also confirmed by looking at the source code of AOSP’s libwilhelm).

I understand that audio routing is done by the system - so Java gives you a method to find out the currently routed audio device. This, however, will only work if you are playing back audio via an AudioTrack. I’m looking for something similar in OpenSL.

Fabian

---

<div class="post-metadata">

**Author:** ![donturner1](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/donturner1/32/4411_2.png) [@donturner1](https://forum.juce.com/u/donturner1)\
**Post date:** [February 21, 2017, 4:23pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/8 "2017-02-21T16:23:27Z")

</div>

Android 7.0 (Nougat, API 24) introduced [some extra methods](https://source.android.com/devices/audio/implement-policy.html#policy_routing_apis) to allow you to obtain an [`AudioRouting`](https://developer.android.com/reference/android/media/AudioRouting.html) object (which will allow you to get the audio device which is currently in use) from OpenSL by using the [`AcquireJavaProxy`](https://android.googlesource.com/platform/frameworks/wilhelm/+/master/include/SLES/OpenSLES_Android.h#215) method.

Here’s how:

1. When creating your OpenSL player include the `SL_IID_ANDROIDCONFIGURATION` interface

2. Once the player is realized obtain the configuration interface:

3. Use the configuration interface to obtain the AudioRouting handle

4. Pass this back to Java (or do some JNI hackery) to obtain an `AudioRouting` object

5. Call `AudioRouting.getRoutedDevice()` to obtain an `AudioDeviceInfo` object

Example app here: [https://android.googlesource.com/platform/cts/+/master/tests/tests/media/libndkaudio](https://android.googlesource.com/platform/cts/+/master/tests/tests/media/libndkaudio)

---

<div class="post-metadata">

**Author:** ![donturner1](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/donturner1/32/4411_2.png) [@donturner1](https://forum.juce.com/u/donturner1)\
**Post date:** [February 21, 2017, 4:34pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/9 "2017-02-21T16:34:37Z")

</div>

BTW, I’m aware this is cumbersome because of the need to go through Java. Have filed internal feature request (id: 35620262) to address this.

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [February 21, 2017, 5:42pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/10 "2017-02-21T17:42:53Z")

</div>

Thanks! This is exactly what I was looking for!

---

<div class="post-metadata">

**Author:** ![akhil](https://avatars.discourse-cdn.com/v4/letter/a/7ab992/32.png) [@akhil](https://forum.juce.com/u/akhil)\
**Post date:** [August 3, 2017, 12:09am UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/11 "2017-08-03T00:09:55Z")

</div>

Hi fabian,  
Just checking to see if you have any updates on this?

---

<div class="post-metadata">

**Author:** ![fr810](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/fr810/32/841_2.png) [@fr810](https://forum.juce.com/u/fr810)\
**Post date:** [August 4, 2017, 8:14am UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/12 "2017-08-04T08:14:35Z")

</div>

Sorry no updates on this yet. But it’s not forgotten.

---

<div class="post-metadata">

**Author:** ![jemur](https://avatars.discourse-cdn.com/v4/letter/j/da6949/32.png) [@jemur](https://forum.juce.com/u/jemur)\
**Post date:** [August 7, 2018, 5:35pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/13 "2018-08-07T17:35:11Z")

</div>

Very useful post. I have been able to use the available java proxy object to access the device type and input channel counts via the AudioRouting object’s ‘getRoutedDevice()’ AudioDeviceInfo using JNI.

What I’m hoping to do is add an AudioRouting.OnRoutingChangedListener to the AudioRouting so I am aware when the input device changes, and propagate any change message back to my c++ so I can ultimately adjust the number of input channels I use in my app. Admittedly, I’m not a JNI expert. Is this even possible with JNI?

---

<div class="post-metadata">

**Author:** ![adamwilson](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/adamwilson/32/1387_2.png) [@adamwilson](https://forum.juce.com/u/adamwilson)\
**Post date:** [August 7, 2018, 6:55pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/14 "2018-08-07T18:55:30Z")

</div>

Anything is possible with JNI… its just a pain to work with!

---

<div class="post-metadata">

**Author:** ![jemur](https://avatars.discourse-cdn.com/v4/letter/j/da6949/32.png) [@jemur](https://forum.juce.com/u/jemur)\
**Post date:** [August 9, 2018, 6:59pm UTC](https://forum.juce.com/t/support-usb-audio-devices-on-android/19616/15 "2018-08-09T18:59:03Z")

</div>

It was indeed a bit of a pain, but I did get it to work swimmingly!
