void OnAudioFilterRead(float[] data, int channels)
    {
        for (int i = 0; i < data.Length; i += 2)
        {
            var smpL = data [i] * gain;
            var smpR = data [i + 1] * gain;

            smpL = left.Tick(smpL);
            smpR = right.Tick(smpR);

            var input = 0.5f * (smpL + smpR);
            var temp0 = allpassCoeff * allpass1.Last;
            temp0 += input;
            temp0  = allpass1.Tick(temp0) - allpassCoeff * temp0;
            var temp1 = allpassCoeff * allpass2.Last;
            temp1 += temp0;
            temp1  = allpass2.Tick(temp1) - allpassCoeff * temp1;
            var out1 = comb1.Tick(temp1 + comb1Coeff * comb1.Last);
            var out2 = comb2.Tick(temp1 + comb2Coeff * comb2.Last);
            out1 = fadeMix * out1 + (1.0f - fadeMix) * smpL;
            out2 = fadeMix * out2 + (1.0f - fadeMix) * smpR;
            smpL = out1;
            smpR = out2;

            smpL = eL.Process(smpL);
            smpR = eR.Process(smpR);

            data [i]     = smpL < -1?-1:smpL > 1?1:smpL;
            data [i + 1] = smpR < -1?-1:smpR > 1?1:smpR;
        }
    }