When loading an .m4a (AAC-LC) file via Superpowered.downloadAndDecode(url, this), the decoded audio includes the encoder delay introduced by the AAC encoder (typically 2112 samples at 44.1 kHz for FFmpeg/libfdk-aac). This manifests as an audible click or gap at every clip boundary when clips are looped or played back-to-back.
FFmpeg writes gapless metadata to strip this delay: the iTunSMPB iTunes tag and the elst (edit list) MP4 box both encode the exact number of leading/trailing padding samples to discard. The browser's own AudioContext.decodeAudioData() reads this metadata correctly and returns clean, delay-free PCM.
Steps to reproduce:
Encode any audio to AAC-LC M4A with FFmpeg: ffmpeg -i input.wav -c:a aac -b:a 220k output.m4a
Load output.m4a via downloadAndDecode into an AdvancedAudioPlayer
Loop or play clips sequentially — click/gap is audible at the seam
Expected behavior: downloadAndDecode reads the elst box / iTunSMPB tag and trims the encoder delay before handing PCM to the player, matching what browsers do natively.
Workaround: Decode M4A in the main thread via AudioContext.decodeAudioData(), re-encode as 16-bit PCM WAV, and pass a Blob URL to downloadAndDecode instead. Works, but adds memory overhead and a main-thread decode step.
Environment: @superpoweredsdk/web v2.7.2, Chrome 148
When loading an .m4a (AAC-LC) file via Superpowered.downloadAndDecode(url, this), the decoded audio includes the encoder delay introduced by the AAC encoder (typically 2112 samples at 44.1 kHz for FFmpeg/libfdk-aac). This manifests as an audible click or gap at every clip boundary when clips are looped or played back-to-back.
FFmpeg writes gapless metadata to strip this delay: the iTunSMPB iTunes tag and the elst (edit list) MP4 box both encode the exact number of leading/trailing padding samples to discard. The browser's own AudioContext.decodeAudioData() reads this metadata correctly and returns clean, delay-free PCM.
Steps to reproduce:
Encode any audio to AAC-LC M4A with FFmpeg: ffmpeg -i input.wav -c:a aac -b:a 220k output.m4a
Load output.m4a via downloadAndDecode into an AdvancedAudioPlayer
Loop or play clips sequentially — click/gap is audible at the seam
Expected behavior: downloadAndDecode reads the elst box / iTunSMPB tag and trims the encoder delay before handing PCM to the player, matching what browsers do natively.
Workaround: Decode M4A in the main thread via AudioContext.decodeAudioData(), re-encode as 16-bit PCM WAV, and pass a Blob URL to downloadAndDecode instead. Works, but adds memory overhead and a main-thread decode step.
Environment: @superpoweredsdk/web v2.7.2, Chrome 148