Проблема создания точного алгоритма фильтра высоких частот Moog (Ladder) - PullRequest
0 голосов
/ 22 мая 2019

Я пытаюсь реализовать высокочастотную версию Ladder-фильтра в стиле Moog в аудиопроцессоре VST, который я разрабатываю с использованием инфраструктуры JUCE. Я основываю алгоритм на фильтре LP Ladder, который можно найти здесь:

http://www.musicdsp.org/en/latest/Filters/24-moog-vcf.html

Чтобы сделать его фильтром HP, я вычитаю выходной сигнал конечного фильтра ("outL4b") из входного, прежде чем применить его к окончательному выходному. Было указано, что он работает в нескольких местах (я не могу вспомнить, где я нашел информацию), но не создает «истинного» высокочастотного сигнала, так как сильно ослабленная версия «сухого» сигнала остается, даже когда значение отсечки фильтра составляет максимум (40 - 22050 Гц). Значение Q может составлять от 0,0 до 4,0. Все переменные устанавливаются в ноль при первоначальном создании плагина, а частота дискретизации в моей DAW установлена ​​на 44100 Гц.

При использовании в качестве фактического LP-фильтра алгоритм работает должным образом.

Я также попытался вычесть все выходы фильтра из всех входов, что не сработало. На данный момент я в растерянности. Функция показана ниже.

void FilterSection::moogHighPass(AudioBuffer<float>& buffer, int 
inputChannels, float cutoff, float q, float sampleRate)
{
    float fs = sampleRate;
    float fs2 = 2 * fs;
    float fc = (2.0f * cutoff) / fs;
    float p = fc * (1.8f - 0.8f * fc);
    float k = 2.0f * sin(fc * pi * 0.5f) - 1.0f;
    float t1 = (1.0f - p) * 1.386249f;
    float t2 = 12.0f + t1 * t1;
    float res = ((q / 4.0f) * (t2 + 6.0f * t1) / (t2 - 6.0f * t1));

    const float* inputChannelDataL = buffer.getReadPointer(0);
    const float* inputChannelDataR = buffer.getReadPointer(1);
    float* outputChannelDataL = {};
    outputChannelDataL = buffer.getWritePointer(0);
    float* outputChannelDataR = {};
    outputChannelDataR = buffer.getWritePointer(1);

    for (int i = 0; i < buffer.getNumSamples(); i++)
    {
            inputLMoogb = inputChannelDataL[i];
            inputRMoogb = inputChannelDataR[i];
            inputLMoogb -= res * out4Lb;
            inputRMoogb -= res * out4Rb;
            //inputLMoogb = tanh(inputLMoogb);
            //inputRMoogb = tanh(inputRMoogb);

            out1Lb = (p * inputLMoogb) + (p * in1Lb) - k * out1Lb; // Pole 1
            out1Rb = (p * inputRMoogb) + (p * in1Rb) - k * out1Rb;
            out2Lb = (p * out1Lb) + (p * in2Lb) - k * out2Lb;  // Pole 2
            out2Rb = (p * out1Rb) + (p * in2Rb) - k * out2Rb;
            out3Lb = (p * out2Lb) + (p * in3Lb) - k * out3Lb;  // Pole 3
            out3Rb = (p * out2Rb) + (p * in3Rb) - k * out3Rb;
            out4Lb = (p * out3Lb) + (p * in4Lb) - k * out4Lb;  // Pole 4, (1 - (g / 2))
            out4Rb = (p * out3Rb) + (p * in4Rb) - k * out4Rb;
            out4Lb = out4Lb - (out4Lb * out4Lb * out4Lb) * 0.166667f;
            out4Rb = out4Rb - (out4Rb * out4Rb * out4Rb) * 0.166667f;

            in1Lb = inputLMoogb;
            in1Rb = inputRMoogb;
            in2Lb = out1Lb;
            in2Rb = out1Rb;
            in3Lb = out2Lb;
            in3Rb = out2Rb;
            in4Lb = out3Lb;
            in4Rb = out3Rb;

            outputChannelDataL[i] = (inputLMoogb - out4Lb) / 2; //(out4L / 2) ???
            outputChannelDataR[i] = (inputRMoogb - out4Rb) / 2;
            //outputChannelDataL[i] = inputLMoogb + in2Lb + in3Lb + in4Lb - out1Lb - out2Lb - out3Lb - out4Lb; //(out4L / 2) ???
            //outputChannelDataR[i] = inputRMoogb + in2Rb + in3Rb + in4Rb - out1Rb - out2Rb - out3Rb - out4Rb;
    }
}

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

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