Skip to content

Commit 1dc7007

Browse files
committed
Audio Routing
1 parent ad002d5 commit 1dc7007

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

SignalBridge/src/main/java/org/operatorfoundation/signalbridge/internal/AudioRecordManager.kt

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@ import android.Manifest
44
import android.annotation.SuppressLint
55
import android.content.Context
66
import android.content.pm.PackageManager
7+
import android.hardware.usb.UsbDevice
78
import android.media.AudioFormat
9+
import android.media.AudioManager
810
import android.media.AudioRecord
911
import android.media.MediaRecorder
12+
import android.os.Build
13+
import androidx.annotation.RequiresApi
1014
import androidx.core.content.ContextCompat
1115
import kotlinx.coroutines.Dispatchers
1216
import kotlinx.coroutines.channels.awaitClose
@@ -32,7 +36,7 @@ import org.operatorfoundation.signalbridge.exceptions.AudioRecordException
3236
* - State management beyond AudioRecord
3337
* - Audio output/playback
3438
*/
35-
internal class AudioRecordManager(private val context: Context)
39+
internal class AudioRecordManager(private val context: Context, private val usbDevice: UsbDevice? = null)
3640
{
3741
companion object
3842
{
@@ -56,6 +60,8 @@ internal class AudioRecordManager(private val context: Context)
5660
private var workingAudioSource: Int = -1
5761
private var bufferSize: Int = 0
5862
private var detectedSampleRate: Int = SAMPLE_RATE // Will be updated during initialization
63+
private val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as android.media.AudioManager
64+
5965

6066
/**
6167
* Tests multiple audio sources and initializes AudioRecord with the first working one.
@@ -65,6 +71,14 @@ internal class AudioRecordManager(private val context: Context)
6571
{
6672
Timber.d("Initializing AudioRecord")
6773

74+
// Set USB audio routing if we have a USB device
75+
if (usbDevice != null)
76+
{
77+
val routingSet = setUsbAudioRouting()
78+
if (routingSet) Timber.i("USB audio routing configured successfully")
79+
else Timber.w("Failed to set USB audio routing, continuing with default routing")
80+
}
81+
6882
// Test each audio source until we find one that works
6983
for (audioSource in AUDIO_SOURCES_TO_TEST)
7084
{
@@ -214,6 +228,41 @@ internal class AudioRecordManager(private val context: Context)
214228
}
215229
}
216230

231+
/**
232+
* Sets USB audio device as the preferred audio input routing
233+
*/
234+
private fun setUsbAudioRouting(): Boolean
235+
{
236+
return try
237+
{
238+
// Get the list of available communication devices
239+
val availableDevices = audioManager.availableCommunicationDevices
240+
241+
val audioDeviceInfo = availableDevices.find { device ->
242+
device.type == android.media.AudioDeviceInfo.TYPE_USB_DEVICE &&
243+
device.productName?.toString() == usbDevice?.productName
244+
}
245+
246+
if (audioDeviceInfo != null)
247+
{
248+
val success = audioManager.setCommunicationDevice(audioDeviceInfo)
249+
Timber.d("Set USB device as communication device: $success")
250+
success
251+
}
252+
else
253+
{
254+
Timber.w("USB audio device not found in available communication devices")
255+
Timber.w("Available devices: ${availableDevices.map { it.productName }}")
256+
false
257+
}
258+
}
259+
catch (e: Exception)
260+
{
261+
Timber.e(e, "Failed to set USB audio routing")
262+
false
263+
}
264+
}
265+
217266
/**
218267
* Starts recording and returns a flow of raw audio samples
219268
* This is a pure data stream with no processing or state management

SignalBridge/src/main/java/org/operatorfoundation/signalbridge/internal/RealUsbAudioConnection.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ internal class RealUsbAudioConnection(
8787
}
8888

8989
// Create and initialize the AudioRecordManager
90-
val recordManager = AudioRecordManager(context)
90+
val recordManager = AudioRecordManager(context, usbDevice)
9191

9292
// Get likely sample rates for this USB device
9393
val likelySampleRates = getLikelySampleRates()

0 commit comments

Comments
 (0)