From 678787ec62cebdc7bde3d156885fefdfed514111 Mon Sep 17 00:00:00 2001 From: rouggy Date: Mon, 22 Jun 2026 21:51:29 +0200 Subject: [PATCH] fix: app crashed sometimes while converting qso in MP3 --- internal/audio/mp3.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/internal/audio/mp3.go b/internal/audio/mp3.go index 922bf1e..c5cc876 100644 --- a/internal/audio/mp3.go +++ b/internal/audio/mp3.go @@ -32,6 +32,20 @@ func writeMP3(path string, pcm []byte) error { for i, v := range mono32 { stereo[2*i], stereo[2*i+1] = v, v } + // Shine's Write() reads a WHOLE frame (samplesPerPass × channels = 1152 × 2 = + // 2304 interleaved samples for MPEG-1) per pass via unsafe pointer arithmetic, + // regardless of how short the trailing chunk is. If the buffer isn't an exact + // multiple of a frame, the final pass reads past the slice and the process + // dies with an access violation (0xc0000005) inside windowFilterSubband. + // Pad with trailing silence to a whole number of frames so no partial pass + // exists. (~36 ms of silence at most — inaudible.) + const frameInterleaved = 1152 * 2 // samplesPerPass(MPEG-1) × 2 channels + if rem := len(stereo) % frameInterleaved; rem != 0 { + stereo = append(stereo, make([]int16, frameInterleaved-rem)...) + } + if len(stereo) == 0 { + return nil // nothing to encode (empty recording) + } enc := mp3.NewEncoder(mp3Rate, 2) return enc.Write(f, stereo) }