Feat: Add replay-gain to audio playback

The `RecordingView` struct now includes `gain_db` to represent
replay-gain. This value is read from the recording's metadata (`.json`
sidecar) and passed to the frontend.

The JavaScript in `case_recordings.html` uses this `data-gain-db`
attribute to apply replay-gain using the Web Audio API. This ensures
consistent playback loudness across different recordings. The
implementation uses a shared `AudioContext` to manage resources
efficiently and handles cases where the browser might not support
`AudioContext`.

Additionally, the audio recording on Wear OS now uses
`MediaRecorder.AudioSource.VOICE_RECOGNITION` instead of `MIC`. This
leverages platform noise and echo cancellation, aiming for a cleaner
signal before server-side gain adjustment.
This commit is contained in:
2026-04-27 17:08:10 +02:00
parent 710b60bb16
commit 99f77b666d
3 changed files with 114 additions and 2 deletions
@@ -26,7 +26,11 @@ class AudioRecorder(private val context: Context) {
require(recorder == null) { "recorder already active" }
outFile.parentFile?.takeIf { !it.exists() }?.mkdirs()
val r = newRecorderInstance().apply {
setAudioSource(MediaRecorder.AudioSource.MIC)
// VOICE_RECOGNITION lowers raw level vs MIC but applies the
// platform's noise/echo cleaning. Combined with the
// server-side replay-gain pass the playback ends up at
// target loudness with cleaner SNR than raw MIC + post-gain.
setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION)
setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
setAudioSamplingRate(16_000)