Opus File Record And Playback (MediaToolsLib)¶
This document explains how Opus audio is recorded to a file and played back from a file in this codebase. It also captures bugs found during a focused review of MediaToolsLib.
Scope¶
- Recording path:
SndWriter->OpusFileEncoder->OggStream-> file - Playback path:
SndReader->OpusFileDecoder->MediaProcessorspeaker output - File metadata/signature path:
MyOpusHeaderand custom NoLimit signature block
High-Level Data Flow¶
Record To File¶
- UI action starts recording through
SndWriter::fromGuiAssetAction(). SndWriter::startSndWrite()opens encoder state (OpusFileEncoder::beginFileEncode()).OpusFileEncoderopens an Ogg stream (OggStream::openOggStream()) and writes:- Opus ID header (
OpusHead) - Opus tags packet (
OpusTags+ custom strings)
- Opus ID header (
SndWritersubscribes toeMediaInputAudioOpusviaMediaProcessor::wantMediaInput(...).- During capture,
MediaProcessorinvokesSndWriter::callbackOpusEncoded(encodedAudio, opusLenBytes). SndWriterforwards frames toOpusFileEncoder::writeEncodedFrame().OpusFileEncodercallsOggStream::writeEncodedFrame()which packetizes and flushes Ogg pages.- On stop,
SndWriter::stopSndWrite()callsOpusFileEncoder::finishFileEncode(). - Finalization closes Ogg stream and writes custom total-frame metadata into file signature region.
Playback From File¶
- UI action starts playback through
SndReader::fromGuiAssetAction(). SndReader::startSndRead()callsOpusFileDecoder::beginFileDecode(file, assetId, seekPos).- Decoder opens file, initializes Ogg sync/state, parses Opus header, optional seek alignment to
OggSpage. - Decoder subscribes to output-space callback using
wantMediaInput(... eMediaInputMixer ...). OpusFileDecoder::callbackAudioOutSpaceAvail()pulls frames viadecodedNextFrame().decodedNextFrame()reads Ogg pages, decodes Opus packets (opus_decode), converts to PCM frames (opusPcmOutputToPcm()), queues intom_DecodedFrames.moveOpusFramesToOutput()pops one queued PCM frame, boosts volume, copies to output buffer.MediaProcessor::playAudio()receives PCM and sends to audio output.- At EOF, decoder disables callback and sends
eAssetActionPlayEndto GUI.
File Format Notes¶
- Container is Ogg Opus.
- Opus ID header starts with
OpusHead. - Tags packet starts with
OpusTags. - NoLimit custom signature expected at offset
0x9c(NO_LIMIT_OPUS_SIGNITURE_OFFS) and includes:- Prefix
nolimitconnect.org v - 16 hex chars for total sound frames
- Version suffix
- Prefix
- Playback reads this custom total-frame value for progress reporting.