Pull to refresh

Comments 26

Баловался с голосовым управлением для «умного дома».

Сделал примитивный скрипт, который записывал 3-секундные ролики и отправлял их на сервера Google. Все работает… но бесплатно декларируется около 50 распознаваний в день. При этом мой скрипт долго и упорно крутится до получения «кодового слова» (после которого, собственно, и идет команда). Надо будет попробовать прикрутить описанное для оффлайн-декодирования «кодовой последовательности» (а потом уже можно реальную команду на сервера Google отправлять на распознавания).

Должно получиться довольно компактно и «прозрачно»,
Мне кажется то, что описано в статье, вряд лм — тут распознавание основано на том, что в записи с помехами/фоном/искажениями все равно сохраняются частоты и тайминг, а в голосе вряд ли это так?
Могу посоветовать использовать движок Sphinx, он работает offline, в том числе для русского, и на небольшом словаре у него хорошая точность.
В домашних условиях, думаю, помехи/фоновые звуки/искажения — тоже присутствуют… а частоты и тайминги — да, плавают, наверняка… но в целом, сохраняются.

За дополнительную наводку — спасибо, тоже попробую.
Я так понял, что данный подход позволяет найти заданный отрезок в зашумленной записи?

Будет ли это работать если я хочу просто найти похожие записи?
Да, все правильно.
По поводу поиска похожих записей — это зависит от того, чем определяется похожесть. Если это например ремиксы или разные версии одной песни, то да, на них у нас как раз было много «ложных» срабатываний. Но допустим одну и ту же песню исполненную немного в разном темпе такой алгоритм не найдет, нужно уже усложнять.
>Если это например ремиксы или разные версии одной песни, то да, на них у нас как раз было много «ложных» срабатываний.

не понял, вы же вроде искали рекламу.

Насчёт похожести, да, это вопрос как определить, какие есть подходы?

В идеале хотелось бы систему которая использует не колаборативную фильтрацию(рекомендательная система) аля last.fm, а использует data-driven подход, т.е. по самому контенту музыкальному.

Из более реального, то что приходит на ум в первую очередь это типа нечеткие дубликаты: например студийная запись песни и запись песни с концерта, второе это одна и та же музыка, но слова разные, типа переделка как пример:
www.youtube.com/watch?v=DW5icEb5nk4
www.youtube.com/watch?v=6PDmZnG8KsM
> не понял, вы же вроде искали рекламу

Да, в этом посте больше про рекламу, но песни мы тоже искали.

data-driven подход к рекомендациям звучит очень заманчиво, да! Интересно, как это можно сделать.
Про студийную/концертную запись сходу не отвечу, нужно попробовать — сложно сказать насколько они в плане темпа точно совпадать будут.

В целом то подход который описан очень ограничен, зато простой.
Вот тут кратко перечислены методы events.yandex.ru/lib/talks/1809/
Описанный в статье не подойдет — он полагается на частоты и временной интервал между ними, которые в разных исполнениях будут слегка разные, а нужно полагаться на ноты.
Не уверен, что здесь (в задаче про рекламу на радио) переход к частотному представлению вообще к месту. Попробуйте погонять мой скрипт, который основан на скалярных произведениях во временном представлении. Он всегда «находит» искомый звук в анализируемом, но сообщает уровень зашумленности. Если SNR мало, то следует считать, что звук на самом деле не найден. Недостаток — сбивается на малейшем растяжении времени, но на радио это вроде как просто не может быть.

Скрипт можно гонять в трех режимах. Режим --this ищет фрагмент, который имеет минимальную сумму квадратов отличий от искомого. --similar = поиск фрагмента, который после домножения на определенную константу будет иметь минимальную сумму квадратов отличий от искомого (т.е. игнорируется изменение амплитуды). --like = поиск фрагмента, который имеет максимальное скалярное произведение с искомым (т.е. игнорируется аддитивный шум и изменение амплитуды).
Попробовал сам — в вашем примере мой скрипт находит рекламу правильно, но с плохим SNR. Если оставить от нее только первую секунду — работает лучше. Т.е. похоже, что раcтяжение таки есть.

Еще добавил графики correlation_at, cos2phi_at и difference_norm_at, и видно, что вторая метрика (квадрат косинуса угла между векторами из семплов) в вашем случае является наиболее надежной.
Очень интересно, спасибо! Насколько я понял, существенную часть работы делает scipy.signal.fftconvolve — но я пока не смог понять интуитивно, как и почему он работает при анализе двух звуковых фрагментов. Не знаете, где про это можно почитать?
Это просто свертка. Прочитать про нее можно в Википедии.

Интуитивно ее можно понять так. Свертка двух сигналов — это функция, которая принимает один аргумент (величину сдвига) и возвращает скалярное произведение одной функции на обращенную во времени и сдвинутую на указанный интервал другую. Ее можно быстро посчитать с помощью преобразования Фурье, поскольку образ Фурье от свертки является произведением образов Фурье от сворачиваемых функций. Т.е. в данном случае fftconvolve — это просто способ посчитать скалярные произведения образцового сигнала и записи, в которой его ищем, быстро и сразу для всех возможных значений сдвига.

Теперь почему это работает (в варианте --like).

