• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "webrtc/modules/audio_coding/main/acm2/acm_isac.h"
11 
12 #include <assert.h>
13 
14 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
15 #include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
16 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
17 #include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h"
18 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19 #include "webrtc/system_wrappers/interface/trace.h"
20 
21 #ifdef WEBRTC_CODEC_ISAC
22 #include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h"
23 #endif
24 
25 #ifdef WEBRTC_CODEC_ISACFX
26 #include "webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h"
27 #endif
28 
29 #if defined (WEBRTC_CODEC_ISAC) || defined (WEBRTC_CODEC_ISACFX)
30 #include "webrtc/modules/audio_coding/main/acm2/acm_isac_macros.h"
31 #endif
32 
33 namespace webrtc {
34 
35 namespace acm2 {
36 
37 // we need this otherwise we cannot use forward declaration
38 // in the header file
39 #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
40 struct ACMISACInst {
41   ACM_ISAC_STRUCT* inst;
42 };
43 #endif
44 
45 #define ISAC_MIN_RATE 10000
46 #define ISAC_MAX_RATE 56000
47 
48 // Tables for bandwidth estimates
49 #define NR_ISAC_BANDWIDTHS 24
50 static const int32_t kIsacRatesWb[NR_ISAC_BANDWIDTHS] = {
51     10000, 11100, 12300, 13700, 15200, 16900, 18800, 20900, 23300, 25900, 28700,
52     31900, 10100, 11200, 12400, 13800, 15300, 17000, 18900, 21000, 23400, 26000,
53     28800, 32000};
54 
55 static const int32_t kIsacRatesSwb[NR_ISAC_BANDWIDTHS] = {
56     10000, 11000, 12400, 13800, 15300, 17000, 18900, 21000, 23200, 25400, 27600,
57     29800, 32000, 34100, 36300, 38500, 40700, 42900, 45100, 47300, 49500, 51700,
58     53900, 56000 };
59 
60 #if (!defined(WEBRTC_CODEC_ISAC) && !defined(WEBRTC_CODEC_ISACFX))
61 
ACMISAC(int16_t)62 ACMISAC::ACMISAC(int16_t /* codec_id */)
63     : codec_inst_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
64       codec_inst_ptr_(NULL),
65       is_enc_initialized_(false),
66       isac_coding_mode_(CHANNEL_INDEPENDENT),
67       enforce_frame_size_(false),
68       isac_currentBN_(32000),
69       samples_in10MsAudio_(160),  // Initiates to 16 kHz mode.
70       decoder_initialized_(false) {
71 }
72 
~ACMISAC()73 ACMISAC::~ACMISAC() {
74   return;
75 }
76 
CreateInstance(void)77 ACMGenericCodec* ACMISAC::CreateInstance(void) { return NULL; }
78 
InternalEncode(uint8_t *,int16_t *)79 int16_t ACMISAC::InternalEncode(uint8_t* /* bitstream */,
80                                 int16_t* /* bitstream_len_byte */) {
81   return -1;
82 }
83 
InternalInitEncoder(WebRtcACMCodecParams *)84 int16_t ACMISAC::InternalInitEncoder(WebRtcACMCodecParams* /* codec_params */) {
85   return -1;
86 }
87 
InternalInitDecoder(WebRtcACMCodecParams *)88 int16_t ACMISAC::InternalInitDecoder(WebRtcACMCodecParams* /* codec_params */) {
89   return -1;
90 }
91 
InternalCreateEncoder()92 int16_t ACMISAC::InternalCreateEncoder() { return -1; }
93 
DestructEncoderSafe()94 void ACMISAC::DestructEncoderSafe() { return; }
95 
InternalDestructEncoderInst(void *)96 void ACMISAC::InternalDestructEncoderInst(void* /* ptr_inst */) { return; }
97 
Transcode(uint8_t *,int16_t *,int16_t,int32_t,bool)98 int16_t ACMISAC::Transcode(uint8_t* /* bitstream */,
99                            int16_t* /* bitstream_len_byte */,
100                            int16_t /* q_bwe */,
101                            int32_t /* scale */,
102                            bool /* is_red */) {
103   return -1;
104 }
105 
SetBitRateSafe(int32_t)106 int16_t ACMISAC::SetBitRateSafe(int32_t /* bit_rate */) { return -1; }
107 
GetEstimatedBandwidthSafe()108 int32_t ACMISAC::GetEstimatedBandwidthSafe() { return -1; }
109 
SetEstimatedBandwidthSafe(int32_t)110 int32_t ACMISAC::SetEstimatedBandwidthSafe(int32_t /* estimated_bandwidth */) {
111   return -1;
112 }
113 
GetRedPayloadSafe(uint8_t *,int16_t *)114 int32_t ACMISAC::GetRedPayloadSafe(uint8_t* /* red_payload */,
115                                    int16_t* /* payload_bytes */) {
116   return -1;
117 }
118 
UpdateDecoderSampFreq(int16_t)119 int16_t ACMISAC::UpdateDecoderSampFreq(int16_t /* codec_id */) { return -1; }
120 
UpdateEncoderSampFreq(uint16_t)121 int16_t ACMISAC::UpdateEncoderSampFreq(uint16_t /* encoder_samp_freq_hz */) {
122   return -1;
123 }
124 
EncoderSampFreq(uint16_t *)125 int16_t ACMISAC::EncoderSampFreq(uint16_t* /* samp_freq_hz */) { return -1; }
126 
ConfigISACBandwidthEstimator(const uint8_t,const uint16_t,const bool)127 int32_t ACMISAC::ConfigISACBandwidthEstimator(
128     const uint8_t /* init_frame_size_msec */,
129     const uint16_t /* init_rate_bit_per_sec */,
130     const bool /* enforce_frame_size  */) {
131   return -1;
132 }
133 
SetISACMaxPayloadSize(const uint16_t)134 int32_t ACMISAC::SetISACMaxPayloadSize(
135     const uint16_t /* max_payload_len_bytes */) {
136   return -1;
137 }
138 
SetISACMaxRate(const uint32_t)139 int32_t ACMISAC::SetISACMaxRate(const uint32_t /* max_rate_bit_per_sec */) {
140   return -1;
141 }
142 
UpdateFrameLen()143 void ACMISAC::UpdateFrameLen() { return; }
144 
CurrentRate(int32_t *)145 void ACMISAC::CurrentRate(int32_t* /*rate_bit_per_sec */) { return; }
146 
DecoderParamsSafe(WebRtcACMCodecParams *,const uint8_t)147 bool ACMISAC::DecoderParamsSafe(WebRtcACMCodecParams* /* dec_params */,
148                                 const uint8_t /* payload_type */) {
149   return false;
150 }
151 
REDPayloadISAC(const int32_t,const int16_t,uint8_t *,int16_t *)152 int16_t ACMISAC::REDPayloadISAC(const int32_t /* isac_rate */,
153                                 const int16_t /* isac_bw_estimate */,
154                                 uint8_t* /* payload */,
155                                 int16_t* /* payload_len_bytes */) {
156   return -1;
157 }
158 
Decoder(int)159 AudioDecoder* ACMISAC::Decoder(int /* codec_id */) { return NULL; }
160 
161 #else     //===================== Actual Implementation =======================
162 
163 #ifdef WEBRTC_CODEC_ISACFX
164 
165 // How the scaling is computed. iSAC computes a gain based on the
166 // bottleneck. It follows the following expression for that
167 //
168 // G(BN_kbps) = pow(10, (a + b * BN_kbps + c * BN_kbps * BN_kbps) / 20.0)
169 //              / 3.4641;
170 //
171 // Where for 30 ms framelength we have,
172 //
173 // a = -23; b = 0.48; c = 0;
174 //
175 // As the default encoder is operating at 32kbps we have the scale as
176 //
177 // S(BN_kbps) = G(BN_kbps) / G(32);
178 
179 #define ISAC_NUM_SUPPORTED_RATES 9
180 
181 static const uint16_t kIsacSuportedRates[ISAC_NUM_SUPPORTED_RATES] = {
182     32000, 30000, 26000, 23000, 21000, 19000, 17000, 15000, 12000};
183 
184 static const float kIsacScale[ISAC_NUM_SUPPORTED_RATES] = {
185     1.0f,    0.8954f,  0.7178f, 0.6081f, 0.5445f,
186     0.4875f, 0.4365f,  0.3908f, 0.3311f
187 };
188 
189 enum IsacSamplingRate {
190   kIsacWideband = 16,
191   kIsacSuperWideband = 32
192 };
193 
ACMISACFixTranscodingScale(uint16_t rate)194 static float ACMISACFixTranscodingScale(uint16_t rate) {
195   // find the scale for transcoding, the scale is rounded
196   // downward
197   float scale = -1;
198   for (int16_t n = 0; n < ISAC_NUM_SUPPORTED_RATES; n++) {
199     if (rate >= kIsacSuportedRates[n]) {
200       scale = kIsacScale[n];
201       break;
202     }
203   }
204   return scale;
205 }
206 
ACMISACFixGetSendBitrate(ACM_ISAC_STRUCT * inst,int32_t * bottleneck)207 static void ACMISACFixGetSendBitrate(ACM_ISAC_STRUCT* inst,
208                                      int32_t* bottleneck) {
209   *bottleneck = WebRtcIsacfix_GetUplinkBw(inst);
210 }
211 
ACMISACFixGetNewBitstream(ACM_ISAC_STRUCT * inst,int16_t bwe_index,int16_t,int32_t rate,int16_t * bitstream,bool is_red)212 static int16_t ACMISACFixGetNewBitstream(ACM_ISAC_STRUCT* inst,
213                                          int16_t bwe_index,
214                                          int16_t /* jitter_index */,
215                                          int32_t rate,
216                                          int16_t* bitstream,
217                                          bool is_red) {
218   if (is_red) {
219     // RED not supported with iSACFIX
220     return -1;
221   }
222   float scale = ACMISACFixTranscodingScale((uint16_t)rate);
223   return WebRtcIsacfix_GetNewBitStream(inst, bwe_index, scale, bitstream);
224 }
225 
ACMISACFixGetSendBWE(ACM_ISAC_STRUCT * inst,int16_t * rate_index,int16_t *)226 static int16_t ACMISACFixGetSendBWE(ACM_ISAC_STRUCT* inst,
227                                     int16_t* rate_index,
228                                     int16_t* /* dummy */) {
229   int16_t local_rate_index;
230   int16_t status = WebRtcIsacfix_GetDownLinkBwIndex(inst, &local_rate_index);
231   if (status < 0) {
232     return -1;
233   } else {
234     *rate_index = local_rate_index;
235     return 0;
236   }
237 }
238 
ACMISACFixControlBWE(ACM_ISAC_STRUCT * inst,int32_t rate_bps,int16_t frame_size_ms,int16_t enforce_frame_size)239 static int16_t ACMISACFixControlBWE(ACM_ISAC_STRUCT* inst,
240                                     int32_t rate_bps,
241                                     int16_t frame_size_ms,
242                                     int16_t enforce_frame_size) {
243   return WebRtcIsacfix_ControlBwe(
244       inst, (int16_t)rate_bps, frame_size_ms, enforce_frame_size);
245 }
246 
ACMISACFixControl(ACM_ISAC_STRUCT * inst,int32_t rate_bps,int16_t frame_size_ms)247 static int16_t ACMISACFixControl(ACM_ISAC_STRUCT* inst,
248                                  int32_t rate_bps,
249                                  int16_t frame_size_ms) {
250   return WebRtcIsacfix_Control(inst, (int16_t)rate_bps, frame_size_ms);
251 }
252 
253 // The following two function should have the same signature as their counter
254 // part in iSAC floating-point, i.e. WebRtcIsac_EncSampRate &
255 // WebRtcIsac_DecSampRate.
ACMISACFixGetEncSampRate(ACM_ISAC_STRUCT *)256 static uint16_t ACMISACFixGetEncSampRate(ACM_ISAC_STRUCT* /* inst */) {
257   return 16000;
258 }
259 
ACMISACFixGetDecSampRate(ACM_ISAC_STRUCT *)260 static uint16_t ACMISACFixGetDecSampRate(ACM_ISAC_STRUCT* /* inst */) {
261   return 16000;
262 }
263 
264 #endif
265 
ACMISAC(int16_t codec_id)266 ACMISAC::ACMISAC(int16_t codec_id)
267     : AudioDecoder(ACMCodecDB::neteq_decoders_[codec_id]),
268       codec_inst_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
269       is_enc_initialized_(false),
270       isac_coding_mode_(CHANNEL_INDEPENDENT),
271       enforce_frame_size_(false),
272       isac_current_bn_(32000),
273       samples_in_10ms_audio_(160),  // Initiates to 16 kHz mode.
274       decoder_initialized_(false) {
275   codec_id_ = codec_id;
276 
277   // Create codec instance.
278   codec_inst_ptr_ = new ACMISACInst;
279   if (codec_inst_ptr_ == NULL) {
280     return;
281   }
282   codec_inst_ptr_->inst = NULL;
283   state_ = codec_inst_ptr_;
284 }
285 
~ACMISAC()286 ACMISAC::~ACMISAC() {
287   if (codec_inst_ptr_ != NULL) {
288     if (codec_inst_ptr_->inst != NULL) {
289       ACM_ISAC_FREE(codec_inst_ptr_->inst);
290       codec_inst_ptr_->inst = NULL;
291     }
292     delete codec_inst_ptr_;
293     codec_inst_ptr_ = NULL;
294   }
295   return;
296 }
297 
InternalInitDecoder(WebRtcACMCodecParams * codec_params)298 int16_t ACMISAC::InternalInitDecoder(WebRtcACMCodecParams* codec_params) {
299   // set decoder sampling frequency.
300   if (codec_params->codec_inst.plfreq == 32000 ||
301       codec_params->codec_inst.plfreq == 48000) {
302     UpdateDecoderSampFreq(ACMCodecDB::kISACSWB);
303   } else {
304     UpdateDecoderSampFreq(ACMCodecDB::kISAC);
305   }
306 
307   // in a one-way communication we may never register send-codec.
308   // However we like that the BWE to work properly so it has to
309   // be initialized. The BWE is initialized when iSAC encoder is initialized.
310   // Therefore, we need this.
311   if (!encoder_initialized_) {
312     // Since we don't require a valid rate or a valid packet size when
313     // initializing the decoder, we set valid values before initializing encoder
314     codec_params->codec_inst.rate = kIsacWbDefaultRate;
315     codec_params->codec_inst.pacsize = kIsacPacSize960;
316     if (InternalInitEncoder(codec_params) < 0) {
317       return -1;
318     }
319     encoder_initialized_ = true;
320   }
321 
322   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
323   return ACM_ISAC_DECODERINIT(codec_inst_ptr_->inst);
324 }
325 
CreateInstance(void)326 ACMGenericCodec* ACMISAC::CreateInstance(void) { return NULL; }
327 
InternalEncode(uint8_t * bitstream,int16_t * bitstream_len_byte)328 int16_t ACMISAC::InternalEncode(uint8_t* bitstream,
329                                 int16_t* bitstream_len_byte) {
330   // ISAC takes 10ms audio every time we call encoder, therefore,
331   // it should be treated like codecs with 'basic coding block'
332   // non-zero, and the following 'while-loop' should not be necessary.
333   // However, due to a mistake in the codec the frame-size might change
334   // at the first 10ms pushed in to iSAC if the bit-rate is low, this is
335   // sort of a bug in iSAC. to address this we treat iSAC as the
336   // following.
337   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
338   if (codec_inst_ptr_ == NULL) {
339     return -1;
340   }
341   *bitstream_len_byte = 0;
342   while ((*bitstream_len_byte == 0) && (in_audio_ix_read_ < frame_len_smpl_)) {
343     if (in_audio_ix_read_ > in_audio_ix_write_) {
344       // something is wrong.
345       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
346                    "The actual frame-size of iSAC appears to be larger that "
347                    "expected. All audio pushed in but no bit-stream is "
348                    "generated.");
349       return -1;
350     }
351     *bitstream_len_byte = ACM_ISAC_ENCODE(
352         codec_inst_ptr_->inst, &in_audio_[in_audio_ix_read_],
353         reinterpret_cast<int16_t*>(bitstream));
354     // increment the read index this tell the caller that how far
355     // we have gone forward in reading the audio buffer
356     in_audio_ix_read_ += samples_in_10ms_audio_;
357   }
358   if (*bitstream_len_byte == 0) {
359     WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, unique_id_,
360                  "ISAC Has encoded the whole frame but no bit-stream is "
361                  "generated.");
362   }
363 
364   // a packet is generated iSAC, is set in adaptive mode may change
365   // the frame length and we like to update the bottleneck value as
366   // well, although updating bottleneck is not crucial
367   if ((*bitstream_len_byte > 0) && (isac_coding_mode_ == ADAPTIVE)) {
368     ACM_ISAC_GETSENDBITRATE(codec_inst_ptr_->inst, &isac_current_bn_);
369   }
370   UpdateFrameLen();
371   return *bitstream_len_byte;
372 }
373 
InternalInitEncoder(WebRtcACMCodecParams * codec_params)374 int16_t ACMISAC::InternalInitEncoder(WebRtcACMCodecParams* codec_params) {
375   // if rate is set to -1 then iSAC has to be in adaptive mode
376   if (codec_params->codec_inst.rate == -1) {
377     isac_coding_mode_ = ADAPTIVE;
378   } else if ((codec_params->codec_inst.rate >= ISAC_MIN_RATE) &&
379              (codec_params->codec_inst.rate <= ISAC_MAX_RATE)) {
380     // sanity check that rate is in acceptable range
381     isac_coding_mode_ = CHANNEL_INDEPENDENT;
382     isac_current_bn_ = codec_params->codec_inst.rate;
383   } else {
384     return -1;
385   }
386 
387   // we need to set the encoder sampling frequency.
388   if (UpdateEncoderSampFreq((uint16_t)codec_params->codec_inst.plfreq) < 0) {
389     return -1;
390   }
391   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
392   if (ACM_ISAC_ENCODERINIT(codec_inst_ptr_->inst, isac_coding_mode_) < 0) {
393     return -1;
394   }
395 
396   // apply the frame-size and rate if operating in
397   // channel-independent mode
398   if (isac_coding_mode_ == CHANNEL_INDEPENDENT) {
399     if (ACM_ISAC_CONTROL(codec_inst_ptr_->inst,
400                          codec_params->codec_inst.rate,
401                          codec_params->codec_inst.pacsize /
402                          (codec_params->codec_inst.plfreq / 1000)) < 0) {
403       return -1;
404     }
405   } else {
406     // We need this for adaptive case and has to be called
407     // after initialization
408     ACM_ISAC_GETSENDBITRATE(codec_inst_ptr_->inst, &isac_current_bn_);
409   }
410   frame_len_smpl_ = ACM_ISAC_GETNEWFRAMELEN(codec_inst_ptr_->inst);
411   return 0;
412 }
413 
InternalCreateEncoder()414 int16_t ACMISAC::InternalCreateEncoder() {
415   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
416   if (codec_inst_ptr_ == NULL) {
417     return -1;
418   }
419   decoder_initialized_ = false;
420   int16_t status = ACM_ISAC_CREATE(&(codec_inst_ptr_->inst));
421 
422   if (status < 0)
423     codec_inst_ptr_->inst = NULL;
424   return status;
425 }
426 
Transcode(uint8_t * bitstream,int16_t * bitstream_len_byte,int16_t q_bwe,int32_t rate,bool is_red)427 int16_t ACMISAC::Transcode(uint8_t* bitstream,
428                            int16_t* bitstream_len_byte,
429                            int16_t q_bwe,
430                            int32_t rate,
431                            bool is_red) {
432   int16_t jitter_info = 0;
433   // transcode from a higher rate to lower rate sanity check
434   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
435   if (codec_inst_ptr_ == NULL) {
436     return -1;
437   }
438 
439   *bitstream_len_byte = ACM_ISAC_GETNEWBITSTREAM(
440       codec_inst_ptr_->inst, q_bwe, jitter_info, rate,
441       reinterpret_cast<int16_t*>(bitstream), (is_red) ? 1 : 0);
442 
443   if (*bitstream_len_byte < 0) {
444     // error happened
445     *bitstream_len_byte = 0;
446     return -1;
447   } else {
448     return *bitstream_len_byte;
449   }
450 }
451 
UpdateFrameLen()452 void ACMISAC::UpdateFrameLen() {
453   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
454   frame_len_smpl_ = ACM_ISAC_GETNEWFRAMELEN(codec_inst_ptr_->inst);
455   encoder_params_.codec_inst.pacsize = frame_len_smpl_;
456 }
457 
DestructEncoderSafe()458 void ACMISAC::DestructEncoderSafe() {
459   // codec with shared instance cannot delete.
460   encoder_initialized_ = false;
461   return;
462 }
463 
InternalDestructEncoderInst(void * ptr_inst)464 void ACMISAC::InternalDestructEncoderInst(void* ptr_inst) {
465   if (ptr_inst != NULL) {
466     ACM_ISAC_FREE(static_cast<ACM_ISAC_STRUCT *>(ptr_inst));
467   }
468   return;
469 }
470 
SetBitRateSafe(int32_t bit_rate)471 int16_t ACMISAC::SetBitRateSafe(int32_t bit_rate) {
472   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
473   if (codec_inst_ptr_ == NULL) {
474     return -1;
475   }
476   uint16_t encoder_samp_freq;
477   EncoderSampFreq(&encoder_samp_freq);
478   bool reinit = false;
479   // change the BN of iSAC
480   if (bit_rate == -1) {
481     // ADAPTIVE MODE
482     // Check if it was already in adaptive mode
483     if (isac_coding_mode_ != ADAPTIVE) {
484       // was not in adaptive, then set the mode to adaptive
485       // and flag for re-initialization
486       isac_coding_mode_ = ADAPTIVE;
487       reinit = true;
488     }
489   } else if ((bit_rate >= ISAC_MIN_RATE) && (bit_rate <= ISAC_MAX_RATE)) {
490     // Sanity check if the rate valid
491     // check if it was in channel-independent mode before
492     if (isac_coding_mode_ != CHANNEL_INDEPENDENT) {
493       // was not in channel independent, set the mode to
494       // channel-independent and flag for re-initialization
495       isac_coding_mode_ = CHANNEL_INDEPENDENT;
496       reinit = true;
497     }
498     // store the bottleneck
499     isac_current_bn_ = (uint16_t)bit_rate;
500   } else {
501     // invlaid rate
502     return -1;
503   }
504 
505   int16_t status = 0;
506   if (reinit) {
507     // initialize and check if it is successful
508     if (ACM_ISAC_ENCODERINIT(codec_inst_ptr_->inst, isac_coding_mode_) < 0) {
509       // failed initialization
510       return -1;
511     }
512   }
513   if (isac_coding_mode_ == CHANNEL_INDEPENDENT) {
514     status = ACM_ISAC_CONTROL(
515         codec_inst_ptr_->inst, isac_current_bn_,
516         (encoder_samp_freq == 32000 || encoder_samp_freq == 48000) ? 30 :
517             (frame_len_smpl_ / 16));
518     if (status < 0) {
519       status = -1;
520     }
521   }
522 
523   // Update encoder parameters
524   encoder_params_.codec_inst.rate = bit_rate;
525 
526   UpdateFrameLen();
527   return status;
528 }
529 
GetEstimatedBandwidthSafe()530 int32_t ACMISAC::GetEstimatedBandwidthSafe() {
531   int16_t bandwidth_index = 0;
532   int16_t delay_index = 0;
533   int samp_rate;
534 
535   // Get bandwidth information
536   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
537   ACM_ISAC_GETSENDBWE(codec_inst_ptr_->inst, &bandwidth_index, &delay_index);
538 
539   // Validy check of index
540   if ((bandwidth_index < 0) || (bandwidth_index >= NR_ISAC_BANDWIDTHS)) {
541     return -1;
542   }
543 
544   // Check sample frequency
545   samp_rate = ACM_ISAC_GETDECSAMPRATE(codec_inst_ptr_->inst);
546   if (samp_rate == 16000) {
547     return kIsacRatesWb[bandwidth_index];
548   } else {
549     return kIsacRatesSwb[bandwidth_index];
550   }
551 }
552 
SetEstimatedBandwidthSafe(int32_t estimated_bandwidth)553 int32_t ACMISAC::SetEstimatedBandwidthSafe(int32_t estimated_bandwidth) {
554   int samp_rate;
555   int16_t bandwidth_index;
556 
557   // Check sample frequency and choose appropriate table
558   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
559   samp_rate = ACM_ISAC_GETENCSAMPRATE(codec_inst_ptr_->inst);
560 
561   if (samp_rate == 16000) {
562     // Search through the WB rate table to find the index
563     bandwidth_index = NR_ISAC_BANDWIDTHS / 2 - 1;
564     for (int i = 0; i < (NR_ISAC_BANDWIDTHS / 2); i++) {
565       if (estimated_bandwidth == kIsacRatesWb[i]) {
566         bandwidth_index = i;
567         break;
568       } else if (estimated_bandwidth
569           == kIsacRatesWb[i + NR_ISAC_BANDWIDTHS / 2]) {
570         bandwidth_index = i + NR_ISAC_BANDWIDTHS / 2;
571         break;
572       } else if (estimated_bandwidth < kIsacRatesWb[i]) {
573         bandwidth_index = i;
574         break;
575       }
576     }
577   } else {
578     // Search through the SWB rate table to find the index
579     bandwidth_index = NR_ISAC_BANDWIDTHS - 1;
580     for (int i = 0; i < NR_ISAC_BANDWIDTHS; i++) {
581       if (estimated_bandwidth <= kIsacRatesSwb[i]) {
582         bandwidth_index = i;
583         break;
584       }
585     }
586   }
587 
588   // Set iSAC Bandwidth Estimate
589   ACM_ISAC_SETBWE(codec_inst_ptr_->inst, bandwidth_index);
590 
591   return 0;
592 }
593 
GetRedPayloadSafe(uint8_t *,int16_t *)594 int32_t ACMISAC::GetRedPayloadSafe(
595 #if (!defined(WEBRTC_CODEC_ISAC))
596     uint8_t* /* red_payload */,
597     int16_t* /* payload_bytes */) {
598   return -1;
599 #else
600     uint8_t* red_payload, int16_t* payload_bytes) {
601   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
602   int16_t bytes =
603       WebRtcIsac_GetRedPayload(
604           codec_inst_ptr_->inst, reinterpret_cast<int16_t*>(red_payload));
605   if (bytes < 0) {
606     return -1;
607   }
608   *payload_bytes = bytes;
609   return 0;
610 #endif
611 }
612 
613 int16_t ACMISAC::UpdateDecoderSampFreq(
614 #ifdef WEBRTC_CODEC_ISAC
615     int16_t codec_id) {
616     // The decoder supports only wideband and super-wideband.
617   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
618   if (ACMCodecDB::kISAC == codec_id) {
619     return WebRtcIsac_SetDecSampRate(codec_inst_ptr_->inst, 16000);
620   } else if (ACMCodecDB::kISACSWB == codec_id ||
621              ACMCodecDB::kISACFB == codec_id) {
622     return WebRtcIsac_SetDecSampRate(codec_inst_ptr_->inst, 32000);
623   } else {
624     return -1;
625   }
626 #else
627     int16_t /* codec_id */) {
628   return 0;
629 #endif
630 }
631 
632 int16_t ACMISAC::UpdateEncoderSampFreq(
633 #ifdef WEBRTC_CODEC_ISAC
634     uint16_t encoder_samp_freq_hz) {
635   uint16_t current_samp_rate_hz;
636   EncoderSampFreq(&current_samp_rate_hz);
637 
638   if (current_samp_rate_hz != encoder_samp_freq_hz) {
639     if ((encoder_samp_freq_hz != 16000) && (encoder_samp_freq_hz != 32000) &&
640         (encoder_samp_freq_hz != 48000)) {
641       return -1;
642     } else {
643       in_audio_ix_read_ = 0;
644       in_audio_ix_write_ = 0;
645       in_timestamp_ix_write_ = 0;
646       CriticalSectionScoped lock(codec_inst_crit_sect_.get());
647       if (WebRtcIsac_SetEncSampRate(codec_inst_ptr_->inst,
648                                     encoder_samp_freq_hz) < 0) {
649         return -1;
650       }
651       samples_in_10ms_audio_ = encoder_samp_freq_hz / 100;
652       frame_len_smpl_ = ACM_ISAC_GETNEWFRAMELEN(codec_inst_ptr_->inst);
653       encoder_params_.codec_inst.pacsize = frame_len_smpl_;
654       encoder_params_.codec_inst.plfreq = encoder_samp_freq_hz;
655       return 0;
656     }
657   }
658 #else
659     uint16_t /* codec_id */) {
660 #endif
661   return 0;
662 }
663 
664 int16_t ACMISAC::EncoderSampFreq(uint16_t* samp_freq_hz) {
665   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
666   *samp_freq_hz = ACM_ISAC_GETENCSAMPRATE(codec_inst_ptr_->inst);
667   return 0;
668 }
669 
670 int32_t ACMISAC::ConfigISACBandwidthEstimator(
671     const uint8_t init_frame_size_msec,
672     const uint16_t init_rate_bit_per_sec,
673     const bool enforce_frame_size) {
674   int16_t status;
675   {
676     uint16_t samp_freq_hz;
677     EncoderSampFreq(&samp_freq_hz);
678     CriticalSectionScoped lock(codec_inst_crit_sect_.get());
679     // TODO(turajs): at 32kHz we hardcode calling with 30ms and enforce
680     // the frame-size otherwise we might get error. Revise if
681     // control-bwe is changed.
682     if (samp_freq_hz == 32000 || samp_freq_hz == 48000) {
683       status = ACM_ISAC_CONTROL_BWE(codec_inst_ptr_->inst,
684                                     init_rate_bit_per_sec, 30, 1);
685     } else {
686       status = ACM_ISAC_CONTROL_BWE(codec_inst_ptr_->inst,
687                                     init_rate_bit_per_sec,
688                                     init_frame_size_msec,
689                                     enforce_frame_size ? 1 : 0);
690     }
691   }
692   if (status < 0) {
693     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
694                  "Couldn't config iSAC BWE.");
695     return -1;
696   }
697   UpdateFrameLen();
698   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
699   ACM_ISAC_GETSENDBITRATE(codec_inst_ptr_->inst, &isac_current_bn_);
700   return 0;
701 }
702 
703 int32_t ACMISAC::SetISACMaxPayloadSize(const uint16_t max_payload_len_bytes) {
704   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
705   return ACM_ISAC_SETMAXPAYLOADSIZE(codec_inst_ptr_->inst,
706                                     max_payload_len_bytes);
707 }
708 
709 int32_t ACMISAC::SetISACMaxRate(const uint32_t max_rate_bit_per_sec) {
710   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
711   return ACM_ISAC_SETMAXRATE(codec_inst_ptr_->inst, max_rate_bit_per_sec);
712 }
713 
714 void ACMISAC::CurrentRate(int32_t* rate_bit_per_sec) {
715   if (isac_coding_mode_ == ADAPTIVE) {
716     CriticalSectionScoped lock(codec_inst_crit_sect_.get());
717     ACM_ISAC_GETSENDBITRATE(codec_inst_ptr_->inst, rate_bit_per_sec);
718   }
719 }
720 
721 int16_t ACMISAC::REDPayloadISAC(const int32_t isac_rate,
722                                 const int16_t isac_bw_estimate,
723                                 uint8_t* payload,
724                                 int16_t* payload_len_bytes) {
725   int16_t status;
726   ReadLockScoped rl(codec_wrapper_lock_);
727   status =
728       Transcode(payload, payload_len_bytes, isac_bw_estimate, isac_rate, true);
729   return status;
730 }
731 
732 int ACMISAC::Decode(const uint8_t* encoded,
733                     size_t encoded_len,
734                     int16_t* decoded,
735                     SpeechType* speech_type) {
736   int16_t temp_type;
737   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
738   int ret =
739       ACM_ISAC_DECODE_B(static_cast<ACM_ISAC_STRUCT*>(codec_inst_ptr_->inst),
740                         reinterpret_cast<const uint16_t*>(encoded),
741                         static_cast<int16_t>(encoded_len),
742                         decoded,
743                         &temp_type);
744   *speech_type = ConvertSpeechType(temp_type);
745   return ret;
746 }
747 
748 int ACMISAC::DecodePlc(int num_frames, int16_t* decoded) {
749   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
750   return ACM_ISAC_DECODEPLC(
751       static_cast<ACM_ISAC_STRUCT*>(codec_inst_ptr_->inst),
752       decoded,
753       static_cast<int16_t>(num_frames));
754 }
755 
756 int ACMISAC::IncomingPacket(const uint8_t* payload,
757                             size_t payload_len,
758                             uint16_t rtp_sequence_number,
759                             uint32_t rtp_timestamp,
760                             uint32_t arrival_timestamp) {
761   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
762   return ACM_ISAC_DECODE_BWE(
763       static_cast<ACM_ISAC_STRUCT*>(codec_inst_ptr_->inst),
764       reinterpret_cast<const uint16_t*>(payload),
765       static_cast<uint32_t>(payload_len),
766       rtp_sequence_number,
767       rtp_timestamp,
768       arrival_timestamp);
769 }
770 
771 int ACMISAC::DecodeRedundant(const uint8_t* encoded,
772                              size_t encoded_len,
773                              int16_t* decoded,
774                              SpeechType* speech_type) {
775   int16_t temp_type = 1;  // Default is speech.
776   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
777   int16_t ret =
778       ACM_ISAC_DECODERCU(static_cast<ACM_ISAC_STRUCT*>(codec_inst_ptr_->inst),
779                          reinterpret_cast<const uint16_t*>(encoded),
780                          static_cast<int16_t>(encoded_len),
781                          decoded,
782                          &temp_type);
783   *speech_type = ConvertSpeechType(temp_type);
784   return ret;
785 }
786 
787 int ACMISAC::ErrorCode() {
788   CriticalSectionScoped lock(codec_inst_crit_sect_.get());
789   return ACM_ISAC_GETERRORCODE(
790       static_cast<ACM_ISAC_STRUCT*>(codec_inst_ptr_->inst));
791 }
792 
793 AudioDecoder* ACMISAC::Decoder(int codec_id) {
794   // Create iSAC instance if it does not exist.
795   if (!encoder_exist_) {
796     CriticalSectionScoped lock(codec_inst_crit_sect_.get());
797     assert(codec_inst_ptr_->inst == NULL);
798     encoder_initialized_ = false;
799     decoder_initialized_ = false;
800     if (ACM_ISAC_CREATE(&(codec_inst_ptr_->inst)) < 0) {
801       codec_inst_ptr_->inst = NULL;
802       return NULL;
803     }
804     encoder_exist_ = true;
805   }
806 
807   WebRtcACMCodecParams codec_params;
808   if (!encoder_initialized_ || !decoder_initialized_) {
809     ACMCodecDB::Codec(codec_id, &codec_params.codec_inst);
810     // The following three values are not used but we set them to valid values.
811     codec_params.enable_dtx = false;
812     codec_params.enable_vad = false;
813     codec_params.vad_mode = VADNormal;
814   }
815 
816   if (!encoder_initialized_) {
817     // Initialize encoder to make sure bandwidth estimator works.
818     if (InternalInitEncoder(&codec_params) < 0)
819       return NULL;
820     encoder_initialized_ = true;
821   }
822 
823   if (!decoder_initialized_) {
824     if (InternalInitDecoder(&codec_params) < 0)
825       return NULL;
826     decoder_initialized_ = true;
827   }
828 
829   return this;
830 }
831 
832 #endif
833 
834 }  // namespace acm2
835 
836 }  // namespace webrtc
837