Per external review (helpful checklist from ChatGPT-style analysis
pointing out we never verified that iOS actually accepted our
preferred sample rate / channels / format): preferredSampleRate
and preferredIOBufferDuration are HINTS, not guarantees. iOS may
substitute its own values if the hardware can't satisfy our
preference. If VPIO is running at 44.1 kHz Float32 stereo while
our render callback writes 48 kHz Int16 mono into the buffer,
the symptoms would match what user reports (broken playback,
pitch shifted, severe distortion) and our previous diagnostics
wouldn't catch it because they only sampled signal-level metrics.
This commit adds two diagnostic emissions to verify:
1. AppDelegate.swift::activateAudioSession: after setActive
succeeds, log the ACTUAL session state \u2014 category, mode,
sampleRate, ioBufferDuration, current route (inputs +
outputs), outputVolume. Lets us see whether iOS honoured our
.default + .defaultToSpeaker setup and which physical route
it picked at launch.
2. ios_voice_unit.rs::IosVoiceUnit::start: after unit.start()
succeeds, log the actual OUTPUT and INPUT stream formats
VPIO accepted (sample_rate, channels, sample_format, flags).
If these differ from our requested 48 kHz Int16 mono, we
have a format-substitution problem.
Three possible outcomes from the next test:
* Both diagnostics confirm 48 kHz Int16 mono on both buses and
the session sampleRate=48000 -> format is correct; the
playback breakage is somewhere else (e.g. AudioHandler
jitter buffer behaviour, route binding, or hardware mixer).
* Session sampleRate != 48000 -> we need to insert a sample
rate converter or pin AVAudioSession's
setPreferredSampleRate(48000) explicitly in Swift before
setActive.
* VPIO substituted Float32 for our Int16 request -> our render
callback is writing i16 magnitudes into a Float32 buffer
which would explain the distortion. Fix: write Float32
directly using data::Interleaved<f32> instead of i16.
Build counter 70 -> 71. Pure diagnostic; no behavioural
change.