Документация Python неофициальный перевод

22.1. audioop – Работа с сырыми аудиоданнымиaudioop – Manipulate raw audio data


The audioop module contains some useful operations on sound fragments. It operates on sound fragments consisting of signed integer samples 8, 16, 24 or 32 bits wide, stored in bytes-like objects. All scalar items are integers, unless specified otherwise.

Changed in version 3.4: Support for 24-bit samples was added. All functions now accept any bytes-like object. String input now results in an immediate error.

Этот модуль предоставляет поддержку кодировок a-LAW, u-LAW и Intel/DVI ADPCM.

Некоторые более сложные операции работают только с 16-битными отсчётами, в остальных случаях размер отсчёта (в байтах) всегда является параметром операции.

Модуль определяет следующие переменные и функции:

exception audioop.error

Это исключение возникает при любых ошибках, например при неизвестном числе байт на отсчёт и т.п.

audioop.add(fragment1, fragment2, width)

Return a fragment which is the addition of the two samples passed as parameters. width is the sample width in bytes, either 1, 2, 3 or 4. Both fragments should have the same length. Samples are truncated in case of overflow.

audioop.adpcm2lin(adpcmfragment, width, state)

Decode an Intel/DVI ADPCM coded fragment to a linear fragment. See the description of lin2adpcm() for details on ADPCM coding. Return a tuple (sample, newstate) where the sample has the width specified in width.

audioop.alaw2lin(fragment, width)

Convert sound fragments in a-LAW encoding to linearly encoded sound fragments. a-LAW encoding always uses 8 bits samples, so width refers only to the sample width of the output fragment here.

audioop.avg(fragment, width)

Возвращает среднее арифметическое всех отсчётов во фрагменте.

audioop.avgpp(fragment, width)

Возвращает среднее размаха (пик-пик) по всем отсчётам во фрагменте. Фильтрация не производится, поэтому полезность этой функции сомнительна.

audioop.bias(fragment, width, bias)

Возвращает фрагмент, представляющий собой исходный фрагмент со смещением (bias), добавленным к каждому отсчёту. В случае переполнения отсчёты оборачиваются.

audioop.byteswap(fragment, width)

«Переворачивает байты» (byteswap) всех отсчётов во фрагменте и возвращает изменённый фрагмент. Преобразует отсчёты из порядка big-endian в little-endian и наоборот.

Новое в версии 3.4.

audioop.cross(fragment, width)

Возвращает количество пересечений нуля во фрагменте, переданном в качестве аргумента.

audioop.findfactor(fragment, reference)

Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal, i.e., return the factor with which you should multiply reference to make it match as well as possible to fragment. The fragments should both contain 2-byte samples.

The time taken by this routine is proportional to len(fragment).

audioop.findfit(fragment, reference)

Try to match reference as well as possible to a portion of fragment (which should be the longer fragment). This is (conceptually) done by taking slices out of fragment, using findfactor() to compute the best match, and minimizing the result. The fragments should both contain 2-byte samples. Return a tuple (offset, factor) where offset is the (integer) offset into fragment where the optimal match started and factor is the (floating-point) factor as per findfactor().

audioop.findmax(fragment, length)

Search fragment for a slice of length length samples (not bytes!) with maximum energy, i.e., return i for which rms(fragment[i*2:(i+length)*2]) is maximal. The fragments should both contain 2-byte samples.

The routine takes time proportional to len(fragment).

audioop.getsample(fragment, width, index)

Возвращает значение сэмпла index из фрагмента.

audioop.lin2adpcm(fragment, width, state)

Преобразует сэмплы в 4-битное кодирование Intel/DVI ADPCM. Кодирование ADPCM – это адаптивная схема кодирования, в которой каждое 4-битное число представляет собой разность между одним сэмплом и следующим, делённую на (изменяемый) шаг. Алгоритм Intel/DVI ADPCM был выбран для использования IMA, так что он вполне может стать стандартом.

state – кортеж, содержащий состояние кодера. Кодер возвращает кортеж (adpcmfrag, newstate), а newstate следует передавать при следующем вызове lin2adpcm(). При первом вызове в качестве состояния можно передать None. adpcmfrag – это ADPCM-кодированный фрагмент, упакованный по 2 4-битных значения на байт.

audioop.lin2alaw(fragment, width)

Преобразует сэмплы в аудиофрагменте в кодировку a-LAW и возвращает результат как объект bytes. a-LAW – это формат аудиокодирования, который позволяет получить динамический диапазон около 13 бит, используя всего 8-битные сэмплы. Он используется, в частности, в аудиооборудовании Sun.

audioop.lin2lin(fragment, width, newwidth)

Преобразует сэмплы между форматами в 1, 2, 3 и 4 байта.

Примечание

В некоторых аудиоформатах, например в файлах .WAV, 16-, 24- и 32-битные сэмплы являются знаковыми, а 8-битные – беззнаковыми. Поэтому при преобразовании в 8-битные сэмплы для таких форматов к результату необходимо добавлять 128:

new_frames = audioop.lin2lin(frames, old_width, 1)
new_frames = audioop.bias(new_frames, 1, 128)

