speech recognition through bluetooth headset in android while playing music - android

I am currently recognizing Hot word(like "ok google") using pocketsphinx library.
The app works fine except that it always uses only the phone's mic to recognize the speech.
My use case is something like this:
I listen for a hot word and use the MediaPlayer to play some music.
Keep listening for next commands while keeping the music being played and react accordingly.
The app works fine and the music is played via the bluetooth headset and the voice is also simultaneously recognized, but it always uses the phone's mic. Even though the bluetooth headset is connected or not connected, it still uses the phone's mic.
I tried using:
AudioManager mAudioManager =
(AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setMode(AudioManager.MODE_IN_CALL);
mAudioManager.startBluetoothSco();
I tried using:
AudioManager mAudioManager =
(AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.startBluetoothSco();
In both the approaches, it cuts off the music and listens in bluetooth mic.
I need an approach where the Music player is not cut from bluetooth headset but still I am able to speech recognize from bluetooth headset.
For example:
I was listening to music via bluetooth headset.
I opened voice recording app(https://play.google.com/store/apps/details?id=com.andrwq.recorder)
I am able to record the audio through bluetooth headset even while listening to music.
This makes me feel that it is possible but I don't know how.
Please help me out. Thanks in advance.

It is correct to start SCO mode, after that pocketsphinx will listen for bluetooth headset.
To disable phone microphone while in sco mode use am.setMicrophoneMute(true);
To play audio through SCO you need the player to play through STREAM_VOICE_CALL. Maybe player must be restarted after SCO switch.

Related

Android Bluetooth App audioManager issues

I am developing an app to control a speaker. I want the app to be able to playback music, do karaoke (play music and mic at same time), and provide a basic EQ to the user. My problem so far has been playing music through Bluetooth at all. My app: -discovers all Bluetooth speakers nearby -puts them in a list -pairs with clicked device and sends user to Bluetooth settings to connect to it
Now my problem is successfully playing music over the bluetooth speakers. I use a AudioManager and set it to play over SCO:
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
And then try to play a music file, but this only plays over the devices speakers and not the connected Bluetooth speakers.
So my question is what am i missing? I read a bit about a A2DP sink but it seems to not be available in recent versions. Any suggestions? Thanks in advance.
TDLR: How do I playback music to paired Bluetooth speakers?
The startBluetoothSco() method returns before SCO is setup. You need to register a BroadcastReceiver for ACTION_SCO_AUDIO_STATE_UPDATED before calling the above method.
http://developer.android.com/reference/android/media/AudioManager.html#startBluetoothSco%28%29
it's a sticky intent to so you can always check the status before calling the setBluetoothScoOn(true).

Voice recognition with bluetooth headset

I have an app which uses voice recognition and tts. I want to use this app through bluetooth headset. I used code from this question: Using the Android RecognizerIntent with a bluetooth headset
Unfotunately, it did not work for me neither recording nor playing. I added in startBluetooth11 method:
mAudioManager.setMode(AudioManager.MODE_IN_CALL);
This make recording working. But still can't get microphone to work.

In Android, is there any way to route the audio to A2DP using "MODE_IN_COMMUNICATION"?

If I set AudioManager mode to MODE_IN_COMMUNICATION, and set the Media Player stream to STREAM_VOICE_CALL, I can route the audio to the speakerphone or the internal handset speaker just fine. And if it's routed to the internal speaker, and a wired headset is plugged int, it automatically routes to it. However, I can't figure out a way to route the audio to an A2DP headset (without changing the audio mode to MODE_NORMAL, or the stream to STREAM_MUSIC). My problem is that using MODE_NORMAL and STREAM_VOICE_CALL causes problems on some devices, and using STREAM_MUSIC is a problem if there is already music playing in the background, then my app "mixes" with that background music.
So, I was hoping that there was a way to force the audio to the A2DP headset using the MODE_IN_COMMUNICATION and STREAM_VOICE_CALL combination. Is that possible?
Perhaps it works on some devices, but if you care about compatibility across the majority of devices then the answer is "No".
When the phone state is MODE_IN_CALL or MODE_IN_COMMUNICATION all streams will typically follow the PHONE routing strategy. This means that routing to A2DP will not be allowed since:
1) A2DP doesn't support two-way voice anyway.
2) If your BT accessory supports the Hands-free profile it will use a SCO link for the voice audio, and the ACL channel used for A2DP should be closed to avoid interference between the two.

Bluetooth SCO to single android application, not to entire android system

I am using following code in my application to use bluetooth headset for audio IN and OUT. It is working fine.
AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);
am.startBluetoothSco();
am.setBluetoothScoOn(true);
But, When I played song using Music Player app, along with my application also running, the song is coming in bluetooth headset. This is because I changed the Audio Manager of android system to Bluetooth SCO.
But my requirement is the audio IN and OUT must work with bluetooth headset to my application only and it should not disturb other apps, Is it possible ?? or not ??
Please provide your valuable suggestions. Any help will be appreciated. Thanks.
When you add a SCO channel you are essentially adding an audio channel. Think of it like a wired handsfree. When you connect the handsfree all audio is routed to it and not just one specific applications's audio. To use the BT headset only for your app, connect the SCO channel when the app starts and disconnect when the app is exited or goes into background.

Playing sound over speakers while playing music through headphones

I have an AudioTrack streaming via headphones. I have to send a SoundPool to built-in speakers only, without interrupting the AudioTrack playing over the headphones. Any hacks gangsters?
Many Android devices use a single output thread in the AudioFlinger / audio HAL for all local playback (earpiece, speaker, wired headset/headphones), making different routing of two tracks simultaneously impossible (which is why on many devices the media streams are forcibly muted if a notification is played and you've got a wired headset attached; because otherwise you'd hear the music in the loudspeaker while the notification is played).
On some devices it might be possible to do what you're looking for if you manage to do a setForceUse(FOR_MEDIA, FORCE_SPEAKER) and use the MUSIC stream type for the stuff you want to play in the loudspeaker, and the VOICE_CALL stream type for the stuff that you want to play in the wired headset.
I'm not sure if there's any way for an application to perform that setForceUse call though. Perhaps you can get at the handleMessage method of the AudioService class through reflection and send it an MSG_SET_FORCE_USE message.. I've never tried it myself so it might fail miserably.
EDIT: I've now tested the setForceUse way of forcing MEDIA streams to the loudspeaker while a wired headset is attached on an actual device, and it does work (though I can't guarantee that it will work across all devices). The implementation was slightly different from what I described above. See my answer to how to turn speaker on/off programatically in android 4.0 for the code I used.

Categories

Resources