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