mod_sndfile: allow overriding the WAV write subtype via a file-string param#3083
Open
celliso1 wants to merge 1 commit into
Open
mod_sndfile: allow overriding the WAV write subtype via a file-string param#3083celliso1 wants to merge 1 commit into
celliso1 wants to merge 1 commit into
Conversation
… param
On write, mod_sndfile unconditionally OR-s SF_FORMAT_PCM_16 into the format
for every standard sample rate, and no extension maps a WAV container to a
companded (u-law/A-law) payload -- the .ul/.ulaw extensions produce
headerless SF_FORMAT_RAW files, not RIFF/WAVE. As a result there is no way
to record, for example, a G.711 call to a RIFF/WAVE file whose payload is
u-law: the recording is always expanded to 16-bit PCM, doubling the size of
audio that was 8-bit companded on the wire and losing the bit-exact
relationship to it.
Honor an optional "subtype" parameter from the standard file-string prefix
so the caller can choose the encoded subtype while keeping the container
implied by the extension:
session:recordFile("{subtype=ulaw}/tmp/foo.wav")
Accepted values: ulaw, alaw, pcm16, pcm24, pcm32. Write mode only; reads
continue to autodetect the subtype from the header. If the requested
subtype is not valid for the container implied by the extension (for
example ulaw on a .flac target), mod_sndfile logs a warning and falls back
to the container's default subtype rather than failing the open;
unrecognized values are likewise ignored with a warning. The change is
therefore inert unless a caller explicitly requests a supported subtype.
Adds unit tests in tests/unit/switch_core_file.c: subtype=ulaw produces a
RIFF/WAVE file with format tag 7 and 8-bit samples that decodes back within
u-law quantization tolerance, an unrecognized subtype falls back to PCM_16,
and an unsupported container/subtype pair (ulaw on .flac) still opens and
yields a valid FLAC.
Signed-off-by: Calvin Ellison <cellison@youmail.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Author
|
cc @andywolk — small, self-contained follow-up in the same area as #3061 (compute/storage cost). This adds an opt-in file-string param to override the WAV write subtype in mod_sndfile; default behavior is unchanged. Would appreciate a review when you have a moment. @jakubkarolczyk @s3rj1k in case you're closer to the formats code. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
On write,
mod_sndfileunconditionally OR-sSF_FORMAT_PCM_16into the formatfor every standard sample rate, and no file extension maps a WAV container to a
companded (u-law/A-law) payload —
.ul/.ulawproduce a headerlessSF_FORMAT_RAWfile, not RIFF/WAVE. As a result there is no way to record, forexample, a G.711 call into a RIFF/WAVE file whose payload stays u-law: the
recording is always expanded to 16-bit PCM, doubling the size on disk and
losing the bit-exact relationship to what crossed the wire.
This adds an optional
subtypeparameter to the standard file-string prefix,so the caller can choose the encoded subtype while the container stays implied
by the extension:
Accepted values:
ulaw,alaw,pcm16,pcm24,pcm32. Write mode only —reads continue to autodetect the subtype from the header. If the requested
subtype is not valid for the container implied by the extension (for example
ulawon a.flactarget),mod_sndfilelogs a warning and falls back to thecontainer's default subtype rather than failing the open; an unrecognized value
is likewise ignored with a warning. The change is therefore inert unless a
caller explicitly requests a supported subtype, and a bad param never costs the
recording.
Recording a G.711 call as u-law WAV is lossless with respect to the wire, half
the size of the PCM-16 file produced today, and trivially decodable by anything
that reads WAV.
Type of Change
Related Issues
No existing issue found for companded WAV write support; happy to open a
tracking issue if the maintainers prefer one.
Testing
Unit tests were added to
tests/unit/switch_core_file.c:{subtype=ulaw}on a.wavtarget produces a RIFF/WAVE file with formattag 7 (ITU G.711 u-law) and 8-bit samples that decodes back within u-law
quantization tolerance.
PCM_16(format tag 1).{subtype=ulaw}on a.flactarget)still opens successfully and yields a valid FLAC file — proving the
warn-and-fall-back path rather than a failed open.
Manual: recorded a live inbound G.711u call via
record_sessionto a{subtype=ulaw}.wavtarget, confirmed the container/subtype withfile(1)(RIFF/WAVE, format tag 7, 8-bit), then decoded and played the file back and
re-transcribed it successfully.
Checklist
Additional Notes
Why not just re-encode to a compressed format?
For telephony audio that will be archived and later transcribed or analyzed,
re-encoding the recording to a low-bitrate lossy codec (e.g. MP3) is a poor
fit: lossy compression at telephony bitrates degrades the exact tokens that
downstream ASR/NLP extract — digit sequences and spelled names — even when
overall intelligibility is preserved. This is not hypothetical: internal A/B
testing that transcribed lossy-re-encoded copies against losslessly-stored
copies of the same calls showed a measurable, repeatable increase in misspelled
names and corrupted number sequences. Storing the native companded payload in a
WAV container sidesteps that entirely — lossless with respect to the wire, half
the size of PCM-16, and readable by any WAV consumer.
Documentation
The parse site in
mod_sndfile.ccarries an inline commentdescribing the parameter and its accepted values. The wiki/params entry below is
ready to drop into the mod_sndfile / file-string documentation so the parameter
is discoverable outside the source: