Ejemplo n.º 1
0
        /// <summary>
        /// Encode side-information parameters to payload
        /// </summary>
        /// <param name="psEncC">I/O  Encoder state</param>
        /// <param name="psRangeEnc">I/O  Compressor data structure</param>
        /// <param name="FrameIndex">I    Frame number</param>
        /// <param name="encode_LBRR">I    Flag indicating LBRR data is being encoded</param>
        /// <param name="condCoding">I    The type of conditional coding to use</param>
        internal static void silk_encode_indices(
            SilkChannelEncoder psEncC,
            EntropyCoder psRangeEnc,
            int FrameIndex,
            int encode_LBRR,
            int condCoding)
        {
            int i, k, typeOffset;
            int encode_absolute_lagIndex, delta_lagIndex;

            short[]         ec_ix   = new short[SilkConstants.MAX_LPC_ORDER];
            byte[]          pred_Q8 = new byte[SilkConstants.MAX_LPC_ORDER];
            SideInfoIndices psIndices;

            if (encode_LBRR != 0)
            {
                psIndices = psEncC.indices_LBRR[FrameIndex];
            }
            else
            {
                psIndices = psEncC.indices;
            }

            /*******************************************/
            /* Encode signal type and quantizer offset */
            /*******************************************/
            typeOffset = 2 * psIndices.signalType + psIndices.quantOffsetType;
            Inlines.OpusAssert(typeOffset >= 0 && typeOffset < 6);
            Inlines.OpusAssert(encode_LBRR == 0 || typeOffset >= 2);
            if (encode_LBRR != 0 || typeOffset >= 2)
            {
                psRangeEnc.enc_icdf(typeOffset - 2, Tables.silk_type_offset_VAD_iCDF, 8);
            }
            else
            {
                psRangeEnc.enc_icdf(typeOffset, Tables.silk_type_offset_no_VAD_iCDF, 8);
            }

            /****************/
            /* Encode gains */
            /****************/
            /* first subframe */
            if (condCoding == SilkConstants.CODE_CONDITIONALLY)
            {
                /* conditional coding */
                Inlines.OpusAssert(psIndices.GainsIndices[0] >= 0 && psIndices.GainsIndices[0] < SilkConstants.MAX_DELTA_GAIN_QUANT - SilkConstants.MIN_DELTA_GAIN_QUANT + 1);
                psRangeEnc.enc_icdf(psIndices.GainsIndices[0], Tables.silk_delta_gain_iCDF, 8);
            }
            else
            {
                /* independent coding, in two stages: MSB bits followed by 3 LSBs */
                Inlines.OpusAssert(psIndices.GainsIndices[0] >= 0 && psIndices.GainsIndices[0] < SilkConstants.N_LEVELS_QGAIN);
                psRangeEnc.enc_icdf(Inlines.silk_RSHIFT(psIndices.GainsIndices[0], 3), Tables.silk_gain_iCDF[psIndices.signalType], 8);
                psRangeEnc.enc_icdf(psIndices.GainsIndices[0] & 7, Tables.silk_uniform8_iCDF, 8);
            }

            /* remaining subframes */
            for (i = 1; i < psEncC.nb_subfr; i++)
            {
                Inlines.OpusAssert(psIndices.GainsIndices[i] >= 0 && psIndices.GainsIndices[i] < SilkConstants.MAX_DELTA_GAIN_QUANT - SilkConstants.MIN_DELTA_GAIN_QUANT + 1);
                psRangeEnc.enc_icdf(psIndices.GainsIndices[i], Tables.silk_delta_gain_iCDF, 8);
            }

            /****************/
            /* Encode NLSFs */
            /****************/
            psRangeEnc.enc_icdf(psIndices.NLSFIndices[0], psEncC.psNLSF_CB.CB1_iCDF, ((psIndices.signalType >> 1) * psEncC.psNLSF_CB.nVectors), 8);
            NLSF.silk_NLSF_unpack(ec_ix, pred_Q8, psEncC.psNLSF_CB, psIndices.NLSFIndices[0]);
            Inlines.OpusAssert(psEncC.psNLSF_CB.order == psEncC.predictLPCOrder);

            for (i = 0; i < psEncC.psNLSF_CB.order; i++)
            {
                if (psIndices.NLSFIndices[i + 1] >= SilkConstants.NLSF_QUANT_MAX_AMPLITUDE)
                {
                    psRangeEnc.enc_icdf(2 * SilkConstants.NLSF_QUANT_MAX_AMPLITUDE, psEncC.psNLSF_CB.ec_iCDF, (ec_ix[i]), 8);
                    psRangeEnc.enc_icdf(psIndices.NLSFIndices[i + 1] - SilkConstants.NLSF_QUANT_MAX_AMPLITUDE, Tables.silk_NLSF_EXT_iCDF, 8);
                }
                else if (psIndices.NLSFIndices[i + 1] <= 0 - SilkConstants.NLSF_QUANT_MAX_AMPLITUDE)
                {
                    psRangeEnc.enc_icdf(0, psEncC.psNLSF_CB.ec_iCDF, ec_ix[i], 8);
                    psRangeEnc.enc_icdf(-psIndices.NLSFIndices[i + 1] - SilkConstants.NLSF_QUANT_MAX_AMPLITUDE, Tables.silk_NLSF_EXT_iCDF, 8);
                }
                else
                {
                    psRangeEnc.enc_icdf(psIndices.NLSFIndices[i + 1] + SilkConstants.NLSF_QUANT_MAX_AMPLITUDE, psEncC.psNLSF_CB.ec_iCDF, ec_ix[i], 8);
                }
            }

            /* Encode NLSF interpolation factor */
            if (psEncC.nb_subfr == SilkConstants.MAX_NB_SUBFR)
            {
                Inlines.OpusAssert(psIndices.NLSFInterpCoef_Q2 >= 0 && psIndices.NLSFInterpCoef_Q2 < 5);
                psRangeEnc.enc_icdf(psIndices.NLSFInterpCoef_Q2, Tables.silk_NLSF_interpolation_factor_iCDF, 8);
            }

            if (psIndices.signalType == SilkConstants.TYPE_VOICED)
            {
                /*********************/
                /* Encode pitch lags */
                /*********************/
                /* lag index */
                encode_absolute_lagIndex = 1;
                if (condCoding == SilkConstants.CODE_CONDITIONALLY && psEncC.ec_prevSignalType == SilkConstants.TYPE_VOICED)
                {
                    /* Delta Encoding */
                    delta_lagIndex = psIndices.lagIndex - psEncC.ec_prevLagIndex;

                    if (delta_lagIndex < -8 || delta_lagIndex > 11)
                    {
                        delta_lagIndex = 0;
                    }
                    else
                    {
                        delta_lagIndex           = delta_lagIndex + 9;
                        encode_absolute_lagIndex = 0; /* Only use delta */
                    }

                    Inlines.OpusAssert(delta_lagIndex >= 0 && delta_lagIndex < 21);
                    psRangeEnc.enc_icdf(delta_lagIndex, Tables.silk_pitch_delta_iCDF, 8);
                }

                if (encode_absolute_lagIndex != 0)
                {
                    /* Absolute encoding */
                    int pitch_high_bits, pitch_low_bits;
                    pitch_high_bits = Inlines.silk_DIV32_16(psIndices.lagIndex, Inlines.silk_RSHIFT(psEncC.fs_kHz, 1));
                    pitch_low_bits  = psIndices.lagIndex - Inlines.silk_SMULBB(pitch_high_bits, Inlines.silk_RSHIFT(psEncC.fs_kHz, 1));
                    Inlines.OpusAssert(pitch_low_bits < psEncC.fs_kHz / 2);
                    Inlines.OpusAssert(pitch_high_bits < 32);
                    psRangeEnc.enc_icdf(pitch_high_bits, Tables.silk_pitch_lag_iCDF, 8);
                    psRangeEnc.enc_icdf(pitch_low_bits, psEncC.pitch_lag_low_bits_iCDF, 8);
                }
                psEncC.ec_prevLagIndex = psIndices.lagIndex;

                /* Countour index */
                Inlines.OpusAssert(psIndices.contourIndex >= 0);
                Inlines.OpusAssert((psIndices.contourIndex < 34 && psEncC.fs_kHz > 8 && psEncC.nb_subfr == 4) || (psIndices.contourIndex < 11 && psEncC.fs_kHz == 8 && psEncC.nb_subfr == 4) || (psIndices.contourIndex < 12 && psEncC.fs_kHz > 8 && psEncC.nb_subfr == 2) || (psIndices.contourIndex < 3 && psEncC.fs_kHz == 8 && psEncC.nb_subfr == 2));
                psRangeEnc.enc_icdf(psIndices.contourIndex, psEncC.pitch_contour_iCDF, 8);

                /********************/
                /* Encode LTP gains */
                /********************/
                /* PERIndex value */
                Inlines.OpusAssert(psIndices.PERIndex >= 0 && psIndices.PERIndex < 3);
                psRangeEnc.enc_icdf(psIndices.PERIndex, Tables.silk_LTP_per_index_iCDF, 8);

                /* Codebook Indices */
                for (k = 0; k < psEncC.nb_subfr; k++)
                {
                    Inlines.OpusAssert(psIndices.LTPIndex[k] >= 0 && psIndices.LTPIndex[k] < (8 << psIndices.PERIndex));
                    psRangeEnc.enc_icdf(psIndices.LTPIndex[k], Tables.silk_LTP_gain_iCDF_ptrs[psIndices.PERIndex], 8);
                }

                /**********************/
                /* Encode LTP scaling */
                /**********************/
                if (condCoding == SilkConstants.CODE_INDEPENDENTLY)
                {
                    Inlines.OpusAssert(psIndices.LTP_scaleIndex >= 0 && psIndices.LTP_scaleIndex < 3);
                    psRangeEnc.enc_icdf(psIndices.LTP_scaleIndex, Tables.silk_LTPscale_iCDF, 8);
                }

                Inlines.OpusAssert(condCoding == 0 || psIndices.LTP_scaleIndex == 0);
            }

            psEncC.ec_prevSignalType = psIndices.signalType;

            /***************/
            /* Encode seed */
            /***************/
            Inlines.OpusAssert(psIndices.Seed >= 0 && psIndices.Seed < 4);
            psRangeEnc.enc_icdf(psIndices.Seed, Tables.silk_uniform4_iCDF, 8);
        }
