Чебышевский ФНЧ вносит шум - PullRequest
1 голос
/ 05 мая 2011

Я создал простой фильтр нижних частот Чебышева на основе коэффициентов, сгенерированных этим сайтом: http://www -users.cs.york.ac.uk / ~ fisher / mkfilter / , который я использую отфильтровать частоты выше 4 кГц в аудиосигнале с частотой дискретизации 16 кГц перед понижением частоты до 8 кГц. Вот мой код (это C #, но этот вопрос не специфичен для C #, не стесняйтесь использовать другие языки на разных языках).

/// <summary>
/// Chebyshev, lowpass, -0.5dB ripple, order 4, 16kHz sample rte, 4kHz cutoff
/// </summary>
class ChebyshevLpf4Pole
{
    const int NZEROS = 4;
    const int NPOLES = 4;
    const float GAIN = 1.403178626e+01f;

    private float[] xv = new float[NZEROS+1];
    private float[] yv = new float[NPOLES + 1];

    public float Filter(float inValue)
    {
        xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4];
        xv[4] = inValue / GAIN;
        yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4];
        yv[4] = (xv[0] + xv[4]) + 4 * (xv[1] + xv[3]) + 6 * xv[2]
                     + (-0.1641503452f * yv[0]) + (0.4023376691f * yv[1])
                     + (-0.9100943707f * yv[2]) + (0.5316388226f * yv[3]);
        return yv[4];
    }
}

Чтобы проверить это, я создал синусоидальную "чириканье" от 20 Гц до 8 кГц, используя Audacity. Тестовый сигнал выглядит так:

test signal

После фильтрации я получаю:

filtered spectrum

Форма сигнала показывает, что фильтр действительно уменьшает амплитуду частот выше 4 кГц, но к моему сигналу добавлена ​​нагрузка шума. Это, похоже, относится к тому типу фильтров, который я пытаюсь реализовать (например, Баттерворт, Рейзин Косинус и т. Д.).

filtered waveform

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

Ответы [ 4 ]

2 голосов
/ 05 мая 2011

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

correctly using filter

2 голосов
/ 05 мая 2011

Я проверил ваш фильтр-код в Mathematica, и он отлично работает здесь, не внося шума, поэтому, вероятно, шум исходит от какой-то другой части вашего кода.

Chirp after filtering

1 голос
/ 05 мая 2011

Возможно, у вас есть проблемы со стабильностью чисел, особенно если какой-либо из полюсов находится близко к окружности.Попробуйте сделать все ваши промежуточные термины двойной точностью, а затем в конце отбросьте до одинарной точности.Я не слишком знаком с C #, но в C это будет:

yv[4] = (float)(((double)xv[0] + (double)xv[4]) + 4.0 * ((double)xv[1] + (double)xv[3]) + 6.0 * xv[2]
             + (-0.1641503452 * (double)yv[0]) + (0.4023376691 * (double)yv[1])
             + (-0.9100943707 * (double)yv[2]) + (0.5316388226 * (double)yv[3]));
0 голосов
/ 05 мая 2011

Вы неправильно инициализировали массивы xv и yv перед их первым использованием.В большинстве языков это означает, что их значения не определены, что может привести к неожиданным результатам, таким как ваш.Инициализация их в правильное значение (например, 0) может решить вашу проблему.

...