google / oboe

Oboe is a C++ library that makes it easy to build high-performance audio apps on Android.
Apache License 2.0
3.71k stars 569 forks source link

Devices list is not updated after connecting headphones #707

Closed lunelasuis closed 4 years ago

lunelasuis commented 4 years ago

Android Version(s): 9 Android Device(s): Samsung Galaxy Note 8

I'm building audio app with Juce framework and Oboe. When app is started without headset connected it is playing thru speakers, and if I connect headset it is still playing thru speakers. If I start app with headphones already connected - it is using headphones. I placed timer tracking list of currently available devices:

When headset is not connected:

Type Android Oboe default - 1
SM-N950F built-in earphone speaker
SM-N950F built-in speaker

And when i connect headphones it remains the same Lets start app with headset already connected:

Type Android Oboe default - 2
SM-N950F built-in earphone speaker
SM-N950F built-in speaker
h2w wired headset

Moreover if app is running without headset, i can connect it and run any other app e.g Youtube and playback in my app will magically switch to headset.

philburk commented 4 years ago

@eatwaves - Have you seen this on any other devices or Android versions?

We need to determine which devices and versions are affected. We may be able to work around this using: https://developer.android.com/reference/android/content/Intent#ACTION_HEADSET_PLUG We also need a CTS Verifier test to prevent this.

lunelasuis commented 4 years ago

@philburk - Our customers are reporting issue on other devices but same Android 9. I don't have this issue on my Nexus 7 with Android 7. I will have results for Pixel2 with Android 10 soon and let you know.

lunelasuis commented 4 years ago

Hi. Ok, I'm able to catch event of headset connection with Intent.ACTION_HEADSET_PLUG. I'm reinitializing my device manager and .now i can see 3 devices after connecting headphones:

Type Android Oboe default - 2
h2w wired headset
SM-N950F built-in earphone speaker
SM-N950F built-in speaker

But the problem is that default device is still speaker. Default device is determined in Juce wrapper by simply building stream with oboe::AudioStreamBuilder and checking which device is activated by default.

Probably I can do dummy check if I have headphones or headset device type connected and force my app to use it instead of default proposed by stream builder. But it sounds not like a good solution

philburk commented 4 years ago

Thanks for trying Intent.ACTION_HEADSET_PLUG. This could be a possible workaround.

Default device is determined in Juce wrapper

When does it determine the default device?

Oboe should open the plugged in headset device if you use kUnspecified in the Builder. Is JUCE not using kUnspecified for the default device? That could be an issue in JUCE.

Also there may be a race condition when the headset is plugged in. What happens if you check the default device a second later? (I'm not saying this is good practice. It is just research.)

BTW, I am working on "Test Disconnect" guided test for OboeTester that we can turn into a CTS Verifier test.

lunelasuis commented 4 years ago

When does it determine the default device?

juce_android_Oboe.cpp line 1074 getDefaultDeviceIndex(). Function is called during init of juce::AudioDeviceManager. The check which device is default is straightforward. They have list of devices and create temp Oboe stream and then roll thru available devices to check which one is created. As device id JUCE team pass -1 to constructor and then:

 if (deviceId != -1)
      builder.setDeviceId (deviceId);.

So device id is not set for builder in this case. Is it same behavior as setting kUnspecified? Also they are passing some values for sample rate and buffer size defined here. Should I pass kUnspecified for these fields to builder instead of android.media.property.OUTPUT_SAMPLE_RATE and android.media.property.OUTPUT_FRAMES_PER_BUFFER?

Also there may be a race condition when the headset is plugged in. What happens if you check the default device a second later?

Well, i'm getting Intent. ACTION_HEADSET_PLUG callback sometimes few seconds after connecting headset. But i will check

Thanks for your help

robclouth commented 4 years ago

@eatwaves hey! did you manage to figure this out?

philburk commented 4 years ago

I created a bug to track the changes needed in JUCE.

https://github.com/google/oboe/issues/747

I also added a tech notes on the ACTION_HEADSET_PLUG workaround:

https://github.com/google/oboe/blob/master/docs/notes/disconnect.md

And OboeTester has a new "TEST DISCONNECT" section.