То же самое, но в обратную сторону, нужно делать при преобразовании из 8-битных сэмплов в 16-, 24- или 32-битные.

audioop.lin2ulaw(fragment, width)

Преобразует сэмплы в аудиофрагменте в кодировку u-LAW и возвращает результат как объект bytes. u-LAW – это формат аудиокодирования, который позволяет получить динамический диапазон около 14 бит, используя всего 8-битные сэмплы. Он используется, в частности, в аудиооборудовании Sun.

audioop.max(fragment, width)

Возвращает максимум абсолютных значений всех сэмплов во фрагменте.

audioop.maxpp(fragment, width)

Возвращает максимальное пик-пик значение в звуковом фрагменте.

audioop.minmax(fragment, width)

Возвращает кортеж, состоящий из минимального и максимального значений всех сэмплов в звуковом фрагменте.

audioop.mul(fragment, width, factor)

Возвращает фрагмент, в котором все сэмплы исходного фрагмента умножены на значение с плавающей запятой factor. При переполнении сэмплы усекаются.

audioop.ratecv(fragment, width, nchannels, inrate, outrate, state[, weightA[, weightB]])

Преобразует частоту кадров входного фрагмента.

state – кортеж, содержащий состояние преобразователя. Преобразователь возвращает кортеж (newfragment, newstate), а newstate следует передавать при следующем вызове ratecv(). При первом вызове в качестве состояния следует передать None.

Аргументы weightA и weightB – это параметры простого цифрового фильтра; по умолчанию они равны 1 и 0 соответственно.

audioop.reverse(fragment, width)

Разворачивает сэмплы во фрагменте и возвращает изменённый фрагмент.

audioop.rms(fragment, width)

Возвращает среднеквадратичное значение фрагмента, т. е. sqrt(sum(S_i^2)/n).

Это мера мощности аудиосигнала.

audioop.tomono(fragment, width, lfactor, rfactor)

Преобразует стереофрагмент в монофрагмент. Левый канал умножается на lfactor, а правый – на rfactor, после чего два канала складываются для получения моносигнала.

audioop.tostereo(fragment, width, lfactor, rfactor)

Создаёт стереофрагмент из монофрагмента. Каждая пара сэмплов в стереофрагменте вычисляется из моно-сэмпла, при этом сэмплы левого канала умножаются на lfactor, а правого – на rfactor.

audioop.ulaw2lin(fragment, width)

Преобразует звуковые фрагменты в кодировке u-LAW во фрагменты с линейным кодированием. Кодировка u-LAW всегда использует 8-битные сэмплы, поэтому width здесь относится только к ширине сэмпла выходного фрагмента.

Обратите внимание, что такие операции, как mul() или max(), не различают моно- и стереофрагменты, то есть все сэмплы обрабатываются одинаково. Если это мешает, стереофрагмент следует сначала разделить на два монофрагмента, а затем снова объединить. Вот пример, как это сделать:

def mul_stereo(sample, width, lfactor, rfactor):
    lsample = audioop.tomono(sample, width, 1, 0)
    rsample = audioop.tomono(sample, width, 0, 1)
    lsample = audioop.mul(lsample, width, lfactor)
    rsample = audioop.mul(rsample, width, rfactor)
    lsample = audioop.tostereo(lsample, width, 1, 0)
    rsample = audioop.tostereo(rsample, width, 0, 1)
    return audioop.add(lsample, rsample, width)

Если вы используете ADPCM-кодер для построения сетевых пакетов и хотите, чтобы протокол был без состояния (т.е. мог переносить потерю пакетов), вам следует передавать не только данные, но и состояние. Обратите внимание, что вместе с декодером нужно отправлять начальное состояние (то, которое было передано в lin2adpcm()), а не итоговое (возвращённое кодером). Если вы хотите использовать struct.Struct для хранения состояния в двоичном виде, первый элемент (предсказанное значение) можно закодировать в 16 бит, а второй (индекс дельты) – в 8.

ADPCM-кодеры никогда не тестировались с другими ADPCM-кодерами, только друг с другом. Вполне возможно, что я неправильно интерпретировал стандарты, и в этом случае они не будут совместимы с соответствующими стандартами.

Процедуры find*() могут выглядеть немного странно на первый взгляд. В первую очередь они предназначены для подавления эха. Достаточно быстрый способ сделать это – выбрать наиболее энергичный участок выходного сэмпла, найти его во входном сэмпле и вычесть весь выходной сэмпл из входного:

def echocancel(outputdata, inputdata):
    pos = audioop.findmax(outputdata, 800)    # одна десятая секунды
    out_test = outputdata[pos*2:]
    in_test = inputdata[pos*2:]
    ipos, factor = audioop.findfit(in_test, out_test)
    # Необязательно (для лучшего подавления):
    # factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],
    #              out_test)
    prefill = '\0'*(pos+ipos)*2
    postfill = '\0'*(len(inputdata)-len(prefill)-len(outputdata))
    outputdata = prefill + audioop.mul(outputdata, 2, -factor) + postfill
    return audioop.add(inputdata, outputdata, 2)