Esempio n. 1
0
        public sealed override int Quant(float[] target, float[] sw, int sws, float[] ak, float[] awk1, float[] awk2, float[] exc, int es, int start, int end, float pitch_coef, int p, int nsf, Bits bits, float[] exc2, int e2s, float[] r, int complexity)
        {
            int[] array = new int[1];
            int   num   = 0;
            int   data  = 0;
            int   num2  = 0;
            float num3  = -1f;
            int   num4  = complexity;

            if (num4 > 10)
            {
                num4 = 10;
            }
            int[]   array2 = new int[num4];
            float[] array3 = new float[num4];
            if (num4 == 0 || end < start)
            {
                bits.Pack(0, this.pitch_bits);
                bits.Pack(0, this.gain_bits);
                for (int i = 0; i < nsf; i++)
                {
                    exc[es + i] = 0f;
                }
                return(start);
            }
            float[] array4 = new float[nsf];
            if (num4 > end - start + 1)
            {
                num4 = end - start + 1;
            }
            Ltp.Open_loop_nbest_pitch(sw, sws, start, end, nsf, array2, array3, num4);
            for (int i = 0; i < num4; i++)
            {
                num = array2[i];
                for (int j = 0; j < nsf; j++)
                {
                    exc[es + j] = 0f;
                }
                float num5 = this.Pitch_gain_search_3tap(target, ak, awk1, awk2, exc, es, num, p, nsf, bits, exc2, e2s, r, array);
                if (num5 < num3 || num3 < 0f)
                {
                    for (int j = 0; j < nsf; j++)
                    {
                        array4[j] = exc[es + j];
                    }
                    num3 = num5;
                    num2 = num;
                    data = array[0];
                }
            }
            bits.Pack(num2 - start, this.pitch_bits);
            bits.Pack(data, this.gain_bits);
            for (int i = 0; i < nsf; i++)
            {
                exc[es + i] = array4[i];
            }
            return(num);
        }
Esempio n. 2
0
        /// <summary>
        /// Line Spectral Pair Quantification (Lbr).
        /// </summary>
        public sealed override void Quant(float[] lsp, float[] qlsp, int order, Bits bits)
        {
            int   i;
            float tmp1, tmp2;
            int   id;

            float[] quant_weight = new float[NSpeex.LspQuant.MAX_LSP_SIZE];

            for (i = 0; i < order; i++)
            {
                qlsp[i] = lsp[i];
            }
            quant_weight[0]         = 1 / (qlsp[1] - qlsp[0]);
            quant_weight[order - 1] = 1 / (qlsp[order - 1] - qlsp[order - 2]);
            for (i = 1; i < order - 1; i++)
            {
                tmp1            = 1 / ((.15f + qlsp[i] - qlsp[i - 1]) * (.15f + qlsp[i] - qlsp[i - 1]));
                tmp2            = 1 / ((.15f + qlsp[i + 1] - qlsp[i]) * (.15f + qlsp[i + 1] - qlsp[i]));
                quant_weight[i] = (tmp1 > tmp2) ? tmp1 : tmp2;
            }

            for (i = 0; i < order; i++)
            {
                qlsp[i] -= ((Single?)(.25d * i + .25d)).Value;
            }
            for (i = 0; i < order; i++)
            {
                qlsp[i] *= 256;
            }

            id = NSpeex.LspQuant.Lsp_quant(qlsp, 0,
                                           NSpeex.Codebook_Constants.cdbk_nb,
                                           NSpeex.Codebook_Constants.NB_CDBK_SIZE, order);
            bits.Pack(id, 6);

            for (i = 0; i < order; i++)
            {
                qlsp[i] *= 2;
            }
            id = NSpeex.LspQuant.Lsp_weight_quant(qlsp, 0, quant_weight, 0,
                                                  NSpeex.Codebook_Constants.cdbk_nb_low1,
                                                  NSpeex.Codebook_Constants.NB_CDBK_SIZE_LOW1, 5);
            bits.Pack(id, 6);
            id = NSpeex.LspQuant.Lsp_weight_quant(qlsp, 5, quant_weight, 5,
                                                  NSpeex.Codebook_Constants.cdbk_nb_high1,
                                                  NSpeex.Codebook_Constants.NB_CDBK_SIZE_HIGH1, 5);
            bits.Pack(id, 6);

            for (i = 0; i < order; i++)
            {
                qlsp[i] *= ((Single?)0.0019531d).Value;
            }
            for (i = 0; i < order; i++)
            {
                qlsp[i] = lsp[i] - qlsp[i];
            }
        }
