it-swarm-ru.tech

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

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

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

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

42
Karl

Рассчитать powerpectrum с помощью скользящего окна 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);

Вы получите реальную часть и воображаемую часть. НЕ выбрасывайте мнимую часть. Сделайте то же самое с реальной частью воображаемого. Хотя верно, что мнимая часть не совпадает с действительной по пи/2, она все же содержит 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. Когда бас тихий, у вас нет ритма, а когда он громкий, у вас есть ритм. 

Удачи!

26
Hallgrim

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

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

15
Nick Johnson

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

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

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

8
Dan Harper

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

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

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

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

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

6
Thomas

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

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

5
eandersson

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

1
pete

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

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

0
Matt Williams

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

0
Lucius Kwok