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

Застаріло з версії 3.11, буде видалено у версії 3.13: Модуль audioop є застарілим (докладніше див. PEP 594).


Модуль audioop містить деякі корисні операції над звуковими фрагментами. Він працює зі звуковими фрагментами, що складаються зі знакових цілих зразків шириною 8, 16, 24 або 32 біти, що зберігаються в байтоподібних об’єктах. Усі скалярні елементи є цілими числами, якщо не вказано інше.

Змінено в версії 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 до лінійного фрагмента. Перегляньте опис lin2adpcm(), щоб дізнатися більше про кодування ADPCM. Повертає кортеж (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» відбирає всі зразки у фрагменті та повертає змінений фрагмент. Перетворює вибірки з порядковим порядком байта на порядковий і навпаки.

Нове в версії 3.4.

audioop.cross(fragment, width)

Повертає кількість перетинів нуля у фрагменті, переданому як аргумент.

audioop.findfactor(fragment, reference)

Повертає такий множник F, що rms(add(fragment, mul(reference, -F))) є мінімальним, тобто повертає множник, на який потрібно помножити посилання, щоб він збігався з можна фрагментувати. Обидва фрагменти повинні містити 2-байтові зразки.

Час, витрачений на цю програму, пропорційний len(fragment).

audioop.findfit(fragment, reference)

Спробуйте якомога краще зіставити посилання з частиною фрагменту (який має бути довшим фрагментом). Це (концептуально) робиться шляхом вилучення фрагментів із fragment, використання findfactor() для обчислення найкращого збігу та мінімізації результату. Обидва фрагменти повинні містити 2-байтові зразки. Повертає кортеж (offset, factor), де offset — це (ціле) зміщення у фрагмент, де почався оптимальний збіг, а factor — це коефіцієнт (з плаваючою комою) відповідно до findfactor().

audioop.findmax(fragment, length)

Пошук fragment для фрагмента довжини 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)

Повертає фрагмент, який містить усі зразки у вихідному фрагменті, помножені на значення з плаваючою комою 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)