/// <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]; }
/// <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); }
/// <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; } }
/// <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; } }
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); } }
/* 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); }
/*********************************************/ /* 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); }
/* 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); }