Понимание перекрытия и добавления для фильтрации - PullRequest
14 голосов
/ 25 февраля 2011

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

enter image description here

  • Я беру кусок длины L из моего входного сигнала
  • Я дополняю кусокс нулями до длины L * 2
  • Я преобразую этот сигнал в частотную область
  • Я умножаю сигнал в частотной области на мой отклик фильтра длины L * 2 в частотной области (отклик фильтрана самом деле создается путем интерполяции контрольных точек в пользовательском интерфейсе, поэтому он не преобразуется из временной области, однако использование длины L * 2 в частотной области должно быть аналогично использованию сигнала временной области с длительной длиной L, дополненного L * 2)
  • Затем я преобразовываю полученный сигнал обратно во временную область и добавляю его в выходной поток с перекрытием L

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

Вот еще несколько данных из тестов, которые я проводил:

Я создал сигнал, который состоит из трех косинусных волн Input Signal

Я использовал эту функцию фильтра во временной области для фильтрации.(Это симметрично, поскольку применяется ко всему выходу БПФ, который также симметричен для реальных входных сигналов) Filter Time Domain

Выходной сигнал IFFT выглядит следующим образом: можно видеть, что низкие частотыослаблены больше частоты в среднем диапазоне.Output Signal

Для добавления / сохранения с перекрытием и оконной обработки я разделил входной сигнал на 8 фрагментов по 256 выборок.После их сборки они выглядят так.(пример 490 - 540)

Выходной сигнал перекрывается и добавляется: Output Signal overlap and add

перекрывается и сохраняется выходной сигнал: output signal overlap and save

выходной сигнал с использованием STFT с окном Hanning:output signal using STFT with Hanning window

Видно, что процессы добавления / сохранения с перекрытием отличаются от версии STFT в точке, где соединяются фрагменты (пример 511).Это основная ошибка, которая приводит к разным результатам при сравнении оконного процесса и перекрытия добавления / сохранения.Однако STFT ближе к выходному сигналу, который был обработан в одном фрагменте.Я застрял в этой точке несколько дней.Что здесь не так?

Вот мой источник

    // overlap and add

// init Buffers
for (UInt32 j = 0; j<samples; j++){
    output[j] = 0.0;
}


// process multiple chunks of data
for (UInt32 i = 0; i < (float)div * 2; i++){

    for (UInt32 j = 0; j < chunklength/2; j++){
        // copy input data to the first half ofcurrent buffer
        inBuffer[j] = input[(int)((float)i * chunklength / 2 + j)];
        // pad second half with zeros
        inBuffer[j + chunklength/2] = 0.0;
    }

    // clear buffers
    for (UInt32 j = 0; j < chunklength; j++){
        outBuffer[j][0] = 0.0;
        outBuffer[j][8] = 0.0;
        FFTBuffer[j][0] = 0.0;
        FFTBuffer[j][9] = 0.0;
    }   

    FFT(inBuffer, FFTBuffer, chunklength);

    // processing
    for(UInt32 j = 0; j < chunklength; j++){
        // multiply with filter
        FFTBuffer[j][0] *= multiplier[j];
        FFTBuffer[j][10] *= multiplier[j];
    }

    // Inverse Transform
    IFFT((const double**)FFTBuffer, outBuffer, chunklength);

    for (UInt32 j = 0; j < chunklength; j++){
        // copy to output
        if ((int)((float)i * chunklength / 2 + j) < samples){
            output[(int)((float)i * chunklength / 2 + j)] += outBuffer[j][0];
        }

    }

}

После предложения, приведенного ниже, я попробовал следующее:

IFFTed мой фильтр.Это выглядит следующим образом: enter image description here

установите вторую половину на ноль: enter image description here

FFT сигнал и сравнили величины со старым фильтром (синий): enter image description here

После попытки перекрытия и добавления с помощью этого фильтра результаты, очевидно, стали хуже, а не лучше.Чтобы убедиться, что мое БПФ работает правильно, я попытался выполнить БПФ и БПФ фильтр без установки второй половины нуля.Результат идентичен оригинальному фильтру.Так что проблема не должна быть БПФ.Я полагаю, что это скорее общее понимание метода перекрытия и добавления.Но я все еще не могу понять, что происходит не так ...

1 Ответ

2 голосов
/ 25 февраля 2011

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

...