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(¤t_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