Глядя на скриншоты исходных аудиофайлов, одним из простых способов обнаружить изменение уровня звука было бы сделать численное интегрирование сэмплов для определения "энергии" волны в конкретное время.
Грубый алгоритм будет:
- Разделите образцы на секции
- Рассчитайте энергию каждой секции
- Возьмите соотношение энергий между предыдущим окном и текущим окном.
- Если отношение превышает некоторый порог, определите, что произошел внезапный громкий шум.
псевдокод
samples = load_audio_samples() // Array containing audio samples
WINDOW_SIZE = 1000 // Sample window of 1000 samples (example)
for (i = 0; i < samples.length; i += WINDOW_SIZE):
// Perform a numerical integration of the current window using simple
// addition of current sample to a sum.
for (j = 0; j < WINDOW_SIZE; j++):
energy += samples[i+j]
// Take ratio of energies of last window and current window, and see
// if there is a big difference in the energies. If so, there is a
// sudden loud noise.
if (energy / last_energy > THRESHOLD):
sudden_sound_detected()
last_energy = energy
energy = 0;
Я должен добавить заявление об отказе от ответственности, что я не пробовал это.
Этот способ должен выполняться без предварительной записи всех сэмплов. Пока существует буфер некоторой длины (WINDOW_SIZE
в примере), числовое интегрирование может быть выполнено для вычисления энергии части звука. Это, однако, означает, что при обработке будет задержка, зависящая от длины WINDOW_SIZE
. Определение хорошей длины для части звука - еще одна проблема.
Как разбить на разделы
В первом аудиофайле кажется, что длительность звука закрытия двери составляет 0,25 секунды, поэтому окно, используемое для численного интегрирования, должно составлять не более половины этого значения или даже больше десятой, так что можно заметить разницу между тишиной и внезапным звуком, даже если окно между секцией тишины и секцией шума перекрывается.
Например, если окно интеграции составляло 0,5 секунды, а первое окно покрывало 0,25 секунды тишины и 0,25 секунды закрытия двери, а второе окно закрывало 0,25 секунды закрытия двери и 0,25 секунды тишины, оно Может показаться, что две звуковые секции имеют одинаковый уровень шума, поэтому не запускается обнаружение звука. Я полагаю, что короткое окно несколько облегчит эту проблему.
Однако наличие слишком короткого окна будет означать, что усиление звука может не полностью вписаться в одно окно, и может появиться впечатление, что существует небольшая разница в энергии между соседними секциями, что может привести к быть пропущенным.
Я полагаю, что WINDOW_SIZE
и THRESHOLD
должны быть определены эмпирически для звука, который будет обнаружен.
Для определения количества сэмплов, которые этот алгоритм должен хранить в памяти, скажем, WINDOW_SIZE
составляет 1/10 от звука закрытия двери, что составляет около 0,025 секунды. При частоте дискретизации 4 кГц это 100 выборок. Кажется, это не слишком большая потребность в памяти. Использование 16-битных семплов это 200 байт.
Преимущества / недостатки
Преимущество этого метода заключается в том, что обработка может выполняться с простой целочисленной арифметикой, если исходный звук подается в виде целых чисел. Подвох заключается в том, что, как уже упоминалось, обработка в реальном времени будет иметь задержку в зависимости от размера интегрируемой секции.
Существует несколько проблем, с которыми я могу столкнуться при таком подходе:
- Если фоновый шум слишком громкий, разница в энергии между фоновым шумом и закрытием двери не будет легко различима, и она может не обнаружить детектор закрытия двери.
- Любой резкий шум, такой как хлопок, может рассматриваться как закрытие двери.
Возможно, объединение предложений в других ответах, таких как попытка анализа частотной сигнатуры закрытия двери с использованием анализа Фурье, что потребовало бы больше обработки, но сделало бы ее менее подверженной ошибкам.
Вероятно, потребуется несколько экспериментов, прежде чем найти способ решить эту проблему.