Обнаружение наибольших изменений динамического диапазона в аудиосэмпле - PullRequest
0 голосов
/ 10 июня 2018

Простите / исправьте любую неправильную терминологию в приведенной ниже (я надеюсь, что это имеет смысл!):

Я хочу обнаружить самые большие динамические изменения звука в данном семпле (т.е. моменты, когда звуковая волна«растет» / «ускоряется» больше всего).

Например, если во время семпла звук затихает в некоторых точках, я хочу знать, когда музыка возвращается после, и упорядочить эти точки данных по относительному динамическому диапазону (громкости?) Увеличению (наибольшемунаименьшее).

Мой аудиосэмпл представляет собой буфер float32[] и частоту дискретизации, и я хотел бы получить результирующий массив объектов, каждый из которых содержит:

  • индекс начального кадра
  • время начала (секунды ... frameIndex/sampleRate?)
  • индекс конца кадра
  • время окончания (секунды)
  • значение динамического изменения

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

Какие-нибудь идеи или существующие алгоритмы, которые это делают?

Не требователен к языкам, но предпочтителен любой синтаксис, такой как C #, Java, JavaScript!

1 Ответ

0 голосов
/ 11 июня 2018

Я немного не уверен относительно того, сколько звукового DSP-фона у вас есть, поэтому извиняюсь, если ступил на старую территорию.

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

Что было бы лучше всего найти, так это корневое среднее значение квадрат сигнала в некотором кадре аудиоданных

, записанных в псевдокоде, и при условии, что у вас уже есть аудиоданные, функция и способ получения среднеквадратичных данных могут быть:

   function rms(frame[], frameSize)
   {
       var rmsValue = 0;

       for(int i = 0; i < frameSize; i++)
       {
           rmsValue += frame[i] * frame[i]; // square the sample and sum over frame
       }

       rmsValue = sqrt(rmsValue / frameSize);

       return rmsValue;
   }




// Main

   var frameNum = floor(numberOfAudioSample / frameSize) // for analysis just floor to a whole number of frames, if thi is real-time, you will need to deal with a partial frame at the end

   var frame = []   // an array or buffer to temporarily store audio data
   var rmsData = [] // an array or buffer to store RMS data  

   for (var i = 0; i < frameNum; i++)
   {
       for (var j = 0; j < frameSize; j++)
       {
           sampleIndex = j + (i * frameSize)
           frame[j] = audioData[sampleIndex]
       }
       rmsData[i] = rms(frame, frameSize)
   }

Затем можно сравнить элементы данных RMS, чтобы определить, когда и насколько меняется динамика.Для цифрового аудио RMS будет ограничено между 0 и 1. Чтобы получить dBFS, все, что вам нужно сделать, это 20 * log10(rmsData)

Найти точную выборку, где изменения динамического диапазона будут сложными.Индекс кадра должен быть достаточно точным с достаточно маленьким размером кадра.Однако чем меньше кадр, тем более ошибочными будут среднеквадратичные значения.Найти время в секундах просто sampleIndex / samplingRate

При небольшом размере кадра вы также можете захотеть отфильтровать среднеквадратичные данные.Это зависит от того, предназначено ли это для приложения в реальном времени или для анализа не в реальном времени.

Чтобы упростить задачу, я бы прототипировал что-то в Octave или в MATLAB сначала

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...