48 kHz extension to iSAC.
Test:
-manual test with voe_cmd_test.
-manual test with RTPEncode & NetEqRTPPlay.
-manual test with simpleKenny.
-Bit-exact test of iSAC-swb and iSAC-wb with head revision of trunk. The bit-exactness is confirmed on all files generated by running webrtc/modules/audio_coding/codecs/isac/main/test/QA/runiSACLongtest.txt
Review URL: https://webrtc-codereview.appspot.com/937025
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@3226 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/modules/audio_coding/codecs/isac/main/interface/isac.h b/modules/audio_coding/codecs/isac/main/interface/isac.h
index 03c260b..6ae6c1a 100644
--- a/modules/audio_coding/codecs/isac/main/interface/isac.h
+++ b/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 @@
* 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 @@
* 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 @@
*
* 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 @@
*
* 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/modules/audio_coding/codecs/isac/main/source/decode_bwe.c b/modules/audio_coding/codecs/isac/main/source/decode_bwe.c
index cdac7fa..a92b9b9 100644
--- a/modules/audio_coding/codecs/isac/main/source/decode_bwe.c
+++ b/modules/audio_coding/codecs/isac/main/source/decode_bwe.c
@@ -68,6 +68,7 @@
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/modules/audio_coding/codecs/isac/main/source/isac.c b/modules/audio_coding/codecs/isac/main/source/isac.c
index 7c90334..428fda8 100644
--- a/modules/audio_coding/codecs/isac/main/source/isac.c
+++ b/modules/audio_coding/codecs/isac/main/source/isac.c
@@ -249,6 +249,7 @@
instISAC->encoderSamplingRateKHz = kIsacWideband;
instISAC->decoderSamplingRateKHz = kIsacWideband;
instISAC->bandwidthKHz = isac8kHz;
+ instISAC->in_sample_rate_hz = 16000;
return 0;
} else {
return -1;
@@ -280,6 +281,7 @@
instISAC->bandwidthKHz = isac8kHz;
instISAC->encoderSamplingRateKHz = kIsacWideband;
instISAC->decoderSamplingRateKHz = kIsacWideband;
+ instISAC->in_sample_rate_hz = 16000;
return 0;
} else {
return -1;
@@ -458,6 +460,7 @@
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 @@
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 @@
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 @@
* 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 @@
*
* 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 @@
/****************************************************************************
* 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 @@
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 @@
} 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 @@
* 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 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 @@
}
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 @@
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 @@
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 @@
*
* 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 @@
if (DecoderInitUb(&(instISAC->instUB)) < 0) {
return -1;
}
- }
- instISAC->decoderSamplingRateKHz = sampRate;
- return 0;
}
+ instISAC->decoderSamplingRateKHz = decoder_operational_rate;
+ return 0;
}
@@ -2284,14 +2345,13 @@
* 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 @@
* 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/modules/audio_coding/codecs/isac/main/source/settings.h b/modules/audio_coding/codecs/isac/main/source/settings.h
index 9c1ec1e..5562c35 100644
--- a/modules/audio_coding/codecs/isac/main/source/settings.h
+++ b/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 @@
#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/modules/audio_coding/codecs/isac/main/source/structs.h b/modules/audio_coding/codecs/isac/main/source/structs.h
index 96cef30..39a86d2 100644
--- a/modules/audio_coding/codecs/isac/main/source/structs.h
+++ b/modules/audio_coding/codecs/isac/main/source/structs.h
@@ -472,6 +472,12 @@
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/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc b/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc
index 04c5367..ca05c2c 100644
--- a/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc
+++ b/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc
@@ -477,8 +477,9 @@
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 @@
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 @@
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/modules/audio_coding/codecs/isac/main/test/SwitchingSampRate/SwitchingSampRate.cc b/modules/audio_coding/codecs/isac/main/test/SwitchingSampRate/SwitchingSampRate.cc
index cccae28..196eb11 100644
--- a/modules/audio_coding/codecs/isac/main/test/SwitchingSampRate/SwitchingSampRate.cc
+++ b/modules/audio_coding/codecs/isac/main/test/SwitchingSampRate/SwitchingSampRate.cc
@@ -38,7 +38,7 @@
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 @@
}
// 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 @@
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 @@
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 @@
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 @@
}
- if(encoderSampRate[senderIdx] == kIsacWideband)
+ if(encoderSampRate[senderIdx] == 16000)
{
WebRtcSpl_UpsampleBy2(audioBuff60ms, lenDecodedAudio, resampledAudio60ms,
resamplerState[receiverIdx]);
diff --git a/modules/audio_coding/codecs/isac/main/test/simpleKenny.c b/modules/audio_coding/codecs/isac/main/test/simpleKenny.c
index be1588c..f1b78c2 100644
--- a/modules/audio_coding/codecs/isac/main/test/simpleKenny.c
+++ b/modules/audio_coding/codecs/isac/main/test/simpleKenny.c
@@ -254,8 +254,9 @@
/* 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/modules/audio_coding/main/source/acm_codec_database.cc b/modules/audio_coding/main/source/acm_codec_database.cc
index 1c9a409..b860b8a 100644
--- a/modules/audio_coding/main/source/acm_codec_database.cc
+++ b/modules/audio_coding/main/source/acm_codec_database.cc
@@ -107,10 +107,10 @@
// 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 @@
{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 @@
{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 @@
kDecoderISAC,
# if (defined(WEBRTC_CODEC_ISAC))
kDecoderISACswb,
+ kDecoderISACfb,
# endif
#endif
#ifdef WEBRTC_CODEC_PCM16
diff --git a/modules/audio_coding/main/source/acm_codec_database.h b/modules/audio_coding/main/source/acm_codec_database.h
index 4822153..30d0462 100644
--- a/modules/audio_coding/main/source/acm_codec_database.h
+++ b/modules/audio_coding/main/source/acm_codec_database.h
@@ -33,6 +33,7 @@
, kISAC
# if (defined(WEBRTC_CODEC_ISAC))
, kISACSWB
+ , kISACFB
# endif
#endif
#ifdef WEBRTC_CODEC_PCM16
@@ -115,6 +116,7 @@
// 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/modules/audio_coding/main/source/acm_common_defs.h b/modules/audio_coding/main/source/acm_common_defs.h
index cdff1c1..06d17f3 100644
--- a/modules/audio_coding/main/source/acm_common_defs.h
+++ b/modules/audio_coding/main/source/acm_common_defs.h
@@ -54,6 +54,7 @@
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/modules/audio_coding/main/source/acm_isac.cc b/modules/audio_coding/main/source/acm_isac.cc
index 0e88bc6..5f734a0 100644
--- a/modules/audio_coding/main/source/acm_isac.cc
+++ b/modules/audio_coding/main/source/acm_isac.cc
@@ -465,7 +465,8 @@
}
// 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 @@
#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_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 @@
// 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::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_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 @@
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::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 @@
// 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/modules/audio_coding/neteq/codec_db.c b/modules/audio_coding/neteq/codec_db.c
index 10277d5..3464ad7 100644
--- a/modules/audio_coding/neteq/codec_db.c
+++ b/modules/audio_coding/neteq/codec_db.c
@@ -115,6 +115,9 @@
#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 @@
#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/modules/audio_coding/neteq/interface/webrtc_neteq.h b/modules/audio_coding/neteq/interface/webrtc_neteq.h
index 9621036..3d5181e 100644
--- a/modules/audio_coding/neteq/interface/webrtc_neteq.h
+++ b/modules/audio_coding/neteq/interface/webrtc_neteq.h
@@ -37,6 +37,7 @@
kDecoderILBC,
kDecoderISAC,
kDecoderISACswb,
+ kDecoderISACfb,
kDecoderPCM16B,
kDecoderPCM16Bwb,
kDecoderPCM16Bswb32kHz,
diff --git a/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h b/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h
index 325fcc4..58822f1 100644
--- a/modules/audio_coding/neteq/interface/webrtc_neteq_help_macros.h
+++ b/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/modules/audio_coding/neteq/neteq.gypi b/modules/audio_coding/neteq/neteq.gypi
index 0d19c89..8bc35d0 100644
--- a/modules/audio_coding/neteq/neteq.gypi
+++ b/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/modules/audio_coding/neteq/neteq_defines.h b/modules/audio_coding/neteq/neteq_defines.h
index 79cb144..1f092df 100644
--- a/modules/audio_coding/neteq/neteq_defines.h
+++ b/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/modules/audio_coding/neteq/packet_buffer.c b/modules/audio_coding/neteq/packet_buffer.c
index 60e5198..bb2d08e 100644
--- a/modules/audio_coding/neteq/packet_buffer.c
+++ b/modules/audio_coding/neteq/packet_buffer.c
@@ -615,7 +615,8 @@
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/modules/audio_coding/neteq/recin.c b/modules/audio_coding/neteq/recin.c
index 00c8f81..c2f0d2d 100644
--- a/modules/audio_coding/neteq/recin.c
+++ b/modules/audio_coding/neteq/recin.c
@@ -380,11 +380,12 @@
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/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.cc b/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.cc
index 0056ddc..25f10b0 100644
--- a/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.cc
+++ b/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.cc
@@ -53,7 +53,7 @@
}
WebRtcIsac_EncoderInit((ISACStruct *) _decoder, 0);
- WebRtcIsac_SetDecSampRate((ISACStruct *) _decoder, kIsacWideband);
+ WebRtcIsac_SetDecSampRate((ISACStruct *) _decoder, 16000);
}
@@ -90,7 +90,7 @@
}
WebRtcIsac_EncoderInit((ISACStruct *) _decoder, 0);
- WebRtcIsac_SetDecSampRate((ISACStruct *) _decoder, kIsacSuperWideband);
+ WebRtcIsac_SetDecSampRate((ISACStruct *) _decoder, 32000);
}
decoder_iSACSWB::~decoder_iSACSWB()
@@ -113,6 +113,32 @@
}
#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/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.h b/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.h
index 6990794..43f16a5 100644
--- a/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.h
+++ b/modules/audio_coding/neteq/test/NETEQTEST_CodecClass.h
@@ -64,6 +64,14 @@
};
+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/modules/audio_coding/neteq/test/NetEqRTPplay.cc b/modules/audio_coding/neteq/test/NetEqRTPplay.cc
index 8aa88d8..83fcbfa 100644
--- a/modules/audio_coding/neteq/test/NetEqRTPplay.cc
+++ b/modules/audio_coding/neteq/test/NetEqRTPplay.cc
@@ -955,6 +955,12 @@
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 @@
*dec = new decoder_iSACSWB( pt );
break;
#endif
+#ifdef CODEC_ISAC_FB
+ case kDecoderISACfb:
+ *dec = new decoder_iSACFB(pt);
+ break;
+#endif
#ifdef CODEC_G729
case kDecoderG729:
*dec = new decoder_G729( pt );
diff --git a/modules/audio_coding/neteq/test/PayloadTypes.h b/modules/audio_coding/neteq/test/PayloadTypes.h
index f6cc3da..f74e245 100644
--- a/modules/audio_coding/neteq/test/PayloadTypes.h
+++ b/modules/audio_coding/neteq/test/PayloadTypes.h
@@ -35,6 +35,7 @@
#define NETEQ_CODEC_ISAC_PT 103
#define NETEQ_CODEC_ISACLC_PT 119
#define NETEQ_CODEC_ISACSWB_PT 104
+#define NETEQ_CODEC_ISACFB_PT 124
#define NETEQ_CODEC_AVT_PT 106
#define NETEQ_CODEC_G722_1_16_PT 108
#define NETEQ_CODEC_G722_1_24_PT 109
@@ -53,7 +54,7 @@
#define NETEQ_CODEC_CN_SWB_PT 126
#define NETEQ_CODEC_G729_1_PT 107
#define NETEQ_CODEC_G729D_PT 123
-#define NETEQ_CODEC_MELPE_PT 124
+//#define NETEQ_CODEC_MELPE_PT 124
#define NETEQ_CODEC_CELT32_PT 114
/* Extra dynamic codepoints */
diff --git a/modules/audio_coding/neteq/test/RTPencode.cc b/modules/audio_coding/neteq/test/RTPencode.cc
index 3aaaf6c..32b0bcc 100644
--- a/modules/audio_coding/neteq/test/RTPencode.cc
+++ b/modules/audio_coding/neteq/test/RTPencode.cc
@@ -110,7 +110,7 @@
#ifdef CODEC_ILBC
#include "ilbc.h"
#endif
-#if (defined CODEC_ISAC || defined CODEC_ISAC_SWB)
+#if (defined CODEC_ISAC || defined CODEC_ISAC_SWB || defined CODEC_ISAC_FB)
#include "isac.h"
#endif
#ifdef NETEQ_ISACFIX_CODEC
@@ -217,6 +217,9 @@
#ifdef CODEC_ISAC_SWB
ISACStruct *ISACSWB_inst[2];
#endif
+#ifdef CODEC_ISAC_FB
+ ISACStruct *ISACFB_inst[2];
+#endif
#ifdef CODEC_GSMFR
GSMFR_encinst_t *GSMFRenc_inst[2];
#endif
@@ -362,6 +365,9 @@
#ifdef CODEC_ISAC_SWB
printf(" : isacswb iSAC SWB (32kHz and 32.0-52.0 kbps). To set rate specify a rate parameter as last parameter\n");
#endif
+#ifdef CODEC_ISAC_FB
+ printf(" : isacfb iSAC FB (48kHz encoder 32kHz decoder and 32.0-52.0 kbps). To set rate specify a rate parameter as last parameter\n");
+#endif
#ifdef CODEC_GSMFR
printf(" : gsmfr GSM FR codec (8kHz and 13kbps)\n");
#endif
@@ -482,7 +488,8 @@
}
}
- if ((usedCodec == kDecoderISAC) || (usedCodec == kDecoderISACswb))
+ if ((usedCodec == kDecoderISAC) || (usedCodec == kDecoderISACswb) ||
+ (usedCodec == kDecoderISACfb))
{
if (argc != 7)
{
@@ -492,7 +499,7 @@
printf(
"Running iSAC at default bitrate of 32000 bps (to specify explicitly add the bps as last parameter)\n");
}
- else // (usedCodec==kDecoderISACswb)
+ else // usedCodec == kDecoderISACswb || usedCodec == kDecoderISACfb
{
bitrate = 56000;
printf(
@@ -513,12 +520,12 @@
}
printf("Running iSAC at bitrate of %i bps\n", bitrate);
}
- else // (usedCodec==kDecoderISACswb)
+ else // usedCodec == kDecoderISACswb || usedCodec == kDecoderISACfb
{
if ((bitrate < 32000) || (bitrate > 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 @@
*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 @@
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 @@
}
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 @@
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 @@
}
}
#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/modules/audio_coding/neteq/test/ptypes.txt b/modules/audio_coding/neteq/test/ptypes.txt
index c3d4e25..04d35a6 100644
--- a/modules/audio_coding/neteq/test/ptypes.txt
+++ b/modules/audio_coding/neteq/test/ptypes.txt
@@ -7,6 +7,7 @@
ilbc 102
isac 103
isacswb 104
+isacfb 124
avt 106
red 117
cn_wb 98
diff --git a/modules/audio_coding/neteq/webrtc_neteq_unittest.cc b/modules/audio_coding/neteq/webrtc_neteq_unittest.cc
index 77e7569..ebb96aa 100644
--- a/modules/audio_coding/neteq/webrtc_neteq_unittest.cc
+++ b/modules/audio_coding/neteq/webrtc_neteq_unittest.cc
@@ -239,6 +239,8 @@
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/voice_engine/test/cmd_test/voe_cmd_test.cc b/voice_engine/test/cmd_test/voe_cmd_test.cc
index bf60946..2035e4e 100644
--- a/voice_engine/test/cmd_test/voe_cmd_test.cc
+++ b/voice_engine/test/cmd_test/voe_cmd_test.cc
@@ -340,8 +340,10 @@
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);
}