Skip to main content

Modules/audioop.c

Source:

cpython 3.14 @ ab2d84fe1023/Modules/audioop.c

audioop processes raw (uncompressed) audio data stored as bytes. It works on signed linear PCM samples at 1, 2, 3, or 4 bytes per sample and provides codec conversions (ulaw, alaw, ADPCM) and signal analysis.

Deprecated in Python 3.11 and removed in Python 3.13.

Map

LinesSymbolRole
1-100audioop_getsampleExtract one sample as a Python int
101-250audioop_max, audioop_rms, audioop_avgSignal statistics
251-400audioop_bias, audioop_mul, audioop_addSample arithmetic
401-550audioop_lin2ulaw, audioop_ulaw2linG.711 mu-law codec
551-700audioop_lin2alaw, audioop_alaw2linG.711 A-law codec
701-850audioop_lin2adpcm, audioop_adpcm2linIMA/DVI ADPCM codec
851-1000audioop_ratecvSample-rate conversion (linear interpolation)
1001-1200audioop_byteswap, audioop_findfitByte order swap, cross-correlation

Reading

Sample extraction

// CPython: Modules/audioop.c:82 audioop_getsample_impl
static PyObject *
audioop_getsample_impl(PyObject *module, Py_buffer *fragment,
int width, Py_ssize_t index)
{
/* width: bytes per sample (1, 2, 3, or 4) */
if (index < 0 || index >= fragment->len / width) {
PyErr_SetString(AudioopError, "index out of range");
return NULL;
}
int sample = GETSAMPLE32(width,
(const unsigned char *)fragment->buf,
index);
return PyLong_FromLong(sample);
}

RMS (root-mean-square) amplitude

// CPython: Modules/audioop.c:160 audioop_rms_impl
static PyObject *
audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width)
{
double sum_squares = 0.0;
Py_ssize_t n = fragment->len / width;
for (Py_ssize_t i = 0; i < n; i++) {
double val = GETSAMPLE32(width, fragment->buf, i);
sum_squares += val * val;
}
return PyLong_FromDouble(n > 0 ? sqrt(sum_squares / n) : 0.0);
}

audioop.rms(data, 2) returns the RMS amplitude for 16-bit audio, useful for silence detection.

mu-law encoding

// CPython: Modules/audioop.c:440 audioop_lin2ulaw_impl
/* G.711 mu-law: compress 16-bit linear PCM to 8-bit */
static PyObject *
audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width)
{
Py_ssize_t n = fragment->len / width;
unsigned char *cp = PyBytes_AS_STRING(rv);
for (Py_ssize_t i = 0; i < n; i++) {
int sample = GETSAMPLE32(width, fragment->buf, i) >> 16;
*cp++ = st_14linear2ulaw(sample);
}
}

mu-law maps 13-bit linear samples to 8-bit compressed samples using logarithmic quantization. Used in North American telephone networks (G.711).

Rate conversion

// CPython: Modules/audioop.c:880 audioop_ratecv_impl
/* Linear interpolation sample-rate converter.
inrate, outrate: integer ratio (will be reduced by GCD).
state: (d, samps) from previous call for streaming use.
*/
static PyObject *
audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
int nchannels, int inrate, int outrate,
PyObject *state, int weightA, int weightB)

audioop.ratecv converts between sample rates using a simple weighted linear interpolation. It accepts a state tuple for incremental (streaming) conversion.

findfit

// CPython: Modules/audioop.c:1080 audioop_findfit_impl
/* Cross-correlation to find the position in 'reference' that
best matches 'fragment'. Returns (offset, factor). */
static PyObject *
audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
Py_buffer *reference)

audioop.findfit is used for audio watermarking and tempo matching. It slides fragment over reference and returns the best-fit offset and scale factor.

gopy notes

audioop was removed in Python 3.13 and is not in gopy's stdlib. The annotation is for completeness. Audio processing in modern Python uses numpy, soundfile, or pyaudio.