Beispiel #1
0
        /// <summary>
        /// Decode mid/side predictors
        /// </summary>
        /// <param name="psRangeDec">I/O  Compressor data structure</param>
        /// <param name="pred_Q13">O Predictors</param>
        internal static void silk_stereo_decode_pred(
            EntropyCoder psRangeDec,
            int[] pred_Q13)
        {
            int n;

            int[][] ix = Arrays.InitTwoDimensionalArray <int>(2, 3);
            int     low_Q13, step_Q13;

            // Entropy decoding
            n        = psRangeDec.dec_icdf(Tables.silk_stereo_pred_joint_iCDF, 8);
            ix[0][2] = Inlines.silk_DIV32_16(n, 5);
            ix[1][2] = n - 5 * ix[0][2];
            for (n = 0; n < 2; n++)
            {
                ix[n][0] = psRangeDec.dec_icdf(Tables.silk_uniform3_iCDF, 8);
                ix[n][1] = psRangeDec.dec_icdf(Tables.silk_uniform5_iCDF, 8);
            }

            // Dequantize
            for (n = 0; n < 2; n++)
            {
                ix[n][0] += 3 * ix[n][2];
                low_Q13   = Tables.silk_stereo_pred_quant_Q13[ix[n][0]];
                step_Q13  = Inlines.silk_SMULWB(Tables.silk_stereo_pred_quant_Q13[ix[n][0] + 1] - low_Q13,
                                                ((int)((0.5f / SilkConstants.STEREO_QUANT_SUB_STEPS) * ((long)1 << (16)) + 0.5)) /*Inlines.SILK_CONST(0.5f / SilkConstants.STEREO_QUANT_SUB_STEPS, 16)*/);
                pred_Q13[n] = Inlines.silk_SMLABB(low_Q13, step_Q13, 2 * ix[n][1] + 1);
            }

            /* Subtract second from first predictor (helps when actually applying these) */
            pred_Q13[0] -= pred_Q13[1];
        }
Beispiel #2
0
 /// <summary>
 /// Decode mid-only flag
 /// </summary>
 /// <param name="psRangeDec">I/O  Compressor data structure</param>
 /// <param name="decode_only_mid">O    Flag that only mid channel has been coded</param>
 internal static void silk_stereo_decode_mid_only(
     EntropyCoder psRangeDec,
     BoxedValueInt decode_only_mid
     )
 {
     /* Decode flag that only mid channel is coded */
     decode_only_mid.Val = psRangeDec.dec_icdf(Tables.silk_stereo_only_code_mid_iCDF, 8);
 }
Beispiel #3
0
        /// <summary>
        /// Decodes signs of excitation
        /// </summary>
        /// <param name="psRangeDec">I/O  Compressor data structure</param>
        /// <param name="pulses">I/O  pulse signal</param>
        /// <param name="length">I    length of input</param>
        /// <param name="signalType">I    Signal type</param>
        /// <param name="quantOffsetType">I    Quantization offset type</param>
        /// <param name="sum_pulses">I    Sum of absolute pulses per block [MAX_NB_SHELL_BLOCKS]</param>
        internal static void silk_decode_signs(
            EntropyCoder psRangeDec,
            short[] pulses,
            int length,
            int signalType,
            int quantOffsetType,
            int[] sum_pulses)
        {
            int i, j, p;

            byte[] icdf = new byte[2];
            int    q_ptr;

            byte[] icdf_table = Tables.silk_sign_iCDF;
            int    icdf_ptr;

            icdf[1]  = 0;
            q_ptr    = 0;
            i        = Inlines.silk_SMULBB(7, Inlines.silk_ADD_LSHIFT(quantOffsetType, signalType, 1));
            icdf_ptr = i;
            length   = Inlines.silk_RSHIFT(length + SilkConstants.SHELL_CODEC_FRAME_LENGTH / 2, SilkConstants.LOG2_SHELL_CODEC_FRAME_LENGTH);

            for (i = 0; i < length; i++)
            {
                p = sum_pulses[i];

                if (p > 0)
                {
                    icdf[0] = icdf_table[icdf_ptr + Inlines.silk_min(p & 0x1F, 6)];
                    for (j = 0; j < SilkConstants.SHELL_CODEC_FRAME_LENGTH; j++)
                    {
                        if (pulses[q_ptr + j] > 0)
                        {
                            /* attach sign */
                            pulses[q_ptr + j] *= (short)(silk_dec_map(psRangeDec.dec_icdf(icdf, 8)));
                        }
                    }
                }

                q_ptr += SilkConstants.SHELL_CODEC_FRAME_LENGTH;
            }
        }
