1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * isac.c 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This C file contains the functions for the ISAC API 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 18c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h" 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include <math.h> 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdio.h> 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdlib.h> 23c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include <string.h> 24c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org 25c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" 26c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/main/source/bandwidth_estimator.h" 27c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/main/source/codec.h" 28c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/main/source/crc.h" 29c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/main/source/entropy_coding.h" 30c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.h" 31c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/main/source/os_specific_inline.h" 32c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org#include "webrtc/modules/audio_coding/codecs/isac/main/source/structs.h" 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define BIT_MASK_DEC_INIT 0x0001 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define BIT_MASK_ENC_INIT 0x0002 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define LEN_CHECK_SUM_WORD8 4 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define MAX_NUM_LAYERS 10 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * UpdatePayloadSizeLimit(...) 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Call this function to update the limit on the payload size. The limit on 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * payload size might change i) if a user ''directly changes the limit by 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * calling xxx_setMaxPayloadSize() or xxx_setMaxRate(), or ii) indirectly 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * when bandwidth is changing. The latter might be the result of bandwidth 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * adaptation, or direct change of the bottleneck in instantaneous mode. 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function takes the current overall limit on payload, and translates it 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * to the limits on lower and upper-band. If the codec is in wideband mode, 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * then the overall limit and the limit on the lower-band is the same. 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Otherwise, a fraction of the limit should be allocated to lower-band 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * leaving some room for the upper-band bit-stream. That is why an update 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * of limit is required every time that the bandwidth is changing. 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void UpdatePayloadSizeLimit(ISACMainStruct* instISAC) { 59fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t lim30MsPayloadBytes = WEBRTC_SPL_MIN( 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->maxPayloadSizeBytes), 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->maxRateBytesPer30Ms)); 62fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t lim60MsPayloadBytes = WEBRTC_SPL_MIN( 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->maxPayloadSizeBytes), 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->maxRateBytesPer30Ms << 1)); 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The only time that iSAC will have 60 ms 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * frame-size is when operating in wideband, so 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * there is no upper-band bit-stream. */ 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->bandwidthKHz == isac8kHz) { 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* At 8 kHz there is no upper-band bit-stream, 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * therefore, the lower-band limit is the overall limit. */ 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.payloadLimitBytes60 = 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lim60MsPayloadBytes; 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lim30MsPayloadBytes; 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* When in super-wideband, we only have 30 ms frames. 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Do a rate allocation for the given limit. */ 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (lim30MsPayloadBytes > 250) { 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 4/5 to lower-band the rest for upper-band. */ 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (lim30MsPayloadBytes << 2) / 5; 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (lim30MsPayloadBytes > 200) { 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* For the interval of 200 to 250 the share of 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * upper-band linearly grows from 20 to 50. */ 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (lim30MsPayloadBytes << 1) / 5 + 100; 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Allocate only 20 for upper-band. */ 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.payloadLimitBytes30 = 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lim30MsPayloadBytes - 20; 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instUB.ISACencUB_obj.maxPayloadSizeBytes = 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lim30MsPayloadBytes; 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * UpdateBottleneck(...) 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function updates the bottleneck only if the codec is operating in 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * channel-adaptive mode. Furthermore, as the update of bottleneck might 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * result in an update of bandwidth, therefore, the bottlenech should be 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * updated just right before the first 10ms of a frame is pushed into encoder. 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void UpdateBottleneck(ISACMainStruct* instISAC) { 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Read the bottleneck from bandwidth estimator for the 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * first 10 ms audio. This way, if there is a change 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in bandwidth, upper and lower-band will be in sync. */ 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->codingMode == 0) && 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->instLB.ISACencLB_obj.buffer_index == 0) && 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) { 116fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t bottleneck; 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetUplinkBandwidth(&(instISAC->bwestimator_obj), 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &bottleneck); 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Adding hysteresis when increasing signal bandwidth. */ 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->bandwidthKHz == isac8kHz) 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org && (bottleneck > 37000) 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org && (bottleneck < 41000)) { 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bottleneck = 37000; 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Switching from 12 kHz to 16 kHz is not allowed at this revision. 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * If we let this happen, we have to take care of buffer_index and 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the last LPC vector. */ 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->bandwidthKHz != isac16kHz) && 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (bottleneck > 46000)) { 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bottleneck = 46000; 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* We might need a rate allocation. */ 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->encoderSamplingRateKHz == kIsacWideband) { 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Wideband is the only choice we have here. */ 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.bottleneck = 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (bottleneck > 32000) ? 32000 : bottleneck; 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = isac8kHz; 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Do the rate-allocation and get the new bandwidth. */ 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBandwidth bandwidth; 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_RateAllocation(bottleneck, 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &(instISAC->instLB.ISACencLB_obj.bottleneck), 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &(instISAC->instUB.ISACencUB_obj.bottleneck), 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &bandwidth); 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidth != isac8kHz) { 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.new_framelength = 480; 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidth != instISAC->bandwidthKHz) { 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Bandwidth is changing. */ 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = bandwidth; 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdatePayloadSizeLimit(instISAC); 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidth == isac12kHz) { 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.buffer_index = 0; 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Currently we don't let the bandwidth to switch to 16 kHz 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * if in adaptive mode. If we let this happen, we have to take 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * care of buffer_index and the last LPC vector. */ 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * GetSendBandwidthInfo(...) 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This is called to get the bandwidth info. This info is the bandwidth and 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the jitter of 'there-to-here' channel, estimated 'here.' These info 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * is signaled in an in-band fashion to the other side. 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The call to the bandwidth estimator triggers a recursive averaging which 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * has to be synchronized between encoder & decoder, therefore, the call to 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * BWE should be once per packet. As the BWE info is inserted into bit-stream 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * We need a valid info right before the encodeLB function is going to 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * generate a bit-stream. That is when lower-band buffer has already 20ms 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * of audio, and the 3rd block of 10ms is going to be injected into encoder. 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Inputs: 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - instISAC : iSAC instance. 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Outputs: 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - bandwidthIndex : an index which has to be encoded in 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * lower-band bit-stream, indicating the 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bandwidth of there-to-here channel. 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - jitterInfo : this indicates if the jitter is high 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * or low and it is encoded in upper-band 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bit-stream. 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void GetSendBandwidthInfo(ISACMainStruct* instISAC, 194fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* bandwidthIndex, 195fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* jitterInfo) { 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->instLB.ISACencLB_obj.buffer_index == 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (FRAMESAMPLES_10ms << 1)) && 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->instLB.ISACencLB_obj.frame_nb == 0)) { 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Bandwidth estimation and coding. */ 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bandwidthIndex, jitterInfo, 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->decoderSamplingRateKHz); 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_AssignSize(...) 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function returns the size of the ISAC instance, so that the instance 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * can be created out side iSAC. 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - sizeinbytes : number of bytes needed to allocate for the 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * instance. 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 - Ok 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 220fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_AssignSize(int* sizeInBytes) { 221fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *sizeInBytes = sizeof(ISACMainStruct) * 2 / sizeof(int16_t); 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_Assign(...) 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function assigns the memory already created to the ISAC instance. 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : address of the pointer to the coder instance. 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - instISAC_Addr : the already allocated memory, where we put the 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * iSAC structure. 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 - Ok 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 239fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_Assign(ISACStruct** ISAC_main_inst, 240fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org void* instISAC_Addr) { 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC_Addr != NULL) { 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)instISAC_Addr; 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = 0; 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->initFlag = 0; 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Assign the address. */ 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *ISAC_main_inst = (ISACStruct*)instISAC_Addr; 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Default is wideband. */ 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->encoderSamplingRateKHz = kIsacWideband; 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->decoderSamplingRateKHz = kIsacWideband; 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = isac8kHz; 253ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org instISAC->in_sample_rate_hz = 16000; 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_Create(...) 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function creates an ISAC instance, which will contain the state 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * information for one coding/decoding channel. 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : address of the pointer to the coder instance. 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 - Ok 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 273fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_Create(ISACStruct** ISAC_main_inst) { 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC; 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 276f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org if (ISAC_main_inst != NULL) { 277c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org instISAC = (ISACMainStruct*)malloc(sizeof(ISACMainStruct)); 278f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org *ISAC_main_inst = (ISACStruct*)instISAC; 279f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org if (*ISAC_main_inst != NULL) { 280f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org instISAC->errorCode = 0; 281f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org instISAC->initFlag = 0; 282f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org /* Default is wideband. */ 283f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org instISAC->bandwidthKHz = isac8kHz; 284f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org instISAC->encoderSamplingRateKHz = kIsacWideband; 285f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org instISAC->decoderSamplingRateKHz = kIsacWideband; 286f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org instISAC->in_sample_rate_hz = 16000; 287f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org return 0; 288f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org } else { 289f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org return -1; 290f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org } 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_Free(...) 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function frees the ISAC instance created at the beginning. 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : a ISAC instance. 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 - Ok 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 308fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_Free(ISACStruct* ISAC_main_inst) { 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 310c141bf968767f4f74c92249c986f9010c974e2b7bjornv@webrtc.org free(instISAC); 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * EncoderInitLb(...) - internal function for initialization of 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Lower Band 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * EncoderInitUb(...) - internal function for initialization of 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Upper Band 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_EncoderInit(...) - API function 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function initializes a ISAC instance prior to the encoder calls. 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance. 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - CodingMode : 0 -> Bit rate and frame length are automatically 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * adjusted to available bandwidth on 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * transmission channel, applicable just to 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * wideband mode. 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1 -> User sets a frame length and a target bit 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * rate which is taken as the maximum 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * short-term average bit rate. 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 - Ok 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 337fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic int16_t EncoderInitLb(ISACLBStruct* instLB, 338fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t codingMode, 339fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org enum IsacSamplingRate sampRate) { 340fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t statusInit = 0; 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Init stream vector to zero */ 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < STREAM_SIZE_MAX_60; k++) { 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.bitstr_obj.stream[k] = 0; 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((codingMode == 1) || (sampRate == kIsacSuperWideband)) { 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 30 ms frame-size if either in super-wideband or 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * instantaneous mode (I-mode). */ 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.new_framelength = 480; 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.new_framelength = INITIAL_FRAMESAMPLES; 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitMasking(&instLB->ISACencLB_obj.maskfiltstr_obj); 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitPreFilterbank(&instLB->ISACencLB_obj.prefiltbankstr_obj); 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitPitchFilter(&instLB->ISACencLB_obj.pitchfiltstr_obj); 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitPitchAnalysis( 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &instLB->ISACencLB_obj.pitchanalysisstr_obj); 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.buffer_index = 0; 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.frame_nb = 0; 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Default for I-mode. */ 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.bottleneck = 32000; 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.current_framesamples = 0; 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.s2nr = 0; 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.payloadLimitBytes30 = STREAM_SIZE_MAX_30; 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.payloadLimitBytes60 = STREAM_SIZE_MAX_60; 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.maxPayloadBytes = STREAM_SIZE_MAX_60; 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.maxRateInBytes = STREAM_SIZE_MAX_30; 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.enforceFrameSize = 0; 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Invalid value prevents getRedPayload to 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org run before encoder is called. */ 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.lastBWIdx = -1; 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return statusInit; 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 379fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic int16_t EncoderInitUb(ISACUBStruct* instUB, 380fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t bandwidth) { 381fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t statusInit = 0; 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Init stream vector to zero. */ 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < STREAM_SIZE_MAX_60; k++) { 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instUB->ISACencUB_obj.bitstr_obj.stream[k] = 0; 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitMasking(&instUB->ISACencUB_obj.maskfiltstr_obj); 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitPreFilterbank(&instUB->ISACencUB_obj.prefiltbankstr_obj); 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidth == isac16kHz) { 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instUB->ISACencUB_obj.buffer_index = LB_TOTAL_DELAY_SAMPLES; 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instUB->ISACencUB_obj.buffer_index = 0; 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Default for I-mode. */ 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instUB->ISACencUB_obj.bottleneck = 32000; 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* These store the limits for the wideband + super-wideband bit-stream. */ 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instUB->ISACencUB_obj.maxPayloadSizeBytes = STREAM_SIZE_MAX_30 << 1; 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This has to be updated after each lower-band encoding to guarantee 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * a correct payload-limitation. */ 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instUB->ISACencUB_obj.numBytesUsed = 0; 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(instUB->ISACencUB_obj.data_buffer_float, 0, 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES) * sizeof(float)); 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&(instUB->ISACencUB_obj.lastLPCVec), 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER); 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return statusInit; 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 414fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_EncoderInit(ISACStruct* ISAC_main_inst, 415fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t codingMode) { 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 417fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t status; 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((codingMode != 0) && (codingMode != 1)) { 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_DISALLOWED_CODING_MODE; 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Default bottleneck. */ 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bottleneck = MAX_ISAC_BW; 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->encoderSamplingRateKHz == kIsacWideband) { 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = isac8kHz; 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = isac16kHz; 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Channel-adaptive = 0; Instantaneous (Channel-independent) = 1. */ 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->codingMode = codingMode; 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj, 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->encoderSamplingRateKHz, 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->decoderSamplingRateKHz); 442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitRateModel(&instISAC->rate_data_obj); 444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Default for I-mode. */ 445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->MaxDelay = 10.0; 446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = EncoderInitLb(&instISAC->instLB, codingMode, 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->encoderSamplingRateKHz); 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = -status; 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Initialize encoder filter-bank. */ 456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(instISAC->analysisFBState1, 0, 457fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org FB_STATE_SIZE_WORD32 * sizeof(int32_t)); 458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(instISAC->analysisFBState2, 0, 459fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org FB_STATE_SIZE_WORD32 * sizeof(int32_t)); 460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = EncoderInitUb(&(instISAC->instUB), 462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz); 463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = -status; 465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 468ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org memset(instISAC->state_in_resampler, 0, sizeof(instISAC->state_in_resampler)); 469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Initialization is successful, set the flag. */ 470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->initFlag |= BIT_MASK_ENC_INIT; 471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_Encode(...) 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function encodes 10ms frame(s) and inserts it into a package. 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input speech length has to be 160 samples (10ms). The encoder buffers those 480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 10ms frames until it reaches the chosen Framesize (480 or 960 samples 481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * corresponding to 30 or 60 ms frames), and then proceeds to the encoding. 482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance. 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - speechIn : input speech vector. 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - encoded : the encoded data vector 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value: 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * : >0 - Length (in bytes) of coded data 492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * : 0 - The buffer didn't reach the chosen 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * frameSize so it keeps buffering speech 494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * samples. 495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * : -1 - Error 496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 497fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_Encode(ISACStruct* ISAC_main_inst, 498fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t* speechIn, 49983a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org uint8_t* encoded) { 500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float inFrame[FRAMESAMPLES_10ms]; 501fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t speechInLB[FRAMESAMPLES_10ms]; 502fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t speechInUB[FRAMESAMPLES_10ms]; 503fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t streamLenLB = 0; 504fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t streamLenUB = 0; 505fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t streamLen = 0; 506fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t k = 0; 507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int garbageLen = 0; 508fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t bottleneck = 0; 509fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t bottleneckIdx = 0; 510fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t jitterInfo = 0; 511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACLBStruct* instLB = &(instISAC->instLB); 514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACUBStruct* instUB = &(instISAC->instUB); 515ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org const int16_t* speech_in_ptr = speechIn; 516ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org int16_t resampled_buff[FRAMESAMPLES_10ms * 2]; 517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check if encoder initiated. */ 519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BIT_MASK_ENC_INIT) { 521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 525ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org if (instISAC->in_sample_rate_hz == 48000) { 526ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org /* Samples in 10 ms @ 48 kHz. */ 527ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org const int kNumInputSamples = FRAMESAMPLES_10ms * 3; 528ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org /* Samples 10 ms @ 32 kHz. */ 529ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org const int kNumOutputSamples = FRAMESAMPLES_10ms * 2; 530ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org /* Resampler divide the input into blocks of 3 samples, i.e. 531ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * kNumInputSamples / 3. */ 532ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org const int kNumResamplerBlocks = FRAMESAMPLES_10ms; 533ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org int32_t buffer32[FRAMESAMPLES_10ms * 3 + SIZE_RESAMPLER_STATE]; 534ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org 535ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org /* Restore last samples from the past to the beginning of the buffer 536ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * and store the last samples of current frame for the next resampling. */ 537ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org for (k = 0; k < SIZE_RESAMPLER_STATE; k++) { 538ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org buffer32[k] = instISAC->state_in_resampler[k]; 539ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org instISAC->state_in_resampler[k] = speechIn[kNumInputSamples - 540ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org SIZE_RESAMPLER_STATE + k]; 541ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org } 542ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org for (k = 0; k < kNumInputSamples; k++) { 543ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org buffer32[SIZE_RESAMPLER_STATE + k] = speechIn[k]; 544ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org } 545ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org /* Resampling 3 samples to 2. Function divides the input in 546ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * |kNumResamplerBlocks| number of 3-sample groups, and output is 547ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * |kNumResamplerBlocks| number of 2-sample groups. */ 548ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org WebRtcSpl_Resample48khzTo32khz(buffer32, buffer32, kNumResamplerBlocks); 549ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org WebRtcSpl_VectorBitShiftW32ToW16(resampled_buff, kNumOutputSamples, 550ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org buffer32, 15); 551ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org speech_in_ptr = resampled_buff; 552ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org } 553ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org 554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { 555e95dc25b14845cbf00ae363e88459c44e2341c47andrew@webrtc.org WebRtcSpl_AnalysisQMF(speech_in_ptr, SWBFRAMESAMPLES_10ms, speechInLB, 556e95dc25b14845cbf00ae363e88459c44e2341c47andrew@webrtc.org speechInUB, instISAC->analysisFBState1, 557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->analysisFBState2); 558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Convert from fixed to floating point. */ 560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES_10ms; k++) { 561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[k] = (float)speechInLB[k]; 562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES_10ms; k++) { 565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[k] = (float) speechIn[k]; 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Add some noise to avoid denormal numbers. */ 570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[0] += (float)1.23455334e-3; 571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[1] -= (float)2.04324239e-3; 572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[2] += (float)1.90854954e-3; 573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[9] += (float)1.84854878e-3; 574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This function will update the bottleneck if required. */ 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateBottleneck(instISAC); 577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Get the bandwith information which has to be sent to the other side. */ 579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GetSendBandwidthInfo(instISAC, &bottleneckIdx, &jitterInfo); 580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode lower-band. */ 582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenLB = WebRtcIsac_EncodeLb(inFrame, &instLB->ISACencLB_obj, 583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->codingMode, bottleneckIdx); 584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (streamLenLB < 0) { 585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instUB = &(instISAC->instUB); 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Convert to float. */ 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < FRAMESAMPLES_10ms; k++) { 593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[k] = (float) speechInUB[k]; 594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Add some noise to avoid denormal numbers. */ 597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[0] += (float)1.23455334e-3; 598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[1] -= (float)2.04324239e-3; 599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[2] += (float)1.90854954e-3; 600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org inFrame[9] += (float)1.84854878e-3; 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Tell to upper-band the number of bytes used so far. 603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This is for payload limitation. */ 604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instUB->ISACencUB_obj.numBytesUsed = streamLenLB + 1 + 605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LEN_CHECK_SUM_WORD8; 606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Encode upper-band. */ 607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (instISAC->bandwidthKHz) { 608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac12kHz: { 609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB = WebRtcIsac_EncodeUb12(inFrame, &instUB->ISACencUB_obj, 610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org jitterInfo); 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac16kHz: { 614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB = WebRtcIsac_EncodeUb16(inFrame, &instUB->ISACencUB_obj, 615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org jitterInfo); 616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac8kHz: { 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB = 0; 620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((streamLenUB < 0) && (streamLenUB != -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) { 625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* An error has happened but this is not the error due to a 626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bit-stream larger than the limit. */ 627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (streamLenLB == 0) { 631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* One byte is allocated for the length. According to older decoders 635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org so the length bit-stream plus one byte for size and 636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LEN_CHECK_SUM_WORD8 for the checksum should be less than or equal 637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org to 255. */ 638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((streamLenUB > (255 - (LEN_CHECK_SUM_WORD8 + 1))) || 639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (streamLenUB == -ISAC_PAYLOAD_LARGER_THAN_LIMIT)) { 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* We have got a too long bit-stream we skip the upper-band 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bit-stream for this frame. */ 642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB = 0; 643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 64583a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org memcpy(encoded, instLB->ISACencLB_obj.bitstr_obj.stream, streamLenLB); 646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLen = streamLenLB; 647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (streamLenUB > 0) { 64883a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org encoded[streamLenLB] = streamLenUB + 1 + LEN_CHECK_SUM_WORD8; 64983a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org memcpy(&encoded[streamLenLB + 1], 65083a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org instUB->ISACencUB_obj.bitstr_obj.stream, 65183a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org streamLenUB); 65283a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org streamLen += encoded[streamLenLB]; 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 65483a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org encoded[streamLenLB] = 0; 655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (streamLenLB == 0) { 658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 66083a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org memcpy(encoded, instLB->ISACencLB_obj.bitstr_obj.stream, streamLenLB); 661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB = 0; 662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLen = streamLenLB; 663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Add Garbage if required. */ 666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetUplinkBandwidth(&instISAC->bwestimator_obj, &bottleneck); 667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->codingMode == 0) { 668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int minBytes; 669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int limit; 670fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint8_t* ptrGarbage; 671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->MaxDelay = (double)WebRtcIsac_GetUplinkMaxDelay( 673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &instISAC->bwestimator_obj); 674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Update rate model and get minimum number of bytes in this packet. */ 676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org minBytes = WebRtcIsac_GetMinBytes( 677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &(instISAC->rate_data_obj), streamLen, 678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck, 679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->MaxDelay, instISAC->bandwidthKHz); 680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Make sure MinBytes does not exceed packet size limit. */ 682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->bandwidthKHz == isac8kHz) { 683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instLB->ISACencLB_obj.current_framesamples == FRAMESAMPLES) { 684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org limit = instLB->ISACencLB_obj.payloadLimitBytes30; 685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org limit = instLB->ISACencLB_obj.payloadLimitBytes60; 687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org limit = instUB->ISACencUB_obj.maxPayloadSizeBytes; 690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org minBytes = (minBytes > limit) ? limit : minBytes; 692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Make sure we don't allow more than 255 bytes of garbage data. 694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * We store the length of the garbage data in 8 bits in the bitstream, 695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 255 is the max garbage length we can signal using 8 bits. */ 696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->bandwidthKHz == isac8kHz) || 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (streamLenUB == 0)) { 69883a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org ptrGarbage = &encoded[streamLenLB]; 699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org limit = streamLen + 255; 700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 70183a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org ptrGarbage = &encoded[streamLenLB + 1 + streamLenUB]; 70283a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org limit = streamLen + (255 - encoded[streamLenLB]); 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org minBytes = (minBytes > limit) ? limit : minBytes; 705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org garbageLen = (minBytes > streamLen) ? (minBytes - streamLen) : 0; 707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Save data for creation of multiple bit-streams. */ 709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If bit-stream too short then add garbage at the end. */ 710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (garbageLen > 0) { 711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < garbageLen; k++) { 712fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org ptrGarbage[k] = (uint8_t)(rand() & 0xFF); 713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* For a correct length of the upper-band bit-stream together 715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * with the garbage. Garbage is embeded in upper-band bit-stream. 716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * That is the only way to preserve backward compatibility. */ 717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->bandwidthKHz == isac8kHz) || 718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (streamLenUB == 0)) { 71983a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org encoded[streamLenLB] = garbageLen; 720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 72183a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org encoded[streamLenLB] += garbageLen; 722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Write the length of the garbage at the end of the upper-band 723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bit-stream, if exists. This helps for sanity check. */ 72483a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org encoded[streamLenLB + 1 + streamLenUB] = garbageLen; 725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLen += garbageLen; 728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* update rate model */ 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_UpdateRateModel( 732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &instISAC->rate_data_obj, streamLen, 733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.current_framesamples, bottleneck); 734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org garbageLen = 0; 735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Generate CRC if required. */ 738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->bandwidthKHz != isac8kHz) && (streamLenUB > 0)) { 739fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t crc; 740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 74183a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org WebRtcIsac_GetCrc((int16_t*)(&(encoded[streamLenLB + 1])), 742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB + garbageLen, &crc); 743d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { 74583a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org encoded[streamLen - LEN_CHECK_SUM_WORD8 + k] = crc >> (24 - k * 8); 746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else 74883a60f3561a5a6d75f0044cf3161424d511f4066kwiberg@webrtc.org memcpy(&encoded[streamLenLB + streamLenUB + 1], &crc, LEN_CHECK_SUM_WORD8); 749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return streamLen; 752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/****************************************************************************** 756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_GetNewBitStream(...) 757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function returns encoded data, with the recieved bwe-index in the 759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * stream. If the rate is set to a value less than bottleneck of codec 760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the new bistream will be re-encoded with the given target rate. 761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * It should always return a complete packet, i.e. only called once 762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * even for 60 msec frames. 763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * NOTE 1! This function does not write in the ISACStruct, it is not allowed. 765ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * NOTE 2! Rates larger than the bottleneck of the codec will be limited 766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * to the current bottleneck. 767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance. 770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - bweIndex : Index of bandwidth estimate to put in new 771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bitstream 772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - rate : target rate of the transcoder is bits/sec. 773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Valid values are the accepted rate in iSAC, 774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * i.e. 10000 to 56000. 775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - encoded : The encoded data vector 778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : >0 - Length (in bytes) of coded data 780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error or called in SWB mode 781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * NOTE! No error code is written to 782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the struct since it is only allowed to read 783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the struct. 784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 785fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_GetNewBitStream(ISACStruct* ISAC_main_inst, 786fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t bweIndex, 787fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t jitterInfo, 788fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t rate, 789fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* encoded, 790fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t isRCU) { 791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr iSACBitStreamInst; /* Local struct for bitstream handling */ 792fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t streamLenLB; 793fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t streamLenUB; 794fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t totalStreamLen; 795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double gain2; 796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double gain1; 797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float scale; 798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBandwidth bandwidthKHz; 799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rateLB; 800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rateUB; 801fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t currentBN; 802fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint8_t* encodedPtrUW8 = (uint8_t*)encoded; 803fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t crc; 804d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 805fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t k; 806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BIT_MASK_ENC_INIT) { 811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Get the bottleneck of this iSAC and limit the 815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * given rate to the current bottleneck. */ 816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetUplinkBw(ISAC_main_inst, ¤tBN); 817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (rate > currentBN) { 818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rate = currentBN; 819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsac_RateAllocation(rate, &rateLB, &rateUB, &bandwidthKHz) < 0) { 822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Cannot transcode from 16 kHz to 12 kHz. */ 826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((bandwidthKHz == isac12kHz) && 827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->bandwidthKHz == isac16kHz)) { 828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* A gain [dB] for the given rate. */ 832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gain1 = WebRtcIsac_GetSnr( 833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rateLB, instISAC->instLB.ISACencLB_obj.current_framesamples); 834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The gain [dB] of this iSAC. */ 835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gain2 = WebRtcIsac_GetSnr( 836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.bottleneck, 837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.current_framesamples); 838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale is the ratio of two gains in normal domain. */ 840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org scale = (float)pow(10, (gain1 - gain2) / 20.0); 841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Change the scale if this is a RCU bit-stream. */ 842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org scale = (isRCU) ? (scale * RCU_TRANSCODING_SCALE) : scale; 843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenLB = WebRtcIsac_EncodeStoredDataLb( 845b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, 846b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &iSACBitStreamInst, bweIndex, scale); 847b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (streamLenLB < 0) { 849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 852fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org /* Convert from bytes to int16_t. */ 853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(encoded, iSACBitStreamInst.stream, streamLenLB); 854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidthKHz == isac8kHz) { 856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return streamLenLB; 857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org totalStreamLen = streamLenLB; 860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* super-wideband is always at 30ms. 861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * These gains are in dB. 862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Gain for the given rate. */ 863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gain1 = WebRtcIsac_GetSnr(rateUB, FRAMESAMPLES); 864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Gain of this iSAC */ 865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org gain2 = WebRtcIsac_GetSnr(instISAC->instUB.ISACencUB_obj.bottleneck, 866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FRAMESAMPLES); 867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Scale is the ratio of two gains in normal domain. */ 869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org scale = (float)pow(10, (gain1 - gain2) / 20.0); 870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Change the scale if this is a RCU bit-stream. */ 872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org scale = (isRCU)? (scale * RCU_TRANSCODING_SCALE_UB) : scale; 873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB = WebRtcIsac_EncodeStoredDataUb( 875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &(instISAC->instUB.ISACencUB_obj.SaveEnc_obj), 876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &iSACBitStreamInst, jitterInfo, scale, 877b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz); 878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (streamLenUB < 0) { 880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (streamLenUB + 1 + LEN_CHECK_SUM_WORD8 > 255) { 884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return streamLenLB; 885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org totalStreamLen = streamLenLB + streamLenUB + 1 + LEN_CHECK_SUM_WORD8; 888b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encodedPtrUW8[streamLenLB] = streamLenUB + 1 + LEN_CHECK_SUM_WORD8; 889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&encodedPtrUW8[streamLenLB + 1], iSACBitStreamInst.stream, 891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB); 892b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 893fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org WebRtcIsac_GetCrc((int16_t*)(&(encodedPtrUW8[streamLenLB + 1])), 894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB, &crc); 895d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { 897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encodedPtrUW8[totalStreamLen - LEN_CHECK_SUM_WORD8 + k] = 898fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org (uint8_t)((crc >> (24 - k * 8)) & 0xFF); 899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else 901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&encodedPtrUW8[streamLenLB + streamLenUB + 1], &crc, 902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LEN_CHECK_SUM_WORD8); 903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return totalStreamLen; 905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * DecoderInitLb(...) - internal function for initialization of 910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Lower Band 911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * DecoderInitUb(...) - internal function for initialization of 912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Upper Band 913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_DecoderInit(...) - API function 914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function initializes a ISAC instance prior to the decoder calls. 916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance. 919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value 921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * : 0 - Ok 922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 924fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic int16_t DecoderInitLb(ISACLBStruct* instISAC) { 925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int i; 926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Initialize stream vector to zero. */ 927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (i = 0; i < STREAM_SIZE_MAX_60; i++) { 928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->ISACdecLB_obj.bitstr_obj.stream[i] = 0; 929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitMasking(&instISAC->ISACdecLB_obj.maskfiltstr_obj); 932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitPostFilterbank( 933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &instISAC->ISACdecLB_obj.postfiltbankstr_obj); 934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitPitchFilter(&instISAC->ISACdecLB_obj.pitchfiltstr_obj); 935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 938fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic int16_t DecoderInitUb(ISACUBStruct* instISAC) { 939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int i; 940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Init stream vector to zero */ 941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (i = 0; i < STREAM_SIZE_MAX_60; i++) { 942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->ISACdecUB_obj.bitstr_obj.stream[i] = 0; 943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitMasking(&instISAC->ISACdecUB_obj.maskfiltstr_obj); 946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitPostFilterbank( 947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &instISAC->ISACdecUB_obj.postfiltbankstr_obj); 948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (0); 949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 951fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_DecoderInit(ISACStruct* ISAC_main_inst) { 952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (DecoderInitLb(&instISAC->instLB) < 0) { 955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->decoderSamplingRateKHz == kIsacSuperWideband) { 958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(instISAC->synthesisFBState1, 0, 959fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org FB_STATE_SIZE_WORD32 * sizeof(int32_t)); 960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(instISAC->synthesisFBState2, 0, 961fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org FB_STATE_SIZE_WORD32 * sizeof(int32_t)); 962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (DecoderInitUb(&(instISAC->instUB)) < 0) { 964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != BIT_MASK_ENC_INIT) { 968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_InitBandwidthEstimator(&instISAC->bwestimator_obj, 969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->encoderSamplingRateKHz, 970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->decoderSamplingRateKHz); 971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->initFlag |= BIT_MASK_DEC_INIT; 973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->resetFlag_8kHz = 0; 974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 976b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_UpdateBwEstimate(...) 980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function updates the estimate of the bandwidth. 982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 983ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * NOTE: 984ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * The estimates of bandwidth is not valid if the sample rate of the far-end 985ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * encoder is set to 48 kHz and send timestamps are increamented according to 986ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * 48 kHz sampling rate. 987ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * 988b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance. 990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - encoded : encoded ISAC frame(s). 991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - packet_size : size of the packet. 992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - rtp_seq_number : the RTP number of the packet. 993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - arr_ts : the arrival time of the packet (from NetEq) 994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in samples. 995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 - Ok 997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 999fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_UpdateBwEstimate(ISACStruct* ISAC_main_inst, 1000fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t* encoded, 1001fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t packet_size, 1002fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t rtp_seq_number, 1003fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t send_ts, 1004fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t arr_ts) { 1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr streamdata; 1007d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 1010fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t err; 1011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check if decoder initiated. */ 1013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_DEC_INIT) != BIT_MASK_DEC_INIT) { 1014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_DECODER_NOT_INITIATED; 1015b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1018f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org /* Check that the size of the packet is valid, and if not return without 1019f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org * updating the bandwidth estimate. A valid size is at least 10 bytes. */ 1020f6e0404878530323f642d00b758b4d6105969c93turaj@webrtc.org if (packet_size < 10) { 1021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Return error code if the packet length is null. */ 1022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_EMPTY_PACKET; 1023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ResetBitstream(&(streamdata)); 1027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1028d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 1029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < 10; k++) { 1030fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org streamdata.stream[k] = (uint8_t)((encoded[k >> 1] >> 1031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ((k & 1) << 3)) & 0xFF); 1032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else 1034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(streamdata.stream, encoded, 10); 1035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 1036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_EstimateBandwidth(&instISAC->bwestimator_obj, &streamdata, 1038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org packet_size, rtp_seq_number, send_ts, 1039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org arr_ts, instISAC->encoderSamplingRateKHz, 1040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->decoderSamplingRateKHz); 1041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Return error code if something went wrong. */ 1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = -err; 1044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1049fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic int16_t Decode(ISACStruct* ISAC_main_inst, 1050fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t* encoded, 1051fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t lenEncodedBytes, 1052fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* decoded, 1053fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* speechType, 1054fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t isRCUPayload) { 1055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Number of samples (480 or 960), output from decoder 1056b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org that were actually used in the encoder/decoder 1057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (determined on the fly). */ 1058fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t numSamplesLB; 1059fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t numSamplesUB; 1060fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t speechIdx; 1061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float outFrame[MAX_FRAMESAMPLES]; 1062fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t outFrameLB[MAX_FRAMESAMPLES]; 1063fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t outFrameUB[MAX_FRAMESAMPLES]; 1064fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t numDecodedBytesLB; 1065fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t numDecodedBytesUB; 1066fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t lenEncodedLBBytes; 1067fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t validChecksum = 1; 1068fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t k; 1069fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint8_t* ptrEncodedUW8 = (uint8_t*)encoded; 1070fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t numLayer; 1071fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t totSizeBytes; 1072fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t err; 1073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1075b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACUBDecStruct* decInstUB = &(instISAC->instUB.ISACdecUB_obj); 1076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACLBDecStruct* decInstLB = &(instISAC->instLB.ISACdecLB_obj); 1077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1078b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check if decoder initiated. */ 1079b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_DEC_INIT) != 1080b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BIT_MASK_DEC_INIT) { 1081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_DECODER_NOT_INITIATED; 1082b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1085b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (lenEncodedBytes <= 0) { 1086b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* return error code if the packet length is null. */ 1087b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_EMPTY_PACKET; 1088b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1089b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1090b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1091b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The size of the encoded lower-band is bounded by 1092b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * STREAM_SIZE_MAX. If a payload with the size larger than STREAM_SIZE_MAX 1093b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * is received, it is not considered erroneous. */ 1094b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lenEncodedLBBytes = (lenEncodedBytes > STREAM_SIZE_MAX) ? 1095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org STREAM_SIZE_MAX : lenEncodedBytes; 1096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1097b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Copy to lower-band bit-stream structure. */ 1098b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(instISAC->instLB.ISACdecLB_obj.bitstr_obj.stream, ptrEncodedUW8, 1099b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lenEncodedLBBytes); 1100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Regardless of that the current codec is setup to work in 1102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * wideband or super-wideband, the decoding of the lower-band 1103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * has to be performed. */ 1104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numDecodedBytesLB = WebRtcIsac_DecodeLb(outFrame, decInstLB, 1105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &numSamplesLB, isRCUPayload); 1106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((numDecodedBytesLB < 0) || (numDecodedBytesLB > lenEncodedLBBytes) || 1108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (numSamplesLB > MAX_FRAMESAMPLES)) { 1109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_LENGTH_MISMATCH; 1110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Error Check, we accept multi-layer bit-stream This will limit number 1114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * of iterations of the while loop. Even without this the number 1115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * of iterations is limited. */ 1116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numLayer = 1; 1117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org totSizeBytes = numDecodedBytesLB; 1118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (totSizeBytes != lenEncodedBytes) { 1119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((totSizeBytes > lenEncodedBytes) || 1120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (ptrEncodedUW8[totSizeBytes] == 0) || 1121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (numLayer > MAX_NUM_LAYERS)) { 1122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_LENGTH_MISMATCH; 1123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org totSizeBytes += ptrEncodedUW8[totSizeBytes]; 1126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numLayer++; 1127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->decoderSamplingRateKHz == kIsacWideband) { 1130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < numSamplesLB; k++) { 1131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (outFrame[k] > 32767) { 1132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org decoded[k] = 32767; 1133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (outFrame[k] < -32768) { 1134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org decoded[k] = -32768; 1135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1136fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org decoded[k] = (int16_t)WebRtcIsac_lrint(outFrame[k]); 1137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numSamplesUB = 0; 1140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1141fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t crc; 1142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* We don't accept larger than 30ms (480 samples at lower-band) 1143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * frame-size. */ 1144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < numSamplesLB; k++) { 1145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (outFrame[k] > 32767) { 1146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outFrameLB[k] = 32767; 1147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (outFrame[k] < -32768) { 1148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outFrameLB[k] = -32768; 1149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1150fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org outFrameLB[k] = (int16_t)WebRtcIsac_lrint(outFrame[k]); 1151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check for possible error, and if upper-band stream exists. */ 1155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (numDecodedBytesLB == lenEncodedBytes) { 1156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Decoding was successful. No super-wideband bit-stream exists. */ 1157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numSamplesUB = numSamplesLB; 1158fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org memset(outFrameUB, 0, sizeof(int16_t) * numSamplesUB); 1159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Prepare for the potential increase of signal bandwidth. */ 1161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->resetFlag_8kHz = 2; 1162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This includes the checksum and the bytes that stores the length. */ 1164fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t lenNextStream = ptrEncodedUW8[numDecodedBytesLB]; 1165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Is this garbage or valid super-wideband bit-stream? 1167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Check if checksum is valid. */ 1168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (lenNextStream <= (LEN_CHECK_SUM_WORD8 + 1)) { 1169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Such a small second layer cannot be super-wideband layer. 1170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * It must be a short garbage. */ 1171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org validChecksum = 0; 1172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Run CRC to see if the checksum match. */ 1174fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org WebRtcIsac_GetCrc((int16_t*)( 1175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ptrEncodedUW8[numDecodedBytesLB + 1]), 1176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lenNextStream - LEN_CHECK_SUM_WORD8 - 1, &crc); 1177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org validChecksum = 1; 1179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { 1180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org validChecksum &= (((crc >> (24 - k * 8)) & 0xFF) == 1181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptrEncodedUW8[numDecodedBytesLB + lenNextStream - 1182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LEN_CHECK_SUM_WORD8 + k]); 1183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!validChecksum) { 1187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* This is a garbage, we have received a wideband 1188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bit-stream with garbage. */ 1189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numSamplesUB = numSamplesLB; 1190fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org memset(outFrameUB, 0, sizeof(int16_t) * numSamplesUB); 1191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* A valid super-wideband biststream exists. */ 1193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBandwidth bandwidthKHz; 1194fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t maxDelayBit; 1195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If we have super-wideband bit-stream, we cannot 1197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * have 60 ms frame-size. */ 1198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (numSamplesLB > FRAMESAMPLES) { 1199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_LENGTH_MISMATCH; 1200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The rest of the bit-stream contains the upper-band 1204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bit-stream curently this is the only thing there, 1205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * however, we might add more layers. */ 1206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Have to exclude one byte where the length is stored 1208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * and last 'LEN_CHECK_SUM_WORD8' bytes where the 1209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * checksum is stored. */ 1210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org lenNextStream -= (LEN_CHECK_SUM_WORD8 + 1); 1211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(decInstUB->bitstr_obj.stream, 1213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &ptrEncodedUW8[numDecodedBytesLB + 1], lenNextStream); 1214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Reset bit-stream object, this is the first decoding. */ 1216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ResetBitstream(&(decInstUB->bitstr_obj)); 1217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Decode jitter information. */ 1219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecodeJitterInfo(&decInstUB->bitstr_obj, &maxDelayBit); 1220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = -err; 1222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Update jitter info which is in the upper-band bit-stream 1226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * only if the encoder is in super-wideband. Otherwise, 1227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the jitter info is already embedded in bandwidth index 1228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * and has been updated. */ 1229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { 1230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_UpdateUplinkJitter( 1231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &(instISAC->bwestimator_obj), maxDelayBit); 1232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = -err; 1234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Decode bandwidth information. */ 1239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecodeBandwidth(&decInstUB->bitstr_obj, 1240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &bandwidthKHz); 1241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = -err; 1243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (bandwidthKHz) { 1247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac12kHz: { 1248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numDecodedBytesUB = WebRtcIsac_DecodeUb12(outFrame, decInstUB, 1249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org isRCUPayload); 1250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Hang-over for transient alleviation - 1252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * wait two frames to add the upper band going up from 8 kHz. */ 1253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->resetFlag_8kHz > 0) { 1254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->resetFlag_8kHz == 2) { 1255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Silence first and a half frame. */ 1256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(outFrame, 0, MAX_FRAMESAMPLES * 1257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(float)); 1258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const float rampStep = 2.0f / MAX_FRAMESAMPLES; 1260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float rampVal = 0; 1261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(outFrame, 0, (MAX_FRAMESAMPLES >> 1) * 1262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(float)); 1263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Ramp up second half of second frame. */ 1265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = MAX_FRAMESAMPLES / 2; k < MAX_FRAMESAMPLES; k++) { 1266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outFrame[k] *= rampVal; 1267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rampVal += rampStep; 1268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->resetFlag_8kHz -= 1; 1271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case isac16kHz: { 1276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numDecodedBytesUB = WebRtcIsac_DecodeUb16(outFrame, decInstUB, 1277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org isRCUPayload); 1278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default: 1281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* It might be less due to garbage. */ 1285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((numDecodedBytesUB != lenNextStream) && 1286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (numDecodedBytesUB != (lenNextStream - 1287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptrEncodedUW8[numDecodedBytesLB + 1 + numDecodedBytesUB]))) { 1288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_LENGTH_MISMATCH; 1289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If there is no error Upper-band always decodes 1293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 30 ms (480 samples). */ 1294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numSamplesUB = FRAMESAMPLES; 1295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Convert to W16. */ 1297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < numSamplesUB; k++) { 1298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (outFrame[k] > 32767) { 1299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outFrameUB[k] = 32767; 1300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (outFrame[k] < -32768) { 1301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outFrameUB[k] = -32768; 1302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1303fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org outFrameUB[k] = (int16_t)WebRtcIsac_lrint( 1304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org outFrame[k]); 1305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org speechIdx = 0; 1311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (speechIdx < numSamplesLB) { 1312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcSpl_SynthesisQMF(&outFrameLB[speechIdx], &outFrameUB[speechIdx], 1313e95dc25b14845cbf00ae363e88459c44e2341c47andrew@webrtc.org FRAMESAMPLES_10ms, &decoded[(speechIdx << 1)], 1314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->synthesisFBState1, 1315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->synthesisFBState2); 1316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org speechIdx += FRAMESAMPLES_10ms; 1318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *speechType = 0; 1321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (numSamplesLB + numSamplesUB); 1322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_Decode(...) 1332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function decodes a ISAC frame. Output speech length 1334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * will be a multiple of 480 samples: 480 or 960 samples, 1335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * depending on the frameSize (30 or 60 ms). 1336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance. 1339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - encoded : encoded ISAC frame(s) 1340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - len : bytes in encoded vector 1341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 1343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - decoded : The decoded vector 1344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : >0 - number of samples in decoded vector 1346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 1347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1349fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_Decode(ISACStruct* ISAC_main_inst, 1350fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t* encoded, 1351fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t lenEncodedBytes, 1352fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* decoded, 1353fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* speechType) { 1354fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t isRCUPayload = 0; 1355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded, 1356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org speechType, isRCUPayload); 1357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_DecodeRcu(...) 1361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function decodes a redundant (RCU) iSAC frame. Function is called in 1363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * NetEq with a stored RCU payload in case of packet loss. Output speech length 1364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * will be a multiple of 480 samples: 480 or 960 samples, 1365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * depending on the framesize (30 or 60 ms). 1366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance. 1369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - encoded : encoded ISAC RCU frame(s) 1370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - len : bytes in encoded vector 1371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 1373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - decoded : The decoded vector 1374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : >0 - number of samples in decoded vector 1376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 1377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1381fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_DecodeRcu(ISACStruct* ISAC_main_inst, 1382fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const uint16_t* encoded, 1383fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t lenEncodedBytes, 1384fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* decoded, 1385fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* speechType) { 1386fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t isRCUPayload = 1; 1387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return Decode(ISAC_main_inst, encoded, lenEncodedBytes, decoded, 1388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org speechType, isRCUPayload); 1389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_DecodePlc(...) 1394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function conducts PLC for ISAC frame(s). Output speech length 1396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * will be a multiple of 480 samples: 480 or 960 samples, 1397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * depending on the frameSize (30 or 60 ms). 1398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance. 1401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - noOfLostFrames : Number of PLC frames to produce 1402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 1404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - decoded : The decoded vector 1405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : >0 - number of samples in decoded PLC vector 1407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 1408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1409fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_DecodePlc(ISACStruct* ISAC_main_inst, 1410fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* decoded, 1411fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t noOfLostFrames) { 1412fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t numSamples = 0; 1413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Limit number of frames to two = 60 millisecond. 1416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Otherwise we exceed data vectors. */ 1417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (noOfLostFrames > 2) { 1418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org noOfLostFrames = 2; 1419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Get the number of samples per frame */ 1422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (instISAC->decoderSamplingRateKHz) { 1423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kIsacWideband: { 1424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numSamples = 480 * noOfLostFrames; 1425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case kIsacSuperWideband: { 1428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org numSamples = 960 * noOfLostFrames; 1429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 1430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Set output samples to zero. */ 1434fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org memset(decoded, 0, numSamples * sizeof(int16_t)); 1435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return numSamples; 1436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * ControlLb(...) - Internal function for controlling Lower Band 1441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * ControlUb(...) - Internal function for controlling Upper Band 1442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_Control(...) - API function 1443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function sets the limit on the short-term average bit rate and the 1445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * frame length. Should be used only in Instantaneous mode. 1446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance. 1449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - rate : limit on the short-term average bit rate, 1450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in bits/second (between 10000 and 32000) 1451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - frameSize : number of milliseconds per frame (30 or 60) 1452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 - ok 1454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 1455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1456fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic int16_t ControlLb(ISACLBStruct* instISAC, double rate, 1457fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t frameSize) { 1458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((rate >= 10000) && (rate <= 32000)) { 1459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->ISACencLB_obj.bottleneck = rate; 1460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_DISALLOWED_BOTTLENECK; 1462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((frameSize == 30) || (frameSize == 60)) { 1465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->ISACencLB_obj.new_framelength = (FS / 1000) * frameSize; 1466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_DISALLOWED_FRAME_LENGTH; 1468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1473fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgstatic int16_t ControlUb(ISACUBStruct* instISAC, double rate) { 1474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((rate >= 10000) && (rate <= 32000)) { 1475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->ISACencUB_obj.bottleneck = rate; 1476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -ISAC_DISALLOWED_BOTTLENECK; 1478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1482fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_Control(ISACStruct* ISAC_main_inst, 1483fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t bottleneckBPS, 1484fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t frameSize) { 1485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1486fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t status; 1487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rateLB; 1488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rateUB; 1489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBandwidth bandwidthKHz; 1490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->codingMode == 0) { 1492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* In adaptive mode. */ 1493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_MODE_MISMATCH; 1494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check if encoder initiated */ 1498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 1499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BIT_MASK_ENC_INIT) { 1500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->encoderSamplingRateKHz == kIsacWideband) { 1505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* If the sampling rate is 16kHz then bandwith should be 8kHz, 1506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * regardless of bottleneck. */ 1507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bandwidthKHz = isac8kHz; 1508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rateLB = (bottleneckBPS > 32000) ? 32000 : bottleneckBPS; 1509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rateUB = 0; 1510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, 1512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &bandwidthKHz) < 0) { 1513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->encoderSamplingRateKHz == kIsacSuperWideband) && 1518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (frameSize != 30) && 1519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (bandwidthKHz != isac8kHz)) { 1520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Cannot have 60 ms in super-wideband. */ 1521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH; 1522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = ControlLb(&instISAC->instLB, rateLB, frameSize); 1526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = -status; 1528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidthKHz != isac8kHz) { 1531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = ControlUb(&(instISAC->instUB), rateUB); 1532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (status < 0) { 1533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = -status; 1534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check if bandwidth is changing from wideband to super-wideband 1540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * then we have to synch data buffer of lower & upper-band. Also 1541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * clean up the upper-band data buffer. */ 1542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->bandwidthKHz == isac8kHz) && (bandwidthKHz != isac8kHz)) { 1544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(instISAC->instUB.ISACencUB_obj.data_buffer_float, 0, 1545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(float) * (MAX_FRAMESAMPLES + LB_TOTAL_DELAY_SAMPLES)); 1546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bandwidthKHz == isac12kHz) { 1548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instUB.ISACencUB_obj.buffer_index = 1549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.buffer_index; 1550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instUB.ISACencUB_obj.buffer_index = 1552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LB_TOTAL_DELAY_SAMPLES + instISAC->instLB.ISACencLB_obj.buffer_index; 1553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&(instISAC->instUB.ISACencUB_obj.lastLPCVec), 1555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_kMeanLarUb16, sizeof(double) * UB_LPC_ORDER); 1556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Update the payload limit if the bandwidth is changing. */ 1560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->bandwidthKHz != bandwidthKHz) { 1561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = bandwidthKHz; 1562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdatePayloadSizeLimit(instISAC); 1563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bottleneck = bottleneckBPS; 1565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_ControlBwe(...) 1571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function sets the initial values of bottleneck and frame-size if 1573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * iSAC is used in channel-adaptive mode. Through this API, users can 1574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * enforce a frame-size for all values of bottleneck. Then iSAC will not 1575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * automatically change the frame-size. 1576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance. 1580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - rateBPS : initial value of bottleneck in bits/second 1581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 10000 <= rateBPS <= 32000 is accepted 1582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * For default bottleneck set rateBPS = 0 1583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - frameSizeMs : number of milliseconds per frame (30 or 60) 1584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - enforceFrameSize : 1 to enforce the given frame-size through out 1585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the adaptation process, 0 to let iSAC change 1586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the frame-size if required. 1587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 - ok 1589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - Error 1590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1591fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_ControlBwe(ISACStruct* ISAC_main_inst, 1592fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t bottleneckBPS, 1593fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t frameSizeMs, 1594fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t enforceFrameSize) { 1595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org enum ISACBandwidth bandwidth; 1597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check if encoder initiated */ 1599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 1600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BIT_MASK_ENC_INIT) { 1601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check that we are in channel-adaptive mode, otherwise, return (-1) */ 1606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->codingMode != 0) { 1607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_MODE_MISMATCH; 1608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((frameSizeMs != 30) && 1611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) { 1612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Set structure variable if enforceFrameSize is set. ISAC will then 1616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * keep the chosen frame size. */ 1617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (enforceFrameSize != 0) { 1618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.enforceFrameSize = 1; 1619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.enforceFrameSize = 0; 1621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Set the initial rate. If the input value is zero then the default intial 1624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * rate is used. Otehrwise, values between 10 to 32 kbps are accepted. */ 1625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (bottleneckBPS != 0) { 1626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rateLB; 1627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org double rateUB; 1628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (WebRtcIsac_RateAllocation(bottleneckBPS, &rateLB, &rateUB, 1629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &bandwidth) < 0) { 1630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bwestimator_obj.send_bw_avg = (float)bottleneckBPS; 1633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = bandwidth; 1634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Set the initial frame-size. If 'enforceFrameSize' is set, the frame-size 1637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * will not change */ 1638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (frameSizeMs != 0) { 1639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((frameSizeMs == 30) || (frameSizeMs == 60)) { 1640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.new_framelength = (FS / 1000) * 1641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org frameSizeMs; 1642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_DISALLOWED_FRAME_LENGTH; 1644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_GetDownLinkBwIndex(...) 1653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function returns index representing the Bandwidth estimate from 1655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the other side to this side. 1656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC structure 1659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 1661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - bweIndex : Bandwidth estimate to transmit to other side. 1662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1664fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_GetDownLinkBwIndex(ISACStruct* ISAC_main_inst, 1665fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* bweIndex, 1666fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* jitterInfo) { 1667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check if encoder initialized. */ 1670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_DEC_INIT) != 1671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BIT_MASK_DEC_INIT) { 1672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Call function to get Bandwidth Estimate. */ 1677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_GetDownlinkBwJitIndexImpl(&(instISAC->bwestimator_obj), bweIndex, 1678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org jitterInfo, 1679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->decoderSamplingRateKHz); 1680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_UpdateUplinkBw(...) 1686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function takes an index representing the Bandwidth estimate from 1688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * this side to other side and updates BWE. 1689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC structure 1692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - rateIndex : Bandwidth estimate from other side. 1693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 - ok 1695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 - index out of range 1696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1697fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_UpdateUplinkBw(ISACStruct* ISAC_main_inst, 1698fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t bweIndex) { 1699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1700fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t returnVal; 1701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check if encoder initiated. */ 1703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 1704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BIT_MASK_ENC_INIT) { 1705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Call function to get Bandwidth Estimate. */ 1710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org returnVal = WebRtcIsac_UpdateUplinkBwImpl( 1711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &(instISAC->bwestimator_obj), bweIndex, 1712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->encoderSamplingRateKHz); 1713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (returnVal < 0) { 1715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = -returnVal; 1716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_ReadBwIndex(...) 1725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function returns the index of the Bandwidth estimate from the 1727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bit-stream. 1728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - encoded : Encoded bit-stream 1731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 1733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - frameLength : Length of frame in packet (in samples) 1734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - bweIndex : Bandwidth estimate in bit-stream 1735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1737fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_ReadBwIndex(const int16_t* encoded, 1738fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* bweIndex) { 1739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr streamdata; 1740d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 1741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 1742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 1743fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t err; 1744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ResetBitstream(&(streamdata)); 1746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1747d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 1748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < 10; k++) { 1749fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org streamdata.stream[k] = (uint8_t)((encoded[k >> 1] >> 1750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ((k & 1) << 3)) & 0xFF); 1751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else 1753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(streamdata.stream, encoded, 10); 1754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 1755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Decode frame length. */ 1757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecodeFrameLen(&streamdata, bweIndex); 1758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Decode BW estimation. */ 1763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecodeSendBW(&streamdata, bweIndex); 1764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return err; 1766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_ReadFrameLen(...) 1774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1775ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * This function returns the number of samples the decoder will generate if 1776ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * the given payload is decoded. 1777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - encoded : Encoded bitstream 1780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 1782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - frameLength : Length of frame in packet (in samples) 1783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1785fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_ReadFrameLen(ISACStruct* ISAC_main_inst, 1786fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org const int16_t* encoded, 1787fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* frameLength) { 1788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr streamdata; 1789d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 1790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 1791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 1792fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t err; 1793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC; 1794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ResetBitstream(&(streamdata)); 1796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1797d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 1798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < 10; k++) { 1799fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org streamdata.stream[k] = (uint8_t)((encoded[k >> 1] >> 1800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ((k & 1) << 3)) & 0xFF); 1801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else 1803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(streamdata.stream, encoded, 10); 1804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 1805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Decode frame length. */ 1807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org err = WebRtcIsac_DecodeFrameLen(&streamdata, frameLength); 1808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (err < 0) { 1809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC = (ISACMainStruct*)ISAC_main_inst; 1812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->decoderSamplingRateKHz == kIsacSuperWideband) { 1814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* The decoded frame length indicates the number of samples in 1815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * lower-band in this case, multiply by 2 to get the total number 1816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * of samples. */ 1817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *frameLength <<= 1; 1818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/******************************************************************************* 1824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_GetNewFrameLen(...) 1825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function returns the frame length (in samples) of the next packet. 1827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * In the case of channel-adaptive mode, iSAC decides on its frame length based 1828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * on the estimated bottleneck, this AOI allows a user to prepare for the next 1829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * packet (at the encoder). 1830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The primary usage is in CE to make the iSAC works in channel-adaptive mode 1832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC struct 1835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return Value : frame lenght in samples 1837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1839fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_GetNewFrameLen(ISACStruct* ISAC_main_inst) { 1840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Return new frame length. */ 1843ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org if (instISAC->in_sample_rate_hz == 16000) 1844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (instISAC->instLB.ISACencLB_obj.new_framelength); 1845ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org else if (instISAC->in_sample_rate_hz == 32000) 1846ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org return ((instISAC->instLB.ISACencLB_obj.new_framelength) * 2); 1847ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org else 1848ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org return ((instISAC->instLB.ISACencLB_obj.new_framelength) * 3); 1849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_GetErrorCode(...) 1854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function can be used to check the error code of an iSAC instance. 1856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * When a function returns -1 an error code will be set for that instance. 1857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The function below extracts the code of the last error that occurred in 1858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the specified instance. 1859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : ISAC instance 1862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : Error code 1864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1865fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_GetErrorCode(ISACStruct* ISAC_main_inst) { 1866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return ((ISACMainStruct*)ISAC_main_inst)->errorCode; 1867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 1871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_GetUplinkBw(...) 1872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function outputs the target bottleneck of the codec. In 1874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * channel-adaptive mode, the target bottleneck is specified through an in-band 1875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * signalling retrieved by bandwidth estimator. 1876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * In channel-independent, also called instantaneous mode, the target 1877b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bottleneck is provided to the encoder by calling xxx_control(...) (if 1878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * xxx_control is never called, the default values are used.). 1879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Note that the output is the iSAC internal operating bottleneck which might 1880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * differ slightly from the one provided through xxx_control(). 1881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC instance 1884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 1886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - *bottleneck : bottleneck in bits/sec 1887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1888b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : -1 if error happens 1889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 0 bit-rates computed correctly. 1890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1891fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_GetUplinkBw(ISACStruct* ISAC_main_inst, 1892fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t* bottleneck) { 1893b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->codingMode == 0) { 1896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* We are in adaptive mode then get the bottleneck from BWE. */ 1897fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org *bottleneck = (int32_t)instISAC->bwestimator_obj.send_bw_avg; 1898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bottleneck = instISAC->bottleneck; 1900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((*bottleneck > 32000) && (*bottleneck < 38000)) { 1903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bottleneck = 32000; 1904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if ((*bottleneck > 45000) && (*bottleneck < 50000)) { 1905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bottleneck = 45000; 1906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else if (*bottleneck > 56000) { 1907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *bottleneck = 56000; 1908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 1910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/****************************************************************************** 1914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_SetMaxPayloadSize(...) 1915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function sets a limit for the maximum payload size of iSAC. The same 1917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * value is used both for 30 and 60 ms packets. If the encoder sampling rate 1918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * is 16 kHz the maximum payload size is between 120 and 400 bytes. If the 1919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * encoder sampling rate is 32 kHz the maximum payload size is between 120 1920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * and 600 bytes. 1921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * --------------- 1923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * IMPORTANT NOTES 1924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * --------------- 1925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The size of a packet is limited to the minimum of 'max-payload-size' and 1926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 'max-rate.' For instance, let's assume the max-payload-size is set to 1927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps 1928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms 1929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * frame-size. Then a packet with a frame-size of 30 ms is limited to 150, 1930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to 1931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 170 bytes, i.e. min(170, 300). 1932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 1934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC instance 1935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - maxPayloadBytes : maximum size of the payload in bytes 1936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * valid values are between 100 and 400 bytes 1937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * if encoder sampling rate is 16 kHz. For 1938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 32 kHz encoder sampling rate valid values 1939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * are between 100 and 600 bytes. 1940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 if successful 1942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 if error happens 1943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 1944fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_SetMaxPayloadSize(ISACStruct* ISAC_main_inst, 1945fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t maxPayloadBytes) { 1946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 1947fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t status = 0; 1948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Check if encoder initiated */ 1950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 1951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BIT_MASK_ENC_INIT) { 1952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 1953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 1954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { 1957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Sanity check. */ 1958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (maxPayloadBytes < 120) { 1959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 'maxRate' is out of valid range 1960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * set to the acceptable value and return -1. */ 1961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org maxPayloadBytes = 120; 1962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = -1; 1963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* sanity check */ 1966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (maxPayloadBytes > STREAM_SIZE_MAX) { 1967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* maxRate is out of valid range, 1968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * set to the acceptable value and return -1. */ 1969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org maxPayloadBytes = STREAM_SIZE_MAX; 1970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = -1; 1971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (maxPayloadBytes < 120) { 1974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Max payload-size is out of valid range 1975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * set to the acceptable value and return -1. */ 1976b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org maxPayloadBytes = 120; 1977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = -1; 1978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (maxPayloadBytes > STREAM_SIZE_MAX_60) { 1980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Max payload-size is out of valid range 1981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * set to the acceptable value and return -1. */ 1982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org maxPayloadBytes = STREAM_SIZE_MAX_60; 1983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = -1; 1984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->maxPayloadSizeBytes = maxPayloadBytes; 1987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdatePayloadSizeLimit(instISAC); 1988b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 1989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/****************************************************************************** 1993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_SetMaxRate(...) 1994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function sets the maximum rate which the codec may not exceed for 1996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * any signal packet. The maximum rate is defined and payload-size per 1997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * frame-size in bits per second. 1998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 1999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The codec has a maximum rate of 53400 bits per second (200 bytes per 30 2000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * ms) if the encoder sampling rate is 16kHz, and 160 kbps (600 bytes/30 ms) 2001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * if the encoder sampling rate is 32 kHz. 2002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * It is possible to set a maximum rate between 32000 and 53400 bits/sec 2004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in wideband mode, and 32000 to 160000 bits/sec in super-wideband mode. 2005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * --------------- 2007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * IMPORTANT NOTES 2008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * --------------- 2009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The size of a packet is limited to the minimum of 'max-payload-size' and 2010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 'max-rate.' For instance, let's assume the max-payload-size is set to 2011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 170 bytes, and max-rate is set to 40 kbps. Note that a limit of 40 kbps 2012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * translates to 150 bytes for 30ms frame-size & 300 bytes for 60ms 2013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * frame-size. Then a packet with a frame-size of 30 ms is limited to 150, 2014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * i.e. min(170, 150), and a packet with 60 ms frame-size is limited to 2015b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 170 bytes, min(170, 300). 2016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 2018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC instance 2019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - maxRate : maximum rate in bits per second, 2020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * valid values are 32000 to 53400 bits/sec in 2021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * wideband mode, and 32000 to 160000 bits/sec in 2022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * super-wideband mode. 2023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 if successful 2025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 if error happens 2026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 2027fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_SetMaxRate(ISACStruct* ISAC_main_inst, 2028fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t maxRate) { 2029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2030fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t maxRateInBytesPer30Ms; 2031fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t status = 0; 2032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* check if encoder initiated */ 2034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != BIT_MASK_ENC_INIT) { 2035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 2036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Calculate maximum number of bytes per 30 msec packets for the 2039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org given maximum rate. Multiply with 30/1000 to get number of 2040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bits per 30 ms, divide by 8 to get number of bytes per 30 ms: 2041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org maxRateInBytes = floor((maxRate * 30/1000) / 8); */ 2042fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org maxRateInBytesPer30Ms = (int16_t)(maxRate * 3 / 800); 2043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->encoderSamplingRateKHz == kIsacWideband) { 2045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (maxRate < 32000) { 2046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 'maxRate' is out of valid range. 2047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Set to the acceptable value and return -1. */ 2048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org maxRateInBytesPer30Ms = 120; 2049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = -1; 2050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (maxRate > 53400) { 2053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 'maxRate' is out of valid range. 2054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Set to the acceptable value and return -1. */ 2055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org maxRateInBytesPer30Ms = 200; 2056b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = -1; 2057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 2059b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (maxRateInBytesPer30Ms < 120) { 2060b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 'maxRate' is out of valid range 2061ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * Set to the acceptable value and return -1. */ 2062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org maxRateInBytesPer30Ms = 120; 2063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = -1; 2064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (maxRateInBytesPer30Ms > STREAM_SIZE_MAX) { 2067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 'maxRate' is out of valid range. 2068b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Set to the acceptable value and return -1. */ 2069b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org maxRateInBytesPer30Ms = STREAM_SIZE_MAX; 2070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org status = -1; 2071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->maxRateBytesPer30Ms = maxRateInBytesPer30Ms; 2074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdatePayloadSizeLimit(instISAC); 2075b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return status; 2076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2078b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2079b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 2080b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_GetRedPayload(...) 2081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2082b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function populates "encoded" with the redundant payload of the recently 2083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * encodedframe. This function has to be called once that WebRtcIsac_Encode(...) 2084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * returns a positive value. Regardless of the frame-size this function will 2085b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be called only once after encoding is completed. The bit-stream is 2086b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * targeted for 16000 bit/sec. 2087b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2088b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 2089b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC struct 2090b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2091b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 2092b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - encoded : the encoded data vector 2093b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2094b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : >0 - Length (in bytes) of coded data 2096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * : -1 - Error 2097b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 2098fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_GetRedPayload(ISACStruct* ISAC_main_inst, 2099fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t* encoded) { 2100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org Bitstr iSACBitStreamInst; 2101fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t streamLenLB; 2102fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t streamLenUB; 2103fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t streamLen; 2104fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t totalLenUB; 2105fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint8_t* ptrEncodedUW8 = (uint8_t*)encoded; 2106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2107d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 2108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int k; 2109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 2110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 2112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BIT_MASK_ENC_INIT) { 2113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_ENCODER_NOT_INITIATED; 2114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_ResetBitstream(&(iSACBitStreamInst)); 2117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenLB = WebRtcIsac_EncodeStoredDataLb( 2119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &instISAC->instLB.ISACencLB_obj.SaveEnc_obj, 2120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &iSACBitStreamInst, 2121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->instLB.ISACencLB_obj.lastBWIdx, 2122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RCU_TRANSCODING_SCALE); 2123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (streamLenLB < 0) { 2124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2127fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org /* convert from bytes to int16_t. */ 2128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(ptrEncodedUW8, iSACBitStreamInst.stream, streamLenLB); 2129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLen = streamLenLB; 2130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->bandwidthKHz == isac8kHz) { 2131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return streamLenLB; 2132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB = WebRtcIsac_GetRedPayloadUb( 2135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &instISAC->instUB.ISACencUB_obj.SaveEnc_obj, 2136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &iSACBitStreamInst, instISAC->bandwidthKHz); 2137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (streamLenUB < 0) { 2138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* An error has happened but this is not the error due to a 2139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * bit-stream larger than the limit. */ 2140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* We have one byte to write the total length of the upper-band. 2144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * The length includes the bit-stream length, check-sum and the 2145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * single byte where the length is written to. This is according to 2146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * iSAC wideband and how the "garbage" is dealt. */ 2147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org totalLenUB = streamLenUB + 1 + LEN_CHECK_SUM_WORD8; 2148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (totalLenUB > 255) { 2149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB = 0; 2150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Generate CRC if required. */ 2153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((instISAC->bandwidthKHz != isac8kHz) && 2154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (streamLenUB > 0)) { 2155fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint32_t crc; 2156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLen += totalLenUB; 2157fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org ptrEncodedUW8[streamLenLB] = (uint8_t)totalLenUB; 2158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ptrEncodedUW8[streamLenLB + 1], iSACBitStreamInst.stream, 2159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB); 2160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2161fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org WebRtcIsac_GetCrc((int16_t*)(&(ptrEncodedUW8[streamLenLB + 1])), 2162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org streamLenUB, &crc); 2163d7e904161d5c59c61cbf094b16bca6e79ada713aandrew@webrtc.org#ifndef WEBRTC_ARCH_BIG_ENDIAN 2164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (k = 0; k < LEN_CHECK_SUM_WORD8; k++) { 2165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ptrEncodedUW8[streamLen - LEN_CHECK_SUM_WORD8 + k] = 2166fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org (uint8_t)((crc >> (24 - k * 8)) & 0xFF); 2167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else 2169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(&ptrEncodedUW8[streamLenLB + streamLenUB + 1], &crc, 2170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LEN_CHECK_SUM_WORD8); 2171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 2172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return streamLen; 2174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/**************************************************************************** 2178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_version(...) 2179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function returns the version number. 2181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Output: 2183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - version : Pointer to character string 2184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 2186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid WebRtcIsac_version(char* version) { 2187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org strcpy(version, "4.3.0"); 2188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/****************************************************************************** 2192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_SetEncSampRate() 2193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function sets the sampling rate of the encoder. Initialization of the 2194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * encoder WILL NOT overwrite the sampling rate of the encoder. The default 2195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * value is 16 kHz which is set when the instance is created. The encoding-mode 2196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * and the bottleneck remain unchanged by this call, however, the maximum rate 2197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * and maximum payload-size will be reset to their default values. 2198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2199ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * NOTE: 2200ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * The maximum internal sampling rate is 32 kHz. If the encoder sample rate is 2201ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * set to 48 kHz the input is expected to be at 48 kHz but will be resampled to 2202ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * 32 kHz before any further processing. 2203ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * This mode is created for compatibility with full-band codecs if iSAC is used 2204ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * in dual-streaming. See SetDecSampleRate() for sampling rates at the decoder. 2205ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * 2206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 2207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC instance 2208ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * - sample_rate_hz : sampling rate in Hertz, valid values are 16000, 2209ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * 32000 and 48000. 2210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 if successful 2212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 if failed. 2213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 2214fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst, 2215fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t sample_rate_hz) { 2216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2217ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org enum IsacSamplingRate encoder_operational_rate; 2218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2219ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org if ((sample_rate_hz != 16000) && (sample_rate_hz != 32000) && 2220ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org (sample_rate_hz != 48000)) { 2221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Sampling Frequency is not supported. */ 2222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; 2223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2224ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org } 2225ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org if (sample_rate_hz == 16000) { 2226ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org encoder_operational_rate = kIsacWideband; 2227ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org } else { 2228ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org encoder_operational_rate = kIsacSuperWideband; 2229ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org } 2230ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org 2231ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != 2232ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org BIT_MASK_ENC_INIT) { 2233ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org if (encoder_operational_rate == kIsacWideband) { 2234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = isac8kHz; 2235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 2236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = isac16kHz; 2237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 2239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACUBStruct* instUB = &(instISAC->instUB); 2240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACLBStruct* instLB = &(instISAC->instLB); 2241fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int32_t bottleneck = instISAC->bottleneck; 2242fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t codingMode = instISAC->codingMode; 2243fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org int16_t frameSizeMs = instLB->ISACencLB_obj.new_framelength / 2244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (FS / 1000); 2245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2246ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org if ((encoder_operational_rate == kIsacWideband) && 2247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) { 2248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Changing from super-wideband to wideband. 2249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * we don't need to re-initialize the encoder of the lower-band. */ 2250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = isac8kHz; 2251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (codingMode == 1) { 2252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ControlLb(instLB, 2253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (bottleneck > 32000) ? 32000 : bottleneck, FRAMESIZE); 2254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; 2256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; 2257ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org } else if ((encoder_operational_rate == kIsacSuperWideband) && 2258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->encoderSamplingRateKHz == kIsacWideband)) { 22599fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org double bottleneckLB = 0; 22609fbd3ec906560447cebb21681c7e79e37c2eed83tommi@webrtc.org double bottleneckUB = 0; 2261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (codingMode == 1) { 2262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WebRtcIsac_RateAllocation(bottleneck, &bottleneckLB, &bottleneckUB, 2263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &(instISAC->bandwidthKHz)); 2264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bandwidthKHz = isac16kHz; 2267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; 2268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; 2269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2270ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org EncoderInitLb(instLB, codingMode, encoder_operational_rate); 2271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EncoderInitUb(instUB, instISAC->bandwidthKHz); 2272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(instISAC->analysisFBState1, 0, 2274fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org FB_STATE_SIZE_WORD32 * sizeof(int32_t)); 2275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(instISAC->analysisFBState2, 0, 2276fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org FB_STATE_SIZE_WORD32 * sizeof(int32_t)); 2277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (codingMode == 1) { 2279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->bottleneck = bottleneck; 2280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ControlLb(instLB, bottleneckLB, 2281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (instISAC->bandwidthKHz == isac8kHz) ? frameSizeMs:FRAMESIZE); 2282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (instISAC->bandwidthKHz > isac8kHz) { 2283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ControlUb(instUB, bottleneckUB); 2284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 2286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.enforceFrameSize = 0; 2287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instLB->ISACencLB_obj.new_framelength = FRAMESAMPLES; 2288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2291ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org instISAC->encoderSamplingRateKHz = encoder_operational_rate; 2292ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org instISAC->in_sample_rate_hz = sample_rate_hz; 2293ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org return 0; 2294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/****************************************************************************** 2298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_SetDecSampRate() 2299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This function sets the sampling rate of the decoder. Initialization of the 2300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * decoder WILL NOT overwrite the sampling rate of the encoder. The default 2301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * value is 16 kHz which is set when the instance is created. 2302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 2304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC instance 2305ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * - sample_rate_hz : sampling rate in Hertz, valid values are 16000 2306ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * and 32000. 2307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return value : 0 if successful 2309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * -1 if failed. 2310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 2311fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgint16_t WebRtcIsac_SetDecSampRate(ISACStruct* ISAC_main_inst, 2312fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org uint16_t sample_rate_hz) { 2313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2314ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org enum IsacSamplingRate decoder_operational_rate; 2315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2316ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org if (sample_rate_hz == 16000) { 2317ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org decoder_operational_rate = kIsacWideband; 2318ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org } else if (sample_rate_hz == 32000) { 2319ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org decoder_operational_rate = kIsacSuperWideband; 2320ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org } else { 2321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Sampling Frequency is not supported. */ 2322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; 2323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2324ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org } 2325ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org 2326ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org if ((instISAC->decoderSamplingRateKHz == kIsacWideband) && 2327ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org (decoder_operational_rate == kIsacSuperWideband)) { 2328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Switching from wideband to super-wideband at the decoder 2329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * we need to reset the filter-bank and initialize upper-band decoder. */ 2330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(instISAC->synthesisFBState1, 0, 2331fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org FB_STATE_SIZE_WORD32 * sizeof(int32_t)); 2332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(instISAC->synthesisFBState2, 0, 2333fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org FB_STATE_SIZE_WORD32 * sizeof(int32_t)); 2334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (DecoderInitUb(&(instISAC->instUB)) < 0) { 2336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 2337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 2339ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org instISAC->decoderSamplingRateKHz = decoder_operational_rate; 2340ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org return 0; 2341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/****************************************************************************** 2345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_EncSampRate() 2346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 2348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC instance 2349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2350ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * Return value : sampling rate in Hertz. The input to encoder 2351ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * is expected to be sampled in this rate. 2352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 2354fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orguint16_t WebRtcIsac_EncSampRate(ISACStruct* ISAC_main_inst) { 2355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2356ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org return instISAC->in_sample_rate_hz; 2357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/****************************************************************************** 2361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WebRtcIsac_DecSampRate() 2362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return the sampling rate of the decoded audio. 2363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Input: 2365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * - ISAC_main_inst : iSAC instance 2366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2367ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * Return value : sampling rate in Hertz. Decoder output is 2368ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org * sampled at this rate. 2369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 2370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 2371fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orguint16_t WebRtcIsac_DecSampRate(ISACStruct* ISAC_main_inst) { 2372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; 2373ad70aa49b2ea2e4750b4596a769ce27278e507d8turaj@webrtc.org return instISAC->decoderSamplingRateKHz == kIsacWideband ? 16000 : 32000; 2374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 2375