audioop.md
1> **Источник:** https://python-all.ru/3.4/library/audioop.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 22.1. [`audioop`](https://python-all.ru/3.4/library/audioop.html#module-audioop) – Управление необработанными аудиоданными89Модуль [`audioop`](https://python-all.ru/3.4/library/audioop.html#module-audioop) содержит несколько полезных операций над звуковыми фрагментами. Он работает со звуковыми фрагментами, состоящими из целочисленных отсчётов со знаком разрядностью 8, 16, 24 или 32 бита, хранящихся в [*байтоподобных объектах*](https://python-all.ru/3.4/glossary.html#term-bytes-like-object). Все скалярные значения являются целыми числами, если не указано иное.1011Changed in version 3.4: Support for 24-bit samples was added. All functions now accept any [*bytes-like object*](https://python-all.ru/3.4/glossary.html#term-bytes-like-object). String input now results in an immediate error.1213Этот модуль предоставляет поддержку кодировок a-LAW, u-LAW и Intel/DVI ADPCM.1415Некоторые более сложные операции работают только с 16-битными отсчётами, в остальных случаях размер отсчёта (в байтах) всегда является параметром операции.1617Модуль определяет следующие переменные и функции:1819#### `exception audioop.error`2021Это исключение возникает при любых ошибках, например при неизвестном числе байт на отсчёт и т.п.2223#### `audioop.add(fragment1, fragment2, width)`2425Return 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.2627#### `audioop.adpcm2lin(adpcmfragment, width, state)`2829Декодирует фрагмент, закодированный в формате Intel/DVI ADPCM, в линейный фрагмент. Описание кодирования ADPCM см. в [`lin2adpcm()`](https://python-all.ru/3.4/library/audioop.html#audioop.lin2adpcm). Возвращает кортеж `(sample, newstate)`, где sample имеет ширину, указанную в *width*.3031#### `audioop.alaw2lin(fragment, width)`3233Convert 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.3435#### `audioop.avg(fragment, width)`3637Возвращает среднее арифметическое всех отсчётов во фрагменте.3839#### `audioop.avgpp(fragment, width)`4041Возвращает среднее размаха (пик-пик) по всем отсчётам во фрагменте. Фильтрация не производится, поэтому полезность этой функции сомнительна.4243#### `audioop.bias(fragment, width, bias)`4445Возвращает фрагмент, представляющий собой исходный фрагмент со смещением (bias), добавленным к каждому отсчёту. В случае переполнения отсчёты оборачиваются.4647#### `audioop.byteswap(fragment, width)`4849«Переворачивает байты» (byteswap) всех отсчётов во фрагменте и возвращает изменённый фрагмент. Преобразует отсчёты из порядка big-endian в little-endian и наоборот.5051Новое в версии 3.4.5253#### `audioop.cross(fragment, width)`5455Возвращает количество пересечений нуля во фрагменте, переданном в качестве аргумента.5657#### `audioop.findfactor(fragment, reference)`5859Возвращает коэффициент *F*, при котором `rms(add(fragment, mul(reference, -F)))` минимально, т.е. возвращает коэффициент, на который следует умножить *reference*, чтобы он как можно точнее соответствовал *fragment*. Оба фрагмента должны содержать 2-байтовые отсчёты.6061Время выполнения этой процедуры пропорционально `len(fragment)`.6263#### `audioop.findfit(fragment, reference)`6465Пытается подобрать *reference* как можно точнее к части *fragment* (которая должна быть более длинным фрагментом). Концептуально это делается путём извлечения срезов из *fragment*, используя [`findfactor()`](https://python-all.ru/3.4/library/audioop.html#audioop.findfactor) для вычисления наилучшего соответствия и минимизации результата. Оба фрагмента должны содержать 2-байтовые отсчёты. Возвращает кортеж `(offset, factor)`, где *offset* – это (целочисленное) смещение в *fragment*, с которого началось оптимальное совпадение, а *factor* – это (вещественный) коэффициент, как в [`findfactor()`](https://python-all.ru/3.4/library/audioop.html#audioop.findfactor).6667#### `audioop.findmax(fragment, length)`6869Ищет в *fragment* срез длиной *length* отсчётов (не байтов!) с максимальной энергией, т.е. возвращает *i*, для которого `rms(fragment[i*2:(i+length)*2])` максимально. Оба фрагмента должны содержать 2-байтовые отсчёты.7071Время выполнения процедуры пропорционально `len(fragment)`.7273#### `audioop.getsample(fragment, width, index)`7475Возвращает значение сэмпла *index* из фрагмента.7677#### `audioop.lin2adpcm(fragment, width, state)`7879Преобразует сэмплы в 4-битное кодирование Intel/DVI ADPCM. Кодирование ADPCM – это адаптивная схема кодирования, в которой каждое 4-битное число представляет собой разность между одним сэмплом и следующим, делённую на (изменяемый) шаг. Алгоритм Intel/DVI ADPCM был выбран для использования IMA, так что он вполне может стать стандартом.8081*state* – это кортеж, содержащий состояние кодера. Кодер возвращает кортеж `(adpcmfrag, newstate)`, и *newstate* следует передавать в следующий вызов [`lin2adpcm()`](https://python-all.ru/3.4/library/audioop.html#audioop.lin2adpcm). В начальном вызове в качестве состояния можно передать `None`. *adpcmfrag* – это ADPCM-кодированный фрагмент, упакованный по 2 4-битных значения на байт.8283#### `audioop.lin2alaw(fragment, width)`8485Преобразует сэмплы в аудиофрагменте в кодировку a-LAW и возвращает результат как объект bytes. a-LAW – это формат аудиокодирования, который позволяет получить динамический диапазон около 13 бит, используя всего 8-битные сэмплы. Он используется, в частности, в аудиооборудовании Sun.8687#### `audioop.lin2lin(fragment, width, newwidth)`8889Преобразует сэмплы между форматами в 1, 2, 3 и 4 байта.9091> **Примечание**92>93> В некоторых аудиоформатах, например в файлах .WAV, 16-, 24- и 32-битные сэмплы являются знаковыми, а 8-битные – беззнаковыми. Поэтому при преобразовании в 8-битные сэмплы для таких форматов к результату необходимо добавлять 128:94>95> ```python96> new_frames = audioop.lin2lin(frames, old_width, 1)97> new_frames = audioop.bias(new_frames, 1, 128)98> ```99>100> То же самое, но в обратную сторону, нужно делать при преобразовании из 8-битных сэмплов в 16-, 24- или 32-битные.101102#### `audioop.lin2ulaw(fragment, width)`103104Преобразует сэмплы в аудиофрагменте в кодировку u-LAW и возвращает результат как объект bytes. u-LAW – это формат аудиокодирования, который позволяет получить динамический диапазон около 14 бит, используя всего 8-битные сэмплы. Он используется, в частности, в аудиооборудовании Sun.105106#### `audioop.max(fragment, width)`107108Возвращает максимум *абсолютных значений* всех сэмплов во фрагменте.109110#### `audioop.maxpp(fragment, width)`111112Возвращает максимальное пик-пик значение в звуковом фрагменте.113114#### `audioop.minmax(fragment, width)`115116Возвращает кортеж, состоящий из минимального и максимального значений всех сэмплов в звуковом фрагменте.117118#### `audioop.mul(fragment, width, factor)`119120Возвращает фрагмент, в котором все сэмплы исходного фрагмента умножены на значение с плавающей запятой *factor*. При переполнении сэмплы усекаются.121122#### `audioop.ratecv(fragment, width, nchannels, inrate, outrate, state[, weightA[, weightB]])`123124Преобразует частоту кадров входного фрагмента.125126*state* – кортеж, содержащий состояние преобразователя. Преобразователь возвращает кортеж `(newfragment, newstate)`, и *newstate* должен передаваться при следующем вызове [`ratecv()`](https://python-all.ru/3.4/library/audioop.html#audioop.ratecv). Первый вызов должен передавать `None` в качестве состояния.127128Аргументы *weightA* и *weightB* – это параметры простого цифрового фильтра; по умолчанию они равны `1` и `0` соответственно.129130#### `audioop.reverse(fragment, width)`131132Разворачивает сэмплы во фрагменте и возвращает изменённый фрагмент.133134#### `audioop.rms(fragment, width)`135136Возвращает среднеквадратичное значение фрагмента, т.е. `sqrt(sum(S_i^2)/n)`.137138Это мера мощности аудиосигнала.139140#### `audioop.tomono(fragment, width, lfactor, rfactor)`141142Преобразует стереофрагмент в монофрагмент. Левый канал умножается на *lfactor*, а правый – на *rfactor*, после чего два канала складываются для получения моносигнала.143144#### `audioop.tostereo(fragment, width, lfactor, rfactor)`145146Создаёт стереофрагмент из монофрагмента. Каждая пара сэмплов в стереофрагменте вычисляется из моно-сэмпла, при этом сэмплы левого канала умножаются на *lfactor*, а правого – на *rfactor*.147148#### `audioop.ulaw2lin(fragment, width)`149150Преобразует звуковые фрагменты в кодировке u-LAW во фрагменты с линейным кодированием. Кодировка u-LAW всегда использует 8-битные сэмплы, поэтому *width* здесь относится только к ширине сэмпла выходного фрагмента.151152Обратите внимание, что такие операции, как [`mul()`](https://python-all.ru/3.4/library/audioop.html#audioop.mul) или [`max()`](https://python-all.ru/3.4/library/audioop.html#audioop.max), не различают моно- и стереофрагменты, то есть все семплы обрабатываются одинаково. Если это проблема, стереофрагмент следует сначала разделить на два монофрагмента, а затем объединить обратно. Вот пример того, как это сделать:153154```python155def mul_stereo(sample, width, lfactor, rfactor):156 lsample = audioop.tomono(sample, width, 1, 0)157 rsample = audioop.tomono(sample, width, 0, 1)158 lsample = audioop.mul(lsample, width, lfactor)159 rsample = audioop.mul(rsample, width, rfactor)160 lsample = audioop.tostereo(lsample, width, 1, 0)161 rsample = audioop.tostereo(rsample, width, 0, 1)162 return audioop.add(lsample, rsample, width)163```164165Если вы используете ADPCM-кодер для построения сетевых пакетов и хотите, чтобы ваш протокол был без сохранения состояния (т.е. мог переносить потери пакетов), вам следует передавать не только данные, но и состояние. Обратите внимание, что декодеру нужно отправлять *начальное* состояние (то, которое было передано в [`lin2adpcm()`](https://python-all.ru/3.4/library/audioop.html#audioop.lin2adpcm)), а не конечное (возвращаемое кодером). Если вы хотите использовать [`struct.Struct`](https://python-all.ru/3.4/library/struct.html#struct.Struct) для хранения состояния в двоичном виде, первый элемент (предсказанное значение) можно закодировать в 16 бит, а второй (индекс дельты) – в 8.166167ADPCM-кодеры никогда не тестировались с другими ADPCM-кодерами, только друг с другом. Вполне возможно, что я неправильно интерпретировал стандарты, и в этом случае они не будут совместимы с соответствующими стандартами.168169Функции `find*()` могут показаться на первый взгляд немного странными. В первую очередь они предназначены для подавления эха. Достаточно быстрый способ сделать это – выбрать наиболее энергичный участок выходного семпла, найти его во входном семпле и вычесть весь выходной семпл из входного:170171```python172def echocancel(outputdata, inputdata):173 pos = audioop.findmax(outputdata, 800) # одна десятая секунды174 out_test = outputdata[pos*2:]175 in_test = inputdata[pos*2:]176 ipos, factor = audioop.findfit(in_test, out_test)177 # Необязательно (для лучшего подавления):178 # factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],179 # out_test)180 prefill = '\0'*(pos+ipos)*2181 postfill = '\0'*(len(inputdata)-len(prefill)-len(outputdata))182 outputdata = prefill + audioop.mul(outputdata,2,-factor) + postfill183 return audioop.add(inputdata, outputdata, 2)184```185