Beispiel #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="p_child1">O    pulse amplitude of first child subframe</param>
 /// <param name="child1_ptr"></param>
 /// <param name="p_child2">O    pulse amplitude of second child subframe</param>
 /// <param name="p_child2_ptr"></param>
 /// <param name="psRangeDec">I/O  Compressor data structure</param>
 /// <param name="p">I    pulse amplitude of current subframe</param>
 /// <param name="shell_table">I    table of shell cdfs</param>
 internal static void decode_split(
     short[] p_child1,
     int child1_ptr,
     short[] p_child2,
     int p_child2_ptr,
     EntropyCoder psRangeDec,
     int p,
     byte[] shell_table)
 {
     if (p > 0)
     {
         p_child1[child1_ptr]   = (short)(psRangeDec.dec_icdf(shell_table, (Tables.silk_shell_code_table_offsets[p]), 8));
         p_child2[p_child2_ptr] = (short)(p - p_child1[child1_ptr]);
     }
     else
     {
         p_child1[child1_ptr]   = 0;
         p_child2[p_child2_ptr] = 0;
     }
 }
Beispiel #5
0
        internal static void unquant_coarse_energy(CeltMode m, int start, int end, int[] oldEBands, int intra, EntropyCoder dec, int C, int LM)
        {
            byte[] prob_model = Tables.e_prob_model[LM][intra];
            int    i, c;

            int[] prev = { 0, 0 };
            int   coef;
            int   beta;
            int   budget;
            int   tell;

            if (intra != 0)
            {
                coef = 0;
                beta = beta_intra;
            }
            else
            {
                beta = beta_coef[LM];
                coef = pred_coef[LM];
            }

            budget = (int)dec.storage * 8;

            /* Decode at a fixed coarse resolution */
            for (i = start; i < end; i++)
            {
                c = 0;
                do
                {
                    int qi;
                    int q;
                    int tmp;

                    /* It would be better to express this invariant as a
                     * test on C at function entry, but that isn't enough
                     * to make the static analyzer happy. */
                    Inlines.OpusAssert(c < 2);
                    tell = dec.tell();
                    if (budget - tell >= 15)
                    {
                        int pi;
                        pi = 2 * Inlines.IMIN(i, 20);
                        qi = Laplace.ec_laplace_decode(dec,
                                                       (uint)prob_model[pi] << 7, prob_model[pi + 1] << 6);
                    }
                    else if (budget - tell >= 2)
                    {
                        qi = dec.dec_icdf(small_energy_icdf, 2);
                        qi = (qi >> 1) ^ -(qi & 1);
                    }
                    else if (budget - tell >= 1)
                    {
                        qi = 0 - dec.dec_bit_logp(1);
                    }
                    else
                    {
                        qi = -1;
                    }
                    q = (int)Inlines.SHL32(qi, CeltConstants.DB_SHIFT); // opus bug: useless extend32

                    oldEBands[i + c * m.nbEBands] = Inlines.MAX16((0 - ((short)(0.5 + (9.0f) * (((int)1) << (CeltConstants.DB_SHIFT)))) /*Inlines.QCONST16(9.0f, CeltConstants.DB_SHIFT)*/), oldEBands[i + c * m.nbEBands]);
                    tmp = Inlines.PSHR32(Inlines.MULT16_16(coef, oldEBands[i + c * m.nbEBands]), 8) + prev[c] + Inlines.SHL32(q, 7);
                    tmp = Inlines.MAX32(-((int)(0.5 + (28.0f) * (((int)1) << (CeltConstants.DB_SHIFT + 7)))) /*Inlines.QCONST32(28.0f, CeltConstants.DB_SHIFT + 7)*/, tmp);
                    oldEBands[i + c * m.nbEBands] = (Inlines.PSHR32(tmp, 7));
                    prev[c] = prev[c] + Inlines.SHL32(q, 7) - Inlines.MULT16_16(beta, Inlines.PSHR32(q, 8));
                } while (++c < C);
            }
        }
