fix(android-audio): revert to 96be740's Oboe config — VoiceCommunication broke callback drain
Build8c36fb5logs showed a new regression: Oboe playout cb#0 fires once at startup then the callback STOPS DRAINING the ring entirely. written_samples sticks at 7679 (= RING_CAPACITY - 1) across every recv heartbeat in a 40-second test. Meanwhile the recv task decodes 1800+ real audio frames (sample range up to [-27920..31907], rms 12065) which all get dropped on the floor by audio_write_playout returning 0 because the ring is full. Bisection:96be740(Usage::Media, no setAudioApi, no ContentType, no MainActivity audio mode change) DID drive the playout callback at the expected 50Hz (playout heartbeat: calls=1100 total_played_real=1055040 over 22 seconds). User still heard nothing there because of OS routing, but at least Oboe accepted the PCM.8c36fb5added three changes on top of96be740: 1. Oboe Usage::Media → Usage::VoiceCommunication 2. Oboe setAudioApi(oboe::AudioApi::AAudio) explicit 3. Oboe setContentType(ContentType::Speech) 4. MainActivity setMode(MODE_IN_COMMUNICATION) + setSpeakerphoneOn(true) Every one of those could have killed the callback; combined they did. Revert to 96be740's exact Oboe config: Usage::Media, no setAudioApi, no ContentType. Keep the PCM recorder, heartbeat logging, and stream-open logging. Separately, MainActivity now maxes STREAM_MUSIC (the stream Usage::Media routes to) but leaves audio mode in MODE_NORMAL — no more speakerphone/call-mode combo that makes Oboe unhappy. In NORMAL mode a STREAM_MUSIC stream plays through the loud speaker by default. Proof that the Rust pipeline is perfect: decoded.pcm recorded in8c36fb5was pulled via `adb shell run-as com.wzp.desktop cat .wzp/decoded.pcm`, converted with ffmpeg, and played back on the Mac — user confirmed audible speech. So 100% of the remaining bug surface is Android audio routing, not anything in the Rust/C++ decode path.
This commit is contained in:
@@ -279,29 +279,33 @@ int wzp_oboe_start(const WzpOboeConfig* config, const WzpOboeRings* rings) {
|
||||
|
||||
// Build playout stream.
|
||||
//
|
||||
// Usage::Media was a failed experiment — diagnosis from build 96be740
|
||||
// showed the whole pipeline is healthy (capture → encode → network →
|
||||
// decode → playout ring → C++ callback reads 960 samples every 20ms
|
||||
// with real audio content) but nothing was audible. This means Oboe
|
||||
// received the PCM and routed it to a silent output. Usage::Media
|
||||
// alone is not enough — the AudioManager must also be switched to
|
||||
// MODE_IN_COMMUNICATION and speakerphone explicitly turned on from
|
||||
// the Activity side, which MainActivity.kt now does on startup.
|
||||
// Regression triangulation between builds:
|
||||
// 96be740 (Usage::Media, default API): playout callback DID drain
|
||||
// the ring at steady 50Hz (playout heartbeat: calls=1100,
|
||||
// total_played_real=1055040). Audio not audible because OS routing
|
||||
// sent it to a silent output.
|
||||
//
|
||||
// Reverting to Usage::VoiceCommunication + ContentType::Speech +
|
||||
// explicit AAudio API (more reliable routing than OpenSLES default)
|
||||
// on top of the Kotlin-side setMode/setSpeakerphoneOn changes.
|
||||
// 8c36fb5 (Usage::VoiceCommunication + setAudioApi(AAudio) +
|
||||
// ContentType::Speech): playout callback fired cb#0 once then
|
||||
// stopped draining the ring entirely. written_samples stuck at
|
||||
// ring capacity (7679) across all subsequent heartbeats, so Oboe
|
||||
// accepted zero samples after startup. Still inaudible.
|
||||
//
|
||||
// Hypothesis: forcing setAudioApi(AAudio) + VoiceCommunication on
|
||||
// Pixel 6 / Android 15 opens a stream that succeeds at cb#0 but
|
||||
// then detaches from the real audio driver. Reverting to the
|
||||
// config that at least drove callbacks correctly, plus the
|
||||
// Kotlin-side MODE_IN_COMMUNICATION + setSpeakerphoneOn(true)
|
||||
// handled in MainActivity.kt to route audio to the loud speaker.
|
||||
oboe::AudioStreamBuilder playoutBuilder;
|
||||
playoutBuilder.setDirection(oboe::Direction::Output)
|
||||
->setAudioApi(oboe::AudioApi::AAudio)
|
||||
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
|
||||
->setSharingMode(oboe::SharingMode::Exclusive)
|
||||
->setFormat(oboe::AudioFormat::I16)
|
||||
->setChannelCount(config->channel_count)
|
||||
->setSampleRate(config->sample_rate)
|
||||
->setFramesPerDataCallback(config->frames_per_burst)
|
||||
->setUsage(oboe::Usage::VoiceCommunication)
|
||||
->setContentType(oboe::ContentType::Speech)
|
||||
->setUsage(oboe::Usage::Media)
|
||||
->setDataCallback(&g_playout_cb);
|
||||
|
||||
result = playoutBuilder.openStream(g_playout_stream);
|
||||
|
||||
Reference in New Issue
Block a user