Помощь с алгоритмом распознавания ритма НЧ в музыке
- Войдите на сайт для отправки комментариев
Приветствую всех. Есть макетка с arduino nano, лентой WS2812 и MSGEQ7. Всё это представляет из себя светомузыку. Хотелка такая: сделать так, чтобы ардуино распознавала партию ударов, например, чтобы на основе этого сделать визуализацию гораздо разнообразнее и ритмичнее.
Теперь к деталям. Музыка подаётся на установку по 3,5 mm jack. Приходя в MSGEQ7, звук разбивается на 7 частот, по 255 значений на частоту. То есть, каждая из 7 частот, в зависимости от её громкости в программе видится значением от 0 до 255. Если взять низкие частоты и вывести в монитор порта, то на многих треках можно заметить интересную картину:
Последовательность ударов (я пронумеровал пики) очень явно прослеживается, а значит, можно написать и код, который бы это всё отслеживал и управлял, к примеру, переменной boolean. Идёт удар №1, за ним №2, алгоритм видит что за №1 идёт №2, что это последовательность одинаковых ударов и пока эта последовательность будет одинакова, при КАЖДОМ ударе (наступлении пика, как на графике), №3,4,5,6 выдаётся nizDetected == true и в конце loop обнуляться будет до false. До этого момента можно будет что-то включить или переключить и всё в таком духе.
Проблемы:
1.Каждый удар имеет разную высоту на графике. Нужно как то или приводить всё к одной или ещё чего-то.
2.В диапазоне значений частоты от 0 до 40 может быть полная каша. На графике ещё ничего, до значения, примерно 30, имеются мелкие пики, никак не связанных друг с другом. Могут случаться и большие пики, как, например, между 7 и 8 на графике или между 5 и 6. Всё это нужно упорно игнорировать.
3. Т.к. это светомузыка и её реакция должна быть как можно более быстрой, нельзя принимать решение, засчитывать этот пик как удар или нет уже после прохождения пика. То есть, алгоритм может смотреть что идёт ДО, вот настал пик и должно именно в этот момент приняться решение, удар это или нет, после уже нужно ждать следующий пик.
Из моментов, которые могут помочь в опознавании. Удары хорошо видно, как мы уже разобрались по графику. Так же, есть ещё одна особенность, между ударами всегда практически одинаковое расстояние, +-5%, то есть, они всегда звучат через фактически одинаковое время.
Любым идеям и мыслям как решить хотя бы одну из описанных проблем буду рад и очень сильно благодарен =).
Лента жа поддерживает некоторый корректируемый диапазон яркости. Можно привязать яркость к уровню сигнала заданной частоты. Чем выше пик, тем ярче лента вспыхивает. Будет банально, но прикольно))
Ну, и как бонус, не нужно никаких переменных "типа boolean", в которых вы судя по всему не очень. Код вообще в 1 строку можно уложить
А еще можно заморочиться сделать продвинутую "мигалку" на анализе остальных частотных диапазонов. Например можно замутить плавное изменение цвета при изменении уровней смежных диапазонов.
Лента уже и так реагирует на громкость. Но это скучно и банально, все имеющиеся сейчас светомузыки это умеют. Мне нужно не просто "чем выше громкость, тем ярче горит", а чтобы ардуина именно что распознавала удары и как то реагировала на них, например, переключала эффекты, сменяла свет ленты или что-то ещё.
Комбинация реакций на разные частоты тоже уже реализована. Даже больше, уже написан алгоритм распознавания, но работает он пока не сказать что как хотелось бы =). Вот демонстрация работы: https://www.youtube.com/watch?v=_3Oq1TF8Ufc&ab_channel=AkkSergey
Лента уже и так реагирует на громкость. Но это скучно и банально, все имеющиеся сейчас светомузыки это умеют. Мне нужно именно не просто "чем выше громкость, тем ярче горит", а чтобы ардуина именно что распознавала удары и как то реагировала на них, например, переключала эффекты, сменяла свет ленты или что-то ещё.
Ну тогда считывайте уровень в uint8_t и реагируйте на достижения порогового значения. Правда придется допилить алгоритм обнаружения пиков, то-есть когда уровень сигнала достиг локального максимума и начал значительно снижаться. Это не сложно
У вас на графике нифига не видно отметок на оси, но и так ясно, что пик можно считать состоявшимся если сигнал превысил примерно 2/3 диапазона то-есть 160-170
Ну тогда считывайте уровень в uint8_t и реагируйте на достижения порогового значения. Правда придется допилить алгоритм обнаружения пиков, то-есть когда уровень сигнала достиг локального максимума и начал значительно снижаться. Это не сложно
У вас на графике нифига не видно отметок на оси, но и так ясно, что пик можно считать состоявшимся если сигнал превысил примерно 2/3 диапазона то-есть 160-170
Я писал об этом в проблеме №1. Суть в том, что уровни пиков могут быть как 80, так и, условно, 200, в зависимости от трека. К тому же, каждый пик отличается по громкости от остальных. То есть, первый пик будет 80, второй 60, третий 120, четвёртый 140 и так далее. А если вспомнить, что есть паразитные пики, которые НЕ нужно распознавать, как между 7 и 8 пиками, то вообще не вариант.
P.S. Загрузил графики на фотохостинг, там разрешение выше: https://imageban.ru/show/2021/03/01/bd7e0d07e9d3da0e428362bdd365856a/jpg
Я одного не пойму, зачем здесь вообще микроконтроллер?
Все хотелки прекрасно реализуются при помощи простых аналоговых цепей.
Я одного не пойму, зачем здесь вообще микроконтроллер?
Все хотелки прекрасно реализуются при помощи простых аналоговых цепей.
И управление WS2812?
Я одного не пойму, зачем здесь вообще микроконтроллер?
Все хотелки прекрасно реализуются при помощи простых аналоговых цепей.
Ну, хотя бы потому что в схеме задействованы MSGEQ7 и лента WS2812. Или это был тонкий сарказм? Тогда ладно =).
Например, почему пики №№7 и 8 - это удары, а пик между ними примерно такой же высоты - не удар? По каким критериям Вы предлагаете их отличать?
Очень просто, пик №7 находится от пика №6 на расстоянии L, пик №8 находится от пика №7 на таком же расстоянии L (я говорил, что между ударами всегда одинаковое расстояние). Паразитный пик между 7 и 8 по расстояниям не сходится с L, по этому его можно игнорировать. Например, как то так.
Это слишком
Попробуйте строго описать Ваш критерий и сразу поймёте, что формально описать свои "как-то" Вы не сможете. Взять хотя бы Вашу L. Чтобы её определить, Вам надо сначала прокрутить мелодию (или несколько пиков).
Или Вы хотите заранее строго определять что именно ищете и эту L жёстко задавать? Нет, ведь
Чтобы её определить, Вам надо сначала прокрутить мелодию (или несколько пиков).
Совершенно верно. Я вроде нигде не ставил задачей определять КАЖДЫЙ удар (пик), задача была определить ПОСЛЕДОВАТЕЛЬНОСТЬ ударов, найти ритм. Определяем пик №1, после него считаем время до наступления пика №2, записываем, затем снова считаем время до наступления пика №3, попутно смотря, какое оно получилось, если оно схоже с временем от №1 до №2, удар засчитан, а дальше уже каждый пик мониторим время между ними и сравниваем. Первые два пика уйдут на анализ и распознаваться не будут, но это будет только один раз, пока в памяти нет вообще никакого времени. Можно записывать сработавшее время в буфер, например и сравнивать его в дальнейшем.
И управление WS2812?
Ну, хотя бы потому что в схеме задействованы MSGEQ7 и лента WS2812. Или это был тонкий сарказм? Тогда ладно =).
Это не сарказм. Это - наводящий вопрос.
А навести он должен был на простую мысль, что следует выкинуть из схемы MSGEQ7 и использовать вместо него нормальные аналоговые фильтры. Тогда не нужно будет чесать репу, как отделить "правильные" пики от "неправильных".
"Управление ws2812" - это не задача, это - вариант реализации.
Так предложите, как проанализировать музыку в реальном времени без микроконтроллера, на чисто аналоговой базе. Распознать удары, сделать различные эффекты вывода визуализаций.
следует выкинуть из схемы MSGEQ7 и использовать вместо него нормальные аналоговые фильтры. Тогда не нужно будет чесать репу, как отделить "правильные" пики от "неправильных".
С аналоговыми фильтрами я работал и MSGEQ7, если он не из числа 90% подделок на рынке конечно, работает на порядок лучше, и места занимает неприлично меньше. Да, её многие срут, потому что как раз попались на подделки, да я сам 5 раз заказывал эти микрухи, пока нормальная не попалась. Неправильные пики это часть звука (различные призвуки, гармоники, гугл в помощь в общем если интересно), а не помехи, если речь об этом. Есть треки, где идут чистые, исключительно правильные пики без лишнего, но это идеальные условия, а есть такие, как я показал, что реальность. Музыка, это, знаете ли, полная каша, поток воды, из которой наша задача выудить нужное.
"Управление ws2812" - это не задача, это - вариант реализации.
Так предложите, как проанализировать музыку в реальном времени без микроконтроллера, на чисто аналоговой базе. Распознать удары, сделать различные эффекты вывода визуализаций.
Если анализировать будете Вы, то предложить я, конечно, могу.
Для начала собрать фильтр типа такого:
и настроить его так, чтобы не было лишних пиков.
Сигнал брать с выхода U3 или U4 (проверить и то, и то).
и настроить его так, чтобы не было лишних пиков.
Это невозможно. В звуке на определённых частотах всегда есть какие то отзвуки или гармоники с частот соседних, да даже сам удар может отдавать чем то, там не будет чисто того, что нам нужно, какой бы фильтр не использовался. Разве что брать фильтр, который разбивает звук на большое количество полос, не 4 или 7 широких полосы, а 20-50 или больше узких полос, тогда может получиться чего.
Неправильные пики это часть звука (различные призвуки, гармоники, гугл в помощь в общем если интересно)
Вы бы хоть сами почитали, что такое гармоники.
Это невозможно. В звуке на определённых частотах всегда есть какие то отзвуки или гармоники с частот соседних, да даже сам удар может отдавать чем то, там не будет чисто того, что нам нужно, какой бы фильтр не использовался. Разве что брать фильтр, который разбивает звук на большое количество полос, не 4 или 7 широких полосы, а 20-50 или больше узких полос, тогда может получиться чего.
Давайте не будем подменять одну задачу другой.
У нас в принципе нет задачи разбивать звук на какое бы то ни было количество полос. У нас задача - выделить ритм. В данном случае - бочку. Вот на нее и надо настраивать фильтр. Причем, совершенно не исключено, что добротность этого фильтра будет выше, чем у 10- или даже 30-полосного фильтра. Нам не нужны широкие полосы, нам нужен фильтр, куда кроме бочки ничего не попадает.
PS. И еще: Вы уже второй раз ошибочно упоминаете гармоники. Желательно не употреблять слова, смысл которых не понимаешь.
ну раз у ТС уже цифровая схема собрана, почему бы не попрограммировать.
У нас в принципе нет задачи разбивать звук на какое бы то ни было количество полос. У нас задача - выделить ритм. В данном случае - бочку. Вот на нее и надо настраивать фильтр. Причем, совершенно не исключено, что добротность этого фильтра будет выше, чем у 10- или даже 30-полосного фильтра. Нам не нужны широкие полосы, нам нужен фильтр, куда кроме бочки ничего не попадает.
После многомесячного анализа музыки, могу смело заявить, что выделить что-то конкретное, особенно в электронной музыке, которой сейчас большинство, это задача для программиста 99+ левела. Там всё настолько плавает на басовой партии и с этой бочкой может столько всего звучать совместно... В общем, мы просто принимаем как факт, что значения до 30-40 будут всегда с какой то сранью и от этого не отделаешься.
А задача наша, распознать ритм в каше, причём именно ритм, одинаковые партии, которые могут звучать не только от бочки, а не выделить чисто бочку. Этот же алгоритм потом можно будет попробовать использовать для ВЧ. Что же, там тоже аналоговый фильтр крутить? Не, слишком муторно.
ну раз у ТС уже цифровая схема собрана, почему бы не попрограммировать.
Вот, наконец то понимающие люди. Я прошу помощи с алгоритмом, так давайте обсуждать программирование, а не переделывать схемотехнику. А то уже нам и MSGEQ7 не то и зачем микроконтроллер, и WS2812 это лишь вариант реализации...
В общем, мы просто принимаем как факт, что значения до 30-40 будут всегда с какой то сранью и от этого не отделаешься.
ну раз у ТС уже цифровая схема собрана, почему бы не попрограммировать.
Вот, наконец то понимающие люди.
30-40 - это чего?
Значения сигнала. В первом посте я писал, что каждая частота (из семи), приходящая с MSGEQ7, представляет собой, в зависимости от громкости, значение от 0 до 255. Значения от 0 до 30-40, чисто по статистике прослушивания музыки на этой системе, содержат в себе много срани.
30-40 - это чего?
Значения сигнала. В первом посте я писал, что каждая частота (из семи), приходящая с MSGEQ7, представляет собой, в зависимости от громкости, значение от 0 до 255. Значения от 0 до 30-40, чисто по статистике прослушивания музыки на этой системе, содержат в себе много срани.
найти ритм.
Попробуйте у ранних Prodigy найти ритм через "расстояние L"(TM). А то, что ищете вы - это не ритм. Это метр.
Опять в восьмибитный микроконтроллер пытаемся всунуть нейросеть...
Я не понимаю, что такое "значения сигнала". Нет такого технического термина. Можете объяснить, используя общепринятую терминологию?
Да в гугле посмотрите, а заодно где находится ближайшая баня.
ок. не лезу.
Я не про это... Какой то ты стал не такой.... Надеюсь все нормально.
Да в гугле посмотрите, а заодно где находится ближайшая баня.
По логике вещей вам бы тоже лучше гуглу свои вопросы задавать с такой манерой обращения. Вы не отвечаете нормально по существу на конкретно поставленные вопросы а требуете алгоритм воплощения своих смутных фантазий. А про баню.. Банная команда уже отметилась в теме...
Я не понимаю, что такое "значения сигнала". Нет такого технического термина. Можете объяснить, используя общепринятую терминологию?
Да в гугле посмотрите, а заодно где находится ближайшая баня.
По логике вещей вам бы тоже лучше гуглу свои вопросы задавать
Да я уже понял, что лучше было так и сделать, чем спрашивать что-то на этом форуме. Кроме вас, за что спасибо, вообще никаких предложений никто так и не выдвинул. Только что всё не так, да контроллер вообще не нужон, хотя нет, это же вообще нереальная задача оказывается, тут нейросети нужны, не меньше, какая там ардуина.
а требуете алгоритм воплощения своих смутных фантазий.
Ну вот, теперь я ещё и требую. Какой же я гадкий тип, однако.
Кстати, AkkSergey, вот еще причина, по которой все всегда будет работать не так, как вам это представляется. Ваши "удары" - не сферические в вакууме, а вполне себе имеют конкретный частотный диапазон. Я не нашел в даташите точных характеристик крутизны, но судя о картинке, максимальная чувствительность находится в очень узком частотном диапазоне и резко уменьшается по обе стороны от опорного значения. Иными словами, при одиноковой громкости воспроизведения, фильтр на опорной частоте 63гц (видимо это и есть ваши "удары") будет хорошо слышать только Си контроктавы и до большой октавы. Уже в секунду в каждую сторону уровень "удара" будет существенно ниже, а в терцию или кварту - процентов на 30. А в реальной музыке, я подозреваю, "удары" не строго на 63гц. Иными словами, ничего более вменяемого, чем просто отлов уровней выше заданного вы на этой железке не сделаете.
Иными словами, ничего более вменяемого, чем просто отлов уровней выше заданного вы на этой железке не сделаете.
Ну да, а мой существующий алгоритм, идей для улучшения которого я и пришёл сюда набрать, это плод моего воображения. Да и американцы, сделавшие стартап Visual Vibes https://www.youtube.com/watch?v=Tqca7houeEc&ab_channel=VisualVibes, светомузыки, на лету анализирующему музыку, в начале разработки которого первоначальная макетка была именно на ардуино нано, это тоже дудки.
Ладно, тема закрыта товарищи, всё ясно с вами. Расходимся, спасибо за внимание.
Ну так поклянчите там алгоритм тогда. Чего тут то время терять с деревенскими высечками
Ну да, а мой существующий алгоритм, идей для улучшения которого я и пришёл сюда набрать, это плод моего воображения.
Да и американцы, сделавшие стартап Visual Vibes https://www.youtube.com/watch?v=Tqca7houeEc&ab_channel=VisualVibes, светомузыки, на лету анализирующему музыку, в начале разработки которого первоначальная макетка была именно на ардуино нано, это тоже дудки.
А что, американцы использовали в этом проекте именно MSGEQ7?
И я что-то не заметил, что они как-то выделяют метр.
Ладно, тема закрыта товарищи, всё ясно с вами. Расходимся, спасибо за внимание.
У меня есть интересная микросхема MSGEQ7. Хочу использовать ее не по назначению, но не знаю, как. Подскажите.
То вряд ли следовало ее и открывать.
Проблема Вашей "идеи" именно в том, что Вы думаете как приспособить неподходящее железо к Вашей задаче, вместо того, чтобы уделить внимание именно адекватному подбору железа под задачу.
Да и задача как то неадекватно поставлена. MSGEQ7 это просто 20 дБ эквалайзер выделяющий полосы и выдающий результат в виде импульсов напряжения через мультиплексор с частотой 20 кГц на канал. Дальше можно этот сигнал конечно превратить в непрерывный и отследить пики. Но что мешает сразу цифровать, делать Фурье-анализ и сразу получать пики. Тем более, что тот же удар по барабану или по басовой струне сопровождается всегда щелчком с кучей высоких частот и анализ звука без этих компонент = гадание на кофейной гуще. Профили FFT спектров инструментов известны. Можно тот же барабан фильтровать с нормировкой и получать ритм независимо от амплитуды сигнала. Не знаю про уну, а блакпилы справятся с этой задачей.
MSGEQ7 это просто 20 дБ эквалайзер
Полосовой фильтр
Чтобы её определить, Вам надо сначала прокрутить мелодию (или несколько пиков).
Совершенно верно. Я вроде нигде не ставил задачей определять КАЖДЫЙ удар (пик),
Точно? А вот здесь?
Тут в соседней теме сказали, что я тупой и не могу понимать прочитанное. Наверное, правы.
А вообще, Вы зря пренебрегаете моим советом
Попробуйте строго описать Ваш критерий
Сделали бы это, глядишь, Вас бы кто-нибудь понял.
Не. Эквалайзер таки MSGEQ7. Там детектор пиковый на каждом частотном канале на выходе.
Ну то херня. Задача ТС решается так. БПФ по входу (можно конечно оставить и MSGEQ7, но уж больно он убогий). Полученный с выхода спектр рассматриваем как набор отсчетов сигналов, каждая частота - свой канал сигнала. Выбираем несколько с большими уровнями. К каждому выбранному каналу снова БПФ. На выходе - спектр ритмов для частоты этого канала. При этих вторичных БПФ активно пользуем тот факт, что ритм не будет больше пары герц. Ну и снова выбираем с большим уровнем.
Не. Эквалайзер таки MSGEQ7. Там детектор пиковый на каждом частотном канале на выходе.
Эквалайзер предполагает вмешательство во внешний сигнал и его регулирование. А здесь просто тупой полосовой фильтр с хорошей крутизной + пиковый детектор
MSGEQ7 это просто 20 дБ эквалайзер
Полосовой фильтр
Совершенно согласен. Недописал что основное предназначение фильтр дисплея эквалайзера, вот и получил исправления. А так, как моргалка светодиодиками сойдёт, как источник для последующей обработки - очень сомнительно.
Задача ТС решается так. БПФ по входу (можно конечно оставить и MSGEQ7, но уж больно он убогий). Полученный с выхода спектр рассматриваем как набор отсчетов сигналов, каждая частота - свой канал сигнала. Выбираем несколько с большими уровнями. К каждому выбранному каналу снова БПФ. На выходе - спектр ритмов для частоты этого канала. При этих вторичных БПФ активно пользуем тот факт, что ритм не будет больше пары герц. Ну и снова выбираем с большим уровнем.
Но не внемлет.
Не. Эквалайзер таки MSGEQ7. Там детектор пиковый на каждом частотном канале на выходе.
Эквалайзер предполагает вмешательство во внешний сигнал и его регулирование. А здесь просто тупой полосовой фильтр с хорошей крутизной + пиковый детектор
А фильтр не должен вносить искажение сигнала в полосе пропускания. С пиковым детектором это не совместимо.
Кстати в даташите первой строкой
Seven Band Graphic Equalizer
https://www.sparkfun.com/datasheets/Components/General/MSGEQ7.pdf
Задача ТС решается так. БПФ по входу (можно конечно оставить и MSGEQ7, но уж больно он убогий). Полученный с выхода спектр рассматриваем как набор отсчетов сигналов, каждая частота - свой канал сигнала. Выбираем несколько с большими уровнями. К каждому выбранному каналу снова БПФ. На выходе - спектр ритмов для частоты этого канала. При этих вторичных БПФ активно пользуем тот факт, что ритм не будет больше пары герц. Ну и снова выбираем с большим уровнем.
Та кто его знает, что его устроит..
Ну даффай пример посмотрим. Бемкнул барабан. Это ритм? Конечно нет. Бемкнул второй раз через 0,5сек. Уже ритм? нет. Бемкнул третий раз, снова через 0,5сек. Да наверно это ритм раз повторяется. Тут от алгоритма обработки не зависит вообще. Ритм по первому удару нельзя выявить никак.
Но можно схитрить. Ввести для основного звукового канала линию задержки на время обработки "ритмовыявителя". Там тоже проблем будет, но думаю и так достаточно ясно что ТС не потянет такую задачу.
Вот и я пишу о том же: ТС наблюдает целостную картину на графике и только при этом, своим трехкиллограммовым мозгом, может выделить какие-то пики, которые являются "правильными" по его собственному мироощущению, сформированному прослушиванием сотен однотипных композиций.
И при этом хочет чтобы 8-битный контроллер прямо с пустой страницы начал в рилтайме безошибочного вылавливать из потока событий устойчивые последовательности, ориентируясь на какие-то невербализованные критерии.
Это как раз работка для нейросети, а не для "blink без delay" на Ардуине.