Beispiel #6
0
        /* Decode a frame */
        internal static int silk_Decode( /* O    Returns error code                              */
            SilkDecoder psDec,           /* I/O  State                                           */
            DecControlState decControl,  /* I/O  Control Structure                               */
            int lostFlag,                /* I    0: no loss, 1 loss, 2 decode fec                */
            int newPacketFlag,           /* I    Indicates first decoder call for this packet    */
            EntropyCoder psRangeDec,     /* I/O  Compressor data structure                       */
            short[] samplesOut,          /* O    Decoded output speech vector                    */
            int samplesOut_ptr,
            out int nSamplesOut          /* O    Number of samples decoded                       */
            )
        {
            int           i, n, decode_only_middle = 0, ret = SilkError.SILK_NO_ERROR;
            int           LBRR_symbol;
            BoxedValueInt nSamplesOutDec = new BoxedValueInt();

            short[] samplesOut_tmp;
            int[]   samplesOut_tmp_ptrs = new int[2];
            short[] samplesOut1_tmp_storage1;
            short[] samplesOut1_tmp_storage2;
            short[] samplesOut2_tmp;
            int[]   MS_pred_Q13 = new int[] { 0, 0 };
            short[] resample_out;
            int     resample_out_ptr;

            SilkChannelDecoder[] channel_state = psDec.channel_state;
            int has_side;
            int stereo_to_mono;
            int delay_stack_alloc;

            nSamplesOut = 0;

            Inlines.OpusAssert(decControl.nChannelsInternal == 1 || decControl.nChannelsInternal == 2);

            /**********************************/
            /* Test if first frame in payload */
            /**********************************/
            if (newPacketFlag != 0)
            {
                for (n = 0; n < decControl.nChannelsInternal; n++)
                {
                    channel_state[n].nFramesDecoded = 0;  /* Used to count frames in packet */
                }
            }

            /* If Mono . Stereo transition in bitstream: init state of second channel */
            if (decControl.nChannelsInternal > psDec.nChannelsInternal)
            {
                ret += channel_state[1].silk_init_decoder();
            }

            stereo_to_mono = (decControl.nChannelsInternal == 1 && psDec.nChannelsInternal == 2 &&
                              (decControl.internalSampleRate == 1000 * channel_state[0].fs_kHz)) ? 1 : 0;

            if (channel_state[0].nFramesDecoded == 0)
            {
                for (n = 0; n < decControl.nChannelsInternal; n++)
                {
                    int fs_kHz_dec;
                    if (decControl.payloadSize_ms == 0)
                    {
                        /* Assuming packet loss, use 10 ms */
                        channel_state[n].nFramesPerPacket = 1;
                        channel_state[n].nb_subfr         = 2;
                    }
                    else if (decControl.payloadSize_ms == 10)
                    {
                        channel_state[n].nFramesPerPacket = 1;
                        channel_state[n].nb_subfr         = 2;
                    }
                    else if (decControl.payloadSize_ms == 20)
                    {
                        channel_state[n].nFramesPerPacket = 1;
                        channel_state[n].nb_subfr         = 4;
                    }
                    else if (decControl.payloadSize_ms == 40)
                    {
                        channel_state[n].nFramesPerPacket = 2;
                        channel_state[n].nb_subfr         = 4;
                    }
                    else if (decControl.payloadSize_ms == 60)
                    {
                        channel_state[n].nFramesPerPacket = 3;
                        channel_state[n].nb_subfr         = 4;
                    }
                    else
                    {
                        Inlines.OpusAssert(false);
                        return(SilkError.SILK_DEC_INVALID_FRAME_SIZE);
                    }
                    fs_kHz_dec = (decControl.internalSampleRate >> 10) + 1;
                    if (fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16)
                    {
                        Inlines.OpusAssert(false);
                        return(SilkError.SILK_DEC_INVALID_SAMPLING_FREQUENCY);
                    }
                    ret += channel_state[n].silk_decoder_set_fs(fs_kHz_dec, decControl.API_sampleRate);
                }
            }

            if (decControl.nChannelsAPI == 2 && decControl.nChannelsInternal == 2 && (psDec.nChannelsAPI == 1 || psDec.nChannelsInternal == 1))
            {
                Arrays.MemSetShort(psDec.sStereo.pred_prev_Q13, 0, 2);
                Arrays.MemSetShort(psDec.sStereo.sSide, 0, 2);
                channel_state[1].resampler_state.Assign(channel_state[0].resampler_state);
            }
            psDec.nChannelsAPI      = decControl.nChannelsAPI;
            psDec.nChannelsInternal = decControl.nChannelsInternal;

            if (decControl.API_sampleRate > (int)SilkConstants.MAX_API_FS_KHZ * 1000 || decControl.API_sampleRate < 8000)
            {
                ret = SilkError.SILK_DEC_INVALID_SAMPLING_FREQUENCY;
                return(ret);
            }

            if (lostFlag != DecoderAPIFlag.FLAG_PACKET_LOST && channel_state[0].nFramesDecoded == 0)
            {
                /* First decoder call for this payload */
                /* Decode VAD flags and LBRR flag */
                for (n = 0; n < decControl.nChannelsInternal; n++)
                {
                    for (i = 0; i < channel_state[n].nFramesPerPacket; i++)
                    {
                        channel_state[n].VAD_flags[i] = psRangeDec.dec_bit_logp(1);
                    }
                    channel_state[n].LBRR_flag = psRangeDec.dec_bit_logp(1);
                }
                /* Decode LBRR flags */
                for (n = 0; n < decControl.nChannelsInternal; n++)
                {
                    Arrays.MemSetInt(channel_state[n].LBRR_flags, 0, SilkConstants.MAX_FRAMES_PER_PACKET);
                    if (channel_state[n].LBRR_flag != 0)
                    {
                        if (channel_state[n].nFramesPerPacket == 1)
                        {
                            channel_state[n].LBRR_flags[0] = 1;
                        }
                        else
                        {
                            LBRR_symbol = psRangeDec.dec_icdf(Tables.silk_LBRR_flags_iCDF_ptr[channel_state[n].nFramesPerPacket - 2], 8) + 1;
                            for (i = 0; i < channel_state[n].nFramesPerPacket; i++)
                            {
                                channel_state[n].LBRR_flags[i] = Inlines.silk_RSHIFT(LBRR_symbol, i) & 1;
                            }
                        }
                    }
                }

                if (lostFlag == DecoderAPIFlag.FLAG_DECODE_NORMAL)
                {
                    /* Regular decoding: skip all LBRR data */
                    for (i = 0; i < channel_state[0].nFramesPerPacket; i++)
                    {
                        for (n = 0; n < decControl.nChannelsInternal; n++)
                        {
                            if (channel_state[n].LBRR_flags[i] != 0)
                            {
                                short[] pulses = new short[SilkConstants.MAX_FRAME_LENGTH];
                                int     condCoding;

                                if (decControl.nChannelsInternal == 2 && n == 0)
                                {
                                    Stereo.silk_stereo_decode_pred(psRangeDec, MS_pred_Q13);
                                    if (channel_state[1].LBRR_flags[i] == 0)
                                    {
                                        BoxedValueInt decodeOnlyMiddleBoxed = new BoxedValueInt(decode_only_middle);
                                        Stereo.silk_stereo_decode_mid_only(psRangeDec, decodeOnlyMiddleBoxed);
                                        decode_only_middle = decodeOnlyMiddleBoxed.Val;
                                    }
                                }
                                /* Use conditional coding if previous frame available */
                                if (i > 0 && (channel_state[n].LBRR_flags[i - 1] != 0))
                                {
                                    condCoding = SilkConstants.CODE_CONDITIONALLY;
                                }
                                else
                                {
                                    condCoding = SilkConstants.CODE_INDEPENDENTLY;
                                }
                                DecodeIndices.silk_decode_indices(channel_state[n], psRangeDec, i, 1, condCoding);
                                DecodePulses.silk_decode_pulses(psRangeDec, pulses, channel_state[n].indices.signalType,
                                                                channel_state[n].indices.quantOffsetType, channel_state[n].frame_length);
                            }
                        }
                    }
                }
            }

            /* Get MS predictor index */
            if (decControl.nChannelsInternal == 2)
            {
                if (lostFlag == DecoderAPIFlag.FLAG_DECODE_NORMAL ||
                    (lostFlag == DecoderAPIFlag.FLAG_DECODE_LBRR && channel_state[0].LBRR_flags[channel_state[0].nFramesDecoded] == 1))
                {
                    Stereo.silk_stereo_decode_pred(psRangeDec, MS_pred_Q13);
                    /* For LBRR data, decode mid-only flag only if side-channel's LBRR flag is false */
                    if ((lostFlag == DecoderAPIFlag.FLAG_DECODE_NORMAL && channel_state[1].VAD_flags[channel_state[0].nFramesDecoded] == 0) ||
                        (lostFlag == DecoderAPIFlag.FLAG_DECODE_LBRR && channel_state[1].LBRR_flags[channel_state[0].nFramesDecoded] == 0))
                    {
                        BoxedValueInt decodeOnlyMiddleBoxed = new BoxedValueInt(decode_only_middle);
                        Stereo.silk_stereo_decode_mid_only(psRangeDec, decodeOnlyMiddleBoxed);
                        decode_only_middle = decodeOnlyMiddleBoxed.Val;
                    }
                    else
                    {
                        decode_only_middle = 0;
                    }
                }
                else
                {
                    for (n = 0; n < 2; n++)
                    {
                        MS_pred_Q13[n] = psDec.sStereo.pred_prev_Q13[n];
                    }
                }
            }

            /* Reset side channel decoder prediction memory for first frame with side coding */
            if (decControl.nChannelsInternal == 2 && decode_only_middle == 0 && psDec.prev_decode_only_middle == 1)
            {
                Arrays.MemSetShort(psDec.channel_state[1].outBuf, 0, SilkConstants.MAX_FRAME_LENGTH + 2 * SilkConstants.MAX_SUB_FRAME_LENGTH);
                Arrays.MemSetInt(psDec.channel_state[1].sLPC_Q14_buf, 0, SilkConstants.MAX_LPC_ORDER);
                psDec.channel_state[1].lagPrev                 = 100;
                psDec.channel_state[1].LastGainIndex           = 10;
                psDec.channel_state[1].prevSignalType          = SilkConstants.TYPE_NO_VOICE_ACTIVITY;
                psDec.channel_state[1].first_frame_after_reset = 1;
            }

            /* Check if the temp buffer fits into the output PCM buffer. If it fits,
             * we can delay allocating the temp buffer until after the SILK peak stack
             * usage. We need to use a < and not a <= because of the two extra samples. */
            delay_stack_alloc = (decControl.internalSampleRate * decControl.nChannelsInternal
                                 < decControl.API_sampleRate * decControl.nChannelsAPI) ? 1 : 0;

            if (delay_stack_alloc != 0)
            {
                samplesOut_tmp         = samplesOut;
                samplesOut_tmp_ptrs[0] = samplesOut_ptr;
                samplesOut_tmp_ptrs[1] = samplesOut_ptr + channel_state[0].frame_length + 2;
            }
            else
            {
                samplesOut1_tmp_storage1 = new short[decControl.nChannelsInternal * (channel_state[0].frame_length + 2)];
                samplesOut_tmp           = samplesOut1_tmp_storage1;
                samplesOut_tmp_ptrs[0]   = 0;
                samplesOut_tmp_ptrs[1]   = channel_state[0].frame_length + 2;
            }

            if (lostFlag == DecoderAPIFlag.FLAG_DECODE_NORMAL)
            {
                has_side = (decode_only_middle == 0) ? 1 : 0;
            }
            else
            {
                has_side = (psDec.prev_decode_only_middle == 0 ||
                            (decControl.nChannelsInternal == 2 &&
                             lostFlag == DecoderAPIFlag.FLAG_DECODE_LBRR &&
                             channel_state[1].LBRR_flags[channel_state[1].nFramesDecoded] == 1)) ? 1 : 0;
            }
            /* Call decoder for one frame */
            for (n = 0; n < decControl.nChannelsInternal; n++)
            {
                if (n == 0 || (has_side != 0))
                {
                    int FrameIndex;
                    int condCoding;

                    FrameIndex = channel_state[0].nFramesDecoded - n;
                    /* Use independent coding if no previous frame available */
                    if (FrameIndex <= 0)
                    {
                        condCoding = SilkConstants.CODE_INDEPENDENTLY;
                    }
                    else if (lostFlag == DecoderAPIFlag.FLAG_DECODE_LBRR)
                    {
                        condCoding = (channel_state[n].LBRR_flags[FrameIndex - 1] != 0) ? SilkConstants.CODE_CONDITIONALLY : SilkConstants.CODE_INDEPENDENTLY;
                    }
                    else if (n > 0 && (psDec.prev_decode_only_middle != 0))
                    {
                        /* If we skipped a side frame in this packet, we don't
                         * need LTP scaling; the LTP state is well-defined. */
                        condCoding = SilkConstants.CODE_INDEPENDENTLY_NO_LTP_SCALING;
                    }
                    else
                    {
                        condCoding = SilkConstants.CODE_CONDITIONALLY;
                    }
                    ret += channel_state[n].silk_decode_frame(psRangeDec, samplesOut_tmp, samplesOut_tmp_ptrs[n] + 2, nSamplesOutDec, lostFlag, condCoding);
                }
                else
                {
                    Arrays.MemSetWithOffset <short>(samplesOut_tmp, 0, samplesOut_tmp_ptrs[n] + 2, nSamplesOutDec.Val);
                }
                channel_state[n].nFramesDecoded++;
            }

            if (decControl.nChannelsAPI == 2 && decControl.nChannelsInternal == 2)
            {
                /* Convert Mid/Side to Left/Right */
                Stereo.silk_stereo_MS_to_LR(psDec.sStereo, samplesOut_tmp, samplesOut_tmp_ptrs[0], samplesOut_tmp, samplesOut_tmp_ptrs[1], MS_pred_Q13, channel_state[0].fs_kHz, nSamplesOutDec.Val);
            }
            else
            {
                /* Buffering */
                Array.Copy(psDec.sStereo.sMid, 0, samplesOut_tmp, samplesOut_tmp_ptrs[0], 2);
                Array.Copy(samplesOut_tmp, samplesOut_tmp_ptrs[0] + nSamplesOutDec.Val, psDec.sStereo.sMid, 0, 2);
            }

            /* Number of output samples */
            nSamplesOut = Inlines.silk_DIV32(nSamplesOutDec.Val * decControl.API_sampleRate, Inlines.silk_SMULBB(channel_state[0].fs_kHz, 1000));

            /* Set up pointers to temp buffers */
            if (decControl.nChannelsAPI == 2)
            {
                samplesOut2_tmp  = new short[nSamplesOut];
                resample_out     = samplesOut2_tmp;
                resample_out_ptr = 0;
            }
            else
            {
                resample_out     = samplesOut;
                resample_out_ptr = samplesOut_ptr;
            }

            if (delay_stack_alloc != 0)
            {
                samplesOut1_tmp_storage2 = new short[decControl.nChannelsInternal * (channel_state[0].frame_length + 2)];
                Array.Copy(samplesOut, samplesOut_ptr, samplesOut1_tmp_storage2, 0, decControl.nChannelsInternal * (channel_state[0].frame_length + 2));
                samplesOut_tmp         = samplesOut1_tmp_storage2;
                samplesOut_tmp_ptrs[0] = 0;
                samplesOut_tmp_ptrs[1] = channel_state[0].frame_length + 2;
            }
            for (n = 0; n < Inlines.silk_min(decControl.nChannelsAPI, decControl.nChannelsInternal); n++)
            {
                /* Resample decoded signal to API_sampleRate */
                ret += Resampler.silk_resampler(channel_state[n].resampler_state, resample_out, resample_out_ptr, samplesOut_tmp, samplesOut_tmp_ptrs[n] + 1, nSamplesOutDec.Val);

                /* Interleave if stereo output and stereo stream */
                if (decControl.nChannelsAPI == 2)
                {
                    int nptr = samplesOut_ptr + n;
                    for (i = 0; i < nSamplesOut; i++)
                    {
                        samplesOut[nptr + 2 * i] = resample_out[resample_out_ptr + i];
                    }
                }
            }

            /* Create two channel output from mono stream */
            if (decControl.nChannelsAPI == 2 && decControl.nChannelsInternal == 1)
            {
                if (stereo_to_mono != 0)
                {
                    /* Resample right channel for newly collapsed stereo just in case
                     * we weren't doing collapsing when switching to mono */
                    ret += Resampler.silk_resampler(channel_state[1].resampler_state, resample_out, resample_out_ptr, samplesOut_tmp, samplesOut_tmp_ptrs[0] + 1, nSamplesOutDec.Val);

                    for (i = 0; i < nSamplesOut; i++)
                    {
                        samplesOut[samplesOut_ptr + 1 + 2 * i] = resample_out[resample_out_ptr + i];
                    }
                }
                else
                {
                    for (i = 0; i < nSamplesOut; i++)
                    {
                        samplesOut[samplesOut_ptr + 1 + 2 * i] = samplesOut[samplesOut_ptr + 2 * i];
                    }
                }
            }

            /* Export pitch lag, measured at 48 kHz sampling rate */
            if (channel_state[0].prevSignalType == SilkConstants.TYPE_VOICED)
            {
                int[] mult_tab = { 6, 4, 3 };
                decControl.prevPitchLag = channel_state[0].lagPrev * mult_tab[(channel_state[0].fs_kHz - 8) >> 2];
            }
            else
            {
                decControl.prevPitchLag = 0;
            }

            if (lostFlag == DecoderAPIFlag.FLAG_PACKET_LOST)
            {
                /* On packet loss, remove the gain clamping to prevent having the energy "bounce back"
                 * if we lose packets when the energy is going down */
                for (i = 0; i < psDec.nChannelsInternal; i++)
                {
                    psDec.channel_state[i].LastGainIndex = 10;
                }
            }
            else
            {
                psDec.prev_decode_only_middle = decode_only_middle;
            }

            return(ret);
        }
