diff --git a/webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h b/webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h index 03c260bb8..6ae6c1a31 100644 --- a/webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h +++ b/webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h @@ -18,9 +18,6 @@ typedef struct WebRtcISACStruct ISACStruct; -enum IsacSamplingRate {kIsacWideband = 16, kIsacSuperWideband = 32}; - - #if defined(__cplusplus) extern "C" { #endif @@ -478,14 +475,11 @@ extern "C" { * Input: * - ISAC_main_inst : iSAC instance * - * Return value : enumerator representing sampling frequency - * associated with the decoder, i.e. the - * sampling rate of the decoded audio. + * Return value : sampling frequency in Hertz. * */ - enum IsacSamplingRate WebRtcIsac_DecSampRate( - ISACStruct* ISAC_main_inst); + WebRtc_UWord16 WebRtcIsac_DecSampRate(ISACStruct* ISAC_main_inst); /****************************************************************************** @@ -494,14 +488,11 @@ extern "C" { * Input: * - ISAC_main_inst : iSAC instance * - * Return value : enumerator representing sampling frequency - * associated with the encoder, the input audio - * is expected to be sampled at this rate. + * Return value : sampling rate in Hertz. * */ - enum IsacSamplingRate WebRtcIsac_EncSampRate( - ISACStruct* ISAC_main_inst); + WebRtc_UWord16 WebRtcIsac_EncSampRate(ISACStruct* ISAC_main_inst); /****************************************************************************** @@ -512,15 +503,14 @@ extern "C" { * * Input: * - ISAC_main_inst : iSAC instance - * - sampRate : enumerator specifying the sampling rate. + * - sampRate : sampling rate in Hertz. * * Return value : 0 if successful * -1 if failed. */ - WebRtc_Word16 WebRtcIsac_SetDecSampRate( - ISACStruct* ISAC_main_inst, - enum IsacSamplingRate sampRate); + WebRtc_Word16 WebRtcIsac_SetDecSampRate(ISACStruct* ISAC_main_inst, + WebRtc_UWord16 samp_rate_hz); /****************************************************************************** @@ -533,15 +523,14 @@ extern "C" { * * Input: * - ISAC_main_inst : iSAC instance - * - sampRate : enumerator specifying the sampling rate. + * - sampRate : sampling rate in Hertz. * * Return value : 0 if successful * -1 if failed. */ - WebRtc_Word16 WebRtcIsac_SetEncSampRate( - ISACStruct* ISAC_main_inst, - enum IsacSamplingRate sampRate); + WebRtc_Word16 WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst, + WebRtc_UWord16 sample_rate_hz); diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/decode_bwe.c b/webrtc/modules/audio_coding/codecs/isac/main/source/decode_bwe.c index cdac7fa8b..a92b9b994 100644 --- a/webrtc/modules/audio_coding/codecs/isac/main/source/decode_bwe.c +++ b/webrtc/modules/audio_coding/codecs/isac/main/source/decode_bwe.c @@ -68,6 +68,7 @@ WebRtcIsac_EstimateBandwidth( diffArrivalTime = (WebRtc_UWord32)diffArrivalTime >> 1; diffSendTime = (WebRtc_UWord32)diffSendTime >> 1; } + // arrival timestamp in 16 kHz arrivalTimestampIn16kHz = (WebRtc_UWord32)((WebRtc_UWord32) bwest_str->prev_rec_arr_ts + (WebRtc_UWord32)diffArrivalTime); diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/isac.c b/webrtc/modules/audio_coding/codecs/isac/main/source/isac.c index 7c9033467..428fda87b 100644 --- a/webrtc/modules/audio_coding/codecs/isac/main/source/isac.c +++ b/webrtc/modules/audio_coding/codecs/isac/main/source/isac.c @@ -249,6 +249,7 @@ WebRtc_Word16 WebRtcIsac_Assign(ISACStruct** ISAC_main_inst, instISAC->encoderSamplingRateKHz = kIsacWideband; instISAC->decoderSamplingRateKHz = kIsacWideband; instISAC->bandwidthKHz = isac8kHz; + instISAC->in_sample_rate_hz = 16000; return 0; } else { return -1; @@ -280,6 +281,7 @@ WebRtc_Word16 WebRtcIsac_Create(ISACStruct** ISAC_main_inst) { instISAC->bandwidthKHz = isac8kHz; instISAC->encoderSamplingRateKHz = kIsacWideband; instISAC->decoderSamplingRateKHz = kIsacWideband; + instISAC->in_sample_rate_hz = 16000; return 0; } else { return -1; @@ -458,6 +460,7 @@ WebRtc_Word16 WebRtcIsac_EncoderInit(ISACStruct* ISAC_main_inst, return -1; } } + memset(instISAC->state_in_resampler, 0, sizeof(instISAC->state_in_resampler)); /* Initialization is successful, set the flag. */ instISAC->initFlag |= BIT_MASK_ENC_INIT; return 0; @@ -505,6 +508,8 @@ WebRtc_Word16 WebRtcIsac_Encode(ISACStruct* ISAC_main_inst, ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; ISACLBStruct* instLB = &(instISAC->instLB); ISACUBStruct* instUB = &(instISAC->instUB); + const int16_t* speech_in_ptr = speechIn; + int16_t resampled_buff[FRAMESAMPLES_10ms * 2]; /* Check if encoder initiated. */ if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != @@ -513,8 +518,37 @@ WebRtc_Word16 WebRtcIsac_Encode(ISACStruct* ISAC_main_inst, return -1; } + if (instISAC->in_sample_rate_hz == 48000) { + /* Samples in 10 ms @ 48 kHz. */ + const int kNumInputSamples = FRAMESAMPLES_10ms * 3; + /* Samples 10 ms @ 32 kHz. */ + const int kNumOutputSamples = FRAMESAMPLES_10ms * 2; + /* Resampler divide the input into blocks of 3 samples, i.e. + * kNumInputSamples / 3. */ + const int kNumResamplerBlocks = FRAMESAMPLES_10ms; + int32_t buffer32[FRAMESAMPLES_10ms * 3 + SIZE_RESAMPLER_STATE]; + + /* Restore last samples from the past to the beginning of the buffer + * and store the last samples of current frame for the next resampling. */ + for (k = 0; k < SIZE_RESAMPLER_STATE; k++) { + buffer32[k] = instISAC->state_in_resampler[k]; + instISAC->state_in_resampler[k] = speechIn[kNumInputSamples - + SIZE_RESAMPLER_STATE + k]; + } + for (k = 0; k < kNumInputSamples; k++) { + buffer32[SIZE_RESAMPLER_STATE + k] = speechIn[k]; + } + /* Resampling 3 samples to 2. Function divides the input in + * |kNumResamplerBlocks| number of 3-sample groups, and output is + * |kNumResamplerBlocks| number of 2-sample groups. */ + WebRtcSpl_Resample48khzTo32khz(buffer32, buffer32, kNumResamplerBlocks); + WebRtcSpl_VectorBitShiftW32ToW16(resampled_buff, kNumOutputSamples, + buffer32, 15); + speech_in_ptr = resampled_buff; + } + if (instISAC->encoderSamplingRateKHz == kIsacSuperWideband) { - WebRtcSpl_AnalysisQMF(speechIn, speechInLB, speechInUB, + WebRtcSpl_AnalysisQMF(speech_in_ptr, speechInLB, speechInUB, instISAC->analysisFBState1, instISAC->analysisFBState2); @@ -728,7 +762,7 @@ WebRtc_Word16 WebRtcIsac_Encode(ISACStruct* ISAC_main_inst, * even for 60 msec frames. * * NOTE 1! This function does not write in the ISACStruct, it is not allowed. - * NOTE 3! Rates larger than the bottleneck of the codec will be limited + * NOTE 2! Rates larger than the bottleneck of the codec will be limited * to the current bottleneck. * * Input: @@ -946,6 +980,11 @@ WebRtc_Word16 WebRtcIsac_DecoderInit(ISACStruct* ISAC_main_inst) { * * This function updates the estimate of the bandwidth. * + * NOTE: + * The estimates of bandwidth is not valid if the sample rate of the far-end + * encoder is set to 48 kHz and send timestamps are increamented according to + * 48 kHz sampling rate. + * * Input: * - ISAC_main_inst : ISAC instance. * - encoded : encoded ISAC frame(s). @@ -1731,7 +1770,8 @@ WebRtc_Word16 WebRtcIsac_ReadBwIndex(const WebRtc_Word16* encoded, /**************************************************************************** * WebRtcIsac_ReadFrameLen(...) * - * This function returns the length of the frame represented in the packet. + * This function returns the number of samples the decoder will generate if + * the given payload is decoded. * * Input: * - encoded : Encoded bitstream @@ -1798,11 +1838,12 @@ WebRtc_Word16 WebRtcIsac_GetNewFrameLen(ISACStruct* ISAC_main_inst) { ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; /* Return new frame length. */ - if (instISAC->encoderSamplingRateKHz == kIsacWideband) { + if (instISAC->in_sample_rate_hz == 16000) return (instISAC->instLB.ISACencLB_obj.new_framelength); - } else { - return ((instISAC->instLB.ISACencLB_obj.new_framelength) << 1); - } + else if (instISAC->in_sample_rate_hz == 32000) + return ((instISAC->instLB.ISACencLB_obj.new_framelength) * 2); + else + return ((instISAC->instLB.ISACencLB_obj.new_framelength) * 3); } @@ -2015,7 +2056,7 @@ WebRtc_Word16 WebRtcIsac_SetMaxRate(ISACStruct* ISAC_main_inst, } else { if (maxRateInBytesPer30Ms < 120) { /* 'maxRate' is out of valid range - * Sset to the acceptable value and return -1. */ + * Set to the acceptable value and return -1. */ maxRateInBytesPer30Ms = 120; status = -1; } @@ -2153,31 +2194,45 @@ void WebRtcIsac_version(char* version) { * and the bottleneck remain unchanged by this call, however, the maximum rate * and maximum payload-size will be reset to their default values. * + * NOTE: + * The maximum internal sampling rate is 32 kHz. If the encoder sample rate is + * set to 48 kHz the input is expected to be at 48 kHz but will be resampled to + * 32 kHz before any further processing. + * This mode is created for compatibility with full-band codecs if iSAC is used + * in dual-streaming. See SetDecSampleRate() for sampling rates at the decoder. + * * Input: * - ISAC_main_inst : iSAC instance - * - sampRate : enumerator specifying the sampling rate. + * - sample_rate_hz : sampling rate in Hertz, valid values are 16000, + * 32000 and 48000. * * Return value : 0 if successful * -1 if failed. */ WebRtc_Word16 WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst, - enum IsacSamplingRate sampRate) { + WebRtc_UWord16 sample_rate_hz) { ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; + enum IsacSamplingRate encoder_operational_rate; - if ((sampRate != kIsacWideband) && - (sampRate != kIsacSuperWideband)) { + if ((sample_rate_hz != 16000) && (sample_rate_hz != 32000) && + (sample_rate_hz != 48000)) { /* Sampling Frequency is not supported. */ instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; return -1; - } else if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != - BIT_MASK_ENC_INIT) { - if (sampRate == kIsacWideband) { + } + if (sample_rate_hz == 16000) { + encoder_operational_rate = kIsacWideband; + } else { + encoder_operational_rate = kIsacSuperWideband; + } + + if ((instISAC->initFlag & BIT_MASK_ENC_INIT) != + BIT_MASK_ENC_INIT) { + if (encoder_operational_rate == kIsacWideband) { instISAC->bandwidthKHz = isac8kHz; } else { instISAC->bandwidthKHz = isac16kHz; } - instISAC->encoderSamplingRateKHz = sampRate; - return 0; } else { ISACUBStruct* instUB = &(instISAC->instUB); ISACLBStruct* instLB = &(instISAC->instLB); @@ -2188,7 +2243,7 @@ WebRtc_Word16 WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst, WebRtc_Word16 frameSizeMs = instLB->ISACencLB_obj.new_framelength / (FS / 1000); - if ((sampRate == kIsacWideband) && + if ((encoder_operational_rate == kIsacWideband) && (instISAC->encoderSamplingRateKHz == kIsacSuperWideband)) { /* Changing from super-wideband to wideband. * we don't need to re-initialize the encoder of the lower-band. */ @@ -2199,7 +2254,7 @@ WebRtc_Word16 WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst, } instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX_60; instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX_30; - } else if ((sampRate == kIsacSuperWideband) && + } else if ((encoder_operational_rate == kIsacSuperWideband) && (instISAC->encoderSamplingRateKHz == kIsacWideband)) { if (codingMode == 1) { WebRtcIsac_RateAllocation(bottleneck, &bottleneckLB, &bottleneckUB, @@ -2210,7 +2265,7 @@ WebRtc_Word16 WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst, instISAC->maxPayloadSizeBytes = STREAM_SIZE_MAX; instISAC->maxRateBytesPer30Ms = STREAM_SIZE_MAX; - EncoderInitLb(instLB, codingMode, sampRate); + EncoderInitLb(instLB, codingMode, encoder_operational_rate); EncoderInitUb(instUB, instISAC->bandwidthKHz); memset(instISAC->analysisFBState1, 0, @@ -2230,9 +2285,10 @@ WebRtc_Word16 WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst, instLB->ISACencLB_obj.new_framelength = FRAMESAMPLES; } } - instISAC->encoderSamplingRateKHz = sampRate; - return 0; } + instISAC->encoderSamplingRateKHz = encoder_operational_rate; + instISAC->in_sample_rate_hz = sample_rate_hz; + return 0; } @@ -2244,23 +2300,29 @@ WebRtc_Word16 WebRtcIsac_SetEncSampRate(ISACStruct* ISAC_main_inst, * * Input: * - ISAC_main_inst : iSAC instance - * - sampRate : enumerator specifying the sampling rate. + * - sample_rate_hz : sampling rate in Hertz, valid values are 16000 + * and 32000. * * Return value : 0 if successful * -1 if failed. */ WebRtc_Word16 WebRtcIsac_SetDecSampRate(ISACStruct* ISAC_main_inst, - enum IsacSamplingRate sampRate) { + WebRtc_UWord16 sample_rate_hz) { ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; + enum IsacSamplingRate decoder_operational_rate; - if ((sampRate != kIsacWideband) && - (sampRate != kIsacSuperWideband)) { + if (sample_rate_hz == 16000) { + decoder_operational_rate = kIsacWideband; + } else if (sample_rate_hz == 32000) { + decoder_operational_rate = kIsacSuperWideband; + } else { /* Sampling Frequency is not supported. */ instISAC->errorCode = ISAC_UNSUPPORTED_SAMPLING_FREQUENCY; return -1; - } else { - if ((instISAC->decoderSamplingRateKHz == kIsacWideband) && - (sampRate == kIsacSuperWideband)) { + } + + if ((instISAC->decoderSamplingRateKHz == kIsacWideband) && + (decoder_operational_rate == kIsacSuperWideband)) { /* Switching from wideband to super-wideband at the decoder * we need to reset the filter-bank and initialize upper-band decoder. */ memset(instISAC->synthesisFBState1, 0, @@ -2271,10 +2333,9 @@ WebRtc_Word16 WebRtcIsac_SetDecSampRate(ISACStruct* ISAC_main_inst, if (DecoderInitUb(&(instISAC->instUB)) < 0) { return -1; } - } - instISAC->decoderSamplingRateKHz = sampRate; - return 0; } + instISAC->decoderSamplingRateKHz = decoder_operational_rate; + return 0; } @@ -2284,14 +2345,13 @@ WebRtc_Word16 WebRtcIsac_SetDecSampRate(ISACStruct* ISAC_main_inst, * Input: * - ISAC_main_inst : iSAC instance * - * Return value : enumerator representing sampling frequency - * associated with the encoder, the input audio - * is expected to be sampled at this rate. + * Return value : sampling rate in Hertz. The input to encoder + * is expected to be sampled in this rate. * */ -enum IsacSamplingRate WebRtcIsac_EncSampRate(ISACStruct* ISAC_main_inst) { +WebRtc_UWord16 WebRtcIsac_EncSampRate(ISACStruct* ISAC_main_inst) { ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; - return instISAC->encoderSamplingRateKHz; + return instISAC->in_sample_rate_hz; } @@ -2302,12 +2362,11 @@ enum IsacSamplingRate WebRtcIsac_EncSampRate(ISACStruct* ISAC_main_inst) { * Input: * - ISAC_main_inst : iSAC instance * - * Return value : enumerator representing sampling frequency - * associated with the decoder, i.e. the - * sampling rate of the decoded audio. + * Return value : sampling rate in Hertz. Decoder output is + * sampled at this rate. * */ -enum IsacSamplingRate WebRtcIsac_DecSampRate(ISACStruct* ISAC_main_inst) { +WebRtc_UWord16 WebRtcIsac_DecSampRate(ISACStruct* ISAC_main_inst) { ISACMainStruct* instISAC = (ISACMainStruct*)ISAC_main_inst; - return instISAC->decoderSamplingRateKHz; + return instISAC->decoderSamplingRateKHz == kIsacWideband ? 16000 : 32000; } diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/settings.h b/webrtc/modules/audio_coding/codecs/isac/main/source/settings.h index 9c1ec1e6a..5562c35ad 100644 --- a/webrtc/modules/audio_coding/codecs/isac/main/source/settings.h +++ b/webrtc/modules/audio_coding/codecs/isac/main/source/settings.h @@ -82,6 +82,7 @@ #define LB_TOTAL_DELAY_SAMPLES 48 enum ISACBandwidth {isac8kHz = 8, isac12kHz = 12, isac16kHz = 16}; enum ISACBand {kIsacLowerBand = 0, kIsacUpperBand12 = 1, kIsacUpperBand16 = 2}; +enum IsacSamplingRate {kIsacWideband = 16, kIsacSuperWideband = 32}; #define UB_LPC_GAIN_DIM SUBFRAMES #define FB_STATE_SIZE_WORD32 6 @@ -167,6 +168,7 @@ enum ISACBand {kIsacLowerBand = 0, kIsacUpperBand12 = 1, kIsacUpperBand16 = 2}; #define RCU_TRANSCODING_SCALE_UB 0.50f #define RCU_TRANSCODING_SCALE_UB_INVERSE 2.0f +#define SIZE_RESAMPLER_STATE 6 /* Define Error codes */ /* 6000 General */ diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/structs.h b/webrtc/modules/audio_coding/codecs/isac/main/source/structs.h index 96cef30bc..39a86d222 100644 --- a/webrtc/modules/audio_coding/codecs/isac/main/source/structs.h +++ b/webrtc/modules/audio_coding/codecs/isac/main/source/structs.h @@ -472,6 +472,12 @@ typedef struct { WebRtc_Word16 maxRateBytesPer30Ms; // Maximum allowed payload-size, measured in Bytes. WebRtc_Word16 maxPayloadSizeBytes; + /* The expected sampling rate of the input signal. Valid values are 16000, + * 32000 and 48000. This is not the operation sampling rate of the codec. + * Input signals at 48 kHz are resampled to 32 kHz, then encoded. */ + WebRtc_UWord16 in_sample_rate_hz; + /* State for the input-resampler. It is only used for 48 kHz input signals. */ + int16_t state_in_resampler[SIZE_RESAMPLER_STATE]; } ISACMainStruct; #endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_ */ diff --git a/webrtc/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc b/webrtc/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc index 04c5367f4..ca05c2ce2 100644 --- a/webrtc/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc +++ b/webrtc/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc @@ -477,8 +477,9 @@ int main(int argc, char* argv[]) if(!useAssign) { err =WebRtcIsac_Create(&ISAC_main_inst); - WebRtcIsac_SetEncSampRate(ISAC_main_inst, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband); - WebRtcIsac_SetDecSampRate(ISAC_main_inst, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband); + WebRtcIsac_SetEncSampRate(ISAC_main_inst, sampFreqKHz * 1000); + WebRtcIsac_SetDecSampRate(ISAC_main_inst, sampFreqKHz >= 32 ? + 32000 : 16000); } else { @@ -488,8 +489,9 @@ int main(int argc, char* argv[]) err = WebRtcIsac_AssignSize(&sss); ppp = malloc(sss); err = WebRtcIsac_Assign(&ISAC_main_inst, ppp); - WebRtcIsac_SetEncSampRate(ISAC_main_inst, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband); - WebRtcIsac_SetDecSampRate(ISAC_main_inst, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband); + WebRtcIsac_SetEncSampRate(ISAC_main_inst, sampFreqKHz * 1000); + WebRtcIsac_SetDecSampRate(ISAC_main_inst, sampFreqKHz >= 32 ? + 32000 : 16000); } /* Error check */ if(err < 0) @@ -510,8 +512,9 @@ int main(int argc, char* argv[]) if(doTransCoding) { WebRtcIsac_Create(&decoderTransCoding); - WebRtcIsac_SetEncSampRate(decoderTransCoding, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband); - WebRtcIsac_SetDecSampRate(decoderTransCoding, (sampFreqKHz == 16)? kIsacWideband:kIsacSuperWideband); + WebRtcIsac_SetEncSampRate(decoderTransCoding, sampFreqKHz * 1000); + WebRtcIsac_SetDecSampRate(decoderTransCoding, sampFreqKHz >= 32 ? + 32000 : 16000); WebRtcIsac_DecoderInit(decoderTransCoding); transCodingFile = fopen(transCodingFileName, "wb"); if(transCodingFile == NULL) diff --git a/webrtc/modules/audio_coding/codecs/isac/main/test/SwitchingSampRate/SwitchingSampRate.cc b/webrtc/modules/audio_coding/codecs/isac/main/test/SwitchingSampRate/SwitchingSampRate.cc index cccae28a6..196eb11c8 100644 --- a/webrtc/modules/audio_coding/codecs/isac/main/test/SwitchingSampRate/SwitchingSampRate.cc +++ b/webrtc/modules/audio_coding/codecs/isac/main/test/SwitchingSampRate/SwitchingSampRate.cc @@ -38,7 +38,7 @@ int main(int argc, char* argv[]) ISACStruct* codecInstance[MAX_NUM_CLIENTS]; WebRtc_Word32 resamplerState[MAX_NUM_CLIENTS][8]; - enum IsacSamplingRate encoderSampRate[MAX_NUM_CLIENTS]; + int encoderSampRate[MAX_NUM_CLIENTS]; int minBn = 16000; int maxBn = 56000; @@ -86,11 +86,11 @@ int main(int argc, char* argv[]) } // THE FIRST CLIENT STARTS IN WIDEBAND - encoderSampRate[0] = kIsacWideband; + encoderSampRate[0] = 16000; OPEN_FILE_RB(inFile[0], fileNameWB); // THE SECOND CLIENT STARTS IN SUPER-WIDEBAND - encoderSampRate[1] = kIsacSuperWideband; + encoderSampRate[1] = 32000; OPEN_FILE_RB(inFile[1], fileNameSWB); strcpy(myFlag, "-I"); @@ -104,7 +104,7 @@ int main(int argc, char* argv[]) printf("Client %d\n", clientCntr + 1); printf("---------\n"); printf("Starting %s", - (encoderSampRate[clientCntr] == kIsacWideband) + (encoderSampRate[clientCntr] == 16000) ? "wideband":"super-wideband"); // Open output File Name @@ -242,17 +242,17 @@ int main(int argc, char* argv[]) printf("Changing Encoder Sampling frequency in client %d to ", senderIdx+1); fclose(inFile[senderIdx]); numSampFreqChanged++; - if(encoderSampRate[senderIdx] == kIsacWideband) + if(encoderSampRate[senderIdx] == 16000) { printf("super-wideband.\n"); OPEN_FILE_RB(inFile[senderIdx], fileNameSWB); - encoderSampRate[senderIdx] = kIsacSuperWideband; + encoderSampRate[senderIdx] = 32000; } else { printf("wideband.\n"); OPEN_FILE_RB(inFile[senderIdx], fileNameWB); - encoderSampRate[senderIdx] = kIsacWideband; + encoderSampRate[senderIdx] = 16000; } WebRtcIsac_SetEncSampRate(codecInstance[senderIdx], encoderSampRate[senderIdx]); WebRtcIsac_SetDecSampRate(codecInstance[receiverIdx], encoderSampRate[senderIdx]); @@ -264,7 +264,7 @@ int main(int argc, char* argv[]) if(numSamplesRead != samplesIn10ms[senderIdx]) { printf(" File %s for client %d has not enough audio\n", - (encoderSampRate[senderIdx]==kIsacWideband)? "wideband":"super-wideband", + (encoderSampRate[senderIdx]==16000)? "wideband":"super-wideband", senderIdx + 1); return -1; } @@ -428,7 +428,7 @@ int main(int argc, char* argv[]) } - if(encoderSampRate[senderIdx] == kIsacWideband) + if(encoderSampRate[senderIdx] == 16000) { WebRtcSpl_UpsampleBy2(audioBuff60ms, lenDecodedAudio, resampledAudio60ms, resamplerState[receiverIdx]); diff --git a/webrtc/modules/audio_coding/codecs/isac/main/test/simpleKenny.c b/webrtc/modules/audio_coding/codecs/isac/main/test/simpleKenny.c index be1588c64..f1b78c267 100644 --- a/webrtc/modules/audio_coding/codecs/isac/main/test/simpleKenny.c +++ b/webrtc/modules/audio_coding/codecs/isac/main/test/simpleKenny.c @@ -254,8 +254,9 @@ valid values are 8 and 16.\n", sampFreqKHz); /* Initialize the ISAC and BN structs */ err = WebRtcIsac_Create(&ISAC_main_inst); - WebRtcIsac_SetEncSampRate(ISAC_main_inst, (sampFreqKHz == 16)? kIsacWideband: kIsacSuperWideband); - WebRtcIsac_SetDecSampRate(ISAC_main_inst, (sampFreqKHz == 16)? kIsacWideband: kIsacSuperWideband); + WebRtcIsac_SetEncSampRate(ISAC_main_inst, sampFreqKHz * 1000); + WebRtcIsac_SetDecSampRate(ISAC_main_inst, sampFreqKHz >= 32 ? 32000 : + 16000); /* Error check */ if (err < 0) { fprintf(stderr,"\n\n Error in create.\n\n"); diff --git a/webrtc/modules/audio_coding/main/source/acm_codec_database.cc b/webrtc/modules/audio_coding/main/source/acm_codec_database.cc index 1c9a40916..b860b8a36 100644 --- a/webrtc/modules/audio_coding/main/source/acm_codec_database.cc +++ b/webrtc/modules/audio_coding/main/source/acm_codec_database.cc @@ -107,10 +107,10 @@ namespace webrtc { // codecs. Note! There are a limited number of payload types. If more codecs // are defined they will receive reserved fixed payload types (values 69-95). const int kDynamicPayloadtypes[ACMCodecDB::kMaxNumCodecs] = { - 105, 107, 108, 109, 111, 112, 113, 114, 115, 116, 117, 92, + 107, 108, 109, 111, 112, 113, 114, 115, 116, 117, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, - 67, 66 + 67, 66, 65 }; // Creates database with all supported codecs at compile time. @@ -129,6 +129,7 @@ const CodecInst ACMCodecDB::database_[] = { {103, "ISAC", 16000, kIsacPacSize480, 1, kIsacWbDefaultRate}, # if (defined(WEBRTC_CODEC_ISAC)) {104, "ISAC", 32000, kIsacPacSize960, 1, kIsacSwbDefaultRate}, + {105, "ISAC", 48000, kIsacPacSize1440, 1, kIsacSwbDefaultRate}, # endif #endif #ifdef WEBRTC_CODEC_PCM16 @@ -221,6 +222,7 @@ const ACMCodecDB::CodecSettings ACMCodecDB::codec_settings_[] = { {2, {kIsacPacSize480, kIsacPacSize960}, 0, 1}, # if (defined(WEBRTC_CODEC_ISAC)) {1, {kIsacPacSize960}, 0, 1}, + {1, {kIsacPacSize1440}, 0, 1}, # endif #endif #ifdef WEBRTC_CODEC_PCM16 @@ -311,6 +313,7 @@ const WebRtcNetEQDecoder ACMCodecDB::neteq_decoders_[] = { kDecoderISAC, # if (defined(WEBRTC_CODEC_ISAC)) kDecoderISACswb, + kDecoderISACfb, # endif #endif #ifdef WEBRTC_CODEC_PCM16 diff --git a/webrtc/modules/audio_coding/main/source/acm_codec_database.h b/webrtc/modules/audio_coding/main/source/acm_codec_database.h index 482215395..30d046217 100644 --- a/webrtc/modules/audio_coding/main/source/acm_codec_database.h +++ b/webrtc/modules/audio_coding/main/source/acm_codec_database.h @@ -33,6 +33,7 @@ class ACMCodecDB { , kISAC # if (defined(WEBRTC_CODEC_ISAC)) , kISACSWB + , kISACFB # endif #endif #ifdef WEBRTC_CODEC_PCM16 @@ -115,6 +116,7 @@ class ACMCodecDB { // Set unsupported codecs to -1 #ifndef WEBRTC_CODEC_ISAC enum {kISACSWB = -1}; + enum {kISACFB = -1}; # ifndef WEBRTC_CODEC_ISACFX enum {kISAC = -1}; # endif diff --git a/webrtc/modules/audio_coding/main/source/acm_common_defs.h b/webrtc/modules/audio_coding/main/source/acm_common_defs.h index cdff1c1c7..06d17f30d 100644 --- a/webrtc/modules/audio_coding/main/source/acm_common_defs.h +++ b/webrtc/modules/audio_coding/main/source/acm_common_defs.h @@ -54,6 +54,7 @@ const int kIsacWbDefaultRate = 32000; const int kIsacSwbDefaultRate = 56000; const int kIsacPacSize480 = 480; const int kIsacPacSize960 = 960; +const int kIsacPacSize1440 = 1440; // An encoded bit-stream is labeled by one of the following enumerators. // diff --git a/webrtc/modules/audio_coding/main/source/acm_isac.cc b/webrtc/modules/audio_coding/main/source/acm_isac.cc index 0e88bc69a..5f734a06e 100644 --- a/webrtc/modules/audio_coding/main/source/acm_isac.cc +++ b/webrtc/modules/audio_coding/main/source/acm_isac.cc @@ -465,7 +465,8 @@ WebRtc_Word16 ACMISAC::InternalInitDecoder(WebRtcACMCodecParams* codecParams) { } // set decoder sampling frequency. - if (codecParams->codecInstant.plfreq == 32000) { + if (codecParams->codecInstant.plfreq == 32000 || + codecParams->codecInstant.plfreq == 48000) { UpdateDecoderSampFreq(ACMCodecDB::kISACSWB); } else { UpdateDecoderSampFreq(ACMCodecDB::kISAC); @@ -556,9 +557,17 @@ WebRtc_Word32 ACMISAC::CodecDef(WebRtcNetEQ_CodecDef& codecDef, #endif } else { #ifdef WEBRTC_CODEC_ISAC - SET_CODEC_PAR((codecDef), kDecoderISACswb, codecInst.pltype, - _codecInstPtr->inst, 32000); - SET_ISACSWB_FUNCTIONS((codecDef)); + // Decoder is either @ 16 kHz or 32 kHz. Even if encoder is set @ 48 kHz + // decoding is @ 32 kHz. + if (codecInst.plfreq == 32000) { + SET_CODEC_PAR((codecDef), kDecoderISACswb, codecInst.pltype, + _codecInstPtr->inst, 32000); + SET_ISACSWB_FUNCTIONS((codecDef)); + } else { + SET_CODEC_PAR((codecDef), kDecoderISACfb, codecInst.pltype, + _codecInstPtr->inst, 32000); + SET_ISACFB_FUNCTIONS((codecDef)); + } #else return -1; #endif @@ -659,7 +668,7 @@ WebRtc_Word16 ACMISAC::SetBitRateSafe(WebRtc_Word32 bitRate) { WebRtc_Word32 ACMISAC::GetEstimatedBandwidthSafe() { WebRtc_Word16 bandwidthIndex = 0; WebRtc_Word16 delayIndex = 0; - IsacSamplingRate sampRate; + int sampRate; // Get bandwidth information ACM_ISAC_GETSENDBWE(_codecInstPtr->inst, &bandwidthIndex, &delayIndex); @@ -671,7 +680,7 @@ WebRtc_Word32 ACMISAC::GetEstimatedBandwidthSafe() { // Check sample frequency sampRate = ACM_ISAC_GETDECSAMPRATE(_codecInstPtr->inst); - if (sampRate == kIsacWideband) { + if (sampRate == 16000) { return isacRatesWB[bandwidthIndex]; } else { return isacRatesSWB[bandwidthIndex]; @@ -680,13 +689,13 @@ WebRtc_Word32 ACMISAC::GetEstimatedBandwidthSafe() { WebRtc_Word32 ACMISAC::SetEstimatedBandwidthSafe( WebRtc_Word32 estimatedBandwidth) { - IsacSamplingRate sampRate; + int sampRate; WebRtc_Word16 bandwidthIndex; // Check sample frequency and choose appropriate table sampRate = ACM_ISAC_GETENCSAMPRATE(_codecInstPtr->inst); - if (sampRate == kIsacWideband) { + if (sampRate == 16000) { // Search through the WB rate table to find the index bandwidthIndex = NR_ISAC_BANDWIDTHS / 2 - 1; for (int i = 0; i < (NR_ISAC_BANDWIDTHS / 2); i++) { @@ -738,10 +747,12 @@ WebRtc_Word32 ACMISAC::GetRedPayloadSafe( WebRtc_Word16 ACMISAC::UpdateDecoderSampFreq( #ifdef WEBRTC_CODEC_ISAC WebRtc_Word16 codecId) { + // The decoder supports only wideband and super-wideband. if (ACMCodecDB::kISAC == codecId) { - return WebRtcIsac_SetDecSampRate(_codecInstPtr->inst, kIsacWideband); - } else if (ACMCodecDB::kISACSWB == codecId) { - return WebRtcIsac_SetDecSampRate(_codecInstPtr->inst, kIsacSuperWideband); + return WebRtcIsac_SetDecSampRate(_codecInstPtr->inst, 16000); + } else if (ACMCodecDB::kISACSWB == codecId || + ACMCodecDB::kISACFB == codecId) { + return WebRtcIsac_SetDecSampRate(_codecInstPtr->inst, 32000); } else { return -1; } @@ -758,24 +769,18 @@ WebRtc_Word16 ACMISAC::UpdateEncoderSampFreq( EncoderSampFreq(currentSampRateHz); if (currentSampRateHz != encoderSampFreqHz) { - if ((encoderSampFreqHz != 16000) && (encoderSampFreqHz != 32000)) { + if ((encoderSampFreqHz != 16000) && (encoderSampFreqHz != 32000) && + (encoderSampFreqHz != 48000)) { return -1; } else { _inAudioIxRead = 0; _inAudioIxWrite = 0; _inTimestampIxWrite = 0; - if (encoderSampFreqHz == 16000) { - if (WebRtcIsac_SetEncSampRate(_codecInstPtr->inst, kIsacWideband) < 0) { - return -1; - } - _samplesIn10MsAudio = 160; - } else { - if (WebRtcIsac_SetEncSampRate(_codecInstPtr->inst, kIsacSuperWideband) - < 0) { - return -1; - } - _samplesIn10MsAudio = 320; + if (WebRtcIsac_SetEncSampRate(_codecInstPtr->inst, + encoderSampFreqHz) < 0) { + return -1; } + _samplesIn10MsAudio = encoderSampFreqHz / 100; _frameLenSmpl = ACM_ISAC_GETNEWFRAMELEN(_codecInstPtr->inst); _encoderParams.codecInstant.pacsize = _frameLenSmpl; _encoderParams.codecInstant.plfreq = encoderSampFreqHz; @@ -789,13 +794,7 @@ WebRtc_Word16 ACMISAC::UpdateEncoderSampFreq( } WebRtc_Word16 ACMISAC::EncoderSampFreq(WebRtc_UWord16& sampFreqHz) { - IsacSamplingRate sampRate; - sampRate = ACM_ISAC_GETENCSAMPRATE(_codecInstPtr->inst); - if (sampRate == kIsacSuperWideband) { - sampFreqHz = 32000; - } else { - sampFreqHz = 16000; - } + sampFreqHz = ACM_ISAC_GETENCSAMPRATE(_codecInstPtr->inst); return 0; } @@ -809,7 +808,7 @@ WebRtc_Word32 ACMISAC::ConfigISACBandwidthEstimator( // TODO(turajs): at 32kHz we hardcode calling with 30ms and enforce // the frame-size otherwise we might get error. Revise if // control-bwe is changed. - if (sampFreqHz == 32000) { + if (sampFreqHz == 32000 || sampFreqHz == 48000) { status = ACM_ISAC_CONTROL_BWE(_codecInstPtr->inst, initRateBitPerSec, 30, 1); } else { diff --git a/webrtc/modules/audio_coding/neteq/codec_db.c b/webrtc/modules/audio_coding/neteq/codec_db.c index 10277d506..3464ad764 100644 --- a/webrtc/modules/audio_coding/neteq/codec_db.c +++ b/webrtc/modules/audio_coding/neteq/codec_db.c @@ -115,6 +115,9 @@ int WebRtcNetEQ_DbAdd(CodecDbInst_t *inst, enum WebRtcNetEQDecoder codec, #ifdef NETEQ_ISAC_SWB_CODEC case kDecoderISACswb : #endif +#ifdef NETEQ_ISAC_FB_CODEC + case kDecoderISACfb : +#endif #ifdef NETEQ_OPUS_CODEC case kDecoderOpus : #endif @@ -463,6 +466,9 @@ int WebRtcNetEQ_DbGetSplitInfo(SplitInfo_t *inst, enum WebRtcNetEQDecoder codecI #ifdef NETEQ_ISAC_SWB_CODEC case kDecoderISACswb: #endif +#ifdef NETEQ_ISAC_FB_CODEC + case kDecoderISACfb: +#endif #ifdef NETEQ_OPUS_CODEC case kDecoderOpus: #endif diff --git a/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq.h b/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq.h index 9621036dc..3d5181e7e 100644 --- a/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq.h +++ b/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq.h @@ -37,6 +37,7 @@ enum WebRtcNetEQDecoder kDecoderILBC, kDecoderISAC, kDecoderISACswb, + kDecoderISACfb, kDecoderPCM16B, kDecoderPCM16Bwb, kDecoderPCM16Bswb32kHz, diff --git a/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h b/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h index 325fcc4bf..58822f1eb 100644 --- a/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h +++ b/webrtc/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h @@ -102,6 +102,18 @@ inst.funcDurationEst=NULL; \ inst.funcGetErrorCode=(WebRtcNetEQ_FuncGetErrorCode)WebRtcIsac_GetErrorCode; +#define SET_ISACFB_FUNCTIONS(inst) \ + inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcIsac_Decode; \ + inst.funcDecodeRCU=(WebRtcNetEQ_FuncDecode)WebRtcIsac_DecodeRcu; \ + inst.funcDecodePLC=NULL; \ + inst.funcDecodeInit=(WebRtcNetEQ_FuncDecodeInit)WebRtcIsac_DecoderInit; \ + inst.funcAddLatePkt=NULL; \ + inst.funcGetMDinfo=NULL; \ + inst.funcGetPitch=NULL; \ + inst.funcUpdBWEst=(WebRtcNetEQ_FuncUpdBWEst)WebRtcIsac_UpdateBwEstimate; \ + inst.funcDurationEst=NULL; \ + inst.funcGetErrorCode=(WebRtcNetEQ_FuncGetErrorCode)WebRtcIsac_GetErrorCode; + #define SET_G729_FUNCTIONS(inst) \ inst.funcDecode=(WebRtcNetEQ_FuncDecode)WebRtcG729_Decode; \ inst.funcDecodeRCU=NULL; \ diff --git a/webrtc/modules/audio_coding/neteq/neteq.gypi b/webrtc/modules/audio_coding/neteq/neteq.gypi index 0d19c8904..8bc35d06a 100644 --- a/webrtc/modules/audio_coding/neteq/neteq.gypi +++ b/webrtc/modules/audio_coding/neteq/neteq.gypi @@ -122,6 +122,7 @@ 'CODEC_ISAC', 'CODEC_PCM16B_WB', 'CODEC_ISAC_SWB', + 'CODEC_ISAC_FB', 'CODEC_PCM16B_32KHZ', 'CODEC_CNGCODEC8', 'CODEC_CNGCODEC16', @@ -159,6 +160,7 @@ 'CODEC_ISAC', 'CODEC_PCM16B_WB', 'CODEC_ISAC_SWB', + 'CODEC_ISAC_FB', 'CODEC_PCM16B_32KHZ', 'CODEC_CNGCODEC8', 'CODEC_CNGCODEC16', @@ -271,6 +273,7 @@ 'CODEC_ISAC', 'CODEC_PCM16B_WB', 'CODEC_ISAC_SWB', + 'CODEC_ISAC_FB', 'CODEC_PCM16B_32KHZ', 'CODEC_CNGCODEC8', 'CODEC_CNGCODEC16', diff --git a/webrtc/modules/audio_coding/neteq/neteq_defines.h b/webrtc/modules/audio_coding/neteq/neteq_defines.h index 79cb144d8..1f092df5f 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_defines.h +++ b/webrtc/modules/audio_coding/neteq/neteq_defines.h @@ -65,6 +65,10 @@ * * NETEQ_ISAC_SWB_CODEC Enable iSAC-SWB * + * Note that the decoder of iSAC full-band operates at 32 kHz, that is the + * decoded signal is at 32 kHz. + * NETEQ_ISAC_FB_CODEC Enable iSAC-FB + * * NETEQ_G722_CODEC Enable G.722 * * NETEQ_G729_CODEC Enable G.729 @@ -302,6 +306,7 @@ /* Fullband 48 kHz codecs */ #define NETEQ_OPUS_CODEC + #define NETEQ_ISAC_FB_CODEC #endif #if (defined(NETEQ_ALL_CODECS)) @@ -339,6 +344,7 @@ /* Super wideband 48kHz codecs */ #define NETEQ_48KHZ_WIDEBAND #define NETEQ_OPUS_CODEC + #define NETEQ_ISAC_FB #endif /* Max output size from decoding one frame */ diff --git a/webrtc/modules/audio_coding/neteq/packet_buffer.c b/webrtc/modules/audio_coding/neteq/packet_buffer.c index 60e51985c..bb2d08e29 100644 --- a/webrtc/modules/audio_coding/neteq/packet_buffer.c +++ b/webrtc/modules/audio_coding/neteq/packet_buffer.c @@ -615,7 +615,8 @@ int WebRtcNetEQ_GetDefaultCodecSettings(const enum WebRtcNetEQDecoder *codecID, codecBytes = 960; /* 240ms @ 32kbps (60ms frames) */ codecBuffers = 8; } - else if (codecID[i] == kDecoderISACswb) + else if ((codecID[i] == kDecoderISACswb) || + (codecID[i] == kDecoderISACfb)) { codecBytes = 1560; /* 240ms @ 52kbps (30ms frames) */ codecBuffers = 8; diff --git a/webrtc/modules/audio_coding/neteq/recin.c b/webrtc/modules/audio_coding/neteq/recin.c index 00c8f81da..c2f0d2d44 100644 --- a/webrtc/modules/audio_coding/neteq/recin.c +++ b/webrtc/modules/audio_coding/neteq/recin.c @@ -380,11 +380,12 @@ int WebRtcNetEQ_GetTimestampScaling(MCUInst_t *MCU_inst, int rtpPayloadType) MCU_inst->scalingFactor = kTSscalingTwo; break; } + case kDecoderISACfb: case kDecoderOpus: { - /* We resample Opus internally to 32 kHz, but timestamps - * are counted at 48 kHz. So there are two output samples - * per three RTP timestamp ticks. */ + /* We resample Opus internally to 32 kHz, and isac-fb decodes at + * 32 kHz, but timestamps are counted at 48 kHz. So there are two + * output samples per three RTP timestamp ticks. */ MCU_inst->scalingFactor = kTSscalingTwoThirds; break; } diff --git a/webrtc/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.cc b/webrtc/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.cc index 0056ddc49..25f10b02f 100644 --- a/webrtc/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.cc +++ b/webrtc/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.cc @@ -53,7 +53,7 @@ NETEQTEST_Decoder(kDecoderISAC, 16000, "iSAC", pt) } WebRtcIsac_EncoderInit((ISACStruct *) _decoder, 0); - WebRtcIsac_SetDecSampRate((ISACStruct *) _decoder, kIsacWideband); + WebRtcIsac_SetDecSampRate((ISACStruct *) _decoder, 16000); } @@ -90,7 +90,7 @@ NETEQTEST_Decoder(kDecoderISACswb, 32000, "iSAC swb", pt) } WebRtcIsac_EncoderInit((ISACStruct *) _decoder, 0); - WebRtcIsac_SetDecSampRate((ISACStruct *) _decoder, kIsacSuperWideband); + WebRtcIsac_SetDecSampRate((ISACStruct *) _decoder, 32000); } decoder_iSACSWB::~decoder_iSACSWB() @@ -113,6 +113,32 @@ int decoder_iSACSWB::loadToNetEQ(NETEQTEST_NetEQClass & neteq) } #endif +#ifdef CODEC_ISAC_FB +decoder_iSACFB::decoder_iSACFB(WebRtc_UWord8 pt) + : NETEQTEST_Decoder(kDecoderISACfb, 32000, "iSAC fb", pt) { + WebRtc_Word16 err = WebRtcIsac_Create((ISACStruct **) &_decoder); + if (err) { + exit(EXIT_FAILURE); + } + + WebRtcIsac_EncoderInit((ISACStruct *) _decoder, 0); + WebRtcIsac_SetDecSampRate((ISACStruct *) _decoder, 32000); +} + +decoder_iSACFB::~decoder_iSACFB() { + if (_decoder) { + WebRtcIsac_Free((ISACStruct *) _decoder); + _decoder = NULL; + } +} + +int decoder_iSACFB::loadToNetEQ(NETEQTEST_NetEQClass & neteq){ + WebRtcNetEQ_CodecDef codecInst; + SET_ISACFB_FUNCTIONS(codecInst); + return(NETEQTEST_Decoder::loadToNetEQ(neteq, codecInst)); +} +#endif + // PCM u/A #ifdef CODEC_G711 #include "g711_interface.h" diff --git a/webrtc/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.h b/webrtc/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.h index 699079429..43f16a5d5 100644 --- a/webrtc/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.h +++ b/webrtc/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.h @@ -64,6 +64,14 @@ public: }; +class decoder_iSACFB : public NETEQTEST_Decoder { + public: + decoder_iSACFB(WebRtc_UWord8 pt = 0); + virtual ~decoder_iSACFB(); + int loadToNetEQ(NETEQTEST_NetEQClass & neteq); +}; + + class decoder_PCMU : public NETEQTEST_Decoder { public: diff --git a/webrtc/modules/audio_coding/neteq/test/NetEqRTPplay.cc b/webrtc/modules/audio_coding/neteq/test/NetEqRTPplay.cc index 8aa88d800..83fcbfaab 100644 --- a/webrtc/modules/audio_coding/neteq/test/NetEqRTPplay.cc +++ b/webrtc/modules/audio_coding/neteq/test/NetEqRTPplay.cc @@ -955,6 +955,12 @@ void parsePtypeFile(FILE *ptypeFile, std::map* dec tempDecoder.fs = 32000; } #endif +#ifdef CODEC_ISAC_FB + else if(strcmp(codec, "isacfb") == 0) { + tempDecoder.codec = kDecoderISACfb; + tempDecoder.fs = 32000; + } +#endif #ifdef CODEC_IPCMWB else if(strcmp(codec, "ipcmwb") == 0) { tempDecoder.codec = kDecoderIPCMwb; @@ -1358,6 +1364,11 @@ void createAndInsertDecoders (NETEQTEST_NetEQClass *neteq, std::map 56000)) { printf( - "Error: iSAC SWB bitrate must be between 32000 and 56000 bps (%i is invalid)\n", + "Error: iSAC SWB/FB bitrate must be between 32000 and 56000 bps (%i is invalid)\n", bitrate); exit(0); } @@ -970,11 +977,16 @@ void NetEQTest_GetCodec_and_PT(char * name, enum WebRtcNetEQDecoder *codec, int *codec=kDecoderISAC; *PT=NETEQ_CODEC_ISAC_PT; } - else if(!strcmp(name,"isacswb")){ - *fs=32000; - *codec=kDecoderISACswb; - *PT=NETEQ_CODEC_ISACSWB_PT; + else if(!strcmp(name,"isacswb")){ + *fs=32000; + *codec=kDecoderISACswb; + *PT=NETEQ_CODEC_ISACSWB_PT; } + else if(!strcmp(name,"isacfb")){ + *fs=48000; + *codec=kDecoderISACfb; + *PT=NETEQ_CODEC_ISACFB_PT; + } else if(!strcmp(name,"g729")){ *fs=8000; *codec=kDecoderG729; @@ -1481,7 +1493,7 @@ int NetEQTest_init_coders(enum WebRtcNetEQDecoder coder, int enc_frameSize, int printf("\nError - iSAC SWB only supports frameSize 30 ms\n"); exit(0); } - ok = WebRtcIsac_SetEncSampRate(ISACSWB_inst[k], kIsacSuperWideband); + ok = WebRtcIsac_SetEncSampRate(ISACSWB_inst[k], 32000); if (ok!=0) { printf("Error: Couldn't set sample rate for iSAC SWB instance\n"); exit(0); @@ -1498,6 +1510,38 @@ int NetEQTest_init_coders(enum WebRtcNetEQDecoder coder, int enc_frameSize, int } break; #endif +#ifdef CODEC_ISAC_FB + case kDecoderISACfb: + if (sampfreq == 48000) { + ok = WebRtcIsac_Create(&ISACFB_inst[k]); + if (ok != 0) { + printf("Error: Couldn't allocate memory for iSAC FB " + "instance\n"); + exit(0); + } + if (enc_frameSize != 1440) { + printf("\nError - iSAC FB only supports frameSize 30 ms\n"); + exit(0); + } + ok = WebRtcIsac_SetEncSampRate(ISACFB_inst[k], 48000); + if (ok != 0) { + printf("Error: Couldn't set sample rate for iSAC FB " + "instance\n"); + exit(0); + } + WebRtcIsac_EncoderInit(ISACFB_inst[k], 1); + if ((bitrate < 32000) || (bitrate > 56000)) { + printf("\nError - iSAC FB bitrate has to be between 32000 and" + "56000 bps (not %i)\n", bitrate); + exit(0); + } + WebRtcIsac_Control(ISACFB_inst[k], bitrate, 30); + } else { + printf("\nError - iSAC FB only support 48 kHz sampling rate.\n"); + exit(0); + } + break; +#endif #ifdef CODEC_GSMFR case kDecoderGSMFR: if (sampfreq==8000) { @@ -1657,6 +1701,11 @@ int NetEQTest_free_coders(enum WebRtcNetEQDecoder coder, int numChannels) { WebRtcIsac_Free(ISACSWB_inst[k]); break; #endif +#ifdef CODEC_ISAC_FB + case kDecoderISACfb: + WebRtcIsac_Free(ISACFB_inst[k]); + break; +#endif #ifdef CODEC_GSMFR case kDecoderGSMFR: WebRtcGSMFR_FreeEnc(GSMFRenc_inst[k]); @@ -1859,6 +1908,18 @@ int NetEQTest_encode(int coder, WebRtc_Word16 *indata, int frameLen, unsigned ch } } #endif +#ifdef CODEC_ISAC_FB + else if (coder == kDecoderISACfb) { /* iSAC FB */ + int noOfCalls = 0; + cdlen = 0; + while (cdlen <= 0) { + cdlen = WebRtcIsac_Encode(ISACFB_inst[k], + &indata[noOfCalls * 480], + (WebRtc_Word16*)encoded); + noOfCalls++; + } + } +#endif #ifdef CODEC_GSMFR else if (coder==kDecoderGSMFR) { /* GSM FR */ cdlen=WebRtcGSMFR_Encode(GSMFRenc_inst[k], indata, frameLen, (WebRtc_Word16*)encoded); diff --git a/webrtc/modules/audio_coding/neteq/test/ptypes.txt b/webrtc/modules/audio_coding/neteq/test/ptypes.txt index c3d4e2572..04d35a6d4 100644 --- a/webrtc/modules/audio_coding/neteq/test/ptypes.txt +++ b/webrtc/modules/audio_coding/neteq/test/ptypes.txt @@ -7,6 +7,7 @@ cn 13 ilbc 102 isac 103 isacswb 104 +isacfb 124 avt 106 red 117 cn_wb 98 diff --git a/webrtc/modules/audio_coding/neteq/webrtc_neteq_unittest.cc b/webrtc/modules/audio_coding/neteq/webrtc_neteq_unittest.cc index 77e756969..ebb96aab8 100644 --- a/webrtc/modules/audio_coding/neteq/webrtc_neteq_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/webrtc_neteq_unittest.cc @@ -239,6 +239,8 @@ void NetEqDecodingTest::SelectDecoders(WebRtcNetEQDecoder* used_codec) { dec_.push_back(new decoder_iSAC(103)); *used_codec++ = kDecoderISACswb; dec_.push_back(new decoder_iSACSWB(104)); + *used_codec++ = kDecoderISACfb; + dec_.push_back(new decoder_iSACFB(105)); *used_codec++ = kDecoderPCM16B; dec_.push_back(new decoder_PCM16B_NB(93)); *used_codec++ = kDecoderPCM16Bwb; diff --git a/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc b/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc index bf6094697..2035e4eea 100644 --- a/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc +++ b/webrtc/voice_engine/test/cmd_test/voe_cmd_test.cc @@ -340,8 +340,10 @@ void RunTest(std::string out_path) { if (strncmp(cinst.plname, "ISAC", 4) == 0 && cinst.plfreq == 32000) { printf("%i. ISAC-swb pltype:%i plfreq:%i channels:%i\n", i, cinst.pltype, cinst.plfreq, cinst.channels); - } - else { + } else if (strncmp(cinst.plname, "ISAC", 4) == 0 && cinst.plfreq == 48000) { + printf("%i. ISAC-fb pltype:%i plfreq:%i channels:%i\n", i, cinst.pltype, + cinst.plfreq, cinst.channels); + } else { printf("%i. %s pltype:%i plfreq:%i channels:%i\n", i, cinst.plname, cinst.pltype, cinst.plfreq, cinst.channels); }