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
WebRtcIsacfix_EncodeImpl(WebRtc_Word16 * in,ISACFIX_EncInst_t * ISACenc_obj,BwEstimatorstr * bw_estimatordata,WebRtc_Word16 CodingMode)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. */
WebRtcIsacfix_EncodeStoredData(ISACFIX_EncInst_t * ISACenc_obj,int BWnumber,float scale)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