You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix intra-doc links to WavMuxOptions / WavDemuxer methods
A-law/μ-law tag 6/7 + WAVEFORMATEXTENSIBLE end-to-end
Added
WAV demuxer parses the plst (Playlist) chunk per docs/container/riff/metadata/microsoft-riffmci.pdf §3 ("Playlist
Chunk"). The 4-byte dwSegments count is followed by N × 12-byte <play-segment> records (dwName, dwLength, dwLoops). Each
segment surfaces under wav:plst.count plus per-segment wav:plst.<n>.cue_id / .length / .loops keys. Unlike the cue
chunk which keys by dwName, the playlist is keyed by zero-based
segment position because the spec explicitly allows a single cue
id to appear in multiple segments (a cue replayed N times = N
segments with identical dwName), so a dwName-indexed key would
collide. A dwSegments count that exceeds the chunk body is
clamped to the records that actually fit; bodies shorter than the
4-byte segment-count header are treated as opaque and skipped.
WAV demuxer parses the smpl (Sampler) and inst (Instrument)
chunks per docs/container/riff/metadata/exiftool-riff-tags.html §
"RIFF Sampler Tags" / "RIFF Instrument Tags" and summarised in docs/container/riff/metadata/README.md § "Sampler / Instrument
chunks". smpl is a 36-byte fixed header (Manufacturer, Product, SamplePeriod, MIDIUnityNote, MIDIPitchFraction, SMPTEFormat, SMPTEOffset, cSampleLoops, cbSamplerData)
followed by N × 24-byte loop records (dwCuePointID, dwType, dwStart, dwEnd, dwFraction, dwPlayCount). inst is a
7-byte fixed struct (UnshiftedNote, FineTune, Gain, LowNote, HighNote, LowVelocity, HighVelocity). Both surface through Demuxer::metadata under wav:smpl.* / wav:inst.* keys; the SMPTEOffsetDWORD is rendered as canonical HH:MM:SS:FF, and FineTune / Gain are decoded as signed i8 (so -3 cents shows
as -3, not 253). A cSampleLoops count exceeding what the chunk
body actually carries is clamped to the records that fit; bodies
shorter than the 36-byte (smpl) or 7-byte (inst) fixed header
are treated as opaque and skipped.
WAV demuxer parses the cue chunk and the LIST adtl (Associated
Data List) sub-chunks per docs/container/riff/metadata/microsoft-riffmci.pdf §3
("Cue-Points Chunk" + "Playlist Chunk" + "Associated Data Chunk").
The cue-point table surfaces under wav:cue.count plus per-point wav:cue.<dwName>.position / .fcc_chunk / .chunk_start / .block_start / .sample_offset (all values as decimal strings; fcc_chunk rendered as a 4-byte ASCII FOURCC when printable). The LIST adtl body's labl / note / ltxt sub-chunks surface
under wav:adtl.labl.<dwName> / wav:adtl.note.<dwName> / wav:adtl.ltxt.<dwName>.{length,purpose,text}. file sub-chunks
(embedded media files) are skipped — their bytes do not fit the
string-typed metadata API. A dwCuePoints count that exceeds the
chunk body is clamped to the records that actually fit so a writer
that lies about the count cannot panic the parser; labl / note
shorter than the 4-byte dwName header and ltxt shorter than the
20-byte fixed header are treated as opaque and skipped.
WAV demuxer parses the bext Broadcast Audio Extension chunk per docs/container/riff/metadata/ebu-tech3285-bwf.pdf (EBU Tech 3285 v2
§2.3 BROADCAST_EXT). The 602-byte fixed struct plus variable CodingHistory is surfaced through Demuxer::metadata under wav:bext.description / .originator / .originator_reference / .origination_date / .origination_time / .time_reference (64-bit
sample count reassembled from the low/high DWORDs) / .version / .umid (hex-encoded SMPTE-330M UMID, v1+ only when non-zero) / .coding_history. For BWF v2 the five loudness WORDs are decoded
from the §2.4 round(100 × value) fixed-point to two decimals under .loudness_value / .loudness_range / .max_true_peak_level / .max_momentary_loudness / .max_short_term_loudness. Loudness and
UMID keys are omitted for v0/v1 streams that leave those fields zero;
a bext chunk shorter than 602 bytes is skipped as opaque.
WAV demuxer dispatches WAVE_FORMAT_ALAW (0x0006) and WAVE_FORMAT_MULAW (0x0007) streams to the pcm_alaw / pcm_mulaw
codecs (host runtime applies G.711 decode through oxideav-g711).
Decoded SampleFormat hint surfaces as S16; bit_rate reflects
the on-wire 8-bit rate (not the post-decode S16 rate).
WAV WAVE_FORMAT_EXTENSIBLE (0xFFFE) end-to-end handling per docs/container/riff/waveformatextensible/README.md: the 22-byte
extension's wValidBitsPerSample, dwChannelMask and SubFormat
GUID are parsed and exposed both through typed accessors on WavDemuxer (format_tag, valid_bits_per_sample, channel_mask, subformat, subformat_text) and through Demuxer::metadata
under the keys wav:fmt.valid_bits_per_sample / wav:fmt.channel_mask / wav:fmt.subformat. Well-known KSDATAFORMAT_SUBTYPE_* GUIDs (PCM, IEEE_FLOAT, ALAW, MULAW)
resolve to the legacy codec ids; unknown GUIDs synthesise a wav:guid_<canonical-text> id so downstream make_decoder
failures name the actual GUID rather than the opaque 0xFFFE tag.
WAV muxer open_muxer_with + WavMuxOptions::with_extensible(mask)
emits a 40-byte WAVEFORMATEXTENSIBLEfmt chunk with caller-
supplied dwChannelMask. wValidBitsPerSample defaults to the
container wBitsPerSample and SubFormat defaults to the well-known
GUID for the codec; both can be overridden via with_valid_bits_per_sample / with_subformat.
New public constants WAVE_FORMAT_PCM / WAVE_FORMAT_IEEE_FLOAT / WAVE_FORMAT_ALAW / WAVE_FORMAT_MULAW / WAVE_FORMAT_EXTENSIBLE
in the wav module for muxer callers.
Fixed
WAV demuxer rejects WAVE_FORMAT_EXTENSIBLE streams whose cbSize < 22 (the spec mandates a 22-byte extension; previously
the demuxer silently dropped the extension fields).
WAV demuxer stamps the on-wire wFormatTag onto CodecParameters.tag so consumers can distinguish legacy WAVEFORMATEX from EXTENSIBLE round-trips without reparsing.