lame_encoder.h
MP3 out, through the user's own LAME.
#include <sonore/lame_encoder.h>- 1type
On this page
Design notes
LAMEEncoderAudioFormat writes an MP3 the way the reference does: the audio goes to a temporary 16-bit WAV, the lame command-line encoder the USER installed is run on it, and the MP3 it writes is read back and handed over.
Why a separate program and not a library
The MP3 patents have expired, but LAME is LGPL. Linked into a plugin it brings LGPL obligations into every binary built with this SDK; run as the user's own executable it brings none -- the user chose and installed it, and the plugin only ever names a path. That is the reference's reason too, and it is why the path is always the caller's: nothing here searches PATH or guesses where an encoder might live.
Launching without a shell
system() and popen() hand a STRING to a shell, and every space, quote, ampersand or dollar sign in a path is then the shell's to interpret. A user called O'Brien, or a song title with "&" in it, is enough to run something that was never meant to run. So the process is started directly -- CreateProcessW on Windows, posix_spawn elsewhere -- with the argument list as a list.
On POSIX that is the whole story: argv arrives as given. Windows has no argv at the system level; CreateProcessW takes one command line and the CHILD splits it, by the C runtime's rules (the ones CommandLineToArgvW implements). Those rules are odd -- backslashes are literal except in runs that precede a quote, where they escape -- so quoteArgument() below is the exact inverse of them, and audio_io_test checks it by having a child echo back what it received for names with spaces, quotes, trailing backslashes and non-ASCII letters.
What can go wrong at the edges
An encoder that hangs (waiting on a terminal, a network drive that went away) would hang the caller with it, so every run has a timeout after which the process is killed and the call fails saying so. The temporary files are created EXCLUSIVELY under random names -- never an existing file reused, never a predictable name another process could plant first -- and removed on every path out, success or not. The child gets no inherited handles: a plugin's host has files and pipes open that are none of the encoder's business, and on Windows an inherited handle keeps those files locked for as long as the child lives.
Offline: this blocks for as long as the encoder runs. Never from process().
Types 1
MP3 through an external LAME executable. Mono or stereo, any rate LAME takes (it resamples what MP3 cannot carry).