예제 #1
0
        public virtual int Encode(Bits bits, float[] ins0)
        {
            Array.Copy(this.frmBuf, this.frameSize, this.frmBuf, 0, this.bufSize - this.frameSize);
            this.frmBuf[this.bufSize - this.frameSize] = ins0[0] - this.preemph * this.pre_mem;
            for (int i = 1; i < this.frameSize; i++)
            {
                this.frmBuf[this.bufSize - this.frameSize + i] = ins0[i] - this.preemph * ins0[i - 1];
            }
            this.pre_mem = ins0[this.frameSize - 1];
            Array.Copy(this.exc2Buf, this.frameSize, this.exc2Buf, 0, this.bufSize - this.frameSize);
            Array.Copy(this.excBuf, this.frameSize, this.excBuf, 0, this.bufSize - this.frameSize);
            Array.Copy(this.swBuf, this.frameSize, this.swBuf, 0, this.bufSize - this.frameSize);
            for (int i = 0; i < this.windowSize; i++)
            {
                this.buf2[i] = this.frmBuf[i + this.frmIdx] * this.window[i];
            }
            Lpc.Autocorr(this.buf2, this.autocorr, this.lpcSize + 1, this.windowSize);
            this.autocorr[0] += 10f;
            this.autocorr[0] *= this.lpc_floor;
            for (int i = 0; i < this.lpcSize + 1; i++)
            {
                this.autocorr[i] *= this.lagWindow[i];
            }
            Lpc.Wld(this.lpc, this.autocorr, this.rc, this.lpcSize);
            Array.Copy(this.lpc, 0, this.lpc, 1, this.lpcSize);
            this.lpc[0] = 1f;
            int num = Lsp.Lpc2lsp(this.lpc, this.lpcSize, this.lsp, 15, 0.2f);

            if (num == this.lpcSize)
            {
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.lsp[i] = (float)Math.Acos((double)this.lsp[i]);
                }
            }
            else
            {
                if (this.complexity > 1)
                {
                    num = Lsp.Lpc2lsp(this.lpc, this.lpcSize, this.lsp, 11, 0.05f);
                }
                if (num == this.lpcSize)
                {
                    for (int i = 0; i < this.lpcSize; i++)
                    {
                        this.lsp[i] = (float)Math.Acos((double)this.lsp[i]);
                    }
                }
                else
                {
                    for (int i = 0; i < this.lpcSize; i++)
                    {
                        this.lsp[i] = this.old_lsp[i];
                    }
                }
            }
            float num2 = 0f;

            for (int i = 0; i < this.lpcSize; i++)
            {
                num2 += (this.old_lsp[i] - this.lsp[i]) * (this.old_lsp[i] - this.lsp[i]);
            }
            if (this.first != 0)
            {
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.interp_lsp[i] = this.lsp[i];
                }
            }
            else
            {
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.interp_lsp[i] = 0.375f * this.old_lsp[i] + 0.625f * this.lsp[i];
                }
            }
            Lsp.Enforce_margin(this.interp_lsp, this.lpcSize, 0.002f);
            for (int i = 0; i < this.lpcSize; i++)
            {
                this.interp_lsp[i] = (float)Math.Cos((double)this.interp_lsp[i]);
            }
            this.m_lsp.Lsp2lpc(this.interp_lsp, this.interp_lpc, this.lpcSize);
            int   num3;
            float num4;

            if (this.submodes[this.submodeID] == null || this.vbr_enabled != 0 || this.vad_enabled != 0 || this.submodes[this.submodeID].ForcedPitchGain != 0 || this.submodes[this.submodeID].LbrPitch != -1)
            {
                int[]   array  = new int[6];
                float[] array2 = new float[6];
                Filters.Bw_lpc(this.gamma1, this.interp_lpc, this.bw_lpc1, this.lpcSize);
                Filters.Bw_lpc(this.gamma2, this.interp_lpc, this.bw_lpc2, this.lpcSize);
                Filters.Filter_mem2(this.frmBuf, this.frmIdx, this.bw_lpc1, this.bw_lpc2, this.swBuf, this.swIdx, this.frameSize, this.lpcSize, this.mem_sw_whole, 0);
                Ltp.Open_loop_nbest_pitch(this.swBuf, this.swIdx, this.min_pitch, this.max_pitch, this.frameSize, array, array2, 6);
                num3 = array[0];
                num4 = array2[0];
                for (int i = 1; i < 6; i++)
                {
                    if ((double)array2[i] > 0.85 * (double)num4 && (Math.Abs((double)array[i] - (double)num3 / 2.0) <= 1.0 || Math.Abs((double)array[i] - (double)num3 / 3.0) <= 1.0 || Math.Abs((double)array[i] - (double)num3 / 4.0) <= 1.0 || Math.Abs((double)array[i] - (double)num3 / 5.0) <= 1.0))
                    {
                        num3 = array[i];
                    }
                }
            }
            else
            {
                num3 = 0;
                num4 = 0f;
            }
            Filters.Fir_mem2(this.frmBuf, this.frmIdx, this.interp_lpc, this.excBuf, this.excIdx, this.frameSize, this.lpcSize, this.mem_exc);
            float num5 = 0f;

            for (int i = 0; i < this.frameSize; i++)
            {
                num5 += this.excBuf[this.excIdx + i] * this.excBuf[this.excIdx + i];
            }
            num5 = (float)Math.Sqrt((double)(1f + num5 / (float)this.frameSize));
            if (this.vbr != null && (this.vbr_enabled != 0 || this.vad_enabled != 0))
            {
                if (this.abr_enabled != 0)
                {
                    float num6 = 0f;
                    if (this.abr_drift2 * this.abr_drift > 0f)
                    {
                        num6 = -1E-05f * this.abr_drift / (1f + this.abr_count);
                        if (num6 > 0.05f)
                        {
                            num6 = 0.05f;
                        }
                        if (num6 < -0.05f)
                        {
                            num6 = -0.05f;
                        }
                    }
                    this.vbr_quality += num6;
                    if (this.vbr_quality > 10f)
                    {
                        this.vbr_quality = 10f;
                    }
                    if (this.vbr_quality < 0f)
                    {
                        this.vbr_quality = 0f;
                    }
                }
                this.relative_quality = this.vbr.Analysis(ins0, this.frameSize, num3, num4);
                if (this.vbr_enabled != 0)
                {
                    int   num7 = 0;
                    float num8 = 100f;
                    int   j;
                    for (j = 8; j > 0; j--)
                    {
                        int   num9 = (int)Math.Floor((double)this.vbr_quality);
                        float num10;
                        if (num9 == 10)
                        {
                            num10 = NSpeex.Vbr.nb_thresh[j][num9];
                        }
                        else
                        {
                            num10 = (this.vbr_quality - (float)num9) * NSpeex.Vbr.nb_thresh[j][num9 + 1] + ((float)(1 + num9) - this.vbr_quality) * NSpeex.Vbr.nb_thresh[j][num9];
                        }
                        if (this.relative_quality > num10 && this.relative_quality - num10 < num8)
                        {
                            num7 = j;
                            num8 = this.relative_quality - num10;
                        }
                    }
                    j = num7;
                    if (j == 0)
                    {
                        if (this.dtx_count == 0 || (double)num2 > 0.05 || this.dtx_enabled == 0 || this.dtx_count > 20)
                        {
                            j = 1;
                            this.dtx_count = 1;
                        }
                        else
                        {
                            j = 0;
                            this.dtx_count++;
                        }
                    }
                    else
                    {
                        this.dtx_count = 0;
                    }
                    this.Mode = j;
                    if (this.abr_enabled != 0)
                    {
                        int bitRate = this.BitRate;
                        this.abr_drift += (float)(bitRate - this.abr_enabled);
                        this.abr_drift2 = 0.95f * this.abr_drift2 + 0.05f * (float)(bitRate - this.abr_enabled);
                        this.abr_count += new float?((float)1.0).Value;
                    }
                }
                else
                {
                    int submodeID;
                    if (this.relative_quality < 2f)
                    {
                        if (this.dtx_count == 0 || (double)num2 > 0.05 || this.dtx_enabled == 0 || this.dtx_count > 20)
                        {
                            this.dtx_count = 1;
                            submodeID      = 1;
                        }
                        else
                        {
                            submodeID = 0;
                            this.dtx_count++;
                        }
                    }
                    else
                    {
                        this.dtx_count = 0;
                        submodeID      = this.submodeSelect;
                    }
                    this.submodeID = submodeID;
                }
            }
            else
            {
                this.relative_quality = -1f;
            }
            bits.Pack(0, 1);
            bits.Pack(this.submodeID, 4);
            if (this.submodes[this.submodeID] == null)
            {
                for (int i = 0; i < this.frameSize; i++)
                {
                    this.excBuf[this.excIdx + i] = (this.exc2Buf[this.exc2Idx + i] = (this.swBuf[this.swIdx + i] = 0f));
                }
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.mem_sw[i] = 0f;
                }
                this.first         = 1;
                this.bounded_pitch = 1;
                Filters.Iir_mem2(this.excBuf, this.excIdx, this.interp_qlpc, this.frmBuf, this.frmIdx, this.frameSize, this.lpcSize, this.mem_sp);
                ins0[0] = this.frmBuf[this.frmIdx] + this.preemph * this.pre_mem2;
                for (int i = 1; i < this.frameSize; i++)
                {
                    ins0[i] = this.frmBuf[this.frmIdx = i] + this.preemph * ins0[i - 1];
                }
                this.pre_mem2 = ins0[this.frameSize - 1];
                return(0);
            }
            if (this.first != 0)
            {
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.old_lsp[i] = this.lsp[i];
                }
            }
            this.submodes[this.submodeID].LsqQuant.Quant(this.lsp, this.qlsp, this.lpcSize, bits);
            if (this.submodes[this.submodeID].LbrPitch != -1)
            {
                bits.Pack(num3 - this.min_pitch, 7);
            }
            if (this.submodes[this.submodeID].ForcedPitchGain != 0)
            {
                int num11 = (int)Math.Floor(0.5 + (double)(15f * num4));
                if (num11 > 15)
                {
                    num11 = 15;
                }
                if (num11 < 0)
                {
                    num11 = 0;
                }
                bits.Pack(num11, 4);
                num4 = 0.066667f * (float)num11;
            }
            int num12 = (int)Math.Floor(0.5 + 3.5 * Math.Log((double)num5));

            if (num12 < 0)
            {
                num12 = 0;
            }
            if (num12 > 31)
            {
                num12 = 31;
            }
            num5 = (float)Math.Exp((double)num12 / 3.5);
            bits.Pack(num12, 5);
            if (this.first != 0)
            {
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.old_qlsp[i] = this.qlsp[i];
                }
            }
            float[] array3 = new float[this.subframeSize];
            float[] array4 = new float[this.subframeSize];
            float[] array5 = new float[this.subframeSize];
            float[] array6 = new float[this.lpcSize];
            float[] array7 = new float[this.frameSize];
            for (int i = 0; i < this.frameSize; i++)
            {
                array7[i] = this.frmBuf[this.frmIdx + i];
            }
            for (int k = 0; k < this.nbSubframes; k++)
            {
                int   num13 = this.subframeSize * k;
                int   num14 = this.frmIdx + num13;
                int   num15 = this.excIdx + num13;
                int   num16 = this.swIdx + num13;
                int   num17 = this.exc2Idx + num13;
                float num18 = (float)(1.0 + (double)k) / (float)this.nbSubframes;
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.interp_lsp[i] = (1f - num18) * this.old_lsp[i] + num18 * this.lsp[i];
                }
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.interp_qlsp[i] = (1f - num18) * this.old_qlsp[i] + num18 * this.qlsp[i];
                }
                Lsp.Enforce_margin(this.interp_lsp, this.lpcSize, 0.002f);
                Lsp.Enforce_margin(this.interp_qlsp, this.lpcSize, 0.002f);
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.interp_lsp[i] = (float)Math.Cos((double)this.interp_lsp[i]);
                }
                this.m_lsp.Lsp2lpc(this.interp_lsp, this.interp_lpc, this.lpcSize);
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.interp_qlsp[i] = (float)Math.Cos((double)this.interp_qlsp[i]);
                }
                this.m_lsp.Lsp2lpc(this.interp_qlsp, this.interp_qlpc, this.lpcSize);
                num18           = 1f;
                this.pi_gain[k] = 0f;
                for (int i = 0; i <= this.lpcSize; i++)
                {
                    this.pi_gain[k] += num18 * this.interp_qlpc[i];
                    num18            = -num18;
                }
                Filters.Bw_lpc(this.gamma1, this.interp_lpc, this.bw_lpc1, this.lpcSize);
                if (this.gamma2 >= 0f)
                {
                    Filters.Bw_lpc(this.gamma2, this.interp_lpc, this.bw_lpc2, this.lpcSize);
                }
                else
                {
                    this.bw_lpc2[0] = 1f;
                    this.bw_lpc2[1] = -this.preemph;
                    for (int i = 2; i <= this.lpcSize; i++)
                    {
                        this.bw_lpc2[i] = 0f;
                    }
                }
                for (int i = 0; i < this.subframeSize; i++)
                {
                    this.excBuf[num15 + i] = 0f;
                }
                this.excBuf[num15] = 1f;
                Filters.Syn_percep_zero(this.excBuf, num15, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, array5, this.subframeSize, this.lpcSize);
                for (int i = 0; i < this.subframeSize; i++)
                {
                    this.excBuf[num15 + i] = 0f;
                }
                for (int i = 0; i < this.subframeSize; i++)
                {
                    this.exc2Buf[num17 + i] = 0f;
                }
                for (int i = 0; i < this.lpcSize; i++)
                {
                    array6[i] = this.mem_sp[i];
                }
                Filters.Iir_mem2(this.excBuf, num15, this.interp_qlpc, this.excBuf, num15, this.subframeSize, this.lpcSize, array6);
                for (int i = 0; i < this.lpcSize; i++)
                {
                    array6[i] = this.mem_sw[i];
                }
                Filters.Filter_mem2(this.excBuf, num15, this.bw_lpc1, this.bw_lpc2, array3, 0, this.subframeSize, this.lpcSize, array6, 0);
                for (int i = 0; i < this.lpcSize; i++)
                {
                    array6[i] = this.mem_sw[i];
                }
                Filters.Filter_mem2(this.frmBuf, num14, this.bw_lpc1, this.bw_lpc2, this.swBuf, num16, this.subframeSize, this.lpcSize, array6, 0);
                for (int i = 0; i < this.subframeSize; i++)
                {
                    array4[i] = this.swBuf[num16 + i] - array3[i];
                }
                for (int i = 0; i < this.subframeSize; i++)
                {
                    this.excBuf[num15 + i] = (this.exc2Buf[num17 + i] = 0f);
                }
                int start;
                int num19;
                if (this.submodes[this.submodeID].LbrPitch != -1)
                {
                    int lbrPitch = this.submodes[this.submodeID].LbrPitch;
                    if (lbrPitch != 0)
                    {
                        if (num3 < this.min_pitch + lbrPitch - 1)
                        {
                            num3 = this.min_pitch + lbrPitch - 1;
                        }
                        if (num3 > this.max_pitch - lbrPitch)
                        {
                            num3 = this.max_pitch - lbrPitch;
                        }
                        start = num3 - lbrPitch + 1;
                        num19 = num3 + lbrPitch;
                    }
                    else
                    {
                        num19 = (start = num3);
                    }
                }
                else
                {
                    start = this.min_pitch;
                    num19 = this.max_pitch;
                }
                if (this.bounded_pitch != 0 && num19 > num13)
                {
                    num19 = num13;
                }
                int num20 = this.submodes[this.submodeID].Ltp.Quant(array4, this.swBuf, num16, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.excBuf, num15, start, num19, num4, this.lpcSize, this.subframeSize, bits, this.exc2Buf, num17, array5, this.complexity);
                this.pitch[k] = num20;
                Filters.Syn_percep_zero(this.excBuf, num15, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, array3, this.subframeSize, this.lpcSize);
                for (int i = 0; i < this.subframeSize; i++)
                {
                    array4[i] -= array3[i];
                }
                float num21 = 0f;
                int   num22 = k * this.subframeSize;
                for (int i = 0; i < this.subframeSize; i++)
                {
                    this.innov[num22 + i] = 0f;
                }
                Filters.Residue_percep_zero(array4, 0, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.buf2, this.subframeSize, this.lpcSize);
                for (int i = 0; i < this.subframeSize; i++)
                {
                    num21 += this.buf2[i] * this.buf2[i];
                }
                num21  = (float)Math.Sqrt((double)(0.1f + num21 / (float)this.subframeSize));
                num21 /= num5;
                if (this.submodes[this.submodeID].HaveSubframeGain != 0)
                {
                    num21 = (float)Math.Log((double)num21);
                    if (this.submodes[this.submodeID].HaveSubframeGain == 3)
                    {
                        int num23 = VQ.Index(num21, NbCodec.exc_gain_quant_scal3, 8);
                        bits.Pack(num23, 3);
                        num21 = NbCodec.exc_gain_quant_scal3[num23];
                    }
                    else
                    {
                        int num23 = VQ.Index(num21, NbCodec.exc_gain_quant_scal1, 2);
                        bits.Pack(num23, 1);
                        num21 = NbCodec.exc_gain_quant_scal1[num23];
                    }
                    num21 = (float)Math.Exp((double)num21);
                }
                else
                {
                    num21 = 1f;
                }
                num21 *= num5;
                float num24 = 1f / num21;
                for (int i = 0; i < this.subframeSize; i++)
                {
                    array4[i] *= num24;
                }
                this.submodes[this.submodeID].Innovation.Quantify(array4, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.lpcSize, this.subframeSize, this.innov, num22, array5, bits, this.complexity);
                for (int i = 0; i < this.subframeSize; i++)
                {
                    this.innov[num22 + i] *= num21;
                }
                for (int i = 0; i < this.subframeSize; i++)
                {
                    this.excBuf[num15 + i] += this.innov[num22 + i];
                }
                if (this.submodes[this.submodeID].DoubleCodebook != 0)
                {
                    float[] array8 = new float[this.subframeSize];
                    for (int i = 0; i < this.subframeSize; i++)
                    {
                        array4[i] *= 2.2f;
                    }
                    this.submodes[this.submodeID].Innovation.Quantify(array4, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.lpcSize, this.subframeSize, array8, 0, array5, bits, this.complexity);
                    for (int i = 0; i < this.subframeSize; i++)
                    {
                        array8[i] *= (float)((double)num21 * 0.45454545454545453);
                    }
                    for (int i = 0; i < this.subframeSize; i++)
                    {
                        this.excBuf[num15 + i] += array8[i];
                    }
                }
                for (int i = 0; i < this.subframeSize; i++)
                {
                    array4[i] *= num21;
                }
                for (int i = 0; i < this.lpcSize; i++)
                {
                    array6[i] = this.mem_sp[i];
                }
                Filters.Iir_mem2(this.excBuf, num15, this.interp_qlpc, this.frmBuf, num14, this.subframeSize, this.lpcSize, this.mem_sp);
                Filters.Filter_mem2(this.frmBuf, num14, this.bw_lpc1, this.bw_lpc2, this.swBuf, num16, this.subframeSize, this.lpcSize, this.mem_sw, 0);
                for (int i = 0; i < this.subframeSize; i++)
                {
                    this.exc2Buf[num17 + i] = this.excBuf[num15 + i];
                }
            }
            if (this.submodeID >= 1)
            {
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.old_lsp[i] = this.lsp[i];
                }
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.old_qlsp[i] = this.qlsp[i];
                }
            }
            if (this.submodeID == 1)
            {
                if (this.dtx_count != 0)
                {
                    bits.Pack(15, 4);
                }
                else
                {
                    bits.Pack(0, 4);
                }
            }
            this.first = 0;
            float num25 = 0f;
            float num26 = 0f;

            for (int i = 0; i < this.frameSize; i++)
            {
                num25 += this.frmBuf[this.frmIdx + i] * this.frmBuf[this.frmIdx + i];
                num26 += (this.frmBuf[this.frmIdx + i] - array7[i]) * (this.frmBuf[this.frmIdx + i] - array7[i]);
            }
            ins0[0] = this.frmBuf[this.frmIdx] + this.preemph * this.pre_mem2;
            for (int i = 1; i < this.frameSize; i++)
            {
                ins0[i] = this.frmBuf[this.frmIdx + i] + this.preemph * ins0[i - 1];
            }
            this.pre_mem2 = ins0[this.frameSize - 1];
            if (this.submodes[this.submodeID].Innovation is NoiseSearch || this.submodeID == 0)
            {
                this.bounded_pitch = 1;
            }
            else
            {
                this.bounded_pitch = 0;
            }
            return(1);
        }
