NАудиочастотная полоса интенсивности - PullRequest
7 голосов
/ 12 октября 2011

У меня есть аудиоплеер, использующий NAudio, и я хотел бы отображать интенсивность в реальном времени для каждой полосы частот.

У меня есть событие, запущенное для каждого блока из 1024 выборок:

public void Update(Complex[] fftResults)
{
   // ??
}

То, что я хотел бы иметь, это массив чисел, указывающих интенсивность каждой полосы частот. Допустим, я хотел бы разделить окно на 16 полос.

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

░░░░░░░░░░░░░░░░
▓▓▓░░░░░░░░░░░░░
▓▓▓░░░░░░░░░░░░░
▓▓▓▓░░░░░░░░░░░░
▓▓▓▓▓░░░░░░░░░░░
▓▓▓▓▓▓▓▓░░░▓░░▓░

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

Приход данных (Комплекс []) уже преобразован с помощью БПФ. Это стереопоток.

Первая попытка:

    double[] bandIntensity = new double[16] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

    public void Update(Complex[] fftResults)
    {
        // using half fftResults because the others are just mirrored
        int band = 0;
        for (int n = 0; n < fftResults.Length/2; n++)
        {
            band = (int)((double)n / (fftResults.Length / 2) * bandIntensity.Length);
            bandIntensity[band] += Math.Sqrt(fftResults[n].X * fftResults[n].X + fftResults[n].Y * fftResults[n].Y);
            bandIntensity[band] /= 2;
        }
    }

Вышесказанное делает что-то, но я думаю, что слишком много идет в первые две группы, и я играю в шакире, у которой не так много баса.

Спасибо!

1 Ответ

8 голосов
/ 12 октября 2011

Есть две отдельные проблемы, которые вы, вероятно, хотите решить здесь:

(1) Функция окна

Вам необходимо применить оконную функцию к вашим данным до БПФ, в противном случае вы получите спектральную утечку , что приведет к очень размытому спектру , Один неприятный побочный эффект спектральной утечки заключается в том, что если у вас есть какой-либо значительный компонент постоянного тока (0 Гц), то это приведет к виду 1 / f, который вы видите на гистограмме.

(2) Логарифмическая ось амплитуды / частоты

Слух человека по сути логарифмический как по оси интенсивности, так и по частоте. Не только это, но речь и музыка имеют тенденцию иметь больше энергии в низкочастотной части спектра. Чтобы получить более приятное и значимое отображение зависимости интенсивности от частоты, мы обычно делаем оси амплитуд и частоты логарифмическими. В случае оси величины это обычно учитывается путем построения дБ в полном масштабе, т. Е.

magnitude_dB = 10 * log10(magnitude);

В случае частотной оси вы, вероятно, захотите сгруппировать свои ячейки в полосы, каждая из которых может быть октавой (частотный диапазон 2: 1) или, чаще, для более высокого разрешения, третьей октавой. Так что, если вы просто хотите 10 "баров", вы можете использовать следующие октавные полосы:

   25 -    50 Hz
   50 -   100 Hz
  100 -   200 Hz
  200 -   400 Hz
  400 -   800 Hz
  800 -  1600 Hz
 1600 -  3200 Hz
 3200 -  6400 Hz
 6400 - 12800 Hz
12800 - 20000 Hz

(при условии, что у вас частота дискретизации 44,1 кГц и верхний предел для оборудования ввода звука 20 кГц).

Обратите внимание, что, хотя масштаб интенсивности (дБ) является в значительной степени обязательным для этого вида применения, ось частоты регистрации менее критична, так что вы можете попробовать с вашим существующим линейным бинингом на данный момент, и просто посмотреть, какой эффект вы получить от применения оконной функции во временной области (при условии, что у вас ее еще нет) и преобразования шкалы величины в дБ.

...