int WebRtcIsacfix_EncodeImpl(int16_t *in, IsacFixEncoderInstance *ISACenc_obj, BwEstimatorstr *bw_estimatordata, int16_t CodingMode) { int16_t stream_length = 0; int16_t usefulstr_len = 0; int k; int16_t BWno; int16_t lofilt_coefQ15[(ORDERLO)*SUBFRAMES]; int16_t hifilt_coefQ15[(ORDERHI)*SUBFRAMES]; int32_t gain_lo_hiQ17[2*SUBFRAMES]; int16_t LPandHP[FRAMESAMPLES/2 + QLOOKAHEAD]; int16_t LP16a[FRAMESAMPLES/2 + QLOOKAHEAD]; int16_t HP16a[FRAMESAMPLES/2 + QLOOKAHEAD]; int16_t PitchLags_Q7[PITCH_SUBFRAMES]; int16_t PitchGains_Q12[PITCH_SUBFRAMES]; int16_t AvgPitchGain_Q12; int16_t frame_mode; /* 0 for 30ms, 1 for 60ms */ int16_t processed_samples; int status; int32_t bits_gainsQ11; int16_t MinBytes; int16_t bmodel; transcode_obj transcodingParam; int16_t payloadLimitBytes; int16_t arithLenBeforeEncodingDFT; int16_t iterCntr; /* copy new frame length and bottle neck rate only for the first 10 ms data */ if (ISACenc_obj->buffer_index == 0) { /* set the framelength for the next packet */ ISACenc_obj->current_framesamples = ISACenc_obj->new_framelength; } frame_mode = ISACenc_obj->current_framesamples/MAX_FRAMESAMPLES; /* 0 (30 ms) or 1 (60 ms) */ processed_samples = ISACenc_obj->current_framesamples/(frame_mode+1); /* 480 (30, 60 ms) */ /* buffer speech samples (by 10ms packet) until the framelength is reached (30 or 60 ms) */ /**************************************************************************************/ /* fill the buffer with 10ms input data */ for(k=0; k<FRAMESAMPLES_10ms; k++) { ISACenc_obj->data_buffer_fix[k + ISACenc_obj->buffer_index] = in[k]; } /* if buffersize is not equal to current framesize, and end of file is not reached yet, */ /* increase index and go back to main to get more speech samples */ if (ISACenc_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) { ISACenc_obj->buffer_index = ISACenc_obj->buffer_index + FRAMESAMPLES_10ms; return 0; } /* if buffer reached the right size, reset index and continue with encoding the frame */ ISACenc_obj->buffer_index = 0; /* end of buffer function */ /**************************/ /* encoding */ /************/ if (frame_mode == 0 || ISACenc_obj->frame_nb == 0 ) { /* reset bitstream */ ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF; ISACenc_obj->bitstr_obj.streamval = 0; ISACenc_obj->bitstr_obj.stream_index = 0; ISACenc_obj->bitstr_obj.full = 1; if (CodingMode == 0) { ISACenc_obj->BottleNeck = WebRtcIsacfix_GetUplinkBandwidth(bw_estimatordata); ISACenc_obj->MaxDelay = WebRtcIsacfix_GetUplinkMaxDelay(bw_estimatordata); } if (CodingMode == 0 && frame_mode == 0 && (ISACenc_obj->enforceFrameSize == 0)) { ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck, ISACenc_obj->current_framesamples); } // multiply the bottleneck by 0.88 before computing SNR, 0.88 is tuned by experimenting on TIMIT // 901/1024 is 0.87988281250000 ISACenc_obj->s2nr = WebRtcIsacfix_GetSnr( (int16_t)(ISACenc_obj->BottleNeck * 901 >> 10), ISACenc_obj->current_framesamples); /* encode frame length */ status = WebRtcIsacfix_EncodeFrameLen(ISACenc_obj->current_framesamples, &ISACenc_obj->bitstr_obj); if (status < 0) { /* Wrong frame size */ if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) { // If this is the second 30ms of a 60ms frame reset this such that in the next call // encoder starts fresh. ISACenc_obj->frame_nb = 0; } return status; } /* Save framelength for multiple packets memory */ if (ISACenc_obj->SaveEnc_ptr != NULL) { (ISACenc_obj->SaveEnc_ptr)->framelength=ISACenc_obj->current_framesamples; } /* bandwidth estimation and coding */ BWno = WebRtcIsacfix_GetDownlinkBwIndexImpl(bw_estimatordata); status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj); if (status < 0) { if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) { // If this is the second 30ms of a 60ms frame reset this such that in the next call // encoder starts fresh. ISACenc_obj->frame_nb = 0; } return status; } }
int WebRtcIsacfix_EncodeImpl(int16_t *in, ISACFIX_EncInst_t *ISACenc_obj, BwEstimatorstr *bw_estimatordata, int16_t CodingMode) { int16_t stream_length = 0; int16_t usefulstr_len = 0; int k; int16_t BWno; int16_t lofilt_coefQ15[(ORDERLO)*SUBFRAMES]; int16_t hifilt_coefQ15[(ORDERHI)*SUBFRAMES]; int32_t gain_lo_hiQ17[2*SUBFRAMES]; int16_t LPandHP[FRAMESAMPLES/2 + QLOOKAHEAD]; int16_t LP16a[FRAMESAMPLES/2 + QLOOKAHEAD]; int16_t HP16a[FRAMESAMPLES/2 + QLOOKAHEAD]; int16_t PitchLags_Q7[PITCH_SUBFRAMES]; int16_t PitchGains_Q12[PITCH_SUBFRAMES]; int16_t AvgPitchGain_Q12; int16_t frame_mode; /* 0 for 30ms, 1 for 60ms */ int16_t processed_samples; int status; int32_t bits_gainsQ11; int16_t MinBytes; int16_t bmodel; transcode_obj transcodingParam; int16_t payloadLimitBytes; int16_t arithLenBeforeEncodingDFT; int16_t iterCntr; /* copy new frame length and bottle neck rate only for the first 10 ms data */ if (ISACenc_obj->buffer_index == 0) { /* set the framelength for the next packet */ ISACenc_obj->current_framesamples = ISACenc_obj->new_framelength; } frame_mode = ISACenc_obj->current_framesamples/MAX_FRAMESAMPLES; /* 0 (30 ms) or 1 (60 ms) */ processed_samples = ISACenc_obj->current_framesamples/(frame_mode+1); /* 480 (30, 60 ms) */ /* buffer speech samples (by 10ms packet) until the framelength is reached (30 or 60 ms) */ /**************************************************************************************/ /* fill the buffer with 10ms input data */ for(k=0; k<FRAMESAMPLES_10ms; k++) { ISACenc_obj->data_buffer_fix[k + ISACenc_obj->buffer_index] = in[k]; } /* if buffersize is not equal to current framesize, and end of file is not reached yet, */ /* increase index and go back to main to get more speech samples */ if (ISACenc_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) { ISACenc_obj->buffer_index = ISACenc_obj->buffer_index + FRAMESAMPLES_10ms; return 0; } /* if buffer reached the right size, reset index and continue with encoding the frame */ ISACenc_obj->buffer_index = 0; /* end of buffer function */ /**************************/ /* encoding */ /************/ if (frame_mode == 0 || ISACenc_obj->frame_nb == 0 ) { /* reset bitstream */ ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF; ISACenc_obj->bitstr_obj.streamval = 0; ISACenc_obj->bitstr_obj.stream_index = 0; ISACenc_obj->bitstr_obj.full = 1; if (CodingMode == 0) { ISACenc_obj->BottleNeck = WebRtcIsacfix_GetUplinkBandwidth(bw_estimatordata); ISACenc_obj->MaxDelay = WebRtcIsacfix_GetUplinkMaxDelay(bw_estimatordata); } if (CodingMode == 0 && frame_mode == 0 && (ISACenc_obj->enforceFrameSize == 0)) { ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck, ISACenc_obj->current_framesamples); } // multiply the bottleneck by 0.88 before computing SNR, 0.88 is tuned by experimenting on TIMIT // 901/1024 is 0.87988281250000 ISACenc_obj->s2nr = WebRtcIsacfix_GetSnr((int16_t)WEBRTC_SPL_MUL_16_16_RSFT(ISACenc_obj->BottleNeck, 901, 10), ISACenc_obj->current_framesamples); /* encode frame length */ status = WebRtcIsacfix_EncodeFrameLen(ISACenc_obj->current_framesamples, &ISACenc_obj->bitstr_obj); if (status < 0) { /* Wrong frame size */ if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) { // If this is the second 30ms of a 60ms frame reset this such that in the next call // encoder starts fresh. ISACenc_obj->frame_nb = 0; } return status; } /* Save framelength for multiple packets memory */ if (ISACenc_obj->SaveEnc_ptr != NULL) { (ISACenc_obj->SaveEnc_ptr)->framelength=ISACenc_obj->current_framesamples; } /* bandwidth estimation and coding */ BWno = WebRtcIsacfix_GetDownlinkBwIndexImpl(bw_estimatordata); status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj); if (status < 0) { if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) { // If this is the second 30ms of a 60ms frame reset this such that in the next call // encoder starts fresh. ISACenc_obj->frame_nb = 0; } return status; } } /* split signal in two bands */ WebRtcIsacfix_SplitAndFilter1(ISACenc_obj->data_buffer_fix, LP16a, HP16a, &ISACenc_obj->prefiltbankstr_obj ); /* estimate pitch parameters and pitch-filter lookahead signal */ WebRtcIsacfix_PitchAnalysis(LP16a+QLOOKAHEAD, LPandHP, &ISACenc_obj->pitchanalysisstr_obj, PitchLags_Q7, PitchGains_Q12); /* LPandHP = LP_lookahead_pfQ0, */ /* Set where to store data in multiple packets memory */ if (ISACenc_obj->SaveEnc_ptr != NULL) { if (frame_mode == 0 || ISACenc_obj->frame_nb == 0) { (ISACenc_obj->SaveEnc_ptr)->startIdx = 0; } else { (ISACenc_obj->SaveEnc_ptr)->startIdx = 1; } } /* quantize & encode pitch parameters */ status = WebRtcIsacfix_EncodePitchGain(PitchGains_Q12, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr); if (status < 0) { if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) { // If this is the second 30ms of a 60ms frame reset this such that in the next call // encoder starts fresh. ISACenc_obj->frame_nb = 0; } return status; } status = WebRtcIsacfix_EncodePitchLag(PitchLags_Q7 , PitchGains_Q12, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr); if (status < 0) { if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) { // If this is the second 30ms of a 60ms frame reset this such that in the next call // encoder starts fresh. ISACenc_obj->frame_nb = 0; } return status; } AvgPitchGain_Q12 = WEBRTC_SPL_RSHIFT_W32(PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3], 2); /* find coefficients for perceptual pre-filters */ WebRtcIsacfix_GetLpcCoef(LPandHP, HP16a+QLOOKAHEAD, &ISACenc_obj->maskfiltstr_obj, ISACenc_obj->s2nr, PitchGains_Q12, gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15); /*LPandHP = LP_lookahead_pfQ0*/ // record LPC Gains for possible bit-rate reduction for(k = 0; k < KLT_ORDER_GAIN; k++) { transcodingParam.lpcGains[k] = gain_lo_hiQ17[k]; } /* code LPC model and shape - gains not quantized yet */ status = WebRtcIsacfix_EncodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15, &bmodel, &bits_gainsQ11, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr, &transcodingParam); if (status < 0) { if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) { // If this is the second 30ms of a 60ms frame reset this such that in the next call // encoder starts fresh. ISACenc_obj->frame_nb = 0; } return status; } arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full); /* low-band filtering */ WebRtcIsacfix_NormLatticeFilterMa(ORDERLO, ISACenc_obj->maskfiltstr_obj.PreStateLoGQ15, LP16a, lofilt_coefQ15, gain_lo_hiQ17, 0, LPandHP);/* LPandHP = LP16b */ /* pitch filter */ WebRtcIsacfix_PitchFilter(LPandHP, LP16a, &ISACenc_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 1);/* LPandHP = LP16b */ /* high-band filtering */ WebRtcIsacfix_NormLatticeFilterMa(ORDERHI, ISACenc_obj->maskfiltstr_obj.PreStateHiGQ15, HP16a, hifilt_coefQ15, gain_lo_hiQ17, 1, LPandHP);/*LPandHP = HP16b*/ /* transform */ WebRtcIsacfix_Time2Spec(LP16a, LPandHP, LP16a, LPandHP); /*LPandHP = HP16b*/ /* Save data for multiple packets memory */ if (ISACenc_obj->SaveEnc_ptr != NULL) { for (k = 0; k < FRAMESAMPLES_HALF; k++) { (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k]; (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k]; } (ISACenc_obj->SaveEnc_ptr)->AvgPitchGain[(ISACenc_obj->SaveEnc_ptr)->startIdx] = AvgPitchGain_Q12; } /* quantization and lossless coding */ status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12); if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/ { if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) { // If this is the second 30ms of a 60ms frame reset this such that in the next call // encoder starts fresh. ISACenc_obj->frame_nb = 0; } return status; } if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0)) { // it is a 60ms and we are in the first 30ms // then the limit at this point should be half of the assigned value payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 >> 1; }