Полски специалист създава AdBlock за радиото (Radio AdBlock)

Оригиналът е на полския програмист Томек Рекавек, който работи върху проекта Jackrabbit Oak в рамките на Apache Software Foundation за Adobe. Статията е публикувана в неговия личен блог на 24 февруари 2016 година. Но е интересна и актуална до днес.

Полското „Радио-3“, известно и като „Тройката“ предлага хубава музика и има интелигентни водещи. От друга страна, предаването изобилства от шумни и дразнещи рекламни блокове, предлагащи от електроника до лекарства. Томек обича и слуша това радио почти непрекъснато и като програмист, преди време си е задал въпроса, а дали не мога да махна тази реклама? Изглежда че решение има.

Цифрова обработка на сигналите

Целта е да се създаде приложение, което заглушава рекламата в радиопредаванията. Рекламният блок започва и приключва със специални „джингли“, които програмата трябва да разпознае и да изключи звука между тях.

Полски специалист създава AdBlock за радиото (Radio AdBlock)

Известно е, че тази област на математиката и информатиката се нарича цифрова обработка на сигналите, но за мнозина DSP е нещо като магия. Но това е и една отлична възможност да се научи нещо ново и полезно. Най-подходящият механизъм за нашия случай е използването на крос-корелация (cross-correlation).

Octave

Всички материали посочват реализацията на различните алгоритми в MATLAB. Но MATLAB е едно голямо, тежко и скъпо приложение, което наистина улеснява изпълняването на сложните математически операции, включително и DSP. За щастие, съществува безплатната алтернатива Octave. В Octave съвсем не е сложно да се стартира взаимната корелация на два аудиофайла. Необходими са само следните пет команди:

pkg load signal
jingle = wavread('jingle.wav')(:,1);
audio = wavread ('audio.wav')(:,1);
[R, lag] = xcorr(jingle, audio);
plot(R);

Получава се и следната диаграма:

Полски специалист създава AdBlock за радиото (Radio AdBlock)

Добре се вижда пика, показващ мястото на jingle.wav в audio.wav. Всичко става съвсем лесно: цялата работа върши функцията xcorr(). Останалият код служи за четене на файловете и показване на резултата.

Сега остава същият алгоритъм да се реализира на Java. Ще се получи инструмент, който:

  1. Чете аудиопотока от стандартния вход, например с помощта на ffmpeg
  2. Анализира го и намира джинглите
  3. Извежда този аудиопоток към стандартния stdout и/или временно го изключва

Използването на stdin и stdout дава възможност за включването на новия анализатор и към други приложения за възпроизвеждане и обработка на звука.

Четене на звуковите файлове

Първата работа, която трябва да свърши Java програмата е прочитането на джингъла, представен като .wav файл и поставянето му в масив. Във файла има допълнителна информация, като заглавие, метаданни и други. Но на нас ни трябва само звука. Подходящият за тази цел формат е PCM – това е просто списък с числа. Преобразуването на WAV във PCM може да стане с помощта на ffmpeg:

ffmpeg -i input.wav -f s16le -acodec pcm_s16le output.raw

Тук всеки семпъл се съхранява във вид на 16-битово число с обратна наредба на байтове (little endian). В Java е подходящо да се използва типа short. А за автоматичното преобразуване на входния поток в short значения може да се използва класа ByteBuffer:

ByteBuffer buf = ByteBuffer.allocate(4);
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.put(bytes);
short leftChannel = buf.readShort(); // stereo stream
short rightChannel = buf.readShort();

Дизасемблиране на xcorr

За да се реализира функцията xcorr() на Java е необходимо да се прегледа сорс кода на Octave. Всичко е доста лесно. Ето как изглежда тази функция на Java:

N = length(audio);
M = 2 ^ nextpow2(2 * N - 1);
pre = fft(postpad(prepad(jingle(:), length(jingle) + N - 1), M));
post = fft(postpad(audio(:), M));
cor = ifft(pre .* conj(post));
R = real(cor(1:2 * N));

Изглежда малко страшно, но това са предимно тривиални операции с масиви. В основата на крос-корелацията е използването на бързото преобразуване на Фурие.

Бързото преобразуване на Фурие

Без никакъв опит в DSP е достатъчно да се гледа на FFT като функция, която на входа си приема масива, описващ звуковия откъс и го преобразува в масив с комплексни числа, показващи честотите. Този минималистичен подход работи много добре. Сравнението на този Java алгоритъм с Octave показва едни и същи резултати. А това е предостатъчно.

Използването на xcorr в стрийминг предаванията

Представеният по-горе алгоритъм предполага, че audio е някакъв масив, в който търсим jingle. Но това не е подходящо за стрийминговите предавания на радиата. За да се анализира подобен поток е достатъчно използването на цикличен буфер с малко по-голям от джингъла размер. Входният поток запълва буфера и след като бъде запълнен се стартира теста за крос-корелацията. Ако нищо не бъда намерено, най-старата част на буфера се премахва. След това той се запълва отново.

Експериментите показват, че най-добри резултати се получават когато размерът на буфера е 1,5 пъти по-голям от размера на джингъла.

Обединяваме всичко на едно място

Да се преобразува радио стрийма в PCM формат също не е сложно. Това отново може да стане с помощта на ffmpeg. Показаната по-долу команда прехвърля аудиопотока към стандартния Java вход и след това извежда Got jingle 0 или Got jingle 1, когато в потока бъде открит съответния образец.

ffmpeg -loglevel -8 \
-i http://stream3.polskieradio.pl:8904/\;stream \
-f s16le -acodec pcm_s16le - \
| java -jar target/analyzer-1.0.0-SNAPSHOT-jar-with-dependencies.jar \
2 \
src/test/resources/commercial-start-44.1k.raw 500 \
src/test/resources/commercial-end-44.1k.raw 700

Автономната версия

Вече е готова несложна автономна версия на анализатора, която самостоятелно се включва към потока на „Тройката“ (без да се използва външен ffmpeg), като резултатът се извежда с помощта на javax.sound. Всичко е събрано само в един JAR и съдържа съвсем базов интерфейс с бутони Start и Stop. Файлът може да бъде изтеглен оттук. А ако не обичате да стартиране на своите устройства чужди jar файлове (което е съвсем правилно), то можете да вземете сорс кодовете от GitHub.

Полски специалист създава AdBlock за радиото (Radio AdBlock)

Изглежда, че всичко работи както трябва.

Следващи цели

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

 


Програмата на Томек Рекавек за блокиране на рекламата в различните аудио потоци, както и хардуерния блокатор на реклами за произволен аудиосигнал, предизвикаха изключителен интерес сред потребителите, който не стихва и до днес. Простотата на алгоритъма и неговата съвсем лесна реализация повдигнаха интересни въпроси относно създаването на подобни блокатори не само за радио, но и за телевизионните предавания. При това не само за блокиране на звука, но и на изображението по време на рекламния блок.

Обсъждане на темата в Hacker News
Разглеждане на темата във Wykop
Обсъждане на темата в Reddit

АбонаментВсичко важно от света на технологиите, директно в пощата ти.

С абонирането приемате нашите Условия и Политика за поверителност. Може да се отпишете с един клик по всяко време.


Коментирайте статията в нашите Форуми. За да научите първи най-важното, харесайте страницата ни във Facebook, и ни последвайте в Google Новини, TikTok, Telegram и Viber или изтеглете приложението на Kaldata.com за Android, iPhone, Huawei, Google Chrome, Microsoft Edge и Opera!

8 Коментара
стари
нови оценка