Esempio n. 3
0
        public sealed override void Quant(float[] lsp, float[] qlsp, int order, Bits bits)
        {
            float[] array = new float[20];
            for (int i = 0; i < order; i++)
            {
                qlsp[i] = lsp[i];
            }
            array[0]         = 1f / (qlsp[1] - qlsp[0]);
            array[order - 1] = 1f / (qlsp[order - 1] - qlsp[order - 2]);
            for (int i = 1; i < order - 1; i++)
            {
                float num  = 1f / ((0.15f + qlsp[i] - qlsp[i - 1]) * (0.15f + qlsp[i] - qlsp[i - 1]));
                float num2 = 1f / ((0.15f + qlsp[i + 1] - qlsp[i]) * (0.15f + qlsp[i + 1] - qlsp[i]));
                array[i] = ((num <= num2) ? num2 : num);
            }
            for (int i = 0; i < order; i++)
            {
                qlsp[i] -= new float?((float)(0.25 * (double)i + 0.25)).Value;
            }
            for (int i = 0; i < order; i++)
            {
                qlsp[i] *= 256f;
            }
            int data = LspQuant.Lsp_quant(qlsp, 0, Codebook_Constants.cdbk_nb, 64, order);

            bits.Pack(data, 6);
            for (int i = 0; i < order; i++)
            {
                qlsp[i] *= 2f;
            }
            data = LspQuant.Lsp_weight_quant(qlsp, 0, array, 0, Codebook_Constants.cdbk_nb_low1, 64, 5);
            bits.Pack(data, 6);
            for (int i = 0; i < 5; i++)
            {
                qlsp[i] *= 2f;
            }
            data = LspQuant.Lsp_weight_quant(qlsp, 0, array, 0, Codebook_Constants.cdbk_nb_low2, 64, 5);
            bits.Pack(data, 6);
            data = LspQuant.Lsp_weight_quant(qlsp, 5, array, 5, Codebook_Constants.cdbk_nb_high1, 64, 5);
            bits.Pack(data, 6);
            for (int i = 5; i < 10; i++)
            {
                qlsp[i] *= 2f;
            }
            data = LspQuant.Lsp_weight_quant(qlsp, 5, array, 5, Codebook_Constants.cdbk_nb_high2, 64, 5);
            bits.Pack(data, 6);
            for (int i = 0; i < order; i++)
            {
                qlsp[i] *= new float?((float)0.00097656).Value;
            }
            for (int i = 0; i < order; i++)
            {
                qlsp[i] = lsp[i] - qlsp[i];
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Line Spectral Pair Quantification (high).
        /// </summary>
        public sealed override void Quant(float[] lsp, float[] qlsp, int order, Bits bits)
        {
            int i;
            int id;

            float[] quant_weight = new float[NSpeex.LspQuant.MAX_LSP_SIZE];

            for (i = 0; i < order; i++)
            {
                qlsp[i] = lsp[i];
            }
            quant_weight[0]         = 1.0f / (qlsp[1] - qlsp[0]);
            quant_weight[order - 1] = 1.0f / (qlsp[order - 1] - qlsp[order - 2]);
            for (i = 1; i < order - 1; i++)
            {
                quant_weight[i] = Math.Max(1.0f / (qlsp[i] - qlsp[i - 1]), 1.0f / (qlsp[i + 1] - qlsp[i]));
            }

            for (i = 0; i < order; i++)
            {
                qlsp[i] -= .3125f * i + .75f;
            }
            for (i = 0; i < order; i++)
            {
                qlsp[i] *= 256;
            }
            id = NSpeex.LspQuant.Lsp_quant(qlsp, 0, NSpeex.Codebook_Constants.high_lsp_cdbk, 64, order);
            bits.Pack(id, 6);

            for (i = 0; i < order; i++)
            {
                qlsp[i] *= 2;
            }
            id = NSpeex.LspQuant.Lsp_weight_quant(qlsp, 0, quant_weight, 0, NSpeex.Codebook_Constants.high_lsp_cdbk2, 64, order);
            bits.Pack(id, 6);

            for (i = 0; i < order; i++)
            {
                qlsp[i] *= 0.0019531f;
            }
            for (i = 0; i < order; i++)
            {
                qlsp[i] = lsp[i] - qlsp[i];
            }
        }
Esempio n. 5
0
        public sealed override void Quant(float[] lsp, float[] qlsp, int order, Bits bits)
        {
            float[] array = new float[20];
            for (int i = 0; i < order; i++)
            {
                qlsp[i] = lsp[i];
            }
            array[0]         = 1f / (qlsp[1] - qlsp[0]);
            array[order - 1] = 1f / (qlsp[order - 1] - qlsp[order - 2]);
            for (int i = 1; i < order - 1; i++)
            {
                array[i] = Math.Max(1f / (qlsp[i] - qlsp[i - 1]), 1f / (qlsp[i + 1] - qlsp[i]));
            }
            for (int i = 0; i < order; i++)
            {
                qlsp[i] -= 0.3125f * (float)i + 0.75f;
            }
            for (int i = 0; i < order; i++)
            {
                qlsp[i] *= 256f;
            }
            int data = LspQuant.Lsp_quant(qlsp, 0, Codebook_Constants.high_lsp_cdbk, 64, order);

            bits.Pack(data, 6);
            for (int i = 0; i < order; i++)
            {
                qlsp[i] *= 2f;
            }
            data = LspQuant.Lsp_weight_quant(qlsp, 0, array, 0, Codebook_Constants.high_lsp_cdbk2, 64, order);
            bits.Pack(data, 6);
            for (int i = 0; i < order; i++)
            {
                qlsp[i] *= 0.0019531f;
            }
            for (int i = 0; i < order; i++)
            {
                qlsp[i] = lsp[i] - qlsp[i];
            }
        }
Esempio n. 6
0
        /// <summary>
        ///  Transforms a stereo frame into a mono frame and stores intensity stereo
        /// </summary>
        /// <param name="bits"></param>
        /// <param name="data"></param>
        /// <param name="frameSize"></param>
        public static void encode(Bits bits, float[] data, int frameSize)
        {
            int   i, tmp;
            float e_left = 0, e_right = 0, e_tot = 0;
            float balance, e_ratio;

            for (i = 0; i < frameSize; i++)
            {
                e_left  += data[2 * i] * data[2 * i];
                e_right += data[2 * i + 1] * data[2 * i + 1];
                data[i]  = .5f * (data[2 * i] + data[2 * i + 1]);
                e_tot   += data[i] * data[i];
            }
            balance = (e_left + 1) / (e_right + 1);
            e_ratio = e_tot / (1 + e_left + e_right);
            /*Quantization*/
            bits.Pack(14, 5);
            bits.Pack(SPEEX_INBAND_STEREO, 4);
            balance = (float)(4 * Math.Log(balance));

            /*Pack balance*/
            if (balance > 0)
            {
                bits.Pack(0, 1);
            }
            else
            {
                bits.Pack(1, 1);
            }
            balance = (float)Math.Floor(.5f + Math.Abs(balance));
            if (balance > 30)
            {
                balance = 31;
            }
            bits.Pack((int)balance, 5);

            /*Quantize energy ratio*/
            tmp = VQ.index(e_ratio, e_ratio_quant, 4);
            bits.Pack(tmp, 2);
        }
Esempio n. 7
0
        public static void Encode(Bits bits, float[] data, int frameSize)
        {
            float num  = 0f;
            float num2 = 0f;
            float num3 = 0f;

            for (int i = 0; i < frameSize; i++)
            {
                num    += data[2 * i] * data[2 * i];
                num2   += data[2 * i + 1] * data[2 * i + 1];
                data[i] = 0.5f * (data[2 * i] + data[2 * i + 1]);
                num3   += data[i] * data[i];
            }
            float num4 = (num + 1f) / (num2 + 1f);
            float ins  = num3 / (1f + num + num2);

            bits.Pack(14, 5);
            bits.Pack(9, 4);
            num4 = (float)(4.0 * Math.Log((double)num4));
            if (num4 > 0f)
            {
                bits.Pack(0, 1);
            }
            else
            {
                bits.Pack(1, 1);
            }
            num4 = (float)Math.Floor((double)(0.5f + Math.Abs(num4)));
            if (num4 > 30f)
            {
                num4 = 31f;
            }
            bits.Pack((int)num4, 5);
            int data2 = VQ.Index(ins, Stereo.e_ratio_quant, 4);

            bits.Pack(data2, 2);
        }
        /// <summary>
        /// Encode the given input signal.
        /// </summary>
        /// <returns>return 1 if successful.</returns>
        public virtual int Encode(Bits bits, float[] ins0)
        {
            int i;

            float[] res, target, mem;
            float[] syn_resp;
            float[] orig;

            /* Copy new data in input buffer */
            System.Array.Copy(frmBuf, frameSize, frmBuf, 0, bufSize
                              - frameSize);
            frmBuf[bufSize - frameSize] = ins0[0] - preemph * pre_mem;
            for (i = 1; i < frameSize; i++)
            {
                frmBuf[bufSize - frameSize + i] = ins0[i] - preemph * ins0[i - 1];
            }
            pre_mem = ins0[frameSize - 1];

            /* Move signals 1 frame towards the past */
            System.Array.Copy(exc2Buf, frameSize, exc2Buf, 0, bufSize
                              - frameSize);
            System.Array.Copy(excBuf, frameSize, excBuf, 0, bufSize
                              - frameSize);
            System.Array.Copy(swBuf, frameSize, swBuf, 0, bufSize
                              - frameSize);

            /* Window for analysis */
            for (i = 0; i < windowSize; i++)
            {
                buf2[i] = frmBuf[i + frmIdx] * window[i];
            }

            /* Compute auto-correlation */
            NSpeex.Lpc.Autocorr(buf2, autocorr, lpcSize + 1, windowSize);

            autocorr[0] += 10;             /* prevents NANs */
            autocorr[0] *= lpc_floor;      /* Noise floor in auto-correlation domain */

            /* Lag windowing: equivalent to filtering in the power-spectrum domain */
            for (i = 0; i < lpcSize + 1; i++)
            {
                autocorr[i] *= lagWindow[i];
            }

            /* Levinson-Durbin */
            NSpeex.Lpc.Wld(lpc, autocorr, rc, lpcSize);             // tmperr
            System.Array.Copy(lpc, 0, lpc, 1, lpcSize);
            lpc[0] = 1;

            /* LPC to LSPs (x-domain) transform */
            int roots = NSpeex.Lsp.Lpc2lsp(lpc, lpcSize, lsp, 15, 0.2f);

            /* Check if we found all the roots */
            if (roots == lpcSize)
            {
                /* LSP x-domain to angle domain */
                for (i = 0; i < lpcSize; i++)
                {
                    lsp[i] = (float)System.Math.Acos(lsp[i]);
                }
            }
            else
            {
                /* Search again if we can afford it */
                if (complexity > 1)
                {
                    roots = NSpeex.Lsp.Lpc2lsp(lpc, lpcSize, lsp, 11, 0.05f);
                }
                if (roots == lpcSize)
                {
                    /* LSP x-domain to angle domain */
                    for (i = 0; i < lpcSize; i++)
                    {
                        lsp[i] = (float)System.Math.Acos(lsp[i]);
                    }
                }
                else
                {
                    /*
                     * If we can't find all LSP's, do some damage control and use
                     * previous filter
                     */
                    for (i = 0; i < lpcSize; i++)
                    {
                        lsp[i] = old_lsp[i];
                    }
                }
            }

            float lsp_dist = 0;

            for (i = 0; i < lpcSize; i++)
            {
                lsp_dist += (old_lsp[i] - lsp[i]) * (old_lsp[i] - lsp[i]);
            }

            /*
             * Whole frame analysis (open-loop estimation of pitch and excitation
             * gain)
             */
            float ol_gain;
            int   ol_pitch;
            float ol_pitch_coef;

            {
                if (first != 0)
                {
                    for (i = 0; i < lpcSize; i++)
                    {
                        interp_lsp[i] = lsp[i];
                    }
                }
                else
                {
                    for (i = 0; i < lpcSize; i++)
                    {
                        interp_lsp[i] = .375f * old_lsp[i] + .625f * lsp[i];
                    }
                }

                NSpeex.Lsp.Enforce_margin(interp_lsp, lpcSize, .002f);

                /* Compute interpolated LPCs (unquantized) for whole frame */
                for (i = 0; i < lpcSize; i++)
                {
                    interp_lsp[i] = (float)System.Math.Cos(interp_lsp[i]);
                }
                m_lsp.Lsp2lpc(interp_lsp, interp_lpc, lpcSize);

                /* Open-loop pitch */
                if (submodes[submodeID] == null || vbr_enabled != 0 ||
                    vad_enabled != 0 ||
                    submodes[submodeID].ForcedPitchGain != 0 ||
                    submodes[submodeID].LbrPitch != -1)
                {
                    int[]   nol_pitch      = new int[6];
                    float[] nol_pitch_coef = new float[6];

                    NSpeex.Filters.Bw_lpc(gamma1, interp_lpc, bw_lpc1, lpcSize);
                    NSpeex.Filters.Bw_lpc(gamma2, interp_lpc, bw_lpc2, lpcSize);

                    NSpeex.Filters.Filter_mem2(frmBuf, frmIdx, bw_lpc1, bw_lpc2,
                                               swBuf, swIdx, frameSize, lpcSize, mem_sw_whole, 0);

                    NSpeex.Ltp.Open_loop_nbest_pitch(swBuf, swIdx, min_pitch,
                                                     max_pitch, frameSize, nol_pitch, nol_pitch_coef, 6);
                    ol_pitch      = nol_pitch[0];
                    ol_pitch_coef = nol_pitch_coef[0];
                    /* Try to remove pitch multiples */
                    for (i = 1; i < 6; i++)
                    {
                        if ((nol_pitch_coef[i] > .85d * ol_pitch_coef) &&
                            (Math.Abs(nol_pitch[i] - ol_pitch
                                      / 2.0d) <= 1 ||
                             Math.Abs(nol_pitch[i]
                                      - ol_pitch / 3.0d) <= 1 ||
                             Math.Abs(nol_pitch[i]
                                      - ol_pitch / 4.0d) <= 1 || Math.Abs(nol_pitch[i] - ol_pitch / 5.0d) <= 1))
                        {
                            /* ol_pitch_coef=nol_pitch_coef[i]; */
                            ol_pitch = nol_pitch[i];
                        }
                    }

                    /*
                     * if (ol_pitch>50) ol_pitch/=2;
                     */
                    /* ol_pitch_coef = sqrt(ol_pitch_coef); */
                }
                else
                {
                    ol_pitch      = 0;
                    ol_pitch_coef = 0;
                }
                /* Compute "real" excitation */
                NSpeex.Filters.Fir_mem2(frmBuf, frmIdx, interp_lpc, excBuf, excIdx,
                                        frameSize, lpcSize, mem_exc);

                /* Compute open-loop excitation gain */
                ol_gain = 0;
                for (i = 0; i < frameSize; i++)
                {
                    ol_gain += excBuf[excIdx + i] * excBuf[excIdx + i];
                }

                ol_gain = (float)Math.Sqrt(1 + ol_gain / frameSize);
            }

            /* VBR stuff */
            if (vbr != null && (vbr_enabled != 0 || vad_enabled != 0))
            {
                if (abr_enabled != 0)
                {
                    float qual_change = 0;
                    if (abr_drift2 * abr_drift > 0)
                    {
                        /*
                         * Only adapt if long-term and short-term drift are the same
                         * sign
                         */
                        qual_change = -.00001f * abr_drift / (1 + abr_count);
                        if (qual_change > .05f)
                        {
                            qual_change = .05f;
                        }
                        if (qual_change < -.05f)
                        {
                            qual_change = -.05f;
                        }
                    }
                    vbr_quality += qual_change;
                    if (vbr_quality > 10)
                    {
                        vbr_quality = 10;
                    }
                    if (vbr_quality < 0)
                    {
                        vbr_quality = 0;
                    }
                }
                relative_quality = vbr.Analysis(ins0, frameSize, ol_pitch,
                                                ol_pitch_coef);
                /* if (delta_qual<0) */
                /* delta_qual*=.1*(3+st->vbr_quality); */
                if (vbr_enabled != 0)
                {
                    int   mode;
                    int   choice   = 0;
                    float min_diff = 100;
                    mode = 8;
                    while (mode > 0)
                    {
                        int   v1;
                        float thresh;
                        v1 = (int)Math.Floor(vbr_quality);
                        if (v1 == 10)
                        {
                            thresh = NSpeex.Vbr.nb_thresh[mode][v1];
                        }
                        else
                        {
                            thresh = (vbr_quality - v1)
                                     * NSpeex.Vbr.nb_thresh[mode][v1 + 1]
                                     + (1 + v1 - vbr_quality)
                                     * NSpeex.Vbr.nb_thresh[mode][v1];
                        }
                        if (relative_quality > thresh &&
                            relative_quality - thresh < min_diff)
                        {
                            choice   = mode;
                            min_diff = relative_quality - thresh;
                        }
                        mode--;
                    }
                    mode = choice;
                    if (mode == 0)
                    {
                        if (dtx_count == 0 || lsp_dist > .05d || dtx_enabled == 0 ||
                            dtx_count > 20)
                        {
                            mode      = 1;
                            dtx_count = 1;
                        }
                        else
                        {
                            mode = 0;
                            dtx_count++;
                        }
                    }
                    else
                    {
                        dtx_count = 0;
                    }
                    Mode = mode;

                    if (abr_enabled != 0)
                    {
                        int bitrate;
                        bitrate    = BitRate;
                        abr_drift += (bitrate - abr_enabled);
                        abr_drift2 = .95f * abr_drift2 + .05f
                                     * (bitrate - abr_enabled);
                        abr_count += ((Single?)1.0d).Value;
                    }
                }
                else
                {
                    /* VAD only case */
                    int mode_0;
                    if (relative_quality < 2)
                    {
                        if (dtx_count == 0 || lsp_dist > .05d || dtx_enabled == 0 ||
                            dtx_count > 20)
                        {
                            dtx_count = 1;
                            mode_0    = 1;
                        }
                        else
                        {
                            mode_0 = 0;
                            dtx_count++;
                        }
                    }
                    else
                    {
                        dtx_count = 0;
                        mode_0    = submodeSelect;
                    }
                    /* speex_encoder_ctl(state, SPEEX_SET_MODE, &mode); */
                    submodeID = mode_0;
                }
            }
            else
            {
                relative_quality = -1;
            }

            /* First, transmit a zero for narrowband */
            bits.Pack(0, 1);

            /* Transmit the sub-mode we use for this frame */
            bits.Pack(submodeID, NSpeex.NbCodec.NB_SUBMODE_BITS);

            /* If null mode (no transmission), just set a couple things to zero */
            if (submodes[submodeID] == null)
            {
                for (i = 0; i < frameSize; i++)
                {
                    excBuf[excIdx + i] = exc2Buf[exc2Idx + i] = swBuf[swIdx + i] = NSpeex.NbCodec.VERY_SMALL;
                }

                for (i = 0; i < lpcSize; i++)
                {
                    mem_sw[i] = 0;
                }
                first         = 1;
                bounded_pitch = 1;

                /* Final signal synthesis from excitation */
                NSpeex.Filters.Iir_mem2(excBuf, excIdx, interp_qlpc, frmBuf, frmIdx,
                                        frameSize, lpcSize, mem_sp);

                ins0[0] = frmBuf[frmIdx] + preemph * pre_mem2;
                for (i = 1; i < frameSize; i++)
                {
                    ins0[i] = frmBuf[frmIdx = i] + preemph * ins0[i - 1];
                }
                pre_mem2 = ins0[frameSize - 1];

                return(0);
            }

            /* LSP Quantization */
            if (first != 0)
            {
                for (i = 0; i < lpcSize; i++)
                {
                    old_lsp[i] = lsp[i];
                }
            }

            /* Quantize LSPs */
            // #if 1 /*0 for unquantized*/
            submodes[submodeID].LsqQuant.Quant(lsp, qlsp, lpcSize, bits);
            // #else
            // for (i=0;i<lpcSize;i++)
            // qlsp[i]=lsp[i];
            // #endif

            /* If we use low bit-rate pitch mode, transmit open-loop pitch */
            if (submodes[submodeID].LbrPitch != -1)
            {
                bits.Pack(ol_pitch - min_pitch, 7);
            }

            if (submodes[submodeID].ForcedPitchGain != 0)
            {
                int quant;
                quant = (int)Math.Floor(.5d + 15 * ol_pitch_coef);
                if (quant > 15)
                {
                    quant = 15;
                }
                if (quant < 0)
                {
                    quant = 0;
                }
                bits.Pack(quant, 4);
                ol_pitch_coef = (float)0.066667d * quant;
            }

            /* Quantize and transmit open-loop excitation gain */
            {
                int qe = (int)(Math.Floor(0.5d + 3.5d * Math.Log(ol_gain)));
                if (qe < 0)
                {
                    qe = 0;
                }
                if (qe > 31)
                {
                    qe = 31;
                }
                ol_gain = (float)Math.Exp(qe / 3.5d);
                bits.Pack(qe, 5);
            }

            /* Special case for first frame */
            if (first != 0)
            {
                for (i = 0; i < lpcSize; i++)
                {
                    old_qlsp[i] = qlsp[i];
                }
            }

            /* Filter response */
            res = new float[subframeSize];
            /* Target signal */
            target   = new float[subframeSize];
            syn_resp = new float[subframeSize];
            mem      = new float[lpcSize];
            orig     = new float[frameSize];
            for (i = 0; i < frameSize; i++)
            {
                orig[i] = frmBuf[frmIdx + i];
            }

            /* Loop on sub-frames */
            for (int sub = 0; sub < nbSubframes; sub++)
            {
                float tmp;
                int   offset;
                int   sp, sw, exc, exc2;
                int   pitchval;

                /* Offset relative to start of frame */
                offset = subframeSize * sub;
                /* Original signal */
                sp = frmIdx + offset;
                /* Excitation */
                exc = excIdx + offset;
                /* Weighted signal */
                sw = swIdx + offset;

                exc2 = exc2Idx + offset;

                /* LSP interpolation (quantized and unquantized) */
                tmp = (float)(1.0d + sub) / nbSubframes;
                for (i = 0; i < lpcSize; i++)
                {
                    interp_lsp[i] = (1 - tmp) * old_lsp[i] + tmp * lsp[i];
                }
                for (i = 0; i < lpcSize; i++)
                {
                    interp_qlsp[i] = (1 - tmp) * old_qlsp[i] + tmp * qlsp[i];
                }

                /* Make sure the filters are stable */
                NSpeex.Lsp.Enforce_margin(interp_lsp, lpcSize, .002f);
                NSpeex.Lsp.Enforce_margin(interp_qlsp, lpcSize, .002f);

                /* Compute interpolated LPCs (quantized and unquantized) */
                for (i = 0; i < lpcSize; i++)
                {
                    interp_lsp[i] = (float)System.Math.Cos(interp_lsp[i]);
                }
                m_lsp.Lsp2lpc(interp_lsp, interp_lpc, lpcSize);

                for (i = 0; i < lpcSize; i++)
                {
                    interp_qlsp[i] = (float)System.Math.Cos(interp_qlsp[i]);
                }
                m_lsp.Lsp2lpc(interp_qlsp, interp_qlpc, lpcSize);

                /* Compute analysis filter gain at w=pi (for use in SB-CELP) */
                tmp          = 1;
                pi_gain[sub] = 0;
                for (i = 0; i <= lpcSize; i++)
                {
                    pi_gain[sub] += tmp * interp_qlpc[i];
                    tmp           = -tmp;
                }

                /*
                 * Compute bandwidth-expanded (unquantized) LPCs for perceptual
                 * weighting
                 */
                NSpeex.Filters.Bw_lpc(gamma1, interp_lpc, bw_lpc1, lpcSize);
                if (gamma2 >= 0)
                {
                    NSpeex.Filters.Bw_lpc(gamma2, interp_lpc, bw_lpc2, lpcSize);
                }
                else
                {
                    bw_lpc2[0] = 1;
                    bw_lpc2[1] = -preemph;
                    for (i = 2; i <= lpcSize; i++)
                    {
                        bw_lpc2[i] = 0;
                    }
                }

                /* Compute impulse response of A(z/g1) / ( A(z)*A(z/g2) ) */
                for (i = 0; i < subframeSize; i++)
                {
                    excBuf[exc + i] = 0;
                }
                excBuf[exc] = 1;
                NSpeex.Filters.Syn_percep_zero(excBuf, exc, interp_qlpc, bw_lpc1,
                                               bw_lpc2, syn_resp, subframeSize, lpcSize);

                /* Reset excitation */
                for (i = 0; i < subframeSize; i++)
                {
                    excBuf[exc + i] = 0;
                }
                for (i = 0; i < subframeSize; i++)
                {
                    exc2Buf[exc2 + i] = 0;
                }

                /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */
                for (i = 0; i < lpcSize; i++)
                {
                    mem[i] = mem_sp[i];
                }
                NSpeex.Filters.Iir_mem2(excBuf, exc, interp_qlpc, excBuf, exc,
                                        subframeSize, lpcSize, mem);

                for (i = 0; i < lpcSize; i++)
                {
                    mem[i] = mem_sw[i];
                }
                NSpeex.Filters.Filter_mem2(excBuf, exc, bw_lpc1, bw_lpc2, res, 0,
                                           subframeSize, lpcSize, mem, 0);

                /* Compute weighted signal */
                for (i = 0; i < lpcSize; i++)
                {
                    mem[i] = mem_sw[i];
                }
                NSpeex.Filters.Filter_mem2(frmBuf, sp, bw_lpc1, bw_lpc2, swBuf, sw,
                                           subframeSize, lpcSize, mem, 0);

                /* Compute target signal */
                for (i = 0; i < subframeSize; i++)
                {
                    target[i] = swBuf[sw + i] - res[i];
                }

                for (i = 0; i < subframeSize; i++)
                {
                    excBuf[exc + i] = exc2Buf[exc2 + i] = 0;
                }

                /* If we have a long-term predictor (otherwise, something's wrong) */
                // if (submodes[submodeID].ltp.quant)
                // {
                int pit_min, pit_max;
                /* Long-term prediction */
                if (submodes[submodeID].LbrPitch != -1)
                {
                    /* Low bit-rate pitch handling */
                    int margin;
                    margin = submodes[submodeID].LbrPitch;
                    if (margin != 0)
                    {
                        if (ol_pitch < min_pitch + margin - 1)
                        {
                            ol_pitch = min_pitch + margin - 1;
                        }
                        if (ol_pitch > max_pitch - margin)
                        {
                            ol_pitch = max_pitch - margin;
                        }
                        pit_min = ol_pitch - margin + 1;
                        pit_max = ol_pitch + margin;
                    }
                    else
                    {
                        pit_min = pit_max = ol_pitch;
                    }
                }
                else
                {
                    pit_min = min_pitch;
                    pit_max = max_pitch;
                }

                /* Force pitch to use only the current frame if needed */
                if (bounded_pitch != 0 && pit_max > offset)
                {
                    pit_max = offset;
                }

                /* Perform pitch search */
                pitchval = submodes[submodeID].Ltp.Quant(target, swBuf, sw,
                                                         interp_qlpc, bw_lpc1, bw_lpc2, excBuf, exc, pit_min,
                                                         pit_max, ol_pitch_coef, lpcSize, subframeSize, bits,
                                                         exc2Buf, exc2, syn_resp, complexity);

                pitch[sub] = pitchval;

                // } else {
                // speex_error ("No pitch prediction, what's wrong");
                // }

                /* Update target for adaptive codebook contribution */
                NSpeex.Filters.Syn_percep_zero(excBuf, exc, interp_qlpc, bw_lpc1,
                                               bw_lpc2, res, subframeSize, lpcSize);
                for (i = 0; i < subframeSize; i++)
                {
                    target[i] -= res[i];
                }

                /* Quantization of innovation */
                {
                    int   innovptr;
                    float ener = 0, ener_1;

                    innovptr = sub * subframeSize;
                    for (i = 0; i < subframeSize; i++)
                    {
                        innov[innovptr + i] = 0;
                    }

                    NSpeex.Filters.Residue_percep_zero(target, 0, interp_qlpc,
                                                       bw_lpc1, bw_lpc2, buf2, subframeSize, lpcSize);
                    for (i = 0; i < subframeSize; i++)
                    {
                        ener += buf2[i] * buf2[i];
                    }
                    ener = (float)Math.Sqrt(.1f + ener / subframeSize);

                    /*
                     * for (i=0;i<subframeSize;i++) System.out.print(buf2[i]/ener +
                     * "\t");
                     */

                    ener /= ol_gain;

                    /* Calculate gain correction for the sub-frame (if any) */
                    if (submodes[submodeID].HaveSubframeGain != 0)
                    {
                        int qe_1;
                        ener = (float)Math.Log(ener);
                        if (submodes[submodeID].HaveSubframeGain == 3)
                        {
                            qe_1 = NSpeex.VQ.Index(ener,
                                                   NSpeex.NbCodec.exc_gain_quant_scal3, 8);
                            bits.Pack(qe_1, 3);
                            ener = NSpeex.NbCodec.exc_gain_quant_scal3[qe_1];
                        }
                        else
                        {
                            qe_1 = NSpeex.VQ.Index(ener,
                                                   NSpeex.NbCodec.exc_gain_quant_scal1, 2);
                            bits.Pack(qe_1, 1);
                            ener = NSpeex.NbCodec.exc_gain_quant_scal1[qe_1];
                        }
                        ener = (float)Math.Exp(ener);
                    }
                    else
                    {
                        ener = 1;
                    }

                    ener *= ol_gain;

                    /* System.out.println(ener + " " + ol_gain); */

                    ener_1 = 1 / ener;

                    /* Normalize innovation */
                    for (i = 0; i < subframeSize; i++)
                    {
                        target[i] *= ener_1;
                    }

                    /* Quantize innovation */
                    // if (submodes[submodeID].innovation != null)
                    // {
                    /* Codebook search */
                    submodes[submodeID].Innovation.Quantify(target, interp_qlpc,
                                                            bw_lpc1, bw_lpc2, lpcSize, subframeSize, innov,
                                                            innovptr, syn_resp, bits, complexity);

                    /* De-normalize innovation and update excitation */
                    for (i = 0; i < subframeSize; i++)
                    {
                        innov[innovptr + i] *= ener;
                    }
                    for (i = 0; i < subframeSize; i++)
                    {
                        excBuf[exc + i] += innov[innovptr + i];
                    }
                    // } else {
                    // speex_error("No fixed codebook");
                    // }

                    /*
                     * In some (rare) modes, we do a second search (more bits) to
                     * reduce noise even more
                     */
                    if (submodes[submodeID].DoubleCodebook != 0)
                    {
                        float[] innov2_2 = new float[subframeSize];
                        // for (i=0;i<subframeSize;i++)
                        // innov2[i]=0;
                        for (i = 0; i < subframeSize; i++)
                        {
                            target[i] *= 2.2f;
                        }
                        submodes[submodeID].Innovation.Quantify(target, interp_qlpc,
                                                                bw_lpc1, bw_lpc2, lpcSize, subframeSize, innov2_2,
                                                                0, syn_resp, bits, complexity);
                        for (i = 0; i < subframeSize; i++)
                        {
                            innov2_2[i] *= (float)(ener * (1 / 2.2d));
                        }
                        for (i = 0; i < subframeSize; i++)
                        {
                            excBuf[exc + i] += innov2_2[i];
                        }
                    }

                    for (i = 0; i < subframeSize; i++)
                    {
                        target[i] *= ener;
                    }
                }

                /* Keep the previous memory */
                for (i = 0; i < lpcSize; i++)
                {
                    mem[i] = mem_sp[i];
                }
                /* Final signal synthesis from excitation */
                NSpeex.Filters.Iir_mem2(excBuf, exc, interp_qlpc, frmBuf, sp,
                                        subframeSize, lpcSize, mem_sp);

                /*
                 * Compute weighted signal again, from synthesized speech (not sure
                 * it's the right thing)
                 */
                NSpeex.Filters.Filter_mem2(frmBuf, sp, bw_lpc1, bw_lpc2, swBuf, sw,
                                           subframeSize, lpcSize, mem_sw, 0);
                for (i = 0; i < subframeSize; i++)
                {
                    exc2Buf[exc2 + i] = excBuf[exc + i];
                }
            }

            /* Store the LSPs for interpolation in the next frame */
            if (submodeID >= 1)
            {
                for (i = 0; i < lpcSize; i++)
                {
                    old_lsp[i] = lsp[i];
                }
                for (i = 0; i < lpcSize; i++)
                {
                    old_qlsp[i] = qlsp[i];
                }
            }

            if (submodeID == 1)
            {
                if (dtx_count != 0)
                {
                    bits.Pack(15, 4);
                }
                else
                {
                    bits.Pack(0, 4);
                }
            }

            /* The next frame will not be the first (Duh!) */
            first = 0;

            {
                float ener_3 = 0, err = 0;
                float snr;
                for (i = 0; i < frameSize; i++)
                {
                    ener_3 += frmBuf[frmIdx + i] * frmBuf[frmIdx + i];
                    err    += (frmBuf[frmIdx + i] - orig[i])
                              * (frmBuf[frmIdx + i] - orig[i]);
                }
                snr = (float)(10 * Math.Log((ener_3 + 1) / (err + 1)));

                /*
                 * System.out.println("Frame result: SNR="+snr+" E="+ener+"
                 * Err="+err+"\r\n");
                 */
            }

            /* Replace input by synthesized speech */
            ins0[0] = frmBuf[frmIdx] + preemph * pre_mem2;
            for (i = 1; i < frameSize; i++)
            {
                ins0[i] = frmBuf[frmIdx + i] + preemph * ins0[i - 1];
            }
            pre_mem2 = ins0[frameSize - 1];

            if (submodes[submodeID].Innovation is NoiseSearch || submodeID == 0)
            {
                bounded_pitch = 1;
            }
            else
            {
                bounded_pitch = 0;
            }

            return(1);
        }
Esempio n. 9
0
        /// <summary>
        /// Long Term Prediction Quantification (3Tap).
        /// </summary>
        /// <returns>pitch</returns>
        public sealed override int Quant(
            float[] target, float[] sw, int sws, float[] ak,
            float[] awk1, float[] awk2, float[] exc, int es, int start,
            int end, float pitch_coef, int p, int nsf, Bits bits, float[] exc2,
            int e2s, float[] r, int complexity)
        {
            int i, j;

            int[] cdbk_index = new int[1];
            int   pitch = 0, best_gain_index = 0;

            float[] best_exc;
            int     best_pitch = 0;
            float   err, best_err = -1;
            int     N;

            int[]   nbest;
            float[] gains;

            N = complexity;
            if (N > 10)
            {
                N = 10;
            }

            nbest = new int[N];
            gains = new float[N];

            if (N == 0 || end < start)
            {
                bits.Pack(0, pitch_bits);
                bits.Pack(0, gain_bits);
                for (i = 0; i < nsf; i++)
                {
                    exc[es + i] = 0;
                }
                return(start);
            }

            best_exc = new float[nsf];

            if (N > end - start + 1)
            {
                N = end - start + 1;
            }
            NSpeex.Ltp.Open_loop_nbest_pitch(sw, sws, start, end, nsf, nbest, gains, N);

            for (i = 0; i < N; i++)
            {
                pitch = nbest[i];
                for (j = 0; j < nsf; j++)
                {
                    exc[es + j] = 0;
                }
                err = Pitch_gain_search_3tap(target, ak, awk1, awk2, exc, es,
                                             pitch, p, nsf, bits, exc2, e2s, r, cdbk_index);
                if (err < best_err || best_err < 0)
                {
                    for (j = 0; j < nsf; j++)
                    {
                        best_exc[j] = exc[es + j];
                    }
                    best_err        = err;
                    best_pitch      = pitch;
                    best_gain_index = cdbk_index[0];
                }
            }

            bits.Pack(best_pitch - start, pitch_bits);
            bits.Pack(best_gain_index, gain_bits);
            for (i = 0; i < nsf; i++)
            {
                exc[es + i] = best_exc[i];
            }

            return(pitch);
        }
Esempio n. 10
0
        /// <summary>
        /// Encode the given input signal.
        /// </summary>
        /// <param name="bits">Speex bits buffer.</param>
        /// <param name="vin">the raw mono audio frame to encode</param>
        /// <returns>1 if successful.</returns>
        public int Encode(Bits bits, float[] vin)
        {
            int i;

            float[] mem, innov, syn_resp;
            float[] low_pi_gain, low_exc, low_innov;
            int     dtx;

            /* Compute the two sub-bands by filtering with h0 and h1*/
            Filters.qmf_decomp(vin, h0, x0d, x1d, fullFrameSize, QMF_ORDER, h0_mem);
            /* Encode the narrowband part*/
            lowenc.Encode(bits, x0d);

            /* High-band buffering / sync with low band */
            for (i = 0; i < windowSize - frameSize; i++)
            {
                high[i] = high[frameSize + i];
            }
            for (i = 0; i < frameSize; i++)
            {
                high[windowSize - frameSize + i] = x1d[i];
            }

            Array.Copy(excBuf, frameSize, excBuf, 0, bufSize - frameSize);

            low_pi_gain = lowenc.PitchGain;
            low_exc     = lowenc.Excitation;
            low_innov   = lowenc.Innovation;


            int low_mode = lowenc.Mode;

            if (low_mode == 0)
            {
                dtx = 1;
            }
            else
            {
                dtx = 0;
            }

            /* Start encoding the high-band */
            for (i = 0; i < windowSize; i++)
            {
                buf[i] = high[i] * window[i];
            }

            /* Compute auto-correlation */
            Lpc.autocorr(buf, autocorr, lpcSize + 1, windowSize);

            autocorr[0] += 1;         /* prevents NANs */
            autocorr[0] *= lpc_floor; /* Noise floor in auto-correlation domain */
            /* Lag windowing: equivalent to filtering in the power-spectrum domain */
            for (i = 0; i < lpcSize + 1; i++)
            {
                autocorr[i] *= lagWindow[i];
            }

            /* Levinson-Durbin */
            Lpc.wld(lpc, autocorr, rc, lpcSize); // tmperr
            Array.Copy(lpc, 0, lpc, 1, lpcSize);
            lpc[0] = 1;
            /* LPC to LSPs (x-domain) transform */
            int roots = Lsp.lpc2lsp(lpc, lpcSize, lsp, 15, 0.2f);

            if (roots != lpcSize)
            {
                roots = Lsp.lpc2lsp(lpc, lpcSize, lsp, 11, 0.02f);
                if (roots != lpcSize)
                {
                    /*If we can't find all LSP's, do some damage control and use a flat filter*/
                    for (i = 0; i < lpcSize; i++)
                    {
                        lsp[i] = (float)Math.Cos(Math.PI * ((float)(i + 1)) / (lpcSize + 1));
                    }
                }
            }
            /* x-domain to angle domain*/
            for (i = 0; i < lpcSize; i++)
            {
                lsp[i] = (float)Math.Acos(lsp[i]);
            }

            float lsp_dist = 0;

            for (i = 0; i < lpcSize; i++)
            {
                lsp_dist += (old_lsp[i] - lsp[i]) * (old_lsp[i] - lsp[i]);
            }
            /*VBR stuff*/
            if ((vbr_enabled != 0 || vad_enabled != 0) && dtx == 0)
            {
                float e_low = 0, e_high = 0;
                float ratio;
                if (abr_enabled != 0)
                {
                    float qual_change = 0;
                    if (abr_drift2 * abr_drift > 0)
                    {
                        /* Only adapt if long-term and short-term drift are the same sign */
                        qual_change = -.00001f * abr_drift / (1 + abr_count);
                        if (qual_change > .1f)
                        {
                            qual_change = .1f;
                        }
                        if (qual_change < -.1f)
                        {
                            qual_change = -.1f;
                        }
                    }
                    vbr_quality += qual_change;
                    if (vbr_quality > 10)
                    {
                        vbr_quality = 10;
                    }
                    if (vbr_quality < 0)
                    {
                        vbr_quality = 0;
                    }
                }
                for (i = 0; i < frameSize; i++)
                {
                    e_low  += x0d[i] * x0d[i];
                    e_high += high[i] * high[i];
                }
                ratio            = (float)Math.Log((1 + e_high) / (1 + e_low));
                relative_quality = lowenc.RelativeQuality;

                if (ratio < -4)
                {
                    ratio = -4;
                }
                if (ratio > 2)
                {
                    ratio = 2;
                }
                /*if (ratio>-2)*/
                if (vbr_enabled != 0)
                {
                    int modeid;
                    modeid            = nb_modes - 1;
                    relative_quality += 1.0f * (ratio + 2f);
                    if (relative_quality < -1)
                    {
                        relative_quality = -1;
                    }
                    while (modeid != 0)
                    {
                        int   v1;
                        float thresh;
                        v1 = (int)Math.Floor(vbr_quality);
                        if (v1 == 10)
                        {
                            thresh = NSpeex.Vbr.hb_thresh[modeid][v1];
                        }
                        else
                        {
                            thresh = (vbr_quality - v1) * NSpeex.Vbr.hb_thresh[modeid][v1 + 1] + (1 + v1 - vbr_quality) * NSpeex.Vbr.hb_thresh[modeid][v1];
                        }
                        if (relative_quality >= thresh)
                        {
                            break;
                        }
                        modeid--;
                    }
                    Mode = modeid;
                    if (abr_enabled != 0)
                    {
                        int bitrate = BitRate;
                        abr_drift += (bitrate - abr_enabled);
                        abr_drift2 = .95f * abr_drift2 + .05f * (bitrate - abr_enabled);
                        abr_count += 1.0f;
                    }
                }
                else
                {
                    /* VAD only */
                    int modeid;
                    if (relative_quality < 2.0)
                    {
                        modeid = 1;
                    }
                    else
                    {
                        modeid = submodeSelect;
                    }
                    /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/
                    submodeID = modeid;
                }
            }
            bits.Pack(1, 1);
            if (dtx != 0)
            {
                bits.Pack(0, SB_SUBMODE_BITS);
            }
            else
            {
                bits.Pack(submodeID, SB_SUBMODE_BITS);
            }
            /* If null mode (no transmission), just set a couple things to zero*/
            if (dtx != 0 || submodes[submodeID] == null)
            {
                for (i = 0; i < frameSize; i++)
                {
                    excBuf[excIdx + i] = swBuf[i] = VERY_SMALL;
                }

                for (i = 0; i < lpcSize; i++)
                {
                    mem_sw[i] = 0;
                }
                first = 1;

                /* Final signal synthesis from excitation */
                Filters.iir_mem2(excBuf, excIdx, interp_qlpc, high, 0, subframeSize, lpcSize, mem_sp);

                /* Reconstruct the original */
                filters.fir_mem_up(x0d, h0, y0, fullFrameSize, QMF_ORDER, g0_mem);
                filters.fir_mem_up(high, h1, y1, fullFrameSize, QMF_ORDER, g1_mem);

                for (i = 0; i < fullFrameSize; i++)
                {
                    vin[i] = 2 * (y0[i] - y1[i]);
                }

                if (dtx != 0)
                {
                    return(0);
                }
                else
                {
                    return(1);
                }
            }
            /* LSP quantization */
            submodes[submodeID].lsqQuant.quant(lsp, qlsp, lpcSize, bits);

            if (first != 0)
            {
                for (i = 0; i < lpcSize; i++)
                {
                    old_lsp[i] = lsp[i];
                }
                for (i = 0; i < lpcSize; i++)
                {
                    old_qlsp[i] = qlsp[i];
                }
            }
            mem      = new float[lpcSize];
            syn_resp = new float[subframeSize];
            innov    = new float[subframeSize];
            for (int sub = 0; sub < nbSubframes; sub++)
            {
                float tmp, filter_ratio;
                int   exc, sp, sw, resp;
                int   offset;
                float rl, rh, eh = 0, el = 0;
                int   fold;

                offset = subframeSize * sub;
                sp     = offset;
                exc    = excIdx + offset;
                resp   = offset;
                sw     = offset;
                /* LSP interpolation (quantized and unquantized) */
                tmp = (1.0f + sub) / nbSubframes;
                for (i = 0; i < lpcSize; i++)
                {
                    interp_lsp[i] = (1 - tmp) * old_lsp[i] + tmp * lsp[i];
                }
                for (i = 0; i < lpcSize; i++)
                {
                    interp_qlsp[i] = (1 - tmp) * old_qlsp[i] + tmp * qlsp[i];
                }

                Lsp.enforce_margin(interp_lsp, lpcSize, .05f);
                Lsp.enforce_margin(interp_qlsp, lpcSize, .05f);
                /* Compute interpolated LPCs (quantized and unquantized) */
                for (i = 0; i < lpcSize; i++)
                {
                    interp_lsp[i] = (float)Math.Cos(interp_lsp[i]);
                }
                for (i = 0; i < lpcSize; i++)
                {
                    interp_qlsp[i] = (float)Math.Cos(interp_qlsp[i]);
                }

                m_lsp.lsp2lpc(interp_lsp, interp_lpc, lpcSize);
                m_lsp.lsp2lpc(interp_qlsp, interp_qlpc, lpcSize);

                Filters.bw_lpc(gamma1, interp_lpc, bw_lpc1, lpcSize);
                Filters.bw_lpc(gamma2, interp_lpc, bw_lpc2, lpcSize);

                /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band
                 * filters */
                rl           = rh = 0;
                tmp          = 1;
                pi_gain[sub] = 0;
                for (i = 0; i <= lpcSize; i++)
                {
                    rh           += tmp * interp_qlpc[i];
                    tmp           = -tmp;
                    pi_gain[sub] += interp_qlpc[i];
                }
                rl = low_pi_gain[sub];
                rl = 1 / (Math.Abs(rl) + .01f);
                rh = 1 / (Math.Abs(rh) + .01f);
                /* Compute ratio, will help predict the gain */
                filter_ratio = Math.Abs(.01f + rh) / (.01f + Math.Abs(rl));

                fold = filter_ratio < 5 ? 1 : 0;
                /*printf ("filter_ratio %f\n", filter_ratio);*/
                fold = 0;
                /* Compute "real excitation" */
                Filters.fir_mem2(high, sp, interp_qlpc, excBuf, exc, subframeSize, lpcSize, mem_sp2);
                /* Compute energy of low-band and high-band excitation */
                for (i = 0; i < subframeSize; i++)
                {
                    eh += excBuf[exc + i] * excBuf[exc + i];
                }
                if (submodes[submodeID].innovation == null)
                {
                    float g;
                    /*speex_bits_pack(bits, 1, 1);*/
                    for (i = 0; i < subframeSize; i++)
                    {
                        el += low_innov[offset + i] * low_innov[offset + i];
                    }

                    /* Gain to use if we want to use the low-band excitation for high-band */
                    g = eh / (.01f + el);
                    g = (float)Math.Sqrt(g);

                    g *= filter_ratio;
                    int quant = (int)Math.Floor(.5 + 10 + 8.0 * Math.Log((g + .0001)));
                    /*speex_warning_int("tata", quant);*/
                    if (quant < 0)
                    {
                        quant = 0;
                    }
                    if (quant > 31)
                    {
                        quant = 31;
                    }
                    bits.Pack(quant, 5);
                    g  = (float)(.1 * Math.Exp(quant / 9.4));
                    g /= filter_ratio;
                }
                else
                {
                    float gc, scale, scale_1;

                    for (i = 0; i < subframeSize; i++)
                    {
                        el += low_exc[offset + i] * low_exc[offset + i];
                    }
                    gc = (float)(Math.Sqrt(1 + eh) * filter_ratio / Math.Sqrt((1 + el) * subframeSize));
                    {
                        int qgc = (int)Math.Floor(.5 + 3.7 * (Math.Log(gc) + 2));
                        if (qgc < 0)
                        {
                            qgc = 0;
                        }
                        if (qgc > 15)
                        {
                            qgc = 15;
                        }
                        bits.Pack(qgc, 4);
                        gc = (float)Math.Exp((1 / 3.7) * qgc - 2);
                    }
                    scale   = gc * (float)Math.Sqrt(1 + el) / filter_ratio;
                    scale_1 = 1 / scale;

                    for (i = 0; i < subframeSize; i++)
                    {
                        excBuf[exc + i] = 0;
                    }
                    excBuf[exc] = 1;
                    Filters.syn_percep_zero(excBuf, exc, interp_qlpc, bw_lpc1, bw_lpc2, syn_resp, subframeSize, lpcSize);

                    /* Reset excitation */
                    for (i = 0; i < subframeSize; i++)
                    {
                        excBuf[exc + i] = 0;
                    }

                    /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */
                    for (i = 0; i < lpcSize; i++)
                    {
                        mem[i] = mem_sp[i];
                    }
                    Filters.iir_mem2(excBuf, exc, interp_qlpc, excBuf, exc, subframeSize, lpcSize, mem);
                    for (i = 0; i < lpcSize; i++)
                    {
                        mem[i] = mem_sw[i];
                    }
                    Filters.filter_mem2(excBuf, exc, bw_lpc1, bw_lpc2, res, resp, subframeSize, lpcSize, mem, 0);

                    /* Compute weighted signal */
                    for (i = 0; i < lpcSize; i++)
                    {
                        mem[i] = mem_sw[i];
                    }
                    Filters.filter_mem2(high, sp, bw_lpc1, bw_lpc2, swBuf, sw, subframeSize, lpcSize, mem, 0);

                    /* Compute target signal */
                    for (i = 0; i < subframeSize; i++)
                    {
                        target[i] = swBuf[sw + i] - res[resp + i];
                    }

                    for (i = 0; i < subframeSize; i++)
                    {
                        excBuf[exc + i] = 0;
                    }

                    for (i = 0; i < subframeSize; i++)
                    {
                        target[i] *= scale_1;
                    }

                    /* Reset excitation */
                    for (i = 0; i < subframeSize; i++)
                    {
                        innov[i] = 0;
                    }
                    /*print_vec(target, st->subframeSize, "\ntarget");*/
                    submodes[submodeID].innovation.Quant(target, interp_qlpc, bw_lpc1, bw_lpc2,
                                                         lpcSize, subframeSize, innov, 0, syn_resp,
                                                         bits, (complexity + 1) >> 1);
                    /*print_vec(target, st->subframeSize, "after");*/

                    for (i = 0; i < subframeSize; i++)
                    {
                        excBuf[exc + i] += innov[i] * scale;
                    }
                    if (submodes[submodeID].double_codebook != 0)
                    {
                        float[] innov2 = new float[subframeSize];
                        for (i = 0; i < subframeSize; i++)
                        {
                            innov2[i] = 0;
                        }
                        for (i = 0; i < subframeSize; i++)
                        {
                            target[i] *= 2.5f;
                        }
                        submodes[submodeID].innovation.Quant(target, interp_qlpc, bw_lpc1, bw_lpc2,
                                                             lpcSize, subframeSize, innov2, 0, syn_resp,
                                                             bits, (complexity + 1) >> 1);
                        for (i = 0; i < subframeSize; i++)
                        {
                            innov2[i] *= scale * (1f / 2.5f);
                        }
                        for (i = 0; i < subframeSize; i++)
                        {
                            excBuf[exc + i] += innov2[i];
                        }
                    }
                }
                /*Keep the previous memory*/
                for (i = 0; i < lpcSize; i++)
                {
                    mem[i] = mem_sp[i];
                }
                /* Final signal synthesis from excitation */
                Filters.iir_mem2(excBuf, exc, interp_qlpc, high, sp, subframeSize, lpcSize, mem_sp);

                /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
                Filters.filter_mem2(high, sp, bw_lpc1, bw_lpc2, swBuf, sw, subframeSize, lpcSize, mem_sw, 0);
            }
            //#ifndef RELEASE
            /* Reconstruct the original */
            filters.fir_mem_up(x0d, h0, y0, fullFrameSize, QMF_ORDER, g0_mem);
            filters.fir_mem_up(high, h1, y1, fullFrameSize, QMF_ORDER, g1_mem);

            for (i = 0; i < fullFrameSize; i++)
            {
                vin[i] = 2 * (y0[i] - y1[i]);
            }
            //#endif
            for (i = 0; i < lpcSize; i++)
            {
                old_lsp[i] = lsp[i];
            }
            for (i = 0; i < lpcSize; i++)
            {
                old_qlsp[i] = qlsp[i];
            }
            first = 0;
            return(1);
        }
Esempio n. 11
0
        /// <summary>
        /// Codebook Search Quantification (Split Shape).
        /// </summary>
        /// <param name="target">target vector</param>
        /// <param name="ak">LPCs for this subframe</param>
        /// <param name="awk1">Weighted LPCs for this subframe</param>
        /// <param name="awk2">Weighted LPCs for this subframe</param>
        /// <param name="p">number of LPC coeffs</param>
        /// <param name="nsf">number of samples in subframe</param>
        /// <param name="exc">excitation array.</param>
        /// <param name="es">position in excitation array.</param>
        /// <param name="r"></param>
        /// <param name="bits">Speex bits buffer.</param>
        /// <param name="complexity"></param>
        public sealed override void Quantify(
            SpeexWord16[] target, SpeexWord16[] ak, SpeexWord16[] awk1,
            SpeexWord16[] awk2, int p, int nsf, SpeexWord32[] exc, int es, SpeexWord16[] r,
            Bits bits, int complexity)
        {
            int i, j, k, m, n, q;

            SpeexWord16[] resp;
            SpeexWord32[] ndist, odist;
            int[]         best_index;
            SpeexWord32[] best_dist;
            int[]         best_nind;
            int[]         best_ntarget;

            int N = complexity;

            if (N > 10)
            {
                N = 10;
            }

            resp = new SpeexWord16[shape_cb_size * subvect_size];

            best_index   = new int[N];
            best_dist    = new SpeexWord32[N];
            ndist        = new SpeexWord32[N];
            odist        = new SpeexWord32[N];
            best_nind    = new int[N];
            best_ntarget = new int[N];

            for (i = 0; i < N; i++)
            {
                for (j = 0; j < nb_subvect; j++)
                {
                    nind[i, j] = oind[i, j] = -1;
                }
            }

            for (j = 0; j < N; j++)
            {
                for (i = 0; i < nsf; i++)
                {
                    ot[j][i] = target[i];
                }
            }

            // System.arraycopy(target, 0, t, 0, nsf);

            /* Pre-compute codewords response and energy */
            for (i = 0; i < shape_cb_size; i++)
            {
                int res;
                int shape;

                res   = i * subvect_size;
                shape = i * subvect_size;

                /* Compute codeword response using convolution with impulse response */
                for (j = 0; j < subvect_size; j++)
                {
                    resp[res + j] = 0;
                    for (k = 0; k <= j; k++)
#if FIXED_POINT
                    { resp[res + j] += (short)((shape_cb[shape + k] * r[j - k]) >> 13); }
#else
                    { resp[res + j] += 0.03125f * shape_cb[shape + k] * r[j - k]; }
#endif
                }

                /* Compute codeword energy */
                E[i] = 0;
                for (j = 0; j < subvect_size; j++)
                {
                    E[i] += resp[res + j] * resp[res + j];
                }
            }

            for (j = 0; j < N; j++)
            {
                odist[j] = 0;
            }

            /* For all subvectors */
            for (i = 0; i < nb_subvect; i++)
            {
                int offset = i * subvect_size;

                /* "erase" nbest list */
                for (j = 0; j < N; j++)
                {
                    ndist[j] = Int32.MaxValue;
                }

                /* This is not strictly necessary, but it provides an additonal safety
                 * to prevent crashes in case something goes wrong in the previous
                 * steps (e.g. NaNs) */
                for (j = 0; j < N; j++)
                {
                    best_nind[j] = best_ntarget[j] = 0;
                }

                /* For all n-bests of previous subvector */
                for (j = 0; j < N; j++)
                {
                    SpeexWord32 tener = 0;
                    for (m = offset; m < offset + subvect_size; m++)
                    {
                        tener += ot[j][m] * ot[j][m];
                    }
#if FIXED_POINT
                    tener = tener >> 1;
#else
                    tener *= 0.5f;
#endif

                    /* Find new n-best based on previous n-best j */
                    if (have_sign != 0)
                    {
                        NSpeex.VQ.Nbest_sign(
                            ot[j], offset, resp, subvect_size,
                            shape_cb_size, E, N, best_index, best_dist);
                    }
                    else
                    {
                        NSpeex.VQ.Nbest(
                            ot[j], offset, resp, subvect_size,
                            shape_cb_size, E, N, best_index, best_dist);
                    }

                    /* For all new n-bests */
                    for (k = 0; k < N; k++)
                    {
                        /* Compute total distance (including previous sub-vectors */
                        SpeexWord32 err = odist[j] + best_dist[k] + tener;

                        /* Update n-best list */
                        if (err < ndist[N - 1])
                        {
                            for (m = 0; m < N; m++)
                            {
                                if (err < ndist[m])
                                {
                                    for (n = N - 1; n > m; n--)
                                    {
                                        ndist[n]        = ndist[n - 1];
                                        best_nind[n]    = best_nind[n - 1];
                                        best_ntarget[n] = best_ntarget[n - 1];
                                    }
                                    /* n is equal to m here, so they're interchangeable */
                                    ndist[m]        = err;
                                    best_nind[n]    = best_index[k];
                                    best_ntarget[n] = j;
                                    break;
                                }
                            }
                        }
                    }
                    if (i == 0)
                    {
                        break;
                    }
                }

                for (j = 0; j < N; j++)
                {
                    /*previous target (we don't care what happened before*/
                    for (m = (i + 1) * subvect_size; m < nsf; m++)
                    {
                        nt[j][m] = ot[best_ntarget[j]][m];
                    }

                    /* New code: update the rest of the target only if it's worth it */
                    for (m = 0; m < subvect_size; m++)
                    {
                        SpeexWord16 g;
                        int         rind;
                        SpeexWord16 sign = 1;
                        rind = best_nind[j];
                        if (rind >= shape_cb_size)
                        {
                            sign  = -1;
                            rind -= shape_cb_size;
                        }

                        q = subvect_size - m;
#if FIXED_POINT
                        g = (short)(sign * shape_cb[rind * subvect_size + m]);
#else
                        g = sign * 0.03125f * shape_cb[rind * subvect_size + m];
#endif
                        int ni;
                        for (n = 0, ni = offset + subvect_size; n < nsf - subvect_size * (i + 1); n++, ni++)
#if FIXED_POINT
                        { nt[j][ni] -= (short)((g * r[n + q]) >> 13); }
#else
                        { nt[j][ni] -= (g * r[n + q]); }
#endif
                    }

                    for (q = 0; q < nb_subvect; q++)
                    {
                        nind[j, q] = oind[best_ntarget[j], q];
                    }
                    nind[j, i] = best_nind[j];
                }

                /*update old-new data*/
                /* just swap pointers instead of a long copy */
                {
                    SpeexWord16[][] tmp2;
                    tmp2 = ot;
                    ot   = nt;
                    nt   = tmp2;
                }

                for (j = 0; j < N; j++)
                {
                    for (m = 0; m < nb_subvect; m++)
                    {
                        oind[j, m] = nind[j, m];
                    }
                }
                for (j = 0; j < N; j++)
                {
                    odist[j] = ndist[j];
                }
            }

            /* save indices */
            for (i = 0; i < nb_subvect; i++)
            {
                ind[i] = nind[0, i];
                bits.Pack(ind[i], shape_bits + have_sign);
            }

            /* Put everything back together */
            for (i = 0; i < nb_subvect; i++)
            {
                int         rind_3;
                SpeexWord16 sign_4 = 1;
                rind_3 = ind[i];
                if (rind_3 >= shape_cb_size)
                {
                    sign_4  = -1;
                    rind_3 -= shape_cb_size;
                }

#if FIXED_POINT
                if (sign_4 == 1)
                {
                    for (j = 0; j < subvect_size; j++)
                    {
                        e[subvect_size * i + j] = (int)(shape_cb[rind_3 * subvect_size + j]) >> (14 - 5);
                    }
                }
                else
                {
                    for (j = 0; j < subvect_size; j++)
                    {
                        e[subvect_size * i + j] = -((int)(shape_cb[rind_3 * subvect_size + j]) >> (14 - 5));
                    }
                }
#else
                for (j = 0; j < subvect_size; j++)
                {
                    e[subvect_size * i + j] = sign_4 * 0.03125f * shape_cb[rind_3 * subvect_size + j];
                }
#endif
            }
            /* Update excitation */
            for (j = 0; j < nsf; j++)
            {
                exc[es + j] += e[j];
            }

            /* Update target */
            NSpeex.Filters.Syn_percep_zero(e, 0, ak, awk1, awk2, r2, nsf, p);
            for (j = 0; j < nsf; j++)
            {
                target[j] -= r2[j];
            }
        }
Esempio n. 12
0
        public sealed override void Quantify(float[] target, float[] ak, float[] awk1, float[] awk2, int p, int nsf, float[] exc, int es, float[] r, Bits bits, int complexity)
        {
            int num = complexity;

            if (num > 10)
            {
                num = 10;
            }
            float[] array  = new float[this.shape_cb_size * this.subvect_size];
            int[]   array2 = new int[num];
            float[] array3 = new float[num];
            float[] array4 = new float[num];
            float[] array5 = new float[num];
            int[]   array6 = new int[num];
            int[]   array7 = new int[num];
            for (int i = 0; i < num; i++)
            {
                for (int j = 0; j < this.nb_subvect; j++)
                {
                    this.nind[i, j] = (this.oind[i, j] = -1);
                }
            }
            for (int j = 0; j < num; j++)
            {
                for (int i = 0; i < nsf; i++)
                {
                    this.ot[j][i] = target[i];
                }
            }
            for (int i = 0; i < this.shape_cb_size; i++)
            {
                int num2 = i * this.subvect_size;
                int num3 = i * this.subvect_size;
                for (int j = 0; j < this.subvect_size; j++)
                {
                    array[num2 + j] = 0f;
                    for (int k = 0; k <= j; k++)
                    {
                        array[num2 + j] += 0.03125f * (float)this.shape_cb[num3 + k] * r[j - k];
                    }
                }
                this.E[i] = 0f;
                for (int j = 0; j < this.subvect_size; j++)
                {
                    this.E[i] += array[num2 + j] * array[num2 + j];
                }
            }
            for (int j = 0; j < num; j++)
            {
                array5[j] = 0f;
            }
            for (int i = 0; i < this.nb_subvect; i++)
            {
                int num4 = i * this.subvect_size;
                for (int j = 0; j < num; j++)
                {
                    array4[j] = 2.14748365E+09f;
                }
                for (int j = 0; j < num; j++)
                {
                    array6[j] = (array7[j] = 0);
                }
                for (int j = 0; j < num; j++)
                {
                    float num5 = 0f;
                    for (int l = num4; l < num4 + this.subvect_size; l++)
                    {
                        num5 += this.ot[j][l] * this.ot[j][l];
                    }
                    num5 *= 0.5f;
                    if (this.have_sign != 0)
                    {
                        VQ.Nbest_sign(this.ot[j], num4, array, this.subvect_size, this.shape_cb_size, this.E, num, array2, array3);
                    }
                    else
                    {
                        VQ.Nbest(this.ot[j], num4, array, this.subvect_size, this.shape_cb_size, this.E, num, array2, array3);
                    }
                    for (int k = 0; k < num; k++)
                    {
                        float num6 = array5[j] + array3[k] + num5;
                        if (num6 < array4[num - 1])
                        {
                            for (int l = 0; l < num; l++)
                            {
                                if (num6 < array4[l])
                                {
                                    int m;
                                    for (m = num - 1; m > l; m--)
                                    {
                                        array4[m] = array4[m - 1];
                                        array6[m] = array6[m - 1];
                                        array7[m] = array7[m - 1];
                                    }
                                    array4[l] = num6;
                                    array6[m] = array2[k];
                                    array7[m] = j;
                                    break;
                                }
                            }
                        }
                    }
                    if (i == 0)
                    {
                        break;
                    }
                }
                for (int j = 0; j < num; j++)
                {
                    for (int l = (i + 1) * this.subvect_size; l < nsf; l++)
                    {
                        this.nt[j][l] = this.ot[array7[j]][l];
                    }
                    for (int l = 0; l < this.subvect_size; l++)
                    {
                        float num7 = 1f;
                        int   num8 = array6[j];
                        if (num8 >= this.shape_cb_size)
                        {
                            num7  = -1f;
                            num8 -= this.shape_cb_size;
                        }
                        int   n     = this.subvect_size - l;
                        float num9  = num7 * 0.03125f * (float)this.shape_cb[num8 * this.subvect_size + l];
                        int   m     = 0;
                        int   num10 = num4 + this.subvect_size;
                        while (m < nsf - this.subvect_size * (i + 1))
                        {
                            this.nt[j][num10] -= num9 * r[m + n];
                            m++;
                            num10++;
                        }
                    }
                    for (int n = 0; n < this.nb_subvect; n++)
                    {
                        this.nind[j, n] = this.oind[array7[j], n];
                    }
                    this.nind[j, i] = array6[j];
                }
                float[][] array8 = this.ot;
                this.ot = this.nt;
                this.nt = array8;
                for (int j = 0; j < num; j++)
                {
                    for (int l = 0; l < this.nb_subvect; l++)
                    {
                        this.oind[j, l] = this.nind[j, l];
                    }
                }
                for (int j = 0; j < num; j++)
                {
                    array5[j] = array4[j];
                }
            }
            for (int i = 0; i < this.nb_subvect; i++)
            {
                this.ind[i] = this.nind[0, i];
                bits.Pack(this.ind[i], this.shape_bits + this.have_sign);
            }
            for (int i = 0; i < this.nb_subvect; i++)
            {
                float num11 = 1f;
                int   num12 = this.ind[i];
                if (num12 >= this.shape_cb_size)
                {
                    num11  = -1f;
                    num12 -= this.shape_cb_size;
                }
                for (int j = 0; j < this.subvect_size; j++)
                {
                    this.e[this.subvect_size * i + j] = num11 * 0.03125f * (float)this.shape_cb[num12 * this.subvect_size + j];
                }
            }
            for (int j = 0; j < nsf; j++)
            {
                exc[es + j] += this.e[j];
            }
            Filters.Syn_percep_zero(this.e, 0, ak, awk1, awk2, this.r2, nsf, p);
            for (int j = 0; j < nsf; j++)
            {
                target[j] -= this.r2[j];
            }
        }
Esempio n. 13
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);
        }
