audioop — Манипулирование необработанными аудиоданными

Не рекомендуется, начиная с версии 3.11: Модуль audioop является устаревшим (подробнее см. PEP 594).


Модуль audioop содержит несколько полезных операций над звуковыми фрагментами. Он работает со звуковыми фрагментами, состоящими из знаковых целочисленных выборок шириной 8, 16, 24 или 32 бита, хранящихся в bytes-like objects. Все скалярные элементы являются целыми числами, если не указано иное.

Изменено в версии 3.4: Добавлена поддержка 24-битных выборок. Все функции теперь принимают любые bytes-like object. Ввод строки теперь приводит к немедленной ошибке.

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

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

В модуле определены следующие переменные и функции:

exception audioop.error

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

audioop.add(fragment1, fragment2, width)

Возвращает фрагмент, который является сложением двух образцов, переданных в качестве параметров. width - это ширина образца в байтах, либо 1, 2, 3, либо 4. Оба фрагмента должны иметь одинаковую длину. В случае переполнения выборки усекаются.

audioop.adpcm2lin(adpcmfragment, width, state)

Декодирование фрагмента Intel/DVI с кодировкой ADPCM в линейный фрагмент. Подробности кодирования ADPCM см. в описании lin2adpcm(). Возвращает кортеж (sample, newstate), где образец имеет ширину, указанную в width.

audioop.alaw2lin(fragment, width)

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

audioop.avg(fragment, width)

Возвращает среднее значение по всем образцам во фрагменте.

audioop.avgpp(fragment, width)

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

audioop.bias(fragment, width, bias)

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

audioop.byteswap(fragment, width)

«Byteswap» всех выборок во фрагменте и возвращает измененный фрагмент. Преобразует выборки big-endian в little-endian и наоборот.

Добавлено в версии 3.4.

audioop.cross(fragment, width)

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

audioop.findfactor(fragment, reference)

Верните коэффициент F такой, что rms(add(fragment, mul(reference, -F))) минимален, т.е. верните коэффициент, на который следует умножить ссылку, чтобы она как можно лучше совпала с фрагментом. Фрагменты должны оба содержать 2-байтовые выборки.

Время, затрачиваемое этой процедурой, пропорционально len(fragment).

audioop.findfit(fragment, reference)

Попытайтесь как можно лучше сопоставить ссылку с частью фрагмента (который должен быть более длинным фрагментом). Это делается (концептуально) путем выделения фрагментов из фрагмента, использования findfactor() для вычисления наилучшего соответствия и минимизации результата. Фрагменты должны оба содержать 2-байтовые выборки. Возвращает кортеж (offset, factor), где offset - это (целое число) смещение в фрагменте, с которого началось оптимальное совпадение, а factor - коэффициент (с плавающей точкой) согласно findfactor().

audioop.findmax(fragment, length)

Поиск фрагмента для фрагмента длиной length выборок (не байтов!) с максимальной энергией, т.е. возвращение i, для которого rms(fragment[i*2:(i+length)*2]) максимально. Фрагменты должны оба содержать 2-байтовые выборки.

Процедура занимает время, пропорциональное 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)

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

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)    # one tenth second
    out_test = outputdata[pos*2:]
    in_test = inputdata[pos*2:]
    ipos, factor = audioop.findfit(in_test, out_test)
    # Optional (for better cancellation):
    # 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)
Вернуться на верх