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

40 Karl [2008-09-17 05:51:00]

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

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

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

c# audio signal-processing


8 ответов


26 Hallgrim [2008-09-17 13:06:00]

Рассчитать коэффициент мощности с раздвижным окном FFT: Возьмите 1024 образца:

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

Подайте его алгоритму FFT:

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

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

EDIT:

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

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. Когда бас тихий, у вас нет удара, и когда он громкий, у вас есть удар.

Удачи!


15 Nick Johnson [2008-09-17 12:30:00]

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

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


8 Dan Harper [2008-09-17 06:04:00]

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

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

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


6 Thomas [2008-09-17 05:57:00]

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

Что вы можете сделать, это примерно следующее:

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

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

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


5 eandersson [2012-04-27 02:19:00]

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

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


1 pete [2010-11-18 23:45:00]

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


0 Matt Williams [2015-03-08 13:46:00]

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

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


0 [2009-03-21 00:44:00]

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