БПФ на аудиоданных: какие точки данных выбрать? - PullRequest
0 голосов
/ 04 ноября 2019

Мне нужно проанализировать длительные непериодические аудиоданные в 16-битном формате PCM RIFF WAV. Обычно я получаю файлы с частотой 11 кГц или 16 кГц, и я делаю снимки с интервалом в 1 секунду, чтобы подготовить 3-D спектрограмму мощности с использованием БПФ.

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

Предел, с которым я работаю, составляет 1024 бина. Поэтому при 11 кГц ширина каждой ячейки будет около 10 Гц, что вполне нормально. Тем не менее, как выбрать образцы для хруста? Средняя каждая группа из 10 образцов и отправить это в БПФ? Серийно преобразовать 10 партий из 1024 образцов и просто отбросить последние несколько? Произвольно брать первые 1024 выборки каждую секунду?

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

РЕДАКТИРОВАТЬ - [после прочтения @fdcpp ответ ниже]

Я прочиталкратковременные преобразования Фурье [очень интересно!] и изменили мою программу. Я все еще получаю очень странные значения на выходе Фурье.

Вот псевдокод того, что я написал:

define N           1024
define SAMPLES     11025
define WINDOWS     10
define SLIPWIDTH   N / 2

        short       audio[0...60 * SAMPLES]
        float       fftvals[0...N/2]
        complex     fftin[N], fftout[N]
        float       hanning[N]
        float       binwidth = SAMPLES / N

for(chunk = 0 to WINDOWS) {
    for(i = 0 to N) {
        fftin[i][real] = ( (float) audio[i + chunk * SLIPWIDTH] / 32768.0 ) * hanning[i];
        fftin[i][imaginary] = 0
    }
    fft(fftin, fftout)
    for(i = 0 to N / 2 + 1) {
        fftvals[i] = sqrt( (fftout[i][real] / binwidth) ^ 2 + (fftout[i][imaginary] / binwidth) ^ 2)
        if (fftvals[i] == 0)
            fftvals[i] = -96
        else
            fftvals[i] = 10 * log10(fftvals[i])
    }

    // add fftvals to totals array here
}

Я настроил этот анализ 16-битного со знакомаудиоданные с частотой 11 тыс. выборок в секунду, поступающие в 1024 бина за раз, каждый раз сдвигая окно на ½ числа бинов. Поэтому я буду пробовать примерно полсекунды каждой секунды звука, проходя через 10 наборов ячеек со скользящим окном шириной N. Я сглаживаю необработанные аудиоданные с помощью окна Ханна, помещая их вВходной массив БПФ.

Я хочу получить массив нормализованных значений децибел в диапазоне от 0 (самое высокое) до -96 (самое низкое). Но, как я уже сказал, значения, которые я получаю в fftvals [], бессмысленны, поэтому я делаю что-то очень неправильное.

Нужно ли делать что-то еще с необработанными аудиоданными, чтобы подготовить их кБПФ? Подходит ли мое масштабирование выходных значений перед преобразованием в децибелы? Вы заметили что-нибудь еще, что я делаю здесь не так?

...