Beispiel #7
0
        /*********************************************/
        /* Decode quantization indices of excitation */
        /*********************************************/
        internal static void silk_decode_pulses(
            EntropyCoder psRangeDec,            /* I/O  Compressor data structure                   */
            short[] pulses,                     /* O    Excitation signal                           */
            int signalType,                     /* I    Sigtype                                     */
            int quantOffsetType,                /* I    quantOffsetType                             */
            int frame_length                    /* I    Frame length                                */
            )
        {
            int i, j, k, iter, abs_q, nLS, RateLevelIndex;

            int[] sum_pulses = new int[SilkConstants.MAX_NB_SHELL_BLOCKS];
            int[] nLshifts   = new int[SilkConstants.MAX_NB_SHELL_BLOCKS];
            int   pulses_ptr;

            /*********************/
            /* Decode rate level */
            /*********************/
            RateLevelIndex = psRangeDec.dec_icdf(Tables.silk_rate_levels_iCDF[signalType >> 1], 8);

            /* Calculate number of shell blocks */
            Inlines.OpusAssert(1 << SilkConstants.LOG2_SHELL_CODEC_FRAME_LENGTH == SilkConstants.SHELL_CODEC_FRAME_LENGTH);
            iter = Inlines.silk_RSHIFT(frame_length, SilkConstants.LOG2_SHELL_CODEC_FRAME_LENGTH);
            if (iter * SilkConstants.SHELL_CODEC_FRAME_LENGTH < frame_length)
            {
                Inlines.OpusAssert(frame_length == 12 * 10); /* Make sure only happens for 10 ms @ 12 kHz */
                iter++;
            }

            /***************************************************/
            /* Sum-Weighted-Pulses Decoding                    */
            /***************************************************/
            for (i = 0; i < iter; i++)
            {
                nLshifts[i]   = 0;
                sum_pulses[i] = psRangeDec.dec_icdf(Tables.silk_pulses_per_block_iCDF[RateLevelIndex], 8);

                /* LSB indication */
                while (sum_pulses[i] == SilkConstants.SILK_MAX_PULSES + 1)
                {
                    nLshifts[i]++;
                    /* When we've already got 10 LSBs, we shift the table to not allow (SILK_MAX_PULSES + 1) */
                    sum_pulses[i] = psRangeDec.dec_icdf(
                        Tables.silk_pulses_per_block_iCDF[SilkConstants.N_RATE_LEVELS - 1], (nLshifts[i] == 10 ? 1 : 0), 8);
                }
            }

            /***************************************************/
            /* Shell decoding                                  */
            /***************************************************/
            for (i = 0; i < iter; i++)
            {
                if (sum_pulses[i] > 0)
                {
                    ShellCoder.silk_shell_decoder(pulses, Inlines.silk_SMULBB(i, SilkConstants.SHELL_CODEC_FRAME_LENGTH), psRangeDec, sum_pulses[i]);
                }
                else
                {
                    Arrays.MemSetWithOffset <short>(pulses, 0, Inlines.silk_SMULBB(i, SilkConstants.SHELL_CODEC_FRAME_LENGTH), SilkConstants.SHELL_CODEC_FRAME_LENGTH);
                }
            }

            /***************************************************/
            /* LSB Decoding                                    */
            /***************************************************/
            for (i = 0; i < iter; i++)
            {
                if (nLshifts[i] > 0)
                {
                    nLS        = nLshifts[i];
                    pulses_ptr = Inlines.silk_SMULBB(i, SilkConstants.SHELL_CODEC_FRAME_LENGTH);
                    for (k = 0; k < SilkConstants.SHELL_CODEC_FRAME_LENGTH; k++)
                    {
                        abs_q = pulses[pulses_ptr + k];
                        for (j = 0; j < nLS; j++)
                        {
                            abs_q  = Inlines.silk_LSHIFT(abs_q, 1);
                            abs_q += psRangeDec.dec_icdf(Tables.silk_lsb_iCDF, 8);
                        }
                        pulses[pulses_ptr + k] = (short)(abs_q);
                    }
                    /* Mark the number of pulses non-zero for sign decoding. */
                    sum_pulses[i] |= nLS << 5;
                }
            }

            /****************************************/
            /* Decode and add signs to pulse signal */
            /****************************************/
            CodeSigns.silk_decode_signs(psRangeDec, pulses, frame_length, signalType, quantOffsetType, sum_pulses);
        }
Beispiel #8
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);
        }