Browse Source

Capture CAMCORDER audio and apply radio AGC changes live

master
evgeny 6 days ago
parent
commit
2e0eb89ad3
  1. 11
      tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamCaptureEngine.kt

11
tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamCaptureEngine.kt

@ -29,6 +29,7 @@ import java.io.ByteArrayOutputStream
class StreamCaptureEngine( class StreamCaptureEngine(
private val context: Context, private val id: Long, private val group: Long, private val context: Context, private val id: Long, private val group: Long,
private val initialConfig: StreamCaptureConfig, private val microphone: Boolean, private val preview: StreamPreview, private val initialConfig: StreamCaptureConfig, private val microphone: Boolean, private val preview: StreamPreview,
initialAudioCompressor: RadioCompressorSettings,
private val ready: (StreamCaptureConfig, Boolean) -> Unit, private val failure: (String) -> Unit private val ready: (StreamCaptureConfig, Boolean) -> Unit, private val failure: (String) -> Unit
) { ) {
private val thread = HandlerThread("stream-camera").apply { start() } private val thread = HandlerThread("stream-camera").apply { start() }
@ -41,6 +42,7 @@ class StreamCaptureEngine(
private var record: AudioRecord? = null private var record: AudioRecord? = null
private var audioThread: Thread? = null private var audioThread: Thread? = null
@Volatile private var audioRunning = false @Volatile private var audioRunning = false
@Volatile var audioCompressorSettings = initialAudioCompressor
@Volatile private var stopped = false @Volatile private var stopped = false
private var stopping = false private var stopping = false
private var terminalFailure = false private var terminalFailure = false
@ -345,10 +347,13 @@ class StreamCaptureEngine(
private fun startAudio() { private fun startAudio() {
val min = AudioRecord.getMinBufferSize(48000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT) val min = AudioRecord.getMinBufferSize(48000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT)
check(min > 0) check(min > 0)
val rec = AudioRecord(MediaRecorder.AudioSource.MIC, 48000, AudioFormat.CHANNEL_IN_MONO, val rec = AudioRecord(MediaRecorder.AudioSource.CAMCORDER, 48000, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, (min * 2).coerceAtLeast(960 * 8)) AudioFormat.ENCODING_PCM_16BIT, (min * 2).coerceAtLeast(960 * 8))
record = rec; check(rec.state == AudioRecord.STATE_INITIALIZED) record = rec; check(rec.state == AudioRecord.STATE_INITIALIZED)
rec.startRecording(); audioRunning = true rec.startRecording(); check(rec.recordingState == AudioRecord.RECORDSTATE_RECORDING) { "CAMCORDER capture did not start" }
audioRunning = true
LogManager.addLog("INFO", "stream", "audio capture started id=$id source=CAMCORDER(${rec.audioSource}) " +
"rate=${rec.sampleRate} channels=${rec.channelCount} compressor=$audioCompressorSettings")
audioThread = Thread({ audioThread = Thread({
var opus = 0L var opus = 0L
try { try {
@ -371,7 +376,7 @@ class StreamCaptureEngine(
waitingStamp = false waitingStamp = false
val pts = (stamp.nanoTime - originNs) / 1000 - (stamp.framePosition - first) * 1_000_000 / 48000 val pts = (stamp.nanoTime - originNs) / 1000 - (stamp.framePosition - first) * 1_000_000 / 48000
check(pts >= 0 && pts > last) { "Audio timestamp discontinuity pts=$pts last=$last" }; last = pts check(pts >= 0 && pts > last) { "Audio timestamp discontinuity pts=$pts last=$last" }; last = pts
val packet = NativeLib.streamOpusEncode(opus, pcm) ?: error("Opus encode failed") val packet = NativeLib.streamOpusEncode(opus, pcm, audioCompressorSettings) ?: error("Stream compressor/Opus encode failed")
check(NativeLib.streamFeed(id, false, pts, false, packet) >= 0) { "Stream audio publisher detached" } check(NativeLib.streamFeed(id, false, pts, false, packet) >= 0) { "Stream audio publisher detached" }
} }
} catch (e: Exception) { if (audioRunning) handler.post { failed("audio capture: ${e.message}") } } } catch (e: Exception) { if (audioRunning) handler.post { failed("audio capture: ${e.message}") } }

Loading…
Cancel
Save