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