Предположим, мы угадали правильный сдвиг. Тогда в каждый момент времени оба сигнала будут иметь одинаковый знак, их произведение будет положительным, а скалярное произведение двух сигналов является просто суммой их произведений во все моменты времени и поэтому будет большим положительным. Если же не угадали — будет примерно одинаковое количество положительных и отрицательных слагаемых, и сумма не будет сильно отличаться от нуля.

Варианты --this и --similar так интуитивно не объяснить, но соответствующие критерии довольно просто переписываются через всякие скалярные произведения сдвинутых сигналов и скалярные квадраты фрагментов сигнала, т.е. через быстрые операции.
Если образец один, то особых проблем нет — ищи себе взаимную корреляцию как вы, и все довольны — устойчивее сложно придумать на самом деле. Но когда образцов тысячи, то сложность O(n) уже не подходит и нужна индексация, которую с корреляцией не построишь. И тут подход с поиском «интересных точек» и обратным индексом {частота_интересной_точки => имя_файла} позволяет ускорить поиск до приемлемых величин. То есть мы находим «интересные частоты» в звуковом потоке и ищем файлы, которые эти частоты содержат, в индексе, а далее выбираем файл, содержащий наибольшее число интересных точек.

Лучший подход — комбинированный. Сначала отфильтровать обратным индексом до пары десятков-сотен кандидатов, а потом посчитать честную корреляцию (лучше на GPU). В массовых приложениях типа Shazam такой подход не используют, чтобы не грузить серверы.

Такую штуку легко построить на основе Echoprint, отредактировав его python api в части отбора лучших кандидатов.
Там в качестве поиска по индексу используется банальный текстовый поиск с помощью Apache Solr. Чем больше «интересных точек», тем выше Solr ранжирует «документ». Solr выдает большой список кандидатов, содержащих интересные точки. Далее в github.com/echonest/echoprint-server/blob/master/API/fp.py#L143 из этих кандидатов выбирается лучший. Каким образом? Таким github.com/echonest/echoprint-server/blob/master/API/fp.py#L262 — то ли строится гистограмма как в статье, то ли еще как, нужно читать код, я уже не помню. Но это не важно. Ничто не мешает или самому делать запросы к Solr или же переписать best_match_for_query, добавив туда «временную» корреляцию, доставая wav образца откуда-нибудь из базы (так как сам echoprint хранит только отпечатки). В итоге поменяв сотню строчек отбора кандидатов, и без написания своего codegen и API, можно получить систему, удобную лично для себя.
Именно так и работает шазам и другие подобные серсисы поиска музыки, да и похожая статья с описанием этого алгоритма уже была (вроде) на хабре
Полезно, спасибо.
Думаю, что если развить алгоритм до состояния, которое позволяет еще и сопоставлять отпечатки, растянутые по времени, то так можно дойти и до распознавания напетых мелодий. Но в любом случае скорость распознавания уже не будет такой высокой и будет много ложных срабатываний.
Кстати, в большинстве программ для ведения радийного эфира, есть подобная функция распознавания рекламной аудиометки. Используется это в основном на региональных радиостанциях, которые ретранслируют эфир своего партнёра ( к примеру какой-нибудь столичной радиостанции).
По этим аудиометкам, во время рекламных блоков происходит автоматическое переключение ретрансляции на свой эфир, для запуска уже своей региональной рекламы.
Задавался как-то вопросом автоматического переключения ТВ на другой канал в начале рекламного блока путём анализа характерного повышения громкости с участием Arduino. Идея так и осталась идеей. Интересно, а есть ли в ТВ эфире подобные радио метки?
Да, для ТВ эфира это тоже есть. Работает аналогично тому, что я писал выше о FM эфирах.
Я немного не корректно выразился. Интересует даже не эфирное, а спутниковое ТВ. А также интересно, как выявить такие метки (эталонные аудио фрагменты), если они заранее не известны. Визуальный анализ спектра, строить предположения? Есть ли какой-то единый стандарт для всех ТВ операторов и регламентируется ли его соблюдение? Читал также, что иногда используются метки видеоряда, а значит аудио метки могут отсутствовать. Наверняка это служебная информация без публичного доступа?
Насчёт выявления таких меток — как обстоит дело с ТВ, я не знаю (хотя подозреваю, что всё-таки аналогично радиоэфиру). А что касается меток на радио — единого стандарта не существует. Это может быть как характерный короткий «пик», так и целая звуковая отбивка. Принцип такой: та станция, которую вы будете ретранслировать, присылает вам свои сэмплы аудиометок и вы уже у себя заливаете эти сэмплы в базу программы-ретранслятора.
Ну да, это если я собираюсь ретранслировать. А если мне просто хочется избавить себя от каких-либо рекламных блоков? :) Тогда, получается, только визуальный анализ…
Да, остаётся только анализировать аудио или видео ряд перед рекламным блоком. И ещё нюанс: актуальных меток может быть несколько и они периодически меняются.
Однажды делали для оператора приблуду для контроля и подсчета рекламных роликов по тв и радио. Было требование, чтобы дешево и сердито. Сошлись на варианте, что во всех роликах будут тональные сигналы, а их распознавание — тривиальная задача.
Аналог tophit.ru для песен (ну и moskva.fm, как же без неё) и admonitor.ru для рекламы?
Подобная функция уже была реализована уже в некоторых программах для радио, в частности — в вещательной программе Synadyn питерской компании Digiton.
Only those users with full accounts are able to leave comments. Log in, please.