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