예제 #2
0
        public virtual int Encode(Bits bits, float[] ins0)
        {
            Filters.Qmf_decomp(ins0, Codebook_Constants.h0, this.x0d, this.x1d, this.fullFrameSize, 64, this.h0_mem);
            this.lowenc.Encode(bits, this.x0d);
            for (int i = 0; i < this.windowSize - this.frameSize; i++)
            {
                this.high[i] = this.high[this.frameSize + i];
            }
            for (int i = 0; i < this.frameSize; i++)
            {
                this.high[this.windowSize - this.frameSize + i] = this.x1d[i];
            }
            Array.Copy(this.excBuf, this.frameSize, this.excBuf, 0, this.bufSize - this.frameSize);
            float[] piGain = this.lowenc.PiGain;
            float[] exc    = this.lowenc.Exc;
            float[] innov  = this.lowenc.Innov;
            int     num;

            if (this.lowenc.Mode == 0)
            {
                num = 1;
            }
            else
            {
                num = 0;
            }
            for (int i = 0; i < this.windowSize; i++)
            {
                this.buf[i] = this.high[i] * this.window[i];
            }
            Lpc.Autocorr(this.buf, this.autocorr, this.lpcSize + 1, this.windowSize);
            this.autocorr[0] += 1f;
            this.autocorr[0] *= this.lpc_floor;
            for (int i = 0; i < this.lpcSize + 1; i++)
            {
                this.autocorr[i] *= this.lagWindow[i];
            }
            Lpc.Wld(this.lpc, this.autocorr, this.rc, this.lpcSize);
            Array.Copy(this.lpc, 0, this.lpc, 1, this.lpcSize);
            this.lpc[0] = 1f;
            int num2 = Lsp.Lpc2lsp(this.lpc, this.lpcSize, this.lsp, 15, 0.2f);

            if (num2 != this.lpcSize)
            {
                num2 = Lsp.Lpc2lsp(this.lpc, this.lpcSize, this.lsp, 11, 0.02f);
                if (num2 != this.lpcSize)
                {
                    for (int i = 0; i < this.lpcSize; i++)
                    {
                        this.lsp[i] = (float)Math.Cos(3.1415926535897931 * (double)((float)(i + 1)) / (double)(this.lpcSize + 1));
                    }
                }
            }
            for (int i = 0; i < this.lpcSize; i++)
            {
                this.lsp[i] = (float)Math.Acos((double)this.lsp[i]);
            }
            float num3 = 0f;

            for (int i = 0; i < this.lpcSize; i++)
            {
                num3 += (this.old_lsp[i] - this.lsp[i]) * (this.old_lsp[i] - this.lsp[i]);
            }
            if ((this.vbr_enabled != 0 || this.vad_enabled != 0) && num == 0)
            {
                float num4 = 0f;
                float num5 = 0f;
                if (this.abr_enabled != 0)
                {
                    float num6 = 0f;
                    if (this.abr_drift2 * this.abr_drift > 0f)
                    {
                        num6 = -1E-05f * this.abr_drift / (1f + this.abr_count);
                        if (num6 > 0.1f)
                        {
                            num6 = 0.1f;
                        }
                        if (num6 < -0.1f)
                        {
                            num6 = -0.1f;
                        }
                    }
                    this.vbr_quality += num6;
                    if (this.vbr_quality > 10f)
                    {
                        this.vbr_quality = 10f;
                    }
                    if (this.vbr_quality < 0f)
                    {
                        this.vbr_quality = 0f;
                    }
                }
                for (int i = 0; i < this.frameSize; i++)
                {
                    num4 += this.x0d[i] * this.x0d[i];
                    num5 += this.high[i] * this.high[i];
                }
                float num7 = (float)Math.Log((double)((1f + num5) / (1f + num4)));
                this.relative_quality = this.lowenc.RelativeQuality;
                if (num7 < -4f)
                {
                    num7 = -4f;
                }
                if (num7 > 2f)
                {
                    num7 = 2f;
                }
                if (this.vbr_enabled != 0)
                {
                    int num8 = this.nb_modes - 1;
                    this.relative_quality += 1f * (num7 + 2f);
                    if (this.relative_quality < -1f)
                    {
                        this.relative_quality = -1f;
                    }
                    while (num8 != 0)
                    {
                        int   num9 = (int)Math.Floor((double)this.vbr_quality);
                        float num10;
                        if (num9 == 10)
                        {
                            num10 = NSpeex.Vbr.hb_thresh[num8][num9];
                        }
                        else
                        {
                            num10 = (this.vbr_quality - (float)num9) * NSpeex.Vbr.hb_thresh[num8][num9 + 1] + ((float)(1 + num9) - this.vbr_quality) * NSpeex.Vbr.hb_thresh[num8][num9];
                        }
                        if (this.relative_quality >= num10)
                        {
                            break;
                        }
                        num8--;
                    }
                    this.Mode = num8;
                    if (this.abr_enabled != 0)
                    {
                        int bitRate = this.BitRate;
                        this.abr_drift += (float)(bitRate - this.abr_enabled);
                        this.abr_drift2 = 0.95f * this.abr_drift2 + 0.05f * (float)(bitRate - this.abr_enabled);
                        this.abr_count += 1f;
                    }
                }
                else
                {
                    int submodeID;
                    if ((double)this.relative_quality < 2.0)
                    {
                        submodeID = 1;
                    }
                    else
                    {
                        submodeID = this.submodeSelect;
                    }
                    this.submodeID = submodeID;
                }
            }
            bits.Pack(1, 1);
            if (num != 0)
            {
                bits.Pack(0, 3);
            }
            else
            {
                bits.Pack(this.submodeID, 3);
            }
            if (num == 0 && this.submodes[this.submodeID] != null)
            {
                this.submodes[this.submodeID].LsqQuant.Quant(this.lsp, this.qlsp, this.lpcSize, bits);
                if (this.first != 0)
                {
                    for (int i = 0; i < this.lpcSize; i++)
                    {
                        this.old_lsp[i] = this.lsp[i];
                    }
                    for (int i = 0; i < this.lpcSize; i++)
                    {
                        this.old_qlsp[i] = this.qlsp[i];
                    }
                }
                float[] array  = new float[this.lpcSize];
                float[] array2 = new float[this.subframeSize];
                float[] array3 = new float[this.subframeSize];
                for (int j = 0; j < this.nbSubframes; j++)
                {
                    float num11 = 0f;
                    float num12 = 0f;
                    int   num13 = this.subframeSize * j;
                    int   num14 = num13;
                    int   num15 = this.excIdx + num13;
                    int   num16 = num13;
                    int   num17 = num13;
                    float num18 = (1f + (float)j) / (float)this.nbSubframes;
                    for (int i = 0; i < this.lpcSize; i++)
                    {
                        this.interp_lsp[i] = (1f - num18) * this.old_lsp[i] + num18 * this.lsp[i];
                    }
                    for (int i = 0; i < this.lpcSize; i++)
                    {
                        this.interp_qlsp[i] = (1f - num18) * this.old_qlsp[i] + num18 * this.qlsp[i];
                    }
                    Lsp.Enforce_margin(this.interp_lsp, this.lpcSize, 0.05f);
                    Lsp.Enforce_margin(this.interp_qlsp, this.lpcSize, 0.05f);
                    for (int i = 0; i < this.lpcSize; i++)
                    {
                        this.interp_lsp[i] = (float)Math.Cos((double)this.interp_lsp[i]);
                    }
                    for (int i = 0; i < this.lpcSize; i++)
                    {
                        this.interp_qlsp[i] = (float)Math.Cos((double)this.interp_qlsp[i]);
                    }
                    this.m_lsp.Lsp2lpc(this.interp_lsp, this.interp_lpc, this.lpcSize);
                    this.m_lsp.Lsp2lpc(this.interp_qlsp, this.interp_qlpc, this.lpcSize);
                    Filters.Bw_lpc(this.gamma1, this.interp_lpc, this.bw_lpc1, this.lpcSize);
                    Filters.Bw_lpc(this.gamma2, this.interp_lpc, this.bw_lpc2, this.lpcSize);
                    float num19 = 0f;
                    num18           = 1f;
                    this.pi_gain[j] = 0f;
                    for (int i = 0; i <= this.lpcSize; i++)
                    {
                        num19           += num18 * this.interp_qlpc[i];
                        num18            = -num18;
                        this.pi_gain[j] += this.interp_qlpc[i];
                    }
                    float value = piGain[j];
                    value = 1f / (Math.Abs(value) + 0.01f);
                    num19 = 1f / (Math.Abs(num19) + 0.01f);
                    float num20 = Math.Abs(0.01f + num19) / (0.01f + Math.Abs(value));
                    Filters.Fir_mem2(this.high, num14, this.interp_qlpc, this.excBuf, num15, this.subframeSize, this.lpcSize, this.mem_sp2);
                    for (int i = 0; i < this.subframeSize; i++)
                    {
                        num11 += this.excBuf[num15 + i] * this.excBuf[num15 + i];
                    }
                    if (this.submodes[this.submodeID].Innovation == null)
                    {
                        for (int i = 0; i < this.subframeSize; i++)
                        {
                            num12 += innov[num13 + i] * innov[num13 + i];
                        }
                        float num21 = num11 / (0.01f + num12);
                        num21  = (float)Math.Sqrt((double)num21);
                        num21 *= num20;
                        int num22 = (int)Math.Floor(10.5 + 8.0 * Math.Log((double)num21 + 0.0001));
                        if (num22 < 0)
                        {
                            num22 = 0;
                        }
                        if (num22 > 31)
                        {
                            num22 = 31;
                        }
                        bits.Pack(num22, 5);
                        num21  = (float)(0.1 * Math.Exp((double)num22 / 9.4));
                        num21 /= num20;
                    }
                    else
                    {
                        for (int i = 0; i < this.subframeSize; i++)
                        {
                            num12 += exc[num13 + i] * exc[num13 + i];
                        }
                        float num23 = (float)(Math.Sqrt((double)(1f + num11)) * (double)num20 / Math.Sqrt((double)((1f + num12) * (float)this.subframeSize)));
                        int   num24 = (int)Math.Floor(0.5 + 3.7 * (Math.Log((double)num23) + 2.0));
                        if (num24 < 0)
                        {
                            num24 = 0;
                        }
                        if (num24 > 15)
                        {
                            num24 = 15;
                        }
                        bits.Pack(num24, 4);
                        num23 = (float)Math.Exp(0.27027027027027023 * (double)num24 - 2.0);
                        float num25 = num23 * (float)Math.Sqrt((double)(1f + num12)) / num20;
                        float num26 = 1f / num25;
                        for (int i = 0; i < this.subframeSize; i++)
                        {
                            this.excBuf[num15 + i] = 0f;
                        }
                        this.excBuf[num15] = 1f;
                        Filters.Syn_percep_zero(this.excBuf, num15, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, array2, this.subframeSize, this.lpcSize);
                        for (int i = 0; i < this.subframeSize; i++)
                        {
                            this.excBuf[num15 + i] = 0f;
                        }
                        for (int i = 0; i < this.lpcSize; i++)
                        {
                            array[i] = this.mem_sp[i];
                        }
                        Filters.Iir_mem2(this.excBuf, num15, this.interp_qlpc, this.excBuf, num15, this.subframeSize, this.lpcSize, array);
                        for (int i = 0; i < this.lpcSize; i++)
                        {
                            array[i] = this.mem_sw[i];
                        }
                        Filters.Filter_mem2(this.excBuf, num15, this.bw_lpc1, this.bw_lpc2, this.res, num16, this.subframeSize, this.lpcSize, array, 0);
                        for (int i = 0; i < this.lpcSize; i++)
                        {
                            array[i] = this.mem_sw[i];
                        }
                        Filters.Filter_mem2(this.high, num14, this.bw_lpc1, this.bw_lpc2, this.swBuf, num17, this.subframeSize, this.lpcSize, array, 0);
                        for (int i = 0; i < this.subframeSize; i++)
                        {
                            this.target[i] = this.swBuf[num17 + i] - this.res[num16 + i];
                        }
                        for (int i = 0; i < this.subframeSize; i++)
                        {
                            this.excBuf[num15 + i] = 0f;
                        }
                        for (int i = 0; i < this.subframeSize; i++)
                        {
                            this.target[i] *= num26;
                        }
                        for (int i = 0; i < this.subframeSize; i++)
                        {
                            array3[i] = 0f;
                        }
                        this.submodes[this.submodeID].Innovation.Quantify(this.target, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.lpcSize, this.subframeSize, array3, 0, array2, bits, this.complexity + 1 >> 1);
                        for (int i = 0; i < this.subframeSize; i++)
                        {
                            this.excBuf[num15 + i] += array3[i] * num25;
                        }
                        if (this.submodes[this.submodeID].DoubleCodebook != 0)
                        {
                            float[] array4 = new float[this.subframeSize];
                            for (int i = 0; i < this.subframeSize; i++)
                            {
                                array4[i] = 0f;
                            }
                            for (int i = 0; i < this.subframeSize; i++)
                            {
                                this.target[i] *= 2.5f;
                            }
                            this.submodes[this.submodeID].Innovation.Quantify(this.target, this.interp_qlpc, this.bw_lpc1, this.bw_lpc2, this.lpcSize, this.subframeSize, array4, 0, array2, bits, this.complexity + 1 >> 1);
                            for (int i = 0; i < this.subframeSize; i++)
                            {
                                array4[i] *= (float)((double)num25 * 0.4);
                            }
                            for (int i = 0; i < this.subframeSize; i++)
                            {
                                this.excBuf[num15 + i] += array4[i];
                            }
                        }
                    }
                    for (int i = 0; i < this.lpcSize; i++)
                    {
                        array[i] = this.mem_sp[i];
                    }
                    Filters.Iir_mem2(this.excBuf, num15, this.interp_qlpc, this.high, num14, this.subframeSize, this.lpcSize, this.mem_sp);
                    Filters.Filter_mem2(this.high, num14, this.bw_lpc1, this.bw_lpc2, this.swBuf, num17, this.subframeSize, this.lpcSize, this.mem_sw, 0);
                }
                this.filters.Fir_mem_up(this.x0d, Codebook_Constants.h0, this.y0, this.fullFrameSize, 64, this.g0_mem);
                this.filters.Fir_mem_up(this.high, Codebook_Constants.h1, this.y1, this.fullFrameSize, 64, this.g1_mem);
                for (int i = 0; i < this.fullFrameSize; i++)
                {
                    ins0[i] = 2f * (this.y0[i] - this.y1[i]);
                }
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.old_lsp[i] = this.lsp[i];
                }
                for (int i = 0; i < this.lpcSize; i++)
                {
                    this.old_qlsp[i] = this.qlsp[i];
                }
                this.first = 0;
                return(1);
            }
            for (int i = 0; i < this.frameSize; i++)
            {
                this.excBuf[this.excIdx + i] = (this.swBuf[i] = 0f);
            }
            for (int i = 0; i < this.lpcSize; i++)
            {
                this.mem_sw[i] = 0f;
            }
            this.first = 1;
            Filters.Iir_mem2(this.excBuf, this.excIdx, this.interp_qlpc, this.high, 0, this.subframeSize, this.lpcSize, this.mem_sp);
            this.filters.Fir_mem_up(this.x0d, Codebook_Constants.h0, this.y0, this.fullFrameSize, 64, this.g0_mem);
            this.filters.Fir_mem_up(this.high, Codebook_Constants.h1, this.y1, this.fullFrameSize, 64, this.g1_mem);
            for (int i = 0; i < this.fullFrameSize; i++)
            {
                ins0[i] = 2f * (this.y0[i] - this.y1[i]);
            }
            if (num != 0)
            {
                return(0);
            }
            return(1);
        }