audioop.md
1> **Источник:** https://python-all.ru/2.7/library/audioop.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 21.1. [`audioop`](https://python-all.ru/2.7/library/audioop.html#module-audioop) – Работа с сырыми аудиоданными89Модуль [`audioop`](https://python-all.ru/2.7/library/audioop.html#module-audioop) содержит несколько полезных операций над звуковыми фрагментами. Он работает со звуковыми фрагментами, состоящими из знаковых целочисленных семплов шириной 8, 16 или 32 бит, хранящихся в строках Python. Это тот же формат, который используется модулями [`al`](https://python-all.ru/2.7/library/al.html#module-al) и [`sunaudiodev`](https://python-all.ru/2.7/library/sunaudio.html#module-sunaudiodev). Все скалярные элементы являются целыми числами, если не указано иное.1011Этот модуль предоставляет поддержку кодировок a-LAW, u-LAW и Intel/DVI ADPCM.1213Некоторые более сложные операции работают только с 16-битными отсчётами, в остальных случаях размер отсчёта (в байтах) всегда является параметром операции.1415Модуль определяет следующие переменные и функции:1617#### `exception audioop.error`1819Это исключение возникает при любых ошибках, например при неизвестном числе байт на отсчёт и т.п.2021#### `audioop.add(fragment1, fragment2, width)`2223Возвращает фрагмент, являющийся суммой двух сэмплов, переданных в качестве параметров. *width* – ширина сэмпла в байтах: `1`, `2` или `4`. Оба фрагмента должны быть одной длины. При переполнении сэмплы усекаются.2425#### `audioop.adpcm2lin(adpcmfragment, width, state)`2627Decode an Intel/DVI ADPCM coded fragment to a linear fragment. See the description of [`lin2adpcm()`](https://python-all.ru/2.7/library/audioop.html#audioop.lin2adpcm) for details on ADPCM coding. Return a tuple `(sample, newstate)` where the sample has the width specified in *width*.2829#### `audioop.alaw2lin(fragment, width)`3031Convert 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.3233Новое в версии 2.5.3435#### `audioop.avg(fragment, width)`3637Возвращает среднее арифметическое всех отсчётов во фрагменте.3839#### `audioop.avgpp(fragment, width)`4041Возвращает среднее размаха (пик-пик) по всем отсчётам во фрагменте. Фильтрация не производится, поэтому полезность этой функции сомнительна.4243#### `audioop.bias(fragment, width, bias)`4445Возвращает фрагмент, представляющий собой исходный фрагмент со смещением (bias), добавленным к каждому отсчёту. В случае переполнения отсчёты оборачиваются.4647#### `audioop.cross(fragment, width)`4849Возвращает количество пересечений нуля во фрагменте, переданном в качестве аргумента.5051#### `audioop.findfactor(fragment, reference)`5253Return 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.5455The time taken by this routine is proportional to `len(fragment)`.5657#### `audioop.findfit(fragment, reference)`5859Try 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()`](https://python-all.ru/2.7/library/audioop.html#audioop.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()`](https://python-all.ru/2.7/library/audioop.html#audioop.findfactor).6061#### `audioop.findmax(fragment, length)`6263Search *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.6465The routine takes time proportional to `len(fragment)`.6667#### `audioop.getsample(fragment, width, index)`6869Возвращает значение сэмпла *index* из фрагмента.7071#### `audioop.lin2adpcm(fragment, width, state)`7273Преобразует сэмплы в 4-битное кодирование Intel/DVI ADPCM. Кодирование ADPCM – это адаптивная схема кодирования, в которой каждое 4-битное число представляет собой разность между одним сэмплом и следующим, делённую на (изменяемый) шаг. Алгоритм Intel/DVI ADPCM был выбран для использования IMA, так что он вполне может стать стандартом.7475*state* – кортеж, содержащий состояние кодера. Кодер возвращает кортеж `(adpcmfrag, newstate)`, а *newstate* следует передавать при следующем вызове [`lin2adpcm()`](https://python-all.ru/2.7/library/audioop.html#audioop.lin2adpcm). При первом вызове в качестве состояния можно передать `None`. *adpcmfrag* – это ADPCM-кодированный фрагмент, упакованный по 2 4-битных значения на байт.7677#### `audioop.lin2alaw(fragment, width)`7879Преобразует сэмплы звукового фрагмента в кодировку a-LAW и возвращает результат в виде строки Python. a-LAW – это формат аудиокодирования, при котором можно получить динамический диапазон около 13 бит, используя только 8-битные сэмплы. Он применяется, в частности, в звуковом оборудовании Sun.8081Новое в версии 2.5.8283#### `audioop.lin2lin(fragment, width, newwidth)`8485Преобразует сэмплы между одно-, двух- и четырёхбайтовыми форматами.8687> **Примечание**88>89> В некоторых аудиоформатах, таких как .WAV, 16- и 32-битные сэмплы являются знаковыми, а 8-битные – беззнаковыми. Поэтому при преобразовании в 8-битные сэмплы для этих форматов к результату необходимо также прибавить 128:90>91> ```python92> new_frames = audioop.lin2lin(frames, old_width, 1)93> new_frames = audioop.bias(new_frames, 1, 128)94> ```95>96> То же самое в обратном порядке следует применять при преобразовании из 8-битных сэмплов в 16- или 32-битные.9798#### `audioop.lin2ulaw(fragment, width)`99100Преобразует сэмплы звукового фрагмента в кодировку u-LAW и возвращает результат в виде строки Python. u-LAW – это формат аудиокодирования, при котором можно получить динамический диапазон около 14 бит, используя только 8-битные сэмплы. Он применяется, в частности, в звуковом оборудовании Sun.101102#### `audioop.max(fragment, width)`103104Возвращает максимум *абсолютных значений* всех сэмплов во фрагменте.105106#### `audioop.maxpp(fragment, width)`107108Возвращает максимальное пик-пик значение в звуковом фрагменте.109110#### `audioop.minmax(fragment, width)`111112Возвращает кортеж, состоящий из минимального и максимального значений всех сэмплов в звуковом фрагменте.113114#### `audioop.mul(fragment, width, factor)`115116Возвращает фрагмент, в котором все сэмплы исходного фрагмента умножены на значение с плавающей запятой *factor*. При переполнении сэмплы усекаются.117118#### `audioop.ratecv(fragment, width, nchannels, inrate, outrate, state[, weightA[, weightB]])`119120Преобразует частоту кадров входного фрагмента.121122*state* – кортеж, содержащий состояние преобразователя. Преобразователь возвращает кортеж `(newfragment, newstate)`, а *newstate* следует передавать при следующем вызове [`ratecv()`](https://python-all.ru/2.7/library/audioop.html#audioop.ratecv). При первом вызове в качестве состояния следует передать `None`.123124Аргументы *weightA* и *weightB* – это параметры простого цифрового фильтра; по умолчанию они равны `1` и `0` соответственно.125126#### `audioop.reverse(fragment, width)`127128Разворачивает сэмплы во фрагменте и возвращает изменённый фрагмент.129130#### `audioop.rms(fragment, width)`131132Возвращает среднеквадратичное значение фрагмента, т. е. `sqrt(sum(S_i^2)/n)`.133134Это мера мощности аудиосигнала.135136#### `audioop.tomono(fragment, width, lfactor, rfactor)`137138Преобразует стереофрагмент в монофрагмент. Левый канал умножается на *lfactor*, а правый – на *rfactor*, после чего два канала складываются для получения моносигнала.139140#### `audioop.tostereo(fragment, width, lfactor, rfactor)`141142Создаёт стереофрагмент из монофрагмента. Каждая пара сэмплов в стереофрагменте вычисляется из моно-сэмпла, при этом сэмплы левого канала умножаются на *lfactor*, а правого – на *rfactor*.143144#### `audioop.ulaw2lin(fragment, width)`145146Преобразует звуковые фрагменты в кодировке u-LAW во фрагменты с линейным кодированием. Кодировка u-LAW всегда использует 8-битные сэмплы, поэтому *width* здесь относится только к ширине сэмпла выходного фрагмента.147148Обратите внимание, что такие операции, как [`mul()`](https://python-all.ru/2.7/library/audioop.html#audioop.mul) или [`max()`](https://python-all.ru/2.7/library/audioop.html#audioop.max), не различают моно- и стереофрагменты, то есть все сэмплы обрабатываются одинаково. Если это мешает, стереофрагмент следует сначала разделить на два монофрагмента, а затем снова объединить. Вот пример, как это сделать:149150```python151def mul_stereo(sample, width, lfactor, rfactor):152 lsample = audioop.tomono(sample, width, 1, 0)153 rsample = audioop.tomono(sample, width, 0, 1)154 lsample = audioop.mul(lsample, width, lfactor)155 rsample = audioop.mul(rsample, width, rfactor)156 lsample = audioop.tostereo(lsample, width, 1, 0)157 rsample = audioop.tostereo(rsample, width, 0, 1)158 return audioop.add(lsample, rsample, width)159```160161Если вы используете ADPCM-кодер для построения сетевых пакетов и хотите, чтобы протокол был без состояния (т.е. мог переносить потерю пакетов), вам следует передавать не только данные, но и состояние. Обратите внимание, что вместе с декодером нужно отправлять *начальное* состояние (то, которое было передано в [`lin2adpcm()`](https://python-all.ru/2.7/library/audioop.html#audioop.lin2adpcm)), а не итоговое (возвращённое кодером). Если вы хотите использовать [`struct.Struct`](https://python-all.ru/2.7/library/struct.html#struct.Struct) для хранения состояния в двоичном виде, первый элемент (предсказанное значение) можно закодировать в 16 бит, а второй (индекс дельты) – в 8.162163ADPCM-кодеры никогда не тестировались с другими ADPCM-кодерами, только друг с другом. Вполне возможно, что я неправильно интерпретировал стандарты, и в этом случае они не будут совместимы с соответствующими стандартами.164165Процедуры `find*()` могут выглядеть немного странно на первый взгляд. В первую очередь они предназначены для подавления эха. Достаточно быстрый способ сделать это – выбрать наиболее энергичный участок выходного сэмпла, найти его во входном сэмпле и вычесть весь выходной сэмпл из входного:166167```python168def echocancel(outputdata, inputdata):169 pos = audioop.findmax(outputdata, 800) # одна десятая секунды170 out_test = outputdata[pos*2:]171 in_test = inputdata[pos*2:]172 ipos, factor = audioop.findfit(in_test, out_test)173 # Необязательно (для лучшего подавления):174 # factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],175 # out_test)176 prefill = '\0'*(pos+ipos)*2177 postfill = '\0'*(len(inputdata)-len(prefill)-len(outputdata))178 outputdata = prefill + audioop.mul(outputdata, 2, -factor) + postfill179 return audioop.add(inputdata, outputdata, 2)180```181