1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 /* 12 * encode.c 13 * 14 * Encoding function for the iSAC coder. 15 * 16 */ 17 18 #include "arith_routins.h" 19 #include "bandwidth_estimator.h" 20 #include "codec.h" 21 #include "pitch_gain_tables.h" 22 #include "pitch_lag_tables.h" 23 #include "entropy_coding.h" 24 #include "lpc_tables.h" 25 #include "lpc_masking_model.h" 26 #include "pitch_estimator.h" 27 #include "structs.h" 28 #include <stdio.h> 29 30 31 int WebRtcIsacfix_EncodeImpl(WebRtc_Word16 *in, 32 ISACFIX_EncInst_t *ISACenc_obj, 33 BwEstimatorstr *bw_estimatordata, 34 WebRtc_Word16 CodingMode) 35 { 36 WebRtc_Word16 stream_length = 0; 37 WebRtc_Word16 usefulstr_len = 0; 38 int k; 39 WebRtc_Word16 BWno; 40 41 WebRtc_Word16 lofilt_coefQ15[(ORDERLO)*SUBFRAMES]; 42 WebRtc_Word16 hifilt_coefQ15[(ORDERHI)*SUBFRAMES]; 43 WebRtc_Word32 gain_lo_hiQ17[2*SUBFRAMES]; 44 45 WebRtc_Word16 LPandHP[FRAMESAMPLES/2 + QLOOKAHEAD]; 46 WebRtc_Word16 LP16a[FRAMESAMPLES/2 + QLOOKAHEAD]; 47 WebRtc_Word16 HP16a[FRAMESAMPLES/2 + QLOOKAHEAD]; 48 49 WebRtc_Word16 PitchLags_Q7[PITCH_SUBFRAMES]; 50 WebRtc_Word16 PitchGains_Q12[PITCH_SUBFRAMES]; 51 WebRtc_Word16 AvgPitchGain_Q12; 52 53 WebRtc_Word16 frame_mode; /* 0 for 30ms, 1 for 60ms */ 54 WebRtc_Word16 processed_samples; 55 int status; 56 57 WebRtc_Word32 bits_gainsQ11; 58 WebRtc_Word16 MinBytes; 59 WebRtc_Word16 bmodel; 60 61 transcode_obj transcodingParam; 62 WebRtc_Word16 payloadLimitBytes; 63 WebRtc_Word16 arithLenBeforeEncodingDFT; 64 WebRtc_Word16 iterCntr; 65 66 /* copy new frame length and bottle neck rate only for the first 10 ms data */ 67 if (ISACenc_obj->buffer_index == 0) { 68 /* set the framelength for the next packet */ 69 ISACenc_obj->current_framesamples = ISACenc_obj->new_framelength; 70 } 71 72 frame_mode = ISACenc_obj->current_framesamples/MAX_FRAMESAMPLES; /* 0 (30 ms) or 1 (60 ms) */ 73 processed_samples = ISACenc_obj->current_framesamples/(frame_mode+1); /* 480 (30, 60 ms) */ 74 75 /* buffer speech samples (by 10ms packet) until the framelength is reached (30 or 60 ms) */ 76 /**************************************************************************************/ 77 /* fill the buffer with 10ms input data */ 78 for(k=0; k<FRAMESAMPLES_10ms; k++) { 79 ISACenc_obj->data_buffer_fix[k + ISACenc_obj->buffer_index] = in[k]; 80 } 81 /* if buffersize is not equal to current framesize, and end of file is not reached yet, */ 82 /* increase index and go back to main to get more speech samples */ 83 if (ISACenc_obj->buffer_index + FRAMESAMPLES_10ms != processed_samples) { 84 ISACenc_obj->buffer_index = ISACenc_obj->buffer_index + FRAMESAMPLES_10ms; 85 return 0; 86 } 87 /* if buffer reached the right size, reset index and continue with encoding the frame */ 88 ISACenc_obj->buffer_index = 0; 89 90 /* end of buffer function */ 91 /**************************/ 92 93 /* encoding */ 94 /************/ 95 96 if (frame_mode == 0 || ISACenc_obj->frame_nb == 0 ) 97 { 98 /* reset bitstream */ 99 ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF; 100 ISACenc_obj->bitstr_obj.streamval = 0; 101 ISACenc_obj->bitstr_obj.stream_index = 0; 102 ISACenc_obj->bitstr_obj.full = 1; 103 104 if (CodingMode == 0) { 105 ISACenc_obj->BottleNeck = WebRtcIsacfix_GetUplinkBandwidth(bw_estimatordata); 106 ISACenc_obj->MaxDelay = WebRtcIsacfix_GetUplinkMaxDelay(bw_estimatordata); 107 } 108 if (CodingMode == 0 && frame_mode == 0 && (ISACenc_obj->enforceFrameSize == 0)) { 109 ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck, 110 ISACenc_obj->current_framesamples); 111 } 112 113 // multiply the bottleneck by 0.88 before computing SNR, 0.88 is tuned by experimenting on TIMIT 114 // 901/1024 is 0.87988281250000 115 ISACenc_obj->s2nr = WebRtcIsacfix_GetSnr((WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ISACenc_obj->BottleNeck, 901, 10), 116 ISACenc_obj->current_framesamples); 117 118 /* encode frame length */ 119 status = WebRtcIsacfix_EncodeFrameLen(ISACenc_obj->current_framesamples, &ISACenc_obj->bitstr_obj); 120 if (status < 0) 121 { 122 /* Wrong frame size */ 123 if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) 124 { 125 // If this is the second 30ms of a 60ms frame reset this such that in the next call 126 // encoder starts fresh. 127 ISACenc_obj->frame_nb = 0; 128 } 129 return status; 130 } 131 132 /* Save framelength for multiple packets memory */ 133 if (ISACenc_obj->SaveEnc_ptr != NULL) { 134 (ISACenc_obj->SaveEnc_ptr)->framelength=ISACenc_obj->current_framesamples; 135 } 136 137 /* bandwidth estimation and coding */ 138 BWno = WebRtcIsacfix_GetDownlinkBwIndexImpl(bw_estimatordata); 139 status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj); 140 if (status < 0) 141 { 142 if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) 143 { 144 // If this is the second 30ms of a 60ms frame reset this such that in the next call 145 // encoder starts fresh. 146 ISACenc_obj->frame_nb = 0; 147 } 148 return status; 149 } 150 } 151 152 /* split signal in two bands */ 153 WebRtcIsacfix_SplitAndFilter1(ISACenc_obj->data_buffer_fix, LP16a, HP16a, &ISACenc_obj->prefiltbankstr_obj ); 154 155 /* estimate pitch parameters and pitch-filter lookahead signal */ 156 WebRtcIsacfix_PitchAnalysis(LP16a+QLOOKAHEAD, LPandHP, 157 &ISACenc_obj->pitchanalysisstr_obj, PitchLags_Q7, PitchGains_Q12); /* LPandHP = LP_lookahead_pfQ0, */ 158 159 /* Set where to store data in multiple packets memory */ 160 if (ISACenc_obj->SaveEnc_ptr != NULL) { 161 if (frame_mode == 0 || ISACenc_obj->frame_nb == 0) 162 { 163 (ISACenc_obj->SaveEnc_ptr)->startIdx = 0; 164 } 165 else 166 { 167 (ISACenc_obj->SaveEnc_ptr)->startIdx = 1; 168 } 169 } 170 171 /* quantize & encode pitch parameters */ 172 status = WebRtcIsacfix_EncodePitchGain(PitchGains_Q12, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr); 173 if (status < 0) 174 { 175 if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) 176 { 177 // If this is the second 30ms of a 60ms frame reset this such that in the next call 178 // encoder starts fresh. 179 ISACenc_obj->frame_nb = 0; 180 } 181 return status; 182 } 183 status = WebRtcIsacfix_EncodePitchLag(PitchLags_Q7 , PitchGains_Q12, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr); 184 if (status < 0) 185 { 186 if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) 187 { 188 // If this is the second 30ms of a 60ms frame reset this such that in the next call 189 // encoder starts fresh. 190 ISACenc_obj->frame_nb = 0; 191 } 192 return status; 193 } 194 AvgPitchGain_Q12 = WEBRTC_SPL_RSHIFT_W32(PitchGains_Q12[0] + PitchGains_Q12[1] + PitchGains_Q12[2] + PitchGains_Q12[3], 2); 195 196 /* find coefficients for perceptual pre-filters */ 197 WebRtcIsacfix_GetLpcCoef(LPandHP, HP16a+QLOOKAHEAD, &ISACenc_obj->maskfiltstr_obj, 198 ISACenc_obj->s2nr, PitchGains_Q12, 199 gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15); /*LPandHP = LP_lookahead_pfQ0*/ 200 201 // record LPC Gains for possible bit-rate reduction 202 for(k = 0; k < KLT_ORDER_GAIN; k++) 203 { 204 transcodingParam.lpcGains[k] = gain_lo_hiQ17[k]; 205 } 206 207 /* code LPC model and shape - gains not quantized yet */ 208 status = WebRtcIsacfix_EncodeLpc(gain_lo_hiQ17, lofilt_coefQ15, hifilt_coefQ15, 209 &bmodel, &bits_gainsQ11, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr, &transcodingParam); 210 if (status < 0) 211 { 212 if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) 213 { 214 // If this is the second 30ms of a 60ms frame reset this such that in the next call 215 // encoder starts fresh. 216 ISACenc_obj->frame_nb = 0; 217 } 218 return status; 219 } 220 arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full); 221 222 /* low-band filtering */ 223 WebRtcIsacfix_NormLatticeFilterMa(ORDERLO, ISACenc_obj->maskfiltstr_obj.PreStateLoGQ15, 224 LP16a, lofilt_coefQ15, gain_lo_hiQ17, 0, LPandHP);/* LPandHP = LP16b */ 225 226 /* pitch filter */ 227 WebRtcIsacfix_PitchFilter(LPandHP, LP16a, &ISACenc_obj->pitchfiltstr_obj, PitchLags_Q7, PitchGains_Q12, 1);/* LPandHP = LP16b */ 228 229 /* high-band filtering */ 230 WebRtcIsacfix_NormLatticeFilterMa(ORDERHI, ISACenc_obj->maskfiltstr_obj.PreStateHiGQ15, 231 HP16a, hifilt_coefQ15, gain_lo_hiQ17, 1, LPandHP);/*LPandHP = HP16b*/ 232 233 /* transform */ 234 WebRtcIsacfix_Time2Spec(LP16a, LPandHP, LP16a, LPandHP); /*LPandHP = HP16b*/ 235 236 /* Save data for multiple packets memory */ 237 if (ISACenc_obj->SaveEnc_ptr != NULL) { 238 for (k = 0; k < FRAMESAMPLES_HALF; k++) { 239 (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k]; 240 (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k]; 241 } 242 (ISACenc_obj->SaveEnc_ptr)->AvgPitchGain[(ISACenc_obj->SaveEnc_ptr)->startIdx] = AvgPitchGain_Q12; 243 } 244 245 /* quantization and lossless coding */ 246 status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12); 247 if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/ 248 { 249 if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) 250 { 251 // If this is the second 30ms of a 60ms frame reset this such that in the next call 252 // encoder starts fresh. 253 ISACenc_obj->frame_nb = 0; 254 } 255 return status; 256 } 257 258 if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0)) 259 { 260 // it is a 60ms and we are in the first 30ms 261 // then the limit at this point should be half of the assigned value 262 payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 >> 1; 263 } 264 else if (frame_mode == 0) 265 { 266 // it is a 30ms frame 267 payloadLimitBytes = (ISACenc_obj->payloadLimitBytes30) - 3; 268 } 269 else 270 { 271 // this is the second half of a 60ms frame. 272 payloadLimitBytes = ISACenc_obj->payloadLimitBytes60 - 3; // subract 3 because termination process may add 3 bytes 273 } 274 275 iterCntr = 0; 276 while((((ISACenc_obj->bitstr_obj.stream_index) << 1) > payloadLimitBytes) || 277 (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) 278 { 279 WebRtc_Word16 arithLenDFTByte; 280 WebRtc_Word16 bytesLeftQ5; 281 WebRtc_Word16 ratioQ5[8] = {0, 6, 9, 12, 16, 19, 22, 25}; 282 283 // According to experiments on TIMIT the following is proper for audio, but it is not agressive enough for tonal inputs 284 // such as DTMF, sweep-sine, ... 285 // 286 // (0.55 - (0.8 - ratio[i]/32) * 5 / 6) * 2^14 287 // WebRtc_Word16 scaleQ14[8] = {0, 648, 1928, 3208, 4915, 6195, 7475, 8755}; 288 289 290 // This is a supper-agressive scaling passed the tests (tonal inputs) tone with one iteration for payload limit 291 // of 120 (32kbps bottleneck), number of frames needed a rate-reduction was 58403 292 // 293 WebRtc_Word16 scaleQ14[8] = {0, 348, 828, 1408, 2015, 3195, 3500, 3500}; 294 WebRtc_Word16 idx; 295 296 if(iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) 297 { 298 // We were not able to limit the payload size 299 300 if((frame_mode == 1) && (ISACenc_obj->frame_nb == 0)) 301 { 302 // This was the first 30ms of a 60ms frame. Although the payload is larger than it 303 // should be but we let the second 30ms be encoded. Maybe togetehr we won't exceed 304 // the limit. 305 ISACenc_obj->frame_nb = 1; 306 return 0; 307 } 308 else if((frame_mode == 1) && (ISACenc_obj->frame_nb == 1)) 309 { 310 ISACenc_obj->frame_nb = 0; 311 } 312 313 if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH) 314 { 315 return -ISAC_PAYLOAD_LARGER_THAN_LIMIT; 316 } 317 else 318 { 319 return status; 320 } 321 } 322 if(status != -ISAC_DISALLOWED_BITSTREAM_LENGTH) 323 { 324 arithLenDFTByte = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full) - arithLenBeforeEncodingDFT; 325 bytesLeftQ5 = (payloadLimitBytes - arithLenBeforeEncodingDFT) << 5; 326 327 // bytesLeft / arithLenDFTBytes indicates how much scaling is required a rough estimate (agressive) 328 // scale = 0.55 - (0.8 - bytesLeft / arithLenDFTBytes) * 5 / 6 329 // bytesLeft / arithLenDFTBytes below 0.2 will have a scale of zero and above 0.8 are treated as 0.8 330 // to avoid division we do more simplification. 331 // 332 // values of (bytesLeft / arithLenDFTBytes)*32 between ratioQ5[i] and ratioQ5[i+1] are rounded to ratioQ5[i] 333 // and the corresponding scale is chosen 334 335 // we compare bytesLeftQ5 with ratioQ5[]*arithLenDFTByte; 336 idx = 4; 337 idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 2:-2; 338 idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 1:-1; 339 idx += (bytesLeftQ5 >= WEBRTC_SPL_MUL_16_16(ratioQ5[idx], arithLenDFTByte))? 0:-1; 340 } 341 else 342 { 343 // we are here because the bit-stream did not fit into the buffer, in this case, the stream_index is not 344 // trustable, especially if the is the first 30ms of a packet. Thereforem, we will go for the most agressive 345 // case. 346 idx = 0; 347 } 348 // scale FFT coefficients to reduce the bit-rate 349 for(k = 0; k < FRAMESAMPLES_HALF; k++) 350 { 351 LP16a[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(LP16a[k], scaleQ14[idx], 14); 352 LPandHP[k] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(LPandHP[k], scaleQ14[idx], 14); 353 } 354 355 // Save data for multiple packets memory 356 if (ISACenc_obj->SaveEnc_ptr != NULL) 357 { 358 for(k = 0; k < FRAMESAMPLES_HALF; k++) 359 { 360 (ISACenc_obj->SaveEnc_ptr)->fre[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LP16a[k]; 361 (ISACenc_obj->SaveEnc_ptr)->fim[k + (ISACenc_obj->SaveEnc_ptr)->startIdx*FRAMESAMPLES_HALF] = LPandHP[k]; 362 } 363 } 364 365 // scale the unquantized LPC gains and save the scaled version for the future use 366 for(k = 0; k < KLT_ORDER_GAIN; k++) 367 { 368 gain_lo_hiQ17[k] = WEBRTC_SPL_MUL_16_32_RSFT14(scaleQ14[idx], transcodingParam.lpcGains[k]);//transcodingParam.lpcGains[k]; // 369 transcodingParam.lpcGains[k] = gain_lo_hiQ17[k]; 370 } 371 372 // reset the bit-stream object to the state which it had before encoding LPC Gains 373 ISACenc_obj->bitstr_obj.full = transcodingParam.full; 374 ISACenc_obj->bitstr_obj.stream_index = transcodingParam.stream_index; 375 ISACenc_obj->bitstr_obj.streamval = transcodingParam.streamval; 376 ISACenc_obj->bitstr_obj.W_upper = transcodingParam.W_upper; 377 ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index-1] = transcodingParam.beforeLastWord; 378 ISACenc_obj->bitstr_obj.stream[transcodingParam.stream_index] = transcodingParam.lastWord; 379 380 381 // quantize and encode LPC gain 382 WebRtcIsacfix_EstCodeLpcGain(gain_lo_hiQ17, &ISACenc_obj->bitstr_obj, ISACenc_obj->SaveEnc_ptr); 383 arithLenBeforeEncodingDFT = (ISACenc_obj->bitstr_obj.stream_index << 1) + (1-ISACenc_obj->bitstr_obj.full); 384 status = WebRtcIsacfix_EncodeSpec(LP16a, LPandHP, &ISACenc_obj->bitstr_obj, AvgPitchGain_Q12); 385 if((status <= -1) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) /*LPandHP = HP16b*/ 386 { 387 if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) 388 { 389 // If this is the second 30ms of a 60ms frame reset this such that in the next call 390 // encoder starts fresh. 391 ISACenc_obj->frame_nb = 0; 392 } 393 return status; 394 } 395 iterCntr++; 396 } 397 398 if (frame_mode == 1 && ISACenc_obj->frame_nb == 0) 399 /* i.e. 60 ms framesize and just processed the first 30ms, */ 400 /* go back to main function to buffer the other 30ms speech frame */ 401 { 402 ISACenc_obj->frame_nb = 1; 403 return 0; 404 } 405 else if (frame_mode == 1 && ISACenc_obj->frame_nb == 1) 406 { 407 ISACenc_obj->frame_nb = 0; 408 /* also update the framelength for next packet, in Adaptive mode only */ 409 if (CodingMode == 0 && (ISACenc_obj->enforceFrameSize == 0)) { 410 ISACenc_obj->new_framelength = WebRtcIsacfix_GetNewFrameLength(ISACenc_obj->BottleNeck, 411 ISACenc_obj->current_framesamples); 412 } 413 } 414 415 416 /* complete arithmetic coding */ 417 stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj); 418 /* can this be negative? */ 419 420 if(CodingMode == 0) 421 { 422 423 /* update rate model and get minimum number of bytes in this packet */ 424 MinBytes = WebRtcIsacfix_GetMinBytes(&ISACenc_obj->rate_data_obj, (WebRtc_Word16) stream_length, 425 ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck, ISACenc_obj->MaxDelay); 426 427 /* if bitstream is too short, add garbage at the end */ 428 429 /* Store length of coded data */ 430 usefulstr_len = stream_length; 431 432 /* Make sure MinBytes does not exceed packet size limit */ 433 if ((ISACenc_obj->frame_nb == 0) && (MinBytes > ISACenc_obj->payloadLimitBytes30)) { 434 MinBytes = ISACenc_obj->payloadLimitBytes30; 435 } else if ((ISACenc_obj->frame_nb == 1) && (MinBytes > ISACenc_obj->payloadLimitBytes60)) { 436 MinBytes = ISACenc_obj->payloadLimitBytes60; 437 } 438 439 /* Make sure we don't allow more than 255 bytes of garbage data. 440 We store the length of the garbage data in 8 bits in the bitstream, 441 255 is the max garbage lenght we can signal using 8 bits. */ 442 if( MinBytes > usefulstr_len + 255 ) { 443 MinBytes = usefulstr_len + 255; 444 } 445 446 /* Save data for creation of multiple bitstreams */ 447 if (ISACenc_obj->SaveEnc_ptr != NULL) { 448 (ISACenc_obj->SaveEnc_ptr)->minBytes = MinBytes; 449 } 450 451 while (stream_length < MinBytes) 452 { 453 if (stream_length & 0x0001){ 454 ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed ); 455 ISACenc_obj->bitstr_obj.stream[ WEBRTC_SPL_RSHIFT_W16(stream_length, 1) ] |= (WebRtc_UWord16)(ISACenc_obj->bitstr_seed & 0xFF); 456 } else { 457 ISACenc_obj->bitstr_seed = WEBRTC_SPL_RAND( ISACenc_obj->bitstr_seed ); 458 ISACenc_obj->bitstr_obj.stream[ WEBRTC_SPL_RSHIFT_W16(stream_length, 1) ] = WEBRTC_SPL_LSHIFT_U16(ISACenc_obj->bitstr_seed, 8); 459 } 460 stream_length++; 461 } 462 463 /* to get the real stream_length, without garbage */ 464 if (usefulstr_len & 0x0001) { 465 ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0xFF00; 466 ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] += (MinBytes - usefulstr_len) & 0x00FF; 467 } 468 else { 469 ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] &= 0x00FF; 470 ISACenc_obj->bitstr_obj.stream[usefulstr_len>>1] += WEBRTC_SPL_LSHIFT_U16((MinBytes - usefulstr_len) & 0x00FF, 8); 471 } 472 } 473 else 474 { 475 /* update rate model */ 476 WebRtcIsacfix_UpdateRateModel(&ISACenc_obj->rate_data_obj, (WebRtc_Word16) stream_length, 477 ISACenc_obj->current_framesamples, ISACenc_obj->BottleNeck); 478 } 479 return stream_length; 480 } 481 482 /* This function is used to create a new bitstream with new BWE. 483 The same data as previously encoded with the fucntion WebRtcIsacfix_EncodeImpl() 484 is used. The data needed is taken from the struct, where it was stored 485 when calling the encoder. */ 486 int WebRtcIsacfix_EncodeStoredData(ISACFIX_EncInst_t *ISACenc_obj, 487 int BWnumber, 488 float scale) 489 { 490 int ii; 491 int status; 492 WebRtc_Word16 BWno = BWnumber; 493 int stream_length = 0; 494 495 WebRtc_Word16 model; 496 const WebRtc_UWord16 *Q_PitchGain_cdf_ptr[1]; 497 const WebRtc_UWord16 **cdf; 498 const ISAC_SaveEncData_t *SaveEnc_str; 499 WebRtc_Word32 tmpLPCcoeffs_g[KLT_ORDER_GAIN<<1]; 500 WebRtc_Word16 tmpLPCindex_g[KLT_ORDER_GAIN<<1]; 501 WebRtc_Word16 tmp_fre[FRAMESAMPLES]; 502 WebRtc_Word16 tmp_fim[FRAMESAMPLES]; 503 504 SaveEnc_str = ISACenc_obj->SaveEnc_ptr; 505 506 /* Check if SaveEnc memory exists */ 507 if (SaveEnc_str == NULL) { 508 return (-1); 509 } 510 511 /* Sanity Check - possible values for BWnumber is 0 - 23 */ 512 if ((BWnumber < 0) || (BWnumber > 23)) { 513 return -ISAC_RANGE_ERROR_BW_ESTIMATOR; 514 } 515 516 /* reset bitstream */ 517 ISACenc_obj->bitstr_obj.W_upper = 0xFFFFFFFF; 518 ISACenc_obj->bitstr_obj.streamval = 0; 519 ISACenc_obj->bitstr_obj.stream_index = 0; 520 ISACenc_obj->bitstr_obj.full = 1; 521 522 /* encode frame length */ 523 status = WebRtcIsacfix_EncodeFrameLen(SaveEnc_str->framelength, &ISACenc_obj->bitstr_obj); 524 if (status < 0) { 525 /* Wrong frame size */ 526 return status; 527 } 528 529 /* encode bandwidth estimate */ 530 status = WebRtcIsacfix_EncodeReceiveBandwidth(&BWno, &ISACenc_obj->bitstr_obj); 531 if (status < 0) { 532 return status; 533 } 534 535 /* Transcoding */ 536 /* If scale < 1, rescale data to produce lower bitrate signal */ 537 if ((0.0 < scale) && (scale < 1.0)) { 538 /* Compensate LPC gain */ 539 for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) { 540 tmpLPCcoeffs_g[ii] = (WebRtc_Word32) ((scale) * (float) SaveEnc_str->LPCcoeffs_g[ii]); 541 } 542 543 /* Scale DFT */ 544 for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) { 545 tmp_fre[ii] = (WebRtc_Word16) ((scale) * (float) SaveEnc_str->fre[ii]) ; 546 tmp_fim[ii] = (WebRtc_Word16) ((scale) * (float) SaveEnc_str->fim[ii]) ; 547 } 548 } else { 549 for (ii = 0; ii < (KLT_ORDER_GAIN*(1+SaveEnc_str->startIdx)); ii++) { 550 tmpLPCindex_g[ii] = SaveEnc_str->LPCindex_g[ii]; 551 } 552 553 for (ii = 0; ii < (FRAMESAMPLES_HALF*(1+SaveEnc_str->startIdx)); ii++) { 554 tmp_fre[ii] = SaveEnc_str->fre[ii]; 555 tmp_fim[ii] = SaveEnc_str->fim[ii]; 556 } 557 } 558 559 /* Loop over number of 30 msec */ 560 for (ii = 0; ii <= SaveEnc_str->startIdx; ii++) 561 { 562 563 /* encode pitch gains */ 564 *Q_PitchGain_cdf_ptr = WebRtcIsacfix_kPitchGainCdf; 565 status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->pitchGain_index[ii], 566 Q_PitchGain_cdf_ptr, 1); 567 if (status < 0) { 568 return status; 569 } 570 571 /* entropy coding of quantization pitch lags */ 572 /* voicing classificiation */ 573 if (SaveEnc_str->meanGain[ii] <= 819) { 574 cdf = WebRtcIsacfix_kPitchLagPtrLo; 575 } else if (SaveEnc_str->meanGain[ii] <= 1638) { 576 cdf = WebRtcIsacfix_kPitchLagPtrMid; 577 } else { 578 cdf = WebRtcIsacfix_kPitchLagPtrHi; 579 } 580 status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, 581 &SaveEnc_str->pitchIndex[PITCH_SUBFRAMES*ii], cdf, PITCH_SUBFRAMES); 582 if (status < 0) { 583 return status; 584 } 585 586 /* LPC */ 587 /* entropy coding of model number */ 588 model = 0; 589 status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &model, 590 WebRtcIsacfix_kModelCdfPtr, 1); 591 if (status < 0) { 592 return status; 593 } 594 595 /* entropy coding of quantization indices - LPC shape only */ 596 status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &SaveEnc_str->LPCindex_s[KLT_ORDER_SHAPE*ii], 597 WebRtcIsacfix_kCdfShapePtr[0], KLT_ORDER_SHAPE); 598 if (status < 0) { 599 return status; 600 } 601 602 /* If transcoding, get new LPC gain indices */ 603 if (scale < 1.0) { 604 WebRtcIsacfix_TranscodeLpcCoef(&tmpLPCcoeffs_g[KLT_ORDER_GAIN*ii], &tmpLPCindex_g[KLT_ORDER_GAIN*ii]); 605 } 606 607 /* entropy coding of quantization indices - LPC gain */ 608 status = WebRtcIsacfix_EncHistMulti(&ISACenc_obj->bitstr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN*ii], 609 WebRtcIsacfix_kCdfGainPtr[0], KLT_ORDER_GAIN); 610 if (status < 0) { 611 return status; 612 } 613 614 /* quantization and lossless coding */ 615 status = WebRtcIsacfix_EncodeSpec(&tmp_fre[ii*FRAMESAMPLES_HALF], &tmp_fim[ii*FRAMESAMPLES_HALF], 616 &ISACenc_obj->bitstr_obj, SaveEnc_str->AvgPitchGain[ii]); 617 if (status < 0) { 618 return status; 619 } 620 } 621 622 /* complete arithmetic coding */ 623 stream_length = WebRtcIsacfix_EncTerminate(&ISACenc_obj->bitstr_obj); 624 625 return stream_length; 626 } 627