Esempio n. 14
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);
        }
Esempio n. 15
0
        /// <summary>
        /// Transforms a stereo frame into a mono frame and stores intensity stereo
        /// info in 'bits'.
        /// </summary>
        public static void Encode(Bits bits, SpeexWord16[] data, int frameSize)
        {
#if FIXED_POINT
            int         i, tmp;
            SpeexWord32 e_left = 0, e_right = 0, e_tot = 0;
            SpeexWord32 balance, e_ratio;
            SpeexWord32 largest, smallest;
            int         shift;
            int         balance_id;

            /* In band marker */
            bits.Pack(14, 5);
            /* Stereo marker */
            bits.Pack(SPEEX_INBAND_STEREO, 4);

            for (i = 0; i < frameSize; i++)
            {
                e_left  += (data[2 * i] * data[2 * i]) >> 8;
                e_right += (data[2 * i + 1] * data[2 * i + 1]) >> 8;
                data[i]  = (SpeexWord16)((data[2 * i] >> 1) + (data[2 * i + 1] >> 1));
                e_tot   += (data[i] * data[i]) >> 8;
            }

            if (e_left > e_right)
            {
                bits.Pack(0, 1);
                largest  = e_left;
                smallest = e_right;
            }
            else
            {
                bits.Pack(1, 1);
                largest  = e_right;
                smallest = e_left;
            }

            /* Balance quantization */
            // ???
            shift      = (int)Math.Log(smallest, 2) - 15;
            largest  >>= shift;
            smallest >>= shift;
            balance    = Math.Min(largest / (smallest + 1), 32767);
            balance_id = VQ.Index((short)balance, balance_bounds, balance_bounds.Length);
            bits.Pack((int)balance_id, 5);

            /* "coherence" quantisation */
            shift     = (int)Math.Log(e_tot, 2);
            e_tot   >>= shift - 25;
            e_left  >>= shift - 10;
            e_right >>= shift - 10;
            e_ratio   = e_tot / (e_left + e_right + 1);

            tmp = NSpeex.VQ.Index((short)e_ratio, e_ratio_quant_bounds, 4);
            bits.Pack(tmp, 2);
#else
            int   i, tmp;
            float e_left = 0, e_right = 0, e_tot = 0;
            float balance_0, e_ratio_1;
            for (i = 0; i < frameSize; i++)
            {
                e_left  += data[2 * i] * data[2 * i];
                e_right += data[2 * i + 1] * data[2 * i + 1];
                data[i]  = .5f * (data[2 * i] + data[2 * i + 1]);
                e_tot   += data[i] * data[i];
            }
            balance_0 = (e_left + 1) / (e_right + 1);
            e_ratio_1 = e_tot / (1 + e_left + e_right);
            /* Quantization */
            bits.Pack(14, 5);
            bits.Pack(SPEEX_INBAND_STEREO, 4);
            balance_0 = (float)(4 * Math.Log(balance_0));

            /* Pack balance */
            if (balance_0 > 0)
            {
                bits.Pack(0, 1);
            }
            else
            {
                bits.Pack(1, 1);
            }
            balance_0 = (float)Math.Floor(.5f + Math.Abs(balance_0));
            if (balance_0 > 30)
            {
                balance_0 = 31;
            }
            bits.Pack((int)balance_0, 5);

            /* Quantize energy ratio */
            tmp = NSpeex.VQ.Index(e_ratio_1, e_ratio_quant, 4);
            bits.Pack(tmp, 2);
#endif
        }