Line data Source code
1 : /*
2 : * Copyright (c) 2012 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 : * This file contains definition of funtions for encoding.
15 : * Decoding of upper-band, including 8-12 kHz, when the bandwidth is
16 : * 0-12 kHz, and 8-16 kHz, when the bandwidth is 0-16 kHz.
17 : *
18 : */
19 :
20 : #include <stdlib.h>
21 : #include <string.h>
22 : #include <stdio.h>
23 :
24 : #include "structs.h"
25 : #include "codec.h"
26 : #include "pitch_estimator.h"
27 : #include "entropy_coding.h"
28 : #include "arith_routines.h"
29 : #include "pitch_gain_tables.h"
30 : #include "pitch_lag_tables.h"
31 : #include "spectrum_ar_model_tables.h"
32 : #include "lpc_tables.h"
33 : #include "lpc_analysis.h"
34 : #include "bandwidth_estimator.h"
35 : #include "lpc_shape_swb12_tables.h"
36 : #include "lpc_shape_swb16_tables.h"
37 : #include "lpc_gain_swb_tables.h"
38 :
39 :
40 : #define UB_LOOKAHEAD 24
41 :
42 :
43 : /*
44 : Rate allocation tables of lower and upper-band bottleneck for
45 : 12kHz & 16kHz bandwidth.
46 :
47 : 12 kHz bandwidth
48 : -----------------
49 : The overall bottleneck of the coder is between 38 kbps and 45 kbps. We have
50 : considered 7 enteries, uniformly distributed in this interval, i.e. 38,
51 : 39.17, 40.33, 41.5, 42.67, 43.83 and 45. For every entery, the lower-band
52 : and the upper-band bottlenecks are specified in
53 : 'kLowerBandBitRate12' and 'kUpperBandBitRate12'
54 : tables, respectively. E.g. the overall rate of 41.5 kbps corresponts to a
55 : bottleneck of 31 kbps for lower-band and 27 kbps for upper-band. Given an
56 : overall bottleneck of the codec, we use linear interpolation to get
57 : lower-band and upper-band bottlenecks.
58 :
59 : 16 kHz bandwidth
60 : -----------------
61 : The overall bottleneck of the coder is between 50 kbps and 56 kbps. We have
62 : considered 7 enteries, uniformly distributed in this interval, i.e. 50, 51.2,
63 : 52.4, 53.6, 54.8 and 56. For every entery, the lower-band and the upper-band
64 : bottlenecks are specified in 'kLowerBandBitRate16' and
65 : 'kUpperBandBitRate16' tables, respectively. E.g. the overall rate
66 : of 53.6 kbps corresponts to a bottleneck of 32 kbps for lower-band and 30
67 : kbps for upper-band. Given an overall bottleneck of the codec, we use linear
68 : interpolation to get lower-band and upper-band bottlenecks.
69 :
70 : */
71 :
72 : /* 38 39.17 40.33 41.5 42.67 43.83 45 */
73 : static const int16_t kLowerBandBitRate12[7] = {
74 : 29000, 30000, 30000, 31000, 31000, 32000, 32000 };
75 : static const int16_t kUpperBandBitRate12[7] = {
76 : 25000, 25000, 27000, 27000, 29000, 29000, 32000 };
77 :
78 : /* 50 51.2 52.4 53.6 54.8 56 */
79 : static const int16_t kLowerBandBitRate16[6] = {
80 : 31000, 31000, 32000, 32000, 32000, 32000 };
81 : static const int16_t kUpperBandBitRate16[6] = {
82 : 28000, 29000, 29000, 30000, 31000, 32000 };
83 :
84 : /******************************************************************************
85 : * WebRtcIsac_RateAllocation()
86 : * Internal function to perform a rate-allocation for upper and lower-band,
87 : * given a total rate.
88 : *
89 : * Input:
90 : * - inRateBitPerSec : a total bottleneck in bits/sec.
91 : *
92 : * Output:
93 : * - rateLBBitPerSec : a bottleneck allocated to the lower-band
94 : * in bits/sec.
95 : * - rateUBBitPerSec : a bottleneck allocated to the upper-band
96 : * in bits/sec.
97 : *
98 : * Return value : 0 if rate allocation has been successful.
99 : * -1 if failed to allocate rates.
100 : */
101 :
102 0 : int16_t WebRtcIsac_RateAllocation(int32_t inRateBitPerSec,
103 : double* rateLBBitPerSec,
104 : double* rateUBBitPerSec,
105 : enum ISACBandwidth* bandwidthKHz) {
106 : int16_t idx;
107 : double idxD;
108 : double idxErr;
109 0 : if (inRateBitPerSec < 38000) {
110 : /* If the given overall bottleneck is less than 38000 then
111 : * then codec has to operate in wideband mode, i.e. 8 kHz
112 : * bandwidth. */
113 0 : *rateLBBitPerSec = (int16_t)((inRateBitPerSec > 32000) ?
114 : 32000 : inRateBitPerSec);
115 0 : *rateUBBitPerSec = 0;
116 0 : *bandwidthKHz = isac8kHz;
117 0 : } else if ((inRateBitPerSec >= 38000) && (inRateBitPerSec < 50000)) {
118 : /* At a bottleneck between 38 and 50 kbps the codec is operating
119 : * at 12 kHz bandwidth. Using xxxBandBitRate12[] to calculates
120 : * upper/lower bottleneck */
121 :
122 : /* Find the bottlenecks by linear interpolation,
123 : * step is (45000 - 38000)/6.0 we use the inverse of it. */
124 0 : const double stepSizeInv = 8.5714286e-4;
125 0 : idxD = (inRateBitPerSec - 38000) * stepSizeInv;
126 0 : idx = (idxD >= 6) ? 6 : ((int16_t)idxD);
127 0 : idxErr = idxD - idx;
128 0 : *rateLBBitPerSec = kLowerBandBitRate12[idx];
129 0 : *rateUBBitPerSec = kUpperBandBitRate12[idx];
130 :
131 0 : if (idx < 6) {
132 0 : *rateLBBitPerSec += (int16_t)(
133 0 : idxErr * (kLowerBandBitRate12[idx + 1] - kLowerBandBitRate12[idx]));
134 0 : *rateUBBitPerSec += (int16_t)(
135 0 : idxErr * (kUpperBandBitRate12[idx + 1] - kUpperBandBitRate12[idx]));
136 : }
137 0 : *bandwidthKHz = isac12kHz;
138 0 : } else if ((inRateBitPerSec >= 50000) && (inRateBitPerSec <= 56000)) {
139 : /* A bottleneck between 50 and 56 kbps corresponds to bandwidth
140 : * of 16 kHz. Using xxxBandBitRate16[] to calculates
141 : * upper/lower bottleneck. */
142 :
143 : /* Find the bottlenecks by linear interpolation
144 : * step is (56000 - 50000)/5 we use the inverse of it. */
145 0 : const double stepSizeInv = 8.3333333e-4;
146 0 : idxD = (inRateBitPerSec - 50000) * stepSizeInv;
147 0 : idx = (idxD >= 5) ? 5 : ((int16_t)idxD);
148 0 : idxErr = idxD - idx;
149 0 : *rateLBBitPerSec = kLowerBandBitRate16[idx];
150 0 : *rateUBBitPerSec = kUpperBandBitRate16[idx];
151 :
152 0 : if (idx < 5) {
153 0 : *rateLBBitPerSec += (int16_t)(idxErr *
154 0 : (kLowerBandBitRate16[idx + 1] -
155 0 : kLowerBandBitRate16[idx]));
156 :
157 0 : *rateUBBitPerSec += (int16_t)(idxErr *
158 0 : (kUpperBandBitRate16[idx + 1] -
159 0 : kUpperBandBitRate16[idx]));
160 : }
161 0 : *bandwidthKHz = isac16kHz;
162 : } else {
163 : /* Out-of-range botlteneck value. */
164 0 : return -1;
165 : }
166 :
167 : /* limit the values. */
168 0 : *rateLBBitPerSec = (*rateLBBitPerSec > 32000) ? 32000 : *rateLBBitPerSec;
169 0 : *rateUBBitPerSec = (*rateUBBitPerSec > 32000) ? 32000 : *rateUBBitPerSec;
170 0 : return 0;
171 : }
172 :
173 :
174 0 : void WebRtcIsac_ResetBitstream(Bitstr* bit_stream) {
175 0 : bit_stream->W_upper = 0xFFFFFFFF;
176 0 : bit_stream->stream_index = 0;
177 0 : bit_stream->streamval = 0;
178 0 : }
179 :
180 0 : int WebRtcIsac_EncodeLb(const TransformTables* transform_tables,
181 : float* in, ISACLBEncStruct* ISACencLB_obj,
182 : int16_t codingMode,
183 : int16_t bottleneckIndex) {
184 0 : int stream_length = 0;
185 : int err;
186 : int k;
187 : int iterCntr;
188 :
189 : double lofilt_coef[(ORDERLO + 1)*SUBFRAMES];
190 : double hifilt_coef[(ORDERHI + 1)*SUBFRAMES];
191 : float LP[FRAMESAMPLES_HALF];
192 : float HP[FRAMESAMPLES_HALF];
193 :
194 : double LP_lookahead[FRAMESAMPLES_HALF];
195 : double HP_lookahead[FRAMESAMPLES_HALF];
196 : double LP_lookahead_pf[FRAMESAMPLES_HALF + QLOOKAHEAD];
197 : double LPw[FRAMESAMPLES_HALF];
198 :
199 : double HPw[FRAMESAMPLES_HALF];
200 : double LPw_pf[FRAMESAMPLES_HALF];
201 : int16_t fre[FRAMESAMPLES_HALF]; /* Q7 */
202 : int16_t fim[FRAMESAMPLES_HALF]; /* Q7 */
203 :
204 : double PitchLags[4];
205 : double PitchGains[4];
206 : int16_t PitchGains_Q12[4];
207 : int16_t AvgPitchGain_Q12;
208 :
209 : int frame_mode; /* 0 for 30ms, 1 for 60ms */
210 0 : int status = 0;
211 : int my_index;
212 : transcode_obj transcodingParam;
213 : double bytesLeftSpecCoding;
214 : uint16_t payloadLimitBytes;
215 :
216 : /* Copy new frame-length and bottleneck rate only for the first 10 ms data */
217 0 : if (ISACencLB_obj->buffer_index == 0) {
218 : /* Set the framelength for the next packet. */
219 0 : ISACencLB_obj->current_framesamples = ISACencLB_obj->new_framelength;
220 : }
221 : /* 'frame_mode' is 0 (30 ms) or 1 (60 ms). */
222 0 : frame_mode = ISACencLB_obj->current_framesamples / MAX_FRAMESAMPLES;
223 :
224 : /* buffer speech samples (by 10ms packet) until the frame-length */
225 : /* is reached (30 or 60 ms). */
226 : /*****************************************************************/
227 :
228 : /* fill the buffer with 10ms input data */
229 0 : for (k = 0; k < FRAMESAMPLES_10ms; k++) {
230 0 : ISACencLB_obj->data_buffer_float[k + ISACencLB_obj->buffer_index] = in[k];
231 : }
232 :
233 : /* If buffersize is not equal to current framesize then increase index
234 : * and return. We do no encoding untill we have enough audio. */
235 0 : if (ISACencLB_obj->buffer_index + FRAMESAMPLES_10ms != FRAMESAMPLES) {
236 0 : ISACencLB_obj->buffer_index += FRAMESAMPLES_10ms;
237 0 : return 0;
238 : }
239 : /* If buffer reached the right size, reset index and continue with
240 : * encoding the frame. */
241 0 : ISACencLB_obj->buffer_index = 0;
242 :
243 : /* End of buffer function. */
244 : /**************************/
245 :
246 : /* Encoding */
247 : /************/
248 :
249 0 : if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) {
250 : /* This is to avoid Linux warnings until we change 'int' to 'Word32'
251 : * at all places. */
252 : int intVar;
253 : /* reset bitstream */
254 0 : WebRtcIsac_ResetBitstream(&(ISACencLB_obj->bitstr_obj));
255 :
256 0 : if ((codingMode == 0) && (frame_mode == 0) &&
257 0 : (ISACencLB_obj->enforceFrameSize == 0)) {
258 0 : ISACencLB_obj->new_framelength = WebRtcIsac_GetNewFrameLength(
259 0 : ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples);
260 : }
261 :
262 0 : ISACencLB_obj->s2nr = WebRtcIsac_GetSnr(
263 0 : ISACencLB_obj->bottleneck, ISACencLB_obj->current_framesamples);
264 :
265 : /* Encode frame length. */
266 0 : status = WebRtcIsac_EncodeFrameLen(
267 0 : ISACencLB_obj->current_framesamples, &ISACencLB_obj->bitstr_obj);
268 0 : if (status < 0) {
269 : /* Wrong frame size. */
270 0 : return status;
271 : }
272 : /* Save framelength for multiple packets memory. */
273 0 : ISACencLB_obj->SaveEnc_obj.framelength =
274 0 : ISACencLB_obj->current_framesamples;
275 :
276 : /* To be used for Redundant Coding. */
277 0 : ISACencLB_obj->lastBWIdx = bottleneckIndex;
278 0 : intVar = (int)bottleneckIndex;
279 0 : WebRtcIsac_EncodeReceiveBw(&intVar, &ISACencLB_obj->bitstr_obj);
280 : }
281 :
282 : /* Split signal in two bands. */
283 0 : WebRtcIsac_SplitAndFilterFloat(ISACencLB_obj->data_buffer_float, LP, HP,
284 : LP_lookahead, HP_lookahead,
285 : &ISACencLB_obj->prefiltbankstr_obj);
286 :
287 : /* estimate pitch parameters and pitch-filter lookahead signal */
288 0 : WebRtcIsac_PitchAnalysis(LP_lookahead, LP_lookahead_pf,
289 : &ISACencLB_obj->pitchanalysisstr_obj, PitchLags,
290 : PitchGains);
291 :
292 : /* Encode in FIX Q12. */
293 :
294 : /* Convert PitchGain to Fixed point. */
295 0 : for (k = 0; k < PITCH_SUBFRAMES; k++) {
296 0 : PitchGains_Q12[k] = (int16_t)(PitchGains[k] * 4096.0);
297 : }
298 :
299 : /* Set where to store data in multiple packets memory. */
300 0 : if (frame_mode == 0 || ISACencLB_obj->frame_nb == 0) {
301 0 : ISACencLB_obj->SaveEnc_obj.startIdx = 0;
302 : } else {
303 0 : ISACencLB_obj->SaveEnc_obj.startIdx = 1;
304 : }
305 :
306 : /* Quantize & encode pitch parameters. */
307 0 : WebRtcIsac_EncodePitchGain(PitchGains_Q12, &ISACencLB_obj->bitstr_obj,
308 : &ISACencLB_obj->SaveEnc_obj);
309 0 : WebRtcIsac_EncodePitchLag(PitchLags, PitchGains_Q12,
310 : &ISACencLB_obj->bitstr_obj,
311 : &ISACencLB_obj->SaveEnc_obj);
312 :
313 0 : AvgPitchGain_Q12 = (PitchGains_Q12[0] + PitchGains_Q12[1] +
314 0 : PitchGains_Q12[2] + PitchGains_Q12[3]) >> 2;
315 :
316 : /* Find coefficients for perceptual pre-filters. */
317 0 : WebRtcIsac_GetLpcCoefLb(LP_lookahead_pf, HP_lookahead,
318 : &ISACencLB_obj->maskfiltstr_obj, ISACencLB_obj->s2nr,
319 : PitchGains_Q12, lofilt_coef, hifilt_coef);
320 :
321 : /* Code LPC model and shape - gains not quantized yet. */
322 0 : WebRtcIsac_EncodeLpcLb(lofilt_coef, hifilt_coef, &ISACencLB_obj->bitstr_obj,
323 : &ISACencLB_obj->SaveEnc_obj);
324 :
325 : /* Convert PitchGains back to FLOAT for pitchfilter_pre. */
326 0 : for (k = 0; k < 4; k++) {
327 0 : PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096;
328 : }
329 :
330 : /* Store the state of arithmetic coder before coding LPC gains. */
331 0 : transcodingParam.W_upper = ISACencLB_obj->bitstr_obj.W_upper;
332 0 : transcodingParam.stream_index = ISACencLB_obj->bitstr_obj.stream_index;
333 0 : transcodingParam.streamval = ISACencLB_obj->bitstr_obj.streamval;
334 0 : transcodingParam.stream[0] =
335 0 : ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index -
336 : 2];
337 0 : transcodingParam.stream[1] =
338 0 : ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index -
339 : 1];
340 0 : transcodingParam.stream[2] =
341 0 : ISACencLB_obj->bitstr_obj.stream[ISACencLB_obj->bitstr_obj.stream_index];
342 :
343 : /* Store LPC Gains before encoding them. */
344 0 : for (k = 0; k < SUBFRAMES; k++) {
345 0 : transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k];
346 0 : transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k];
347 : }
348 :
349 : /* Code gains */
350 0 : WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef,
351 : &ISACencLB_obj->bitstr_obj,
352 : &ISACencLB_obj->SaveEnc_obj);
353 :
354 : /* Get the correct value for the payload limit and calculate the
355 : * number of bytes left for coding the spectrum. */
356 0 : if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) {
357 : /* It is a 60ms and we are in the first 30ms then the limit at
358 : * this point should be half of the assigned value. */
359 0 : payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 >> 1;
360 0 : } else if (frame_mode == 0) {
361 : /* It is a 30ms frame */
362 : /* Subract 3 because termination process may add 3 bytes. */
363 0 : payloadLimitBytes = ISACencLB_obj->payloadLimitBytes30 - 3;
364 : } else {
365 : /* This is the second half of a 60ms frame. */
366 : /* Subract 3 because termination process may add 3 bytes. */
367 0 : payloadLimitBytes = ISACencLB_obj->payloadLimitBytes60 - 3;
368 : }
369 0 : bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index;
370 :
371 : /* Perceptual pre-filtering (using normalized lattice filter). */
372 : /* Low-band filtering. */
373 0 : WebRtcIsac_NormLatticeFilterMa(ORDERLO,
374 0 : ISACencLB_obj->maskfiltstr_obj.PreStateLoF,
375 0 : ISACencLB_obj->maskfiltstr_obj.PreStateLoG,
376 : LP, lofilt_coef, LPw);
377 : /* High-band filtering. */
378 0 : WebRtcIsac_NormLatticeFilterMa(ORDERHI,
379 0 : ISACencLB_obj->maskfiltstr_obj.PreStateHiF,
380 0 : ISACencLB_obj->maskfiltstr_obj.PreStateHiG,
381 : HP, hifilt_coef, HPw);
382 : /* Pitch filter. */
383 0 : WebRtcIsac_PitchfilterPre(LPw, LPw_pf, &ISACencLB_obj->pitchfiltstr_obj,
384 : PitchLags, PitchGains);
385 : /* Transform */
386 0 : WebRtcIsac_Time2Spec(transform_tables,
387 : LPw_pf, HPw, fre, fim, &ISACencLB_obj->fftstr_obj);
388 :
389 : /* Save data for multiple packets memory. */
390 0 : my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
391 0 : memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre));
392 0 : memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim));
393 :
394 0 : ISACencLB_obj->SaveEnc_obj.AvgPitchGain[ISACencLB_obj->SaveEnc_obj.startIdx] =
395 : AvgPitchGain_Q12;
396 :
397 : /* Quantization and loss-less coding. */
398 0 : err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand,
399 : &ISACencLB_obj->bitstr_obj);
400 0 : if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
401 : /* There has been an error but it was not too large payload
402 : (we can cure too large payload). */
403 0 : if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) {
404 : /* If this is the second 30ms of a 60ms frame reset
405 : this such that in the next call encoder starts fresh. */
406 0 : ISACencLB_obj->frame_nb = 0;
407 : }
408 0 : return err;
409 : }
410 0 : iterCntr = 0;
411 0 : while ((ISACencLB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
412 : (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
413 : double bytesSpecCoderUsed;
414 : double transcodeScale;
415 :
416 0 : if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) {
417 : /* We were not able to limit the payload size */
418 0 : if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 0)) {
419 : /* This was the first 30ms of a 60ms frame. Although
420 : the payload is larger than it should be but we let
421 : the second 30ms be encoded. Maybe together we
422 : won't exceed the limit. */
423 0 : ISACencLB_obj->frame_nb = 1;
424 0 : return 0;
425 0 : } else if ((frame_mode == 1) && (ISACencLB_obj->frame_nb == 1)) {
426 0 : ISACencLB_obj->frame_nb = 0;
427 : }
428 :
429 0 : if (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
430 0 : return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
431 : } else {
432 0 : return status;
433 : }
434 : }
435 :
436 0 : if (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
437 0 : bytesSpecCoderUsed = STREAM_SIZE_MAX;
438 : /* Being conservative */
439 0 : transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5;
440 : } else {
441 0 : bytesSpecCoderUsed = ISACencLB_obj->bitstr_obj.stream_index -
442 0 : transcodingParam.stream_index;
443 0 : transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed;
444 : }
445 :
446 : /* To be safe, we reduce the scale depending on
447 : the number of iterations. */
448 0 : transcodeScale *= (1.0 - (0.9 * (double)iterCntr /
449 : (double)MAX_PAYLOAD_LIMIT_ITERATION));
450 :
451 : /* Scale the LPC Gains. */
452 0 : for (k = 0; k < SUBFRAMES; k++) {
453 0 : lofilt_coef[(LPC_LOBAND_ORDER + 1) * k] =
454 0 : transcodingParam.loFiltGain[k] * transcodeScale;
455 0 : hifilt_coef[(LPC_HIBAND_ORDER + 1) * k] =
456 0 : transcodingParam.hiFiltGain[k] * transcodeScale;
457 0 : transcodingParam.loFiltGain[k] = lofilt_coef[(LPC_LOBAND_ORDER + 1) * k];
458 0 : transcodingParam.hiFiltGain[k] = hifilt_coef[(LPC_HIBAND_ORDER + 1) * k];
459 : }
460 :
461 : /* Scale DFT coefficients. */
462 0 : for (k = 0; k < FRAMESAMPLES_HALF; k++) {
463 0 : fre[k] = (int16_t)(fre[k] * transcodeScale);
464 0 : fim[k] = (int16_t)(fim[k] * transcodeScale);
465 : }
466 :
467 : /* Save data for multiple packets memory. */
468 0 : my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
469 0 : memcpy(&ISACencLB_obj->SaveEnc_obj.fre[my_index], fre, sizeof(fre));
470 0 : memcpy(&ISACencLB_obj->SaveEnc_obj.fim[my_index], fim, sizeof(fim));
471 :
472 : /* Re-store the state of arithmetic coder before coding LPC gains. */
473 0 : ISACencLB_obj->bitstr_obj.W_upper = transcodingParam.W_upper;
474 0 : ISACencLB_obj->bitstr_obj.stream_index = transcodingParam.stream_index;
475 0 : ISACencLB_obj->bitstr_obj.streamval = transcodingParam.streamval;
476 0 : ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 2] =
477 0 : transcodingParam.stream[0];
478 0 : ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index - 1] =
479 0 : transcodingParam.stream[1];
480 0 : ISACencLB_obj->bitstr_obj.stream[transcodingParam.stream_index] =
481 0 : transcodingParam.stream[2];
482 :
483 : /* Code gains. */
484 0 : WebRtcIsac_EncodeLpcGainLb(lofilt_coef, hifilt_coef,
485 : &ISACencLB_obj->bitstr_obj,
486 : &ISACencLB_obj->SaveEnc_obj);
487 :
488 : /* Update the number of bytes left for encoding the spectrum. */
489 0 : bytesLeftSpecCoding = payloadLimitBytes - transcodingParam.stream_index;
490 :
491 : /* Encode the spectrum. */
492 0 : err = WebRtcIsac_EncodeSpec(fre, fim, AvgPitchGain_Q12, kIsacLowerBand,
493 : &ISACencLB_obj->bitstr_obj);
494 :
495 0 : if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
496 : /* There has been an error but it was not too large
497 : payload (we can cure too large payload). */
498 0 : if (frame_mode == 1 && ISACencLB_obj->frame_nb == 1) {
499 : /* If this is the second 30 ms of a 60 ms frame reset
500 : this such that in the next call encoder starts fresh. */
501 0 : ISACencLB_obj->frame_nb = 0;
502 : }
503 0 : return err;
504 : }
505 0 : iterCntr++;
506 : }
507 :
508 : /* If 60 ms frame-size and just processed the first 30 ms, */
509 : /* go back to main function to buffer the other 30 ms speech frame. */
510 0 : if (frame_mode == 1) {
511 0 : if (ISACencLB_obj->frame_nb == 0) {
512 0 : ISACencLB_obj->frame_nb = 1;
513 0 : return 0;
514 0 : } else if (ISACencLB_obj->frame_nb == 1) {
515 0 : ISACencLB_obj->frame_nb = 0;
516 : /* Also update the frame-length for next packet,
517 : in Adaptive mode only. */
518 0 : if (codingMode == 0 && (ISACencLB_obj->enforceFrameSize == 0)) {
519 0 : ISACencLB_obj->new_framelength =
520 0 : WebRtcIsac_GetNewFrameLength(ISACencLB_obj->bottleneck,
521 0 : ISACencLB_obj->current_framesamples);
522 : }
523 : }
524 : } else {
525 0 : ISACencLB_obj->frame_nb = 0;
526 : }
527 :
528 : /* Complete arithmetic coding. */
529 0 : stream_length = WebRtcIsac_EncTerminate(&ISACencLB_obj->bitstr_obj);
530 0 : return stream_length;
531 : }
532 :
533 :
534 :
535 0 : static int LimitPayloadUb(ISACUBEncStruct* ISACencUB_obj,
536 : uint16_t payloadLimitBytes,
537 : double bytesLeftSpecCoding,
538 : transcode_obj* transcodingParam,
539 : int16_t* fre, int16_t* fim,
540 : double* lpcGains, enum ISACBand band, int status) {
541 :
542 0 : int iterCntr = 0;
543 : int k;
544 : double bytesSpecCoderUsed;
545 : double transcodeScale;
546 0 : const int16_t kAveragePitchGain = 0.0;
547 :
548 : do {
549 0 : if (iterCntr >= MAX_PAYLOAD_LIMIT_ITERATION) {
550 : /* We were not able to limit the payload size. */
551 0 : return -ISAC_PAYLOAD_LARGER_THAN_LIMIT;
552 : }
553 :
554 0 : if (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH) {
555 0 : bytesSpecCoderUsed = STREAM_SIZE_MAX;
556 : /* Being conservative. */
557 0 : transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed * 0.5;
558 : } else {
559 0 : bytesSpecCoderUsed = ISACencUB_obj->bitstr_obj.stream_index -
560 0 : transcodingParam->stream_index;
561 0 : transcodeScale = bytesLeftSpecCoding / bytesSpecCoderUsed;
562 : }
563 :
564 : /* To be safe, we reduce the scale depending on the
565 : number of iterations. */
566 0 : transcodeScale *= (1.0 - (0.9 * (double)iterCntr /
567 : (double)MAX_PAYLOAD_LIMIT_ITERATION));
568 :
569 : /* Scale the LPC Gains. */
570 0 : if (band == kIsacUpperBand16) {
571 : /* Two sets of coefficients if 16 kHz. */
572 0 : for (k = 0; k < SUBFRAMES; k++) {
573 0 : transcodingParam->loFiltGain[k] *= transcodeScale;
574 0 : transcodingParam->hiFiltGain[k] *= transcodeScale;
575 : }
576 : } else {
577 : /* One sets of coefficients if 12 kHz. */
578 0 : for (k = 0; k < SUBFRAMES; k++) {
579 0 : transcodingParam->loFiltGain[k] *= transcodeScale;
580 : }
581 : }
582 :
583 : /* Scale DFT coefficients. */
584 0 : for (k = 0; k < FRAMESAMPLES_HALF; k++) {
585 0 : fre[k] = (int16_t)(fre[k] * transcodeScale + 0.5);
586 0 : fim[k] = (int16_t)(fim[k] * transcodeScale + 0.5);
587 : }
588 : /* Store FFT coefficients for multiple encoding. */
589 0 : memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
590 : sizeof(ISACencUB_obj->SaveEnc_obj.realFFT));
591 0 : memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim,
592 : sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT));
593 :
594 : /* Store the state of arithmetic coder before coding LPC gains */
595 0 : ISACencUB_obj->bitstr_obj.W_upper = transcodingParam->W_upper;
596 0 : ISACencUB_obj->bitstr_obj.stream_index = transcodingParam->stream_index;
597 0 : ISACencUB_obj->bitstr_obj.streamval = transcodingParam->streamval;
598 0 : ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 2] =
599 0 : transcodingParam->stream[0];
600 0 : ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index - 1] =
601 0 : transcodingParam->stream[1];
602 0 : ISACencUB_obj->bitstr_obj.stream[transcodingParam->stream_index] =
603 0 : transcodingParam->stream[2];
604 :
605 : /* Store the gains for multiple encoding. */
606 0 : memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains,
607 : SUBFRAMES * sizeof(double));
608 : /* Entropy Code lpc-gains, indices are stored for a later use.*/
609 0 : WebRtcIsac_EncodeLpcGainUb(transcodingParam->loFiltGain,
610 : &ISACencUB_obj->bitstr_obj,
611 0 : ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
612 :
613 : /* If 16kHz should do one more set. */
614 0 : if (band == kIsacUpperBand16) {
615 : /* Store the gains for multiple encoding. */
616 0 : memcpy(&ISACencUB_obj->SaveEnc_obj.lpcGain[SUBFRAMES],
617 0 : &lpcGains[SUBFRAMES], SUBFRAMES * sizeof(double));
618 : /* Entropy Code lpc-gains, indices are stored for a later use.*/
619 0 : WebRtcIsac_EncodeLpcGainUb(
620 0 : transcodingParam->hiFiltGain, &ISACencUB_obj->bitstr_obj,
621 : &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]);
622 : }
623 :
624 : /* Update the number of bytes left for encoding the spectrum. */
625 0 : bytesLeftSpecCoding = payloadLimitBytes -
626 0 : ISACencUB_obj->bitstr_obj.stream_index;
627 :
628 : /* Save the bit-stream object at this point for FEC. */
629 0 : memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj,
630 0 : &ISACencUB_obj->bitstr_obj, sizeof(Bitstr));
631 :
632 : /* Encode the spectrum. */
633 0 : status = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain,
634 : band, &ISACencUB_obj->bitstr_obj);
635 0 : if ((status < 0) && (status != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
636 : /* There has been an error but it was not too large payload
637 : (we can cure too large payload). */
638 0 : return status;
639 : }
640 0 : iterCntr++;
641 0 : } while ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
642 0 : (status == -ISAC_DISALLOWED_BITSTREAM_LENGTH));
643 0 : return 0;
644 : }
645 :
646 0 : int WebRtcIsac_EncodeUb16(const TransformTables* transform_tables,
647 : float* in, ISACUBEncStruct* ISACencUB_obj,
648 : int32_t jitterInfo) {
649 : int err;
650 : int k;
651 :
652 : double lpcVecs[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
653 : double percepFilterParams[(1 + UB_LPC_ORDER) * (SUBFRAMES << 1) +
654 : (1 + UB_LPC_ORDER)];
655 :
656 : double LP_lookahead[FRAMESAMPLES];
657 : int16_t fre[FRAMESAMPLES_HALF]; /* Q7 */
658 : int16_t fim[FRAMESAMPLES_HALF]; /* Q7 */
659 :
660 0 : int status = 0;
661 :
662 : double varscale[2];
663 : double corr[SUBFRAMES << 1][UB_LPC_ORDER + 1];
664 : double lpcGains[SUBFRAMES << 1];
665 : transcode_obj transcodingParam;
666 : uint16_t payloadLimitBytes;
667 : double s2nr;
668 0 : const int16_t kAveragePitchGain = 0.0;
669 : int bytesLeftSpecCoding;
670 :
671 : /* Buffer speech samples (by 10ms packet) until the frame-length is */
672 : /* reached (30 ms). */
673 : /*********************************************************************/
674 :
675 : /* fill the buffer with 10ms input data */
676 0 : memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in,
677 : FRAMESAMPLES_10ms * sizeof(float));
678 :
679 : /* If buffer size is not equal to current frame-size, and end of file is
680 : * not reached yet, we don't do encoding unless we have the whole frame. */
681 0 : if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) {
682 0 : ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms;
683 0 : return 0;
684 : }
685 :
686 : /* End of buffer function. */
687 : /**************************/
688 :
689 : /* Encoding */
690 : /************/
691 :
692 : /* Reset bit-stream */
693 0 : WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj));
694 :
695 : /* Encoding of bandwidth information. */
696 0 : WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj);
697 :
698 0 : status = WebRtcIsac_EncodeBandwidth(isac16kHz, &ISACencUB_obj->bitstr_obj);
699 0 : if (status < 0) {
700 0 : return status;
701 : }
702 :
703 0 : s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES);
704 :
705 0 : memcpy(lpcVecs, ISACencUB_obj->lastLPCVec, UB_LPC_ORDER * sizeof(double));
706 :
707 0 : for (k = 0; k < FRAMESAMPLES; k++) {
708 0 : LP_lookahead[k] = ISACencUB_obj->data_buffer_float[UB_LOOKAHEAD + k];
709 : }
710 :
711 : /* Find coefficients for perceptual pre-filters. */
712 0 : WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj,
713 : &lpcVecs[UB_LPC_ORDER], corr, varscale, isac16kHz);
714 :
715 0 : memcpy(ISACencUB_obj->lastLPCVec,
716 : &lpcVecs[(UB16_LPC_VEC_PER_FRAME - 1) * (UB_LPC_ORDER)],
717 : sizeof(double) * UB_LPC_ORDER);
718 :
719 : /* Code LPC model and shape - gains not quantized yet. */
720 0 : WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj,
721 : percepFilterParams, isac16kHz,
722 : &ISACencUB_obj->SaveEnc_obj);
723 :
724 : /* the first set of lpc parameters are from the last sub-frame of
725 : * the previous frame. so we don't care about them. */
726 0 : WebRtcIsac_GetLpcGain(s2nr, &percepFilterParams[UB_LPC_ORDER + 1],
727 : (SUBFRAMES << 1), lpcGains, corr, varscale);
728 :
729 : /* Store the state of arithmetic coder before coding LPC gains */
730 0 : transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index;
731 0 : transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper;
732 0 : transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval;
733 0 : transcodingParam.stream[0] =
734 0 : ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
735 : 2];
736 0 : transcodingParam.stream[1] =
737 0 : ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
738 : 1];
739 0 : transcodingParam.stream[2] =
740 0 : ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index];
741 :
742 : /* Store LPC Gains before encoding them. */
743 0 : for (k = 0; k < SUBFRAMES; k++) {
744 0 : transcodingParam.loFiltGain[k] = lpcGains[k];
745 0 : transcodingParam.hiFiltGain[k] = lpcGains[SUBFRAMES + k];
746 : }
747 :
748 : /* Store the gains for multiple encoding. */
749 0 : memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains,
750 : (SUBFRAMES << 1) * sizeof(double));
751 :
752 0 : WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj,
753 0 : ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
754 0 : WebRtcIsac_EncodeLpcGainUb(
755 : &lpcGains[SUBFRAMES], &ISACencUB_obj->bitstr_obj,
756 : &ISACencUB_obj->SaveEnc_obj.lpcGainIndex[SUBFRAMES]);
757 :
758 : /* Get the correct value for the payload limit and calculate the number of
759 : bytes left for coding the spectrum. It is a 30ms frame
760 : Subract 3 because termination process may add 3 bytes */
761 0 : payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes -
762 0 : ISACencUB_obj->numBytesUsed - 3;
763 0 : bytesLeftSpecCoding = payloadLimitBytes -
764 0 : ISACencUB_obj->bitstr_obj.stream_index;
765 :
766 0 : for (k = 0; k < (SUBFRAMES << 1); k++) {
767 0 : percepFilterParams[k * (UB_LPC_ORDER + 1) + (UB_LPC_ORDER + 1)] =
768 0 : lpcGains[k];
769 : }
770 :
771 : /* LPC filtering (using normalized lattice filter), */
772 : /* first half-frame. */
773 0 : WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER,
774 0 : ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
775 0 : ISACencUB_obj->maskfiltstr_obj.PreStateLoG,
776 : &ISACencUB_obj->data_buffer_float[0],
777 : &percepFilterParams[UB_LPC_ORDER + 1],
778 : &LP_lookahead[0]);
779 :
780 : /* Second half-frame filtering. */
781 0 : WebRtcIsac_NormLatticeFilterMa(
782 0 : UB_LPC_ORDER, ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
783 0 : ISACencUB_obj->maskfiltstr_obj.PreStateLoG,
784 : &ISACencUB_obj->data_buffer_float[FRAMESAMPLES_HALF],
785 : &percepFilterParams[(UB_LPC_ORDER + 1) + SUBFRAMES * (UB_LPC_ORDER + 1)],
786 : &LP_lookahead[FRAMESAMPLES_HALF]);
787 :
788 0 : WebRtcIsac_Time2Spec(transform_tables,
789 : &LP_lookahead[0], &LP_lookahead[FRAMESAMPLES_HALF],
790 : fre, fim, &ISACencUB_obj->fftstr_obj);
791 :
792 : /* Store FFT coefficients for multiple encoding. */
793 0 : memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre, sizeof(fre));
794 0 : memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim, sizeof(fim));
795 :
796 : /* Prepare the audio buffer for the next packet
797 : * move the last 3 ms to the beginning of the buffer. */
798 0 : memcpy(ISACencUB_obj->data_buffer_float,
799 0 : &ISACencUB_obj->data_buffer_float[FRAMESAMPLES],
800 : LB_TOTAL_DELAY_SAMPLES * sizeof(float));
801 : /* start writing with 3 ms delay to compensate for the delay
802 : * of the lower-band. */
803 0 : ISACencUB_obj->buffer_index = LB_TOTAL_DELAY_SAMPLES;
804 :
805 : /* Save the bit-stream object at this point for FEC. */
806 0 : memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj, &ISACencUB_obj->bitstr_obj,
807 : sizeof(Bitstr));
808 :
809 : /* Qantization and lossless coding */
810 : /* Note that there is no pitch-gain for this band so kAveragePitchGain = 0
811 : * is passed to the function. In fact, the function ignores the 3rd parameter
812 : * for this band. */
813 0 : err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand16,
814 : &ISACencUB_obj->bitstr_obj);
815 0 : if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
816 0 : return err;
817 : }
818 :
819 0 : if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
820 : (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
821 0 : err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding,
822 : &transcodingParam, fre, fim, lpcGains,
823 : kIsacUpperBand16, err);
824 : }
825 0 : if (err < 0) {
826 0 : return err;
827 : }
828 : /* Complete arithmetic coding. */
829 0 : return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj);
830 : }
831 :
832 :
833 0 : int WebRtcIsac_EncodeUb12(const TransformTables* transform_tables,
834 : float* in, ISACUBEncStruct* ISACencUB_obj,
835 : int32_t jitterInfo) {
836 : int err;
837 : int k;
838 :
839 : double lpcVecs[UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME];
840 :
841 : double percepFilterParams[(1 + UB_LPC_ORDER) * SUBFRAMES];
842 : float LP[FRAMESAMPLES_HALF];
843 : float HP[FRAMESAMPLES_HALF];
844 :
845 : double LP_lookahead[FRAMESAMPLES_HALF];
846 : double HP_lookahead[FRAMESAMPLES_HALF];
847 : double LPw[FRAMESAMPLES_HALF];
848 :
849 : double HPw[FRAMESAMPLES_HALF];
850 : int16_t fre[FRAMESAMPLES_HALF]; /* Q7 */
851 : int16_t fim[FRAMESAMPLES_HALF]; /* Q7 */
852 :
853 0 : int status = 0;
854 :
855 : double varscale[1];
856 :
857 : double corr[UB_LPC_GAIN_DIM][UB_LPC_ORDER + 1];
858 : double lpcGains[SUBFRAMES];
859 : transcode_obj transcodingParam;
860 : uint16_t payloadLimitBytes;
861 : double s2nr;
862 0 : const int16_t kAveragePitchGain = 0.0;
863 : double bytesLeftSpecCoding;
864 :
865 : /* Buffer speech samples (by 10ms packet) until the framelength is */
866 : /* reached (30 ms). */
867 : /********************************************************************/
868 :
869 : /* Fill the buffer with 10ms input data. */
870 0 : memcpy(&ISACencUB_obj->data_buffer_float[ISACencUB_obj->buffer_index], in,
871 : FRAMESAMPLES_10ms * sizeof(float));
872 :
873 : /* if buffer-size is not equal to current frame-size then increase the
874 : index and return. We do the encoding when we have enough audio. */
875 0 : if (ISACencUB_obj->buffer_index + FRAMESAMPLES_10ms < FRAMESAMPLES) {
876 0 : ISACencUB_obj->buffer_index += FRAMESAMPLES_10ms;
877 0 : return 0;
878 : }
879 : /* If buffer reached the right size, reset index and continue
880 : with encoding the frame */
881 0 : ISACencUB_obj->buffer_index = 0;
882 :
883 : /* End of buffer function */
884 : /**************************/
885 :
886 : /* Encoding */
887 : /************/
888 :
889 : /* Reset bit-stream. */
890 0 : WebRtcIsac_ResetBitstream(&(ISACencUB_obj->bitstr_obj));
891 :
892 : /* Encoding bandwidth information. */
893 0 : WebRtcIsac_EncodeJitterInfo(jitterInfo, &ISACencUB_obj->bitstr_obj);
894 0 : status = WebRtcIsac_EncodeBandwidth(isac12kHz, &ISACencUB_obj->bitstr_obj);
895 0 : if (status < 0) {
896 0 : return status;
897 : }
898 :
899 0 : s2nr = WebRtcIsac_GetSnr(ISACencUB_obj->bottleneck, FRAMESAMPLES);
900 :
901 : /* Split signal in two bands. */
902 0 : WebRtcIsac_SplitAndFilterFloat(ISACencUB_obj->data_buffer_float, HP, LP,
903 : HP_lookahead, LP_lookahead,
904 : &ISACencUB_obj->prefiltbankstr_obj);
905 :
906 : /* Find coefficients for perceptual pre-filters. */
907 0 : WebRtcIsac_GetLpcCoefUb(LP_lookahead, &ISACencUB_obj->maskfiltstr_obj,
908 : lpcVecs, corr, varscale, isac12kHz);
909 :
910 : /* Code LPC model and shape - gains not quantized yet. */
911 0 : WebRtcIsac_EncodeLpcUB(lpcVecs, &ISACencUB_obj->bitstr_obj,
912 : percepFilterParams, isac12kHz,
913 : &ISACencUB_obj->SaveEnc_obj);
914 :
915 0 : WebRtcIsac_GetLpcGain(s2nr, percepFilterParams, SUBFRAMES, lpcGains, corr,
916 : varscale);
917 :
918 : /* Store the state of arithmetic coder before coding LPC gains. */
919 0 : transcodingParam.W_upper = ISACencUB_obj->bitstr_obj.W_upper;
920 0 : transcodingParam.stream_index = ISACencUB_obj->bitstr_obj.stream_index;
921 0 : transcodingParam.streamval = ISACencUB_obj->bitstr_obj.streamval;
922 0 : transcodingParam.stream[0] =
923 0 : ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
924 : 2];
925 0 : transcodingParam.stream[1] =
926 0 : ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index -
927 : 1];
928 0 : transcodingParam.stream[2] =
929 0 : ISACencUB_obj->bitstr_obj.stream[ISACencUB_obj->bitstr_obj.stream_index];
930 :
931 : /* Store LPC Gains before encoding them. */
932 0 : for (k = 0; k < SUBFRAMES; k++) {
933 0 : transcodingParam.loFiltGain[k] = lpcGains[k];
934 : }
935 :
936 : /* Store the gains for multiple encoding. */
937 0 : memcpy(ISACencUB_obj->SaveEnc_obj.lpcGain, lpcGains, SUBFRAMES *
938 : sizeof(double));
939 :
940 0 : WebRtcIsac_EncodeLpcGainUb(lpcGains, &ISACencUB_obj->bitstr_obj,
941 0 : ISACencUB_obj->SaveEnc_obj.lpcGainIndex);
942 :
943 0 : for (k = 0; k < SUBFRAMES; k++) {
944 0 : percepFilterParams[k * (UB_LPC_ORDER + 1)] = lpcGains[k];
945 : }
946 :
947 : /* perceptual pre-filtering (using normalized lattice filter) */
948 : /* low-band filtering */
949 0 : WebRtcIsac_NormLatticeFilterMa(UB_LPC_ORDER,
950 0 : ISACencUB_obj->maskfiltstr_obj.PreStateLoF,
951 0 : ISACencUB_obj->maskfiltstr_obj.PreStateLoG, LP,
952 : percepFilterParams, LPw);
953 :
954 : /* Get the correct value for the payload limit and calculate the number
955 : of bytes left for coding the spectrum. It is a 30ms frame Subract 3
956 : because termination process may add 3 bytes */
957 0 : payloadLimitBytes = ISACencUB_obj->maxPayloadSizeBytes -
958 0 : ISACencUB_obj->numBytesUsed - 3;
959 0 : bytesLeftSpecCoding = payloadLimitBytes -
960 0 : ISACencUB_obj->bitstr_obj.stream_index;
961 :
962 0 : memset(HPw, 0, sizeof(HPw));
963 :
964 : /* Transform */
965 0 : WebRtcIsac_Time2Spec(transform_tables,
966 : LPw, HPw, fre, fim, &ISACencUB_obj->fftstr_obj);
967 :
968 : /* Store FFT coefficients for multiple encoding. */
969 0 : memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
970 : sizeof(ISACencUB_obj->SaveEnc_obj.realFFT));
971 0 : memcpy(ISACencUB_obj->SaveEnc_obj.imagFFT, fim,
972 : sizeof(ISACencUB_obj->SaveEnc_obj.imagFFT));
973 :
974 : /* Save the bit-stream object at this point for FEC. */
975 0 : memcpy(&ISACencUB_obj->SaveEnc_obj.bitStreamObj,
976 0 : &ISACencUB_obj->bitstr_obj, sizeof(Bitstr));
977 :
978 : /* Quantization and loss-less coding */
979 : /* The 4th parameter to this function is pitch-gain, which is only used
980 : * when encoding 0-8 kHz band, and irrelevant in this function, therefore,
981 : * we insert zero here. */
982 0 : err = WebRtcIsac_EncodeSpec(fre, fim, kAveragePitchGain, kIsacUpperBand12,
983 : &ISACencUB_obj->bitstr_obj);
984 0 : if ((err < 0) && (err != -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
985 : /* There has been an error but it was not too large
986 : payload (we can cure too large payload) */
987 0 : return err;
988 : }
989 :
990 0 : if ((ISACencUB_obj->bitstr_obj.stream_index > payloadLimitBytes) ||
991 : (err == -ISAC_DISALLOWED_BITSTREAM_LENGTH)) {
992 0 : err = LimitPayloadUb(ISACencUB_obj, payloadLimitBytes, bytesLeftSpecCoding,
993 : &transcodingParam, fre, fim, lpcGains,
994 : kIsacUpperBand12, err);
995 : }
996 0 : if (err < 0) {
997 0 : return err;
998 : }
999 : /* Complete arithmetic coding. */
1000 0 : return WebRtcIsac_EncTerminate(&ISACencUB_obj->bitstr_obj);
1001 : }
1002 :
1003 :
1004 :
1005 :
1006 :
1007 :
1008 : /* This function is used to create a new bit-stream with new BWE.
1009 : The same data as previously encoded with the function WebRtcIsac_Encoder().
1010 : The data needed is taken from the structure, where it was stored
1011 : when calling the encoder. */
1012 :
1013 0 : int WebRtcIsac_EncodeStoredDataLb(const IsacSaveEncoderData* ISACSavedEnc_obj,
1014 : Bitstr* ISACBitStr_obj, int BWnumber,
1015 : float scale) {
1016 : int ii;
1017 : int status;
1018 0 : int BWno = BWnumber;
1019 :
1020 : const uint16_t* WebRtcIsac_kQPitchGainCdf_ptr[1];
1021 : const uint16_t** cdf;
1022 :
1023 : double tmpLPCcoeffs_lo[(ORDERLO + 1)*SUBFRAMES * 2];
1024 : double tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * 2];
1025 : int tmpLPCindex_g[12 * 2];
1026 : int16_t tmp_fre[FRAMESAMPLES], tmp_fim[FRAMESAMPLES];
1027 0 : const int kModel = 0;
1028 :
1029 : /* Sanity Check - possible values for BWnumber is 0 - 23. */
1030 0 : if ((BWnumber < 0) || (BWnumber > 23)) {
1031 0 : return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
1032 : }
1033 :
1034 : /* Reset bit-stream. */
1035 0 : WebRtcIsac_ResetBitstream(ISACBitStr_obj);
1036 :
1037 : /* Encode frame length */
1038 0 : status = WebRtcIsac_EncodeFrameLen(ISACSavedEnc_obj->framelength,
1039 : ISACBitStr_obj);
1040 0 : if (status < 0) {
1041 : /* Wrong frame size. */
1042 0 : return status;
1043 : }
1044 :
1045 : /* Transcoding */
1046 0 : if ((scale > 0.0) && (scale < 1.0)) {
1047 : /* Compensate LPC gain. */
1048 0 : for (ii = 0;
1049 0 : ii < ((ORDERLO + 1)* SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx));
1050 0 : ii++) {
1051 0 : tmpLPCcoeffs_lo[ii] = scale * ISACSavedEnc_obj->LPCcoeffs_lo[ii];
1052 : }
1053 0 : for (ii = 0;
1054 0 : ii < ((ORDERHI + 1) * SUBFRAMES * (1 + ISACSavedEnc_obj->startIdx));
1055 0 : ii++) {
1056 0 : tmpLPCcoeffs_hi[ii] = scale * ISACSavedEnc_obj->LPCcoeffs_hi[ii];
1057 : }
1058 : /* Scale DFT. */
1059 0 : for (ii = 0;
1060 0 : ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx));
1061 0 : ii++) {
1062 0 : tmp_fre[ii] = (int16_t)((scale) * (float)ISACSavedEnc_obj->fre[ii]);
1063 0 : tmp_fim[ii] = (int16_t)((scale) * (float)ISACSavedEnc_obj->fim[ii]);
1064 : }
1065 : } else {
1066 0 : for (ii = 0;
1067 0 : ii < (KLT_ORDER_GAIN * (1 + ISACSavedEnc_obj->startIdx));
1068 0 : ii++) {
1069 0 : tmpLPCindex_g[ii] = ISACSavedEnc_obj->LPCindex_g[ii];
1070 : }
1071 0 : for (ii = 0;
1072 0 : ii < (FRAMESAMPLES_HALF * (1 + ISACSavedEnc_obj->startIdx));
1073 0 : ii++) {
1074 0 : tmp_fre[ii] = ISACSavedEnc_obj->fre[ii];
1075 0 : tmp_fim[ii] = ISACSavedEnc_obj->fim[ii];
1076 : }
1077 : }
1078 :
1079 : /* Encode bandwidth estimate. */
1080 0 : WebRtcIsac_EncodeReceiveBw(&BWno, ISACBitStr_obj);
1081 :
1082 : /* Loop over number of 30 msec */
1083 0 : for (ii = 0; ii <= ISACSavedEnc_obj->startIdx; ii++) {
1084 : /* Encode pitch gains. */
1085 0 : *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf;
1086 0 : WebRtcIsac_EncHistMulti(ISACBitStr_obj,
1087 : &ISACSavedEnc_obj->pitchGain_index[ii],
1088 : WebRtcIsac_kQPitchGainCdf_ptr, 1);
1089 :
1090 : /* Entropy coding of quantization pitch lags */
1091 : /* Voicing classification. */
1092 0 : if (ISACSavedEnc_obj->meanGain[ii] < 0.2) {
1093 0 : cdf = WebRtcIsac_kQPitchLagCdfPtrLo;
1094 0 : } else if (ISACSavedEnc_obj->meanGain[ii] < 0.4) {
1095 0 : cdf = WebRtcIsac_kQPitchLagCdfPtrMid;
1096 : } else {
1097 0 : cdf = WebRtcIsac_kQPitchLagCdfPtrHi;
1098 : }
1099 0 : WebRtcIsac_EncHistMulti(ISACBitStr_obj,
1100 0 : &ISACSavedEnc_obj->pitchIndex[PITCH_SUBFRAMES * ii],
1101 : cdf, PITCH_SUBFRAMES);
1102 :
1103 : /* LPC */
1104 : /* Only one model exists. The entropy coding is done only for backward
1105 : * compatibility. */
1106 0 : WebRtcIsac_EncHistMulti(ISACBitStr_obj, &kModel,
1107 : WebRtcIsac_kQKltModelCdfPtr, 1);
1108 : /* Entropy coding of quantization indices - LPC shape only. */
1109 0 : WebRtcIsac_EncHistMulti(ISACBitStr_obj,
1110 0 : &ISACSavedEnc_obj->LPCindex_s[KLT_ORDER_SHAPE * ii],
1111 : WebRtcIsac_kQKltCdfPtrShape,
1112 : KLT_ORDER_SHAPE);
1113 :
1114 : /* If transcoding, get new LPC gain indices */
1115 0 : if (scale < 1.0) {
1116 0 : WebRtcIsac_TranscodeLPCCoef(
1117 0 : &tmpLPCcoeffs_lo[(ORDERLO + 1) * SUBFRAMES * ii],
1118 0 : &tmpLPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * ii],
1119 0 : &tmpLPCindex_g[KLT_ORDER_GAIN * ii]);
1120 : }
1121 :
1122 : /* Entropy coding of quantization indices - LPC gain. */
1123 0 : WebRtcIsac_EncHistMulti(ISACBitStr_obj, &tmpLPCindex_g[KLT_ORDER_GAIN * ii],
1124 : WebRtcIsac_kQKltCdfPtrGain, KLT_ORDER_GAIN);
1125 :
1126 : /* Quantization and loss-less coding. */
1127 0 : status = WebRtcIsac_EncodeSpec(&tmp_fre[ii * FRAMESAMPLES_HALF],
1128 0 : &tmp_fim[ii * FRAMESAMPLES_HALF],
1129 0 : ISACSavedEnc_obj->AvgPitchGain[ii],
1130 : kIsacLowerBand, ISACBitStr_obj);
1131 0 : if (status < 0) {
1132 0 : return status;
1133 : }
1134 : }
1135 : /* Complete arithmetic coding. */
1136 0 : return WebRtcIsac_EncTerminate(ISACBitStr_obj);
1137 : }
1138 :
1139 :
1140 0 : int WebRtcIsac_EncodeStoredDataUb(
1141 : const ISACUBSaveEncDataStruct* ISACSavedEnc_obj,
1142 : Bitstr* bitStream,
1143 : int32_t jitterInfo,
1144 : float scale,
1145 : enum ISACBandwidth bandwidth) {
1146 : int n;
1147 : int err;
1148 : double lpcGain[SUBFRAMES];
1149 : int16_t realFFT[FRAMESAMPLES_HALF];
1150 : int16_t imagFFT[FRAMESAMPLES_HALF];
1151 : const uint16_t** shape_cdf;
1152 : int shape_len;
1153 0 : const int16_t kAveragePitchGain = 0.0;
1154 : enum ISACBand band;
1155 : /* Reset bitstream. */
1156 0 : WebRtcIsac_ResetBitstream(bitStream);
1157 :
1158 : /* Encode jitter index. */
1159 0 : WebRtcIsac_EncodeJitterInfo(jitterInfo, bitStream);
1160 :
1161 0 : err = WebRtcIsac_EncodeBandwidth(bandwidth, bitStream);
1162 0 : if (err < 0) {
1163 0 : return err;
1164 : }
1165 :
1166 : /* Encode LPC-shape. */
1167 0 : if (bandwidth == isac12kHz) {
1168 0 : shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb12;
1169 0 : shape_len = UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME;
1170 0 : band = kIsacUpperBand12;
1171 : } else {
1172 0 : shape_cdf = WebRtcIsac_kLpcShapeCdfMatUb16;
1173 0 : shape_len = UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME;
1174 0 : band = kIsacUpperBand16;
1175 : }
1176 0 : WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->indexLPCShape,
1177 : shape_cdf, shape_len);
1178 :
1179 0 : if ((scale <= 0.0) || (scale >= 1.0)) {
1180 : /* We only consider scales between zero and one. */
1181 0 : WebRtcIsac_EncHistMulti(bitStream, ISACSavedEnc_obj->lpcGainIndex,
1182 : WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM);
1183 0 : if (bandwidth == isac16kHz) {
1184 : /* Store gain indices of the second half. */
1185 0 : WebRtcIsac_EncHistMulti(bitStream,
1186 : &ISACSavedEnc_obj->lpcGainIndex[SUBFRAMES],
1187 : WebRtcIsac_kLpcGainCdfMat, UB_LPC_GAIN_DIM);
1188 : }
1189 : /* Store FFT coefficients. */
1190 0 : err = WebRtcIsac_EncodeSpec(ISACSavedEnc_obj->realFFT,
1191 0 : ISACSavedEnc_obj->imagFFT, kAveragePitchGain,
1192 : band, bitStream);
1193 : } else {
1194 : /* Scale LPC gain and FFT coefficients. */
1195 0 : for (n = 0; n < SUBFRAMES; n++) {
1196 0 : lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n];
1197 : }
1198 : /* Store LPC gains. */
1199 0 : WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream);
1200 :
1201 0 : if (bandwidth == isac16kHz) {
1202 : /* Scale and code the gains of the second half of the frame, if 16kHz. */
1203 0 : for (n = 0; n < SUBFRAMES; n++) {
1204 0 : lpcGain[n] = scale * ISACSavedEnc_obj->lpcGain[n + SUBFRAMES];
1205 : }
1206 0 : WebRtcIsac_StoreLpcGainUb(lpcGain, bitStream);
1207 : }
1208 :
1209 0 : for (n = 0; n < FRAMESAMPLES_HALF; n++) {
1210 0 : realFFT[n] = (int16_t)(scale * (float)ISACSavedEnc_obj->realFFT[n] +
1211 : 0.5f);
1212 0 : imagFFT[n] = (int16_t)(scale * (float)ISACSavedEnc_obj->imagFFT[n] +
1213 : 0.5f);
1214 : }
1215 : /* Store FFT coefficients. */
1216 0 : err = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain,
1217 : band, bitStream);
1218 : }
1219 0 : if (err < 0) {
1220 : /* Error happened while encoding FFT coefficients. */
1221 0 : return err;
1222 : }
1223 :
1224 : /* Complete arithmetic coding. */
1225 0 : return WebRtcIsac_EncTerminate(bitStream);
1226 : }
1227 :
1228 0 : int16_t WebRtcIsac_GetRedPayloadUb(
1229 : const ISACUBSaveEncDataStruct* ISACSavedEncObj,
1230 : Bitstr* bitStreamObj,
1231 : enum ISACBandwidth bandwidth) {
1232 : int n;
1233 : int16_t status;
1234 : int16_t realFFT[FRAMESAMPLES_HALF];
1235 : int16_t imagFFT[FRAMESAMPLES_HALF];
1236 : enum ISACBand band;
1237 0 : const int16_t kAveragePitchGain = 0.0;
1238 : /* Store bit-stream object. */
1239 0 : memcpy(bitStreamObj, &ISACSavedEncObj->bitStreamObj, sizeof(Bitstr));
1240 :
1241 : /* Scale FFT coefficients. */
1242 0 : for (n = 0; n < FRAMESAMPLES_HALF; n++) {
1243 0 : realFFT[n] = (int16_t)((float)ISACSavedEncObj->realFFT[n] *
1244 0 : RCU_TRANSCODING_SCALE_UB + 0.5);
1245 0 : imagFFT[n] = (int16_t)((float)ISACSavedEncObj->imagFFT[n] *
1246 0 : RCU_TRANSCODING_SCALE_UB + 0.5);
1247 : }
1248 :
1249 0 : band = (bandwidth == isac12kHz) ? kIsacUpperBand12 : kIsacUpperBand16;
1250 0 : status = WebRtcIsac_EncodeSpec(realFFT, imagFFT, kAveragePitchGain, band,
1251 : bitStreamObj);
1252 0 : if (status < 0) {
1253 0 : return status;
1254 : } else {
1255 : /* Terminate entropy coding */
1256 0 : return WebRtcIsac_EncTerminate(bitStreamObj);
1257 : }
1258 : }
|