Ejemplo n.º 2
0
        /* Decode side-information parameters from payload */
        internal static void silk_decode_indices(
            SilkChannelDecoder psDec,           /* I/O  State                                       */
            EntropyCoder psRangeDec,            /* I/O  Compressor data structure                   */
            int FrameIndex,                     /* I    Frame number                                */
            int decode_LBRR,                    /* I    Flag indicating LBRR data is being decoded  */
            int condCoding                      /* I    The type of conditional coding to use       */
            )
        {
            int i, k, Ix;
            int decode_absolute_lagIndex, delta_lagIndex;

            short[] ec_ix   = new short[psDec.LPC_order];
            byte[]  pred_Q8 = new byte[psDec.LPC_order];

            /*******************************************/
            /* Decode signal type and quantizer offset */
            /*******************************************/
            if (decode_LBRR != 0 || psDec.VAD_flags[FrameIndex] != 0)
            {
                Ix = psRangeDec.dec_icdf(Tables.silk_type_offset_VAD_iCDF, 8) + 2;
            }
            else
            {
                Ix = psRangeDec.dec_icdf(Tables.silk_type_offset_no_VAD_iCDF, 8);
            }
            psDec.indices.signalType      = (sbyte)Inlines.silk_RSHIFT(Ix, 1);
            psDec.indices.quantOffsetType = (sbyte)(Ix & 1);

            /****************/
            /* Decode gains */
            /****************/
            /* First subframe */
            if (condCoding == SilkConstants.CODE_CONDITIONALLY)
            {
                /* Conditional coding */
                psDec.indices.GainsIndices[0] = (sbyte)psRangeDec.dec_icdf(Tables.silk_delta_gain_iCDF, 8);
            }
            else
            {
                /* Independent coding, in two stages: MSB bits followed by 3 LSBs */
                psDec.indices.GainsIndices[0]  = (sbyte)Inlines.silk_LSHIFT(psRangeDec.dec_icdf(Tables.silk_gain_iCDF[psDec.indices.signalType], 8), 3);
                psDec.indices.GainsIndices[0] += (sbyte)psRangeDec.dec_icdf(Tables.silk_uniform8_iCDF, 8);
            }

            /* Remaining subframes */
            for (i = 1; i < psDec.nb_subfr; i++)
            {
                psDec.indices.GainsIndices[i] = (sbyte)psRangeDec.dec_icdf(Tables.silk_delta_gain_iCDF, 8);
            }

            /**********************/
            /* Decode LSF Indices */
            /**********************/
            psDec.indices.NLSFIndices[0] = (sbyte)psRangeDec.dec_icdf(psDec.psNLSF_CB.CB1_iCDF, (psDec.indices.signalType >> 1) * psDec.psNLSF_CB.nVectors, 8);
            NLSF.silk_NLSF_unpack(ec_ix, pred_Q8, psDec.psNLSF_CB, psDec.indices.NLSFIndices[0]);
            Inlines.OpusAssert(psDec.psNLSF_CB.order == psDec.LPC_order);
            for (i = 0; i < psDec.psNLSF_CB.order; i++)
            {
                Ix = psRangeDec.dec_icdf(psDec.psNLSF_CB.ec_iCDF, (ec_ix[i]), 8);
                if (Ix == 0)
                {
                    Ix -= psRangeDec.dec_icdf(Tables.silk_NLSF_EXT_iCDF, 8);
                }
                else if (Ix == 2 * SilkConstants.NLSF_QUANT_MAX_AMPLITUDE)
                {
                    Ix += psRangeDec.dec_icdf(Tables.silk_NLSF_EXT_iCDF, 8);
                }
                psDec.indices.NLSFIndices[i + 1] = (sbyte)(Ix - SilkConstants.NLSF_QUANT_MAX_AMPLITUDE);
            }

            /* Decode LSF interpolation factor */
            if (psDec.nb_subfr == SilkConstants.MAX_NB_SUBFR)
            {
                psDec.indices.NLSFInterpCoef_Q2 = (sbyte)psRangeDec.dec_icdf(Tables.silk_NLSF_interpolation_factor_iCDF, 8);
            }
            else
            {
                psDec.indices.NLSFInterpCoef_Q2 = 4;
            }

            if (psDec.indices.signalType == SilkConstants.TYPE_VOICED)
            {
                /*********************/
                /* Decode pitch lags */
                /*********************/
                /* Get lag index */
                decode_absolute_lagIndex = 1;
                if (condCoding == SilkConstants.CODE_CONDITIONALLY && psDec.ec_prevSignalType == SilkConstants.TYPE_VOICED)
                {
                    /* Decode Delta index */
                    delta_lagIndex = (short)psRangeDec.dec_icdf(Tables.silk_pitch_delta_iCDF, 8);
                    if (delta_lagIndex > 0)
                    {
                        delta_lagIndex           = delta_lagIndex - 9;
                        psDec.indices.lagIndex   = (short)(psDec.ec_prevLagIndex + delta_lagIndex);
                        decode_absolute_lagIndex = 0;
                    }
                }
                if (decode_absolute_lagIndex != 0)
                {
                    /* Absolute decoding */
                    psDec.indices.lagIndex  = (short)(psRangeDec.dec_icdf(Tables.silk_pitch_lag_iCDF, 8) * Inlines.silk_RSHIFT(psDec.fs_kHz, 1));
                    psDec.indices.lagIndex += (short)psRangeDec.dec_icdf(psDec.pitch_lag_low_bits_iCDF, 8);
                }
                psDec.ec_prevLagIndex = psDec.indices.lagIndex;

                /* Get countour index */
                psDec.indices.contourIndex = (sbyte)psRangeDec.dec_icdf(psDec.pitch_contour_iCDF, 8);

                /********************/
                /* Decode LTP gains */
                /********************/
                /* Decode PERIndex value */
                psDec.indices.PERIndex = (sbyte)psRangeDec.dec_icdf(Tables.silk_LTP_per_index_iCDF, 8);

                for (k = 0; k < psDec.nb_subfr; k++)
                {
                    psDec.indices.LTPIndex[k] = (sbyte)psRangeDec.dec_icdf(Tables.silk_LTP_gain_iCDF_ptrs[psDec.indices.PERIndex], 8);
                }

                /**********************/
                /* Decode LTP scaling */
                /**********************/
                if (condCoding == SilkConstants.CODE_INDEPENDENTLY)
                {
                    psDec.indices.LTP_scaleIndex = (sbyte)psRangeDec.dec_icdf(Tables.silk_LTPscale_iCDF, 8);
                }
                else
                {
                    psDec.indices.LTP_scaleIndex = 0;
                }
            }
            psDec.ec_prevSignalType = psDec.indices.signalType;

            /***************/
            /* Decode seed */
            /***************/
            psDec.indices.Seed = (sbyte)psRangeDec.dec_icdf(Tables.silk_uniform4_iCDF, 8);
        }