Ударов в минуту от аудио входа в реальном времени

Я хотел бы написать простое приложение на C#, чтобы отслеживать линейный звук и давать мне текущие (ну, скользящее среднее) удары в минуту.

Я видел эту статью от gamedev, и это абсолютно не помогло. Я прошел и попытался реализовать то, что он делал, но это просто не работало.

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

8 ответов

Рассчитать PowerSpectrum с помощью скользящего окна FFT: взять 1024 образца:

double[] signal = stream.Take(1024);

Поток к алгоритму БПФ:

double[] real = new double[signal.Length];
double[] imag = new double[signal.Length);
FFT(signal, out real, out imag);

Вы получите реальную часть и воображаемую часть. НЕ выбрасывайте мнимую часть. Сделайте то же самое с реальной частью воображаемого. Хотя это правда, что мнимая часть не совпадает с действительной, она все еще содержит 50% информации о спектре.

РЕДАКТИРОВАТЬ:

Рассчитайте мощность в противоположность амплитуде, чтобы иметь большое число, когда оно громкое, и близко к нулю, когда тихо:

for (i=0; i < real.Length; i++) real[i] = real[i] * real[i];

Аналогично для мнимой части.

for (i=0; i < imag.Length; i++) imag[i] = imag[i] * imag[i];

Теперь у вас есть спектр мощности для последних 1024 образцов. Где первая часть спектра - это низкие частоты, а последняя часть спектра - это высокие частоты.

Если вы хотите найти BPM в популярной музыке, вы должны сосредоточиться на басу. Вы можете подобрать интенсивность низких частот, суммируя нижнюю часть спектра мощности. Какие цифры использовать, зависит от частоты дискретизации:

double bassIntensity = 0;
for (i=8; i < 96; i++) bassIntensity += real[i];

Теперь сделайте то же самое снова, но переместите окно на 256 сэмплов, прежде чем вычислять новый спектр. Теперь вам нужно рассчитать bassIntensity для каждых 256 сэмплов.

Это хороший вклад в ваш анализ BPM. Когда бас тихий, у вас нет ритма, а когда он громкий, у вас есть ритм.

Удачи!

Есть отличный проект под названием Dancing Monkeys, который процедурно генерирует танцевальные шаги DDR из музыки. Большая часть того, что он делает, основана на (обязательно очень точном) анализе ударов, и в их проектной статье подробно описываются различные алгоритмы обнаружения ударов и их пригодность для выполнения задачи. Они включают ссылки на оригинальные статьи для каждого из алгоритмов. Они также опубликовали код Matlab для своего решения. Я уверен, что среди них вы можете найти то, что вам нужно.

Это все доступно здесь: http://monket.net/dancing-monkeys-v2/Main_Page

Не то чтобы я имел представление о том, как это реализовать, но с точки зрения звуковой инженерии, вам нужно сначала отфильтровать. Хиты басового барабана будут первыми проверять. Фильтр низких частот, который дает вам частоту ниже 200 Гц, должен дать вам довольно четкое представление о басовом барабане. Ворота также могут быть необходимы для очистки любого беспорядка от других инструментов с такими низкими гармониками.

Следующей проверкой будут хитрые удары. Вы должны были бы эквалайзер этого. "Трещина" в ловушке составляет около 1,5 кГц от памяти, но вам, безусловно, нужно ограничить это.

Следующей задачей было бы разработать алгоритм для броских ударов. Как бы вы программно нашли ритм 1? Я предполагаю, что вы будете отслеживать предыдущие доли и использовать шаблон, соответствующий чему-то или другому. Итак, вам, вероятно, понадобится несколько тактов, чтобы точно найти ритм. Тогда есть проблемы времени, такие как 4/4, 3/4, 6/8, вау, я не могу себе представить, что потребуется для того, чтобы сделать это точно! Я уверен, что это будет стоить серьезных денег компаниям, производящим аудио / аппаратное обеспечение.

Это ни в коем случае не простая проблема. Я постараюсь дать вам только обзор.

Что вы можете сделать, это что-то вроде следующего:

  1. Вычислите среднюю (среднеквадратичную) громкость сигнала по блокам, скажем, 5 миллисекунд. (Никогда не делая этого раньше, я не знаю, какой будет хороший размер блока.)
  2. Возьмем преобразование Фурье "заблокированного" сигнала, используя алгоритм FFT.
  3. Найти компонент в преобразованном сигнале, который имеет наибольшую величину.

Преобразование Фурье в основном представляет собой способ вычисления силы всех частот, присутствующих в сигнале. Если вы сделаете это по "заблокированному" сигналу, то, вероятно, частота удара будет самой сильной.

Возможно, вам нужно сначала применить фильтр, чтобы сосредоточиться на определенных частотах (например, на низких частотах), которые обычно содержат наибольшую информацию о BPM.

Я обнаружил, что у этой библиотеки довольно солидная реализация для определения ударов в минуту. http://soundtouchdotnet.codeplex.com/

Он основан на http://www.surina.net/soundtouch/index.html который используется в довольно многих проектах DJ. http://www.surina.net/soundtouch/applications.html

Прежде всего, то, что производит Халлгрим, не является функцией спектральной плотности мощности. Статистические периодичности в любом сигнале можно определить с помощью функции автокорреляции. Фурье-преобразование автокорреляционного сигнала является спектральной плотностью мощности. Доминирующие пики в PSD, отличные от 0 Гц, будут соответствовать эффективной периодичности сигнала (в Гц)...

Я бы порекомендовал проверить аудиобиблиотеку BASS и оболочку BASS.NET. Он имеет встроенный класс BPMCounter.

Подробную информацию об этой конкретной функции можно найти по адресу http://bass.radio42.com/help/html/0833aa5a-3be9-037c-66f2-9adfd42a8512.htm.

Самый простой способ сделать это - заставить пользователя ритмично нажимать на кнопку и считать количество нажатий, деленное на время.

Другие вопросы по тегам