The problem is that we are using an HDMI capture device to renderer frame and audio. The device uses UAC protocol which is registered as an input audio device and selected as the default source of input for the speech engine. We want to change the input audio source for the speech engine to use the built-in bottom microphone or back CAMCORDER microphone.
There are limited resources available on the internet. Few related questions
- Android Speech Recognition Custom Audio Source
- Android speech recognizing and audio recording in the same time
We have tried the following code. The below solution is inspired by Github.com/KieronQuinn/AmbientMusicMod
This code muting the source for the speech engine, but not working!
val SAMPLE_RATE = 44100
val CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO
val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT
// val bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT)
val audioRecord = AudioRecord.Builder()
.setAudioSource(MediaRecorder.AudioSource.CAMCORDER)
.setAudioFormat(AudioFormat.Builder()
.setEncoding(AUDIO_FORMAT)
.setSampleRate(SAMPLE_RATE)
.setChannelMask(CHANNEL_CONFIG)
.build())
// .setBufferSizeInBytes(bufferSize)
.build()
val fileDescriptors = ParcelFileDescriptor.createReliablePipe()
val clientRead = fileDescriptors[0]
audioRecord.startRecording()
Thread {
try {
// datagramSocket.send(datagramPacket)
val audioSink = fileDescriptors[1]
ParcelFileDescriptor.AutoCloseOutputStream(audioSink).use { fos ->
val buffer = ByteArray(audioRecord.bufferSizeInFrames)
while (isListening) {
val bytesRead =
audioRecord.read(buffer, 0, buffer.size, AudioRecord.READ_BLOCKING)
if (bytesRead > 0) {
// datagramSocket.send(datagramPacket)
fos.write(buffer)
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
audioRecord.stop()
audioRecord.release()
}.start()
speechIntent.putExtra("android.speech.extra.AUDIO_SOURCE", clientRead)
speechIntent.putExtra("android.speech.extra.AUDIO_SOURCE_ENCODING", AUDIO_FORMAT)
speechIntent.putExtra("android.speech.extra.AUDIO_SOURCE_SAMPLING_RATE", SAMPLE_RATE)
speechIntent.putExtra("android.speech.extra.AUDIO_SOURCE_CHANNEL_COUNT", CHANNEL_CONFIG)
speechRecognizer.startListening(speechIntent)
Android 13 Google Speech Recognition v20230807 Google Groups Thread
Or
Any workaround to disable automatic routing to USB audio peripherals
programmatically!?
Your app should have WRITE_SECURE_SETTINGS permission granted. Then call
Settings.Secure.putInt(context.getContentResolver(), "usb_audio_automatic_routing_disabled", 1)
. – Irfan LatifWe can grant WRITE_SECURE_SETTINGS permission with the following ADB command.
adb shell pm grant app.package.name android.permission.WRITE_SECURE_SETTINGS
Read more here (USB-audio)
Side note
For now, this is the only workaround to our problem. I hope Google/AOSP will consider the case.