iSAC: Move global trig tables into the codec instance
These tables are constant, so it makes sense for all encoders to share one copy---but it was initialized in a racy way, and there's no appealing way to fix that without adding dependencies on locking functions. So we simply give each codec instance its own copy, which costs 8 * (240 + 240 + 120 + 120) = 5760 bytes apiece. As noted in the TODO comment, the size of the tables could be reduced, and they could be filled in at compile-time, but that would make the encoder output slightly different, which would mess with our tests. R=henrik.lundin@webrtc.org, solenberg@webrtc.org Review URL: https://codereview.webrtc.org/1177993003. Cr-Commit-Position: refs/heads/master@{#9442}
This commit is contained in:
@ -31,16 +31,20 @@ int WebRtcIsac_EstimateBandwidth(BwEstimatorstr* bwest_str, Bitstr* streamdata,
|
|||||||
enum IsacSamplingRate encoderSampRate,
|
enum IsacSamplingRate encoderSampRate,
|
||||||
enum IsacSamplingRate decoderSampRate);
|
enum IsacSamplingRate decoderSampRate);
|
||||||
|
|
||||||
int WebRtcIsac_DecodeLb(float* signal_out, ISACLBDecStruct* ISACdec_obj,
|
int WebRtcIsac_DecodeLb(const TransformTables* transform_tables,
|
||||||
|
float* signal_out,
|
||||||
|
ISACLBDecStruct* ISACdec_obj,
|
||||||
int16_t* current_framesamples,
|
int16_t* current_framesamples,
|
||||||
int16_t isRCUPayload);
|
int16_t isRCUPayload);
|
||||||
|
|
||||||
int WebRtcIsac_DecodeRcuLb(float* signal_out, ISACLBDecStruct* ISACdec_obj,
|
int WebRtcIsac_DecodeRcuLb(float* signal_out, ISACLBDecStruct* ISACdec_obj,
|
||||||
int16_t* current_framesamples);
|
int16_t* current_framesamples);
|
||||||
|
|
||||||
int WebRtcIsac_EncodeLb(float* in, ISACLBEncStruct* ISACencLB_obj,
|
int WebRtcIsac_EncodeLb(const TransformTables* transform_tables,
|
||||||
int16_t codingMode, int16_t
|
float* in,
|
||||||
bottleneckIndex);
|
ISACLBEncStruct* ISACencLB_obj,
|
||||||
|
int16_t codingMode,
|
||||||
|
int16_t bottleneckIndex);
|
||||||
|
|
||||||
int WebRtcIsac_EncodeStoredDataLb(const IsacSaveEncoderData* ISACSavedEnc_obj,
|
int WebRtcIsac_EncodeStoredDataLb(const IsacSaveEncoderData* ISACSavedEnc_obj,
|
||||||
Bitstr* ISACBitStr_obj, int BWnumber,
|
Bitstr* ISACBitStr_obj, int BWnumber,
|
||||||
@ -93,10 +97,11 @@ int16_t WebRtcIsac_RateAllocation(int32_t inRateBitPerSec,
|
|||||||
* Return value : >0 number of decoded bytes.
|
* Return value : >0 number of decoded bytes.
|
||||||
* <0 if an error occurred.
|
* <0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int WebRtcIsac_DecodeUb16(float* signal_out, ISACUBDecStruct* ISACdec_obj,
|
int WebRtcIsac_DecodeUb16(const TransformTables* transform_tables,
|
||||||
|
float* signal_out,
|
||||||
|
ISACUBDecStruct* ISACdec_obj,
|
||||||
int16_t isRCUPayload);
|
int16_t isRCUPayload);
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* WebRtcIsac_DecodeUb12()
|
* WebRtcIsac_DecodeUb12()
|
||||||
*
|
*
|
||||||
@ -112,10 +117,11 @@ int WebRtcIsac_DecodeUb16(float* signal_out, ISACUBDecStruct* ISACdec_obj,
|
|||||||
* Return value : >0 number of decoded bytes.
|
* Return value : >0 number of decoded bytes.
|
||||||
* <0 if an error occurred.
|
* <0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int WebRtcIsac_DecodeUb12(float* signal_out, ISACUBDecStruct* ISACdec_obj,
|
int WebRtcIsac_DecodeUb12(const TransformTables* transform_tables,
|
||||||
|
float* signal_out,
|
||||||
|
ISACUBDecStruct* ISACdec_obj,
|
||||||
int16_t isRCUPayload);
|
int16_t isRCUPayload);
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* WebRtcIsac_EncodeUb16()
|
* WebRtcIsac_EncodeUb16()
|
||||||
*
|
*
|
||||||
@ -131,10 +137,11 @@ int WebRtcIsac_DecodeUb12(float* signal_out, ISACUBDecStruct* ISACdec_obj,
|
|||||||
* Return value : >0 number of encoded bytes.
|
* Return value : >0 number of encoded bytes.
|
||||||
* <0 if an error occurred.
|
* <0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACenc_obj,
|
int WebRtcIsac_EncodeUb16(const TransformTables* transform_tables,
|
||||||
|
float* in,
|
||||||
|
ISACUBEncStruct* ISACenc_obj,
|
||||||
int32_t jitterInfo);
|
int32_t jitterInfo);
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* WebRtcIsac_EncodeUb12()
|
* WebRtcIsac_EncodeUb12()
|
||||||
*
|
*
|
||||||
@ -150,7 +157,9 @@ int WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACenc_obj,
|
|||||||
* Return value : >0 number of encoded bytes.
|
* Return value : >0 number of encoded bytes.
|
||||||
* <0 if an error occurred.
|
* <0 if an error occurred.
|
||||||
*/
|
*/
|
||||||
int WebRtcIsac_EncodeUb12(float* in, ISACUBEncStruct* ISACenc_obj,
|
int WebRtcIsac_EncodeUb12(const TransformTables* transform_tables,
|
||||||
|
float* in,
|
||||||
|
ISACUBEncStruct* ISACenc_obj,
|
||||||
int32_t jitterInfo);
|
int32_t jitterInfo);
|
||||||
|
|
||||||
/************************** initialization functions *************************/
|
/************************** initialization functions *************************/
|
||||||
@ -168,14 +177,21 @@ void WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct* State);
|
|||||||
|
|
||||||
/**************************** transform functions ****************************/
|
/**************************** transform functions ****************************/
|
||||||
|
|
||||||
void WebRtcIsac_InitTransform();
|
void WebRtcIsac_InitTransform(TransformTables* tables);
|
||||||
|
|
||||||
void WebRtcIsac_Time2Spec(double* inre1, double* inre2, int16_t* outre,
|
void WebRtcIsac_Time2Spec(const TransformTables* tables,
|
||||||
int16_t* outim, FFTstr* fftstr_obj);
|
double* inre1,
|
||||||
|
double* inre2,
|
||||||
void WebRtcIsac_Spec2time(double* inre, double* inim, double* outre1,
|
int16_t* outre,
|
||||||
double* outre2, FFTstr* fftstr_obj);
|
int16_t* outim,
|
||||||
|
FFTstr* fftstr_obj);
|
||||||
|
|
||||||
|
void WebRtcIsac_Spec2time(const TransformTables* tables,
|
||||||
|
double* inre,
|
||||||
|
double* inim,
|
||||||
|
double* outre1,
|
||||||
|
double* outre2,
|
||||||
|
FFTstr* fftstr_obj);
|
||||||
|
|
||||||
/******************************* filter functions ****************************/
|
/******************************* filter functions ****************************/
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@
|
|||||||
* function to decode the bitstream
|
* function to decode the bitstream
|
||||||
* returns the total number of bytes in the stream
|
* returns the total number of bytes in the stream
|
||||||
*/
|
*/
|
||||||
int WebRtcIsac_DecodeLb(float* signal_out, ISACLBDecStruct* ISACdecLB_obj,
|
int WebRtcIsac_DecodeLb(const TransformTables* transform_tables,
|
||||||
|
float* signal_out, ISACLBDecStruct* ISACdecLB_obj,
|
||||||
int16_t* current_framesamples,
|
int16_t* current_framesamples,
|
||||||
int16_t isRCUPayload) {
|
int16_t isRCUPayload) {
|
||||||
int k;
|
int k;
|
||||||
@ -122,7 +123,7 @@ int WebRtcIsac_DecodeLb(float* signal_out, ISACLBDecStruct* ISACdecLB_obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Inverse transform. */
|
/* Inverse transform. */
|
||||||
WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw,
|
WebRtcIsac_Spec2time(transform_tables, real_f, imag_f, LPw, HPw,
|
||||||
&ISACdecLB_obj->fftstr_obj);
|
&ISACdecLB_obj->fftstr_obj);
|
||||||
|
|
||||||
/* Convert PitchGains back to float for pitchfilter_post */
|
/* Convert PitchGains back to float for pitchfilter_post */
|
||||||
@ -181,7 +182,8 @@ int WebRtcIsac_DecodeLb(float* signal_out, ISACLBDecStruct* ISACdecLB_obj,
|
|||||||
* Contrary to lower-band, the upper-band (8-16 kHz) is not split in
|
* Contrary to lower-band, the upper-band (8-16 kHz) is not split in
|
||||||
* frequency, but split to 12 sub-frames, i.e. twice as lower-band.
|
* frequency, but split to 12 sub-frames, i.e. twice as lower-band.
|
||||||
*/
|
*/
|
||||||
int WebRtcIsac_DecodeUb16(float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
|
int WebRtcIsac_DecodeUb16(const TransformTables* transform_tables,
|
||||||
|
float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
|
||||||
int16_t isRCUPayload) {
|
int16_t isRCUPayload) {
|
||||||
int len, err;
|
int len, err;
|
||||||
|
|
||||||
@ -218,7 +220,8 @@ int WebRtcIsac_DecodeUb16(float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Inverse transform. */
|
/* Inverse transform. */
|
||||||
WebRtcIsac_Spec2time(real_f, imag_f, halfFrameFirst, halfFrameSecond,
|
WebRtcIsac_Spec2time(transform_tables,
|
||||||
|
real_f, imag_f, halfFrameFirst, halfFrameSecond,
|
||||||
&ISACdecUB_obj->fftstr_obj);
|
&ISACdecUB_obj->fftstr_obj);
|
||||||
|
|
||||||
/* Perceptual post-filtering (using normalized lattice filter). */
|
/* Perceptual post-filtering (using normalized lattice filter). */
|
||||||
@ -245,8 +248,9 @@ int WebRtcIsac_DecodeUb16(float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
|
|||||||
* reconstructed and 12-16 kHz replaced with zeros. Then two bands
|
* reconstructed and 12-16 kHz replaced with zeros. Then two bands
|
||||||
* are combined, to reconstruct the upperband 8-16 kHz.
|
* are combined, to reconstruct the upperband 8-16 kHz.
|
||||||
*/
|
*/
|
||||||
int WebRtcIsac_DecodeUb12(float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
|
int WebRtcIsac_DecodeUb12(const TransformTables* transform_tables,
|
||||||
int16_t isRCUPayload) {
|
float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
|
||||||
|
int16_t isRCUPayload) {
|
||||||
int len, err;
|
int len, err;
|
||||||
|
|
||||||
float LP_dec_float[FRAMESAMPLES_HALF];
|
float LP_dec_float[FRAMESAMPLES_HALF];
|
||||||
@ -284,7 +288,8 @@ int WebRtcIsac_DecodeUb12(float* signal_out, ISACUBDecStruct* ISACdecUB_obj,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Inverse transform. */
|
/* Inverse transform. */
|
||||||
WebRtcIsac_Spec2time(real_f, imag_f, LPw, HPw, &ISACdecUB_obj->fftstr_obj);
|
WebRtcIsac_Spec2time(transform_tables,
|
||||||
|
real_f, imag_f, LPw, HPw, &ISACdecUB_obj->fftstr_obj);
|
||||||
/* perceptual post-filtering (using normalized lattice filter) */
|
/* perceptual post-filtering (using normalized lattice filter) */
|
||||||
WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER,
|
WebRtcIsac_NormLatticeFilterAr(UB_LPC_ORDER,
|
||||||
ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
|
ISACdecUB_obj->maskfiltstr_obj.PostStateLoF,
|
||||||
|
@ -177,7 +177,8 @@ void WebRtcIsac_ResetBitstream(Bitstr* bit_stream) {
|
|||||||
bit_stream->streamval = 0;
|
bit_stream->streamval = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebRtcIsac_EncodeLb(float* in, ISACLBEncStruct* ISACencLB_obj,
|
int WebRtcIsac_EncodeLb(const TransformTables* transform_tables,
|
||||||
|
float* in, ISACLBEncStruct* ISACencLB_obj,
|
||||||
int16_t codingMode,
|
int16_t codingMode,
|
||||||
int16_t bottleneckIndex) {
|
int16_t bottleneckIndex) {
|
||||||
int stream_length = 0;
|
int stream_length = 0;
|
||||||
@ -382,7 +383,8 @@ int WebRtcIsac_EncodeLb(float* in, ISACLBEncStruct* ISACencLB_obj,
|
|||||||
WebRtcIsac_PitchfilterPre(LPw, LPw_pf, &ISACencLB_obj->pitchfiltstr_obj,
|
WebRtcIsac_PitchfilterPre(LPw, LPw_pf, &ISACencLB_obj->pitchfiltstr_obj,
|
||||||
PitchLags, PitchGains);
|
PitchLags, PitchGains);
|
||||||
/* Transform */
|
/* Transform */
|
||||||
WebRtcIsac_Time2Spec(LPw_pf, HPw, fre, fim, &ISACencLB_obj->fftstr_obj);
|
WebRtcIsac_Time2Spec(transform_tables,
|
||||||
|
LPw_pf, HPw, fre, fim, &ISACencLB_obj->fftstr_obj);
|
||||||
|
|
||||||
/* Save data for multiple packets memory. */
|
/* Save data for multiple packets memory. */
|
||||||
my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
|
my_index = ISACencLB_obj->SaveEnc_obj.startIdx * FRAMESAMPLES_HALF;
|
||||||
@ -641,7 +643,8 @@ static int LimitPayloadUb(ISACUBEncStruct* ISACencUB_obj,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACencUB_obj,
|
int WebRtcIsac_EncodeUb16(const TransformTables* transform_tables,
|
||||||
|
float* in, ISACUBEncStruct* ISACencUB_obj,
|
||||||
int32_t jitterInfo) {
|
int32_t jitterInfo) {
|
||||||
int err;
|
int err;
|
||||||
int k;
|
int k;
|
||||||
@ -782,7 +785,8 @@ int WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACencUB_obj,
|
|||||||
&percepFilterParams[(UB_LPC_ORDER + 1) + SUBFRAMES * (UB_LPC_ORDER + 1)],
|
&percepFilterParams[(UB_LPC_ORDER + 1) + SUBFRAMES * (UB_LPC_ORDER + 1)],
|
||||||
&LP_lookahead[FRAMESAMPLES_HALF]);
|
&LP_lookahead[FRAMESAMPLES_HALF]);
|
||||||
|
|
||||||
WebRtcIsac_Time2Spec(&LP_lookahead[0], &LP_lookahead[FRAMESAMPLES_HALF],
|
WebRtcIsac_Time2Spec(transform_tables,
|
||||||
|
&LP_lookahead[0], &LP_lookahead[FRAMESAMPLES_HALF],
|
||||||
fre, fim, &ISACencUB_obj->fftstr_obj);
|
fre, fim, &ISACencUB_obj->fftstr_obj);
|
||||||
|
|
||||||
/* Store FFT coefficients for multiple encoding. */
|
/* Store FFT coefficients for multiple encoding. */
|
||||||
@ -826,7 +830,8 @@ int WebRtcIsac_EncodeUb16(float* in, ISACUBEncStruct* ISACencUB_obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int WebRtcIsac_EncodeUb12(float* in, ISACUBEncStruct* ISACencUB_obj,
|
int WebRtcIsac_EncodeUb12(const TransformTables* transform_tables,
|
||||||
|
float* in, ISACUBEncStruct* ISACencUB_obj,
|
||||||
int32_t jitterInfo) {
|
int32_t jitterInfo) {
|
||||||
int err;
|
int err;
|
||||||
int k;
|
int k;
|
||||||
@ -957,7 +962,8 @@ int WebRtcIsac_EncodeUb12(float* in, ISACUBEncStruct* ISACencUB_obj,
|
|||||||
memset(HPw, 0, sizeof(HPw));
|
memset(HPw, 0, sizeof(HPw));
|
||||||
|
|
||||||
/* Transform */
|
/* Transform */
|
||||||
WebRtcIsac_Time2Spec(LPw, HPw, fre, fim, &ISACencUB_obj->fftstr_obj);
|
WebRtcIsac_Time2Spec(transform_tables,
|
||||||
|
LPw, HPw, fre, fim, &ISACencUB_obj->fftstr_obj);
|
||||||
|
|
||||||
/* Store FFT coefficients for multiple encoding. */
|
/* Store FFT coefficients for multiple encoding. */
|
||||||
memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
|
memcpy(ISACencUB_obj->SaveEnc_obj.realFFT, fre,
|
||||||
|
@ -40,10 +40,6 @@ void WebRtcIsac_InitMasking(MaskFiltstr *maskdata) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
maskdata->OldEnergy = 10.0;
|
maskdata->OldEnergy = 10.0;
|
||||||
|
|
||||||
/* fill tables for transforms */
|
|
||||||
WebRtcIsac_InitTransform();
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,6 +251,8 @@ int16_t WebRtcIsac_Assign(ISACStruct** ISAC_main_inst,
|
|||||||
instISAC->decoderSamplingRateKHz = kIsacWideband;
|
instISAC->decoderSamplingRateKHz = kIsacWideband;
|
||||||
instISAC->bandwidthKHz = isac8kHz;
|
instISAC->bandwidthKHz = isac8kHz;
|
||||||
instISAC->in_sample_rate_hz = 16000;
|
instISAC->in_sample_rate_hz = 16000;
|
||||||
|
|
||||||
|
WebRtcIsac_InitTransform(&instISAC->transform_tables);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
@ -284,6 +286,8 @@ int16_t WebRtcIsac_Create(ISACStruct** ISAC_main_inst) {
|
|||||||
instISAC->encoderSamplingRateKHz = kIsacWideband;
|
instISAC->encoderSamplingRateKHz = kIsacWideband;
|
||||||
instISAC->decoderSamplingRateKHz = kIsacWideband;
|
instISAC->decoderSamplingRateKHz = kIsacWideband;
|
||||||
instISAC->in_sample_rate_hz = 16000;
|
instISAC->in_sample_rate_hz = 16000;
|
||||||
|
|
||||||
|
WebRtcIsac_InitTransform(&instISAC->transform_tables);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
@ -579,7 +583,8 @@ int WebRtcIsac_Encode(ISACStruct* ISAC_main_inst,
|
|||||||
GetSendBandwidthInfo(instISAC, &bottleneckIdx, &jitterInfo);
|
GetSendBandwidthInfo(instISAC, &bottleneckIdx, &jitterInfo);
|
||||||
|
|
||||||
/* Encode lower-band. */
|
/* Encode lower-band. */
|
||||||
streamLenLB = WebRtcIsac_EncodeLb(inFrame, &instLB->ISACencLB_obj,
|
streamLenLB = WebRtcIsac_EncodeLb(&instISAC->transform_tables,
|
||||||
|
inFrame, &instLB->ISACencLB_obj,
|
||||||
instISAC->codingMode, bottleneckIdx);
|
instISAC->codingMode, bottleneckIdx);
|
||||||
if (streamLenLB < 0) {
|
if (streamLenLB < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -606,12 +611,14 @@ int WebRtcIsac_Encode(ISACStruct* ISAC_main_inst,
|
|||||||
/* Encode upper-band. */
|
/* Encode upper-band. */
|
||||||
switch (instISAC->bandwidthKHz) {
|
switch (instISAC->bandwidthKHz) {
|
||||||
case isac12kHz: {
|
case isac12kHz: {
|
||||||
streamLenUB = WebRtcIsac_EncodeUb12(inFrame, &instUB->ISACencUB_obj,
|
streamLenUB = WebRtcIsac_EncodeUb12(&instISAC->transform_tables,
|
||||||
|
inFrame, &instUB->ISACencUB_obj,
|
||||||
jitterInfo);
|
jitterInfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isac16kHz: {
|
case isac16kHz: {
|
||||||
streamLenUB = WebRtcIsac_EncodeUb16(inFrame, &instUB->ISACencUB_obj,
|
streamLenUB = WebRtcIsac_EncodeUb16(&instISAC->transform_tables,
|
||||||
|
inFrame, &instUB->ISACencUB_obj,
|
||||||
jitterInfo);
|
jitterInfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1106,7 +1113,8 @@ static int Decode(ISACStruct* ISAC_main_inst,
|
|||||||
/* Regardless of that the current codec is setup to work in
|
/* Regardless of that the current codec is setup to work in
|
||||||
* wideband or super-wideband, the decoding of the lower-band
|
* wideband or super-wideband, the decoding of the lower-band
|
||||||
* has to be performed. */
|
* has to be performed. */
|
||||||
numDecodedBytesLB = WebRtcIsac_DecodeLb(outFrame, decInstLB,
|
numDecodedBytesLB = WebRtcIsac_DecodeLb(&instISAC->transform_tables,
|
||||||
|
outFrame, decInstLB,
|
||||||
&numSamplesLB, isRCUPayload);
|
&numSamplesLB, isRCUPayload);
|
||||||
|
|
||||||
if ((numDecodedBytesLB < 0) || (numDecodedBytesLB > lenEncodedLBBytes) ||
|
if ((numDecodedBytesLB < 0) || (numDecodedBytesLB > lenEncodedLBBytes) ||
|
||||||
@ -1249,8 +1257,8 @@ static int Decode(ISACStruct* ISAC_main_inst,
|
|||||||
|
|
||||||
switch (bandwidthKHz) {
|
switch (bandwidthKHz) {
|
||||||
case isac12kHz: {
|
case isac12kHz: {
|
||||||
numDecodedBytesUB = WebRtcIsac_DecodeUb12(outFrame, decInstUB,
|
numDecodedBytesUB = WebRtcIsac_DecodeUb12(
|
||||||
isRCUPayload);
|
&instISAC->transform_tables, outFrame, decInstUB, isRCUPayload);
|
||||||
|
|
||||||
/* Hang-over for transient alleviation -
|
/* Hang-over for transient alleviation -
|
||||||
* wait two frames to add the upper band going up from 8 kHz. */
|
* wait two frames to add the upper band going up from 8 kHz. */
|
||||||
@ -1277,8 +1285,8 @@ static int Decode(ISACStruct* ISAC_main_inst,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isac16kHz: {
|
case isac16kHz: {
|
||||||
numDecodedBytesUB = WebRtcIsac_DecodeUb16(outFrame, decInstUB,
|
numDecodedBytesUB = WebRtcIsac_DecodeUb16(
|
||||||
isRCUPayload);
|
&instISAC->transform_tables, outFrame, decInstUB, isRCUPayload);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -428,6 +428,16 @@ typedef struct {
|
|||||||
uint8_t stream[3];
|
uint8_t stream[3];
|
||||||
} transcode_obj;
|
} transcode_obj;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// TODO(kwiberg): The size of these tables could be reduced by storing floats
|
||||||
|
// instead of doubles, and by making use of the identity cos(x) =
|
||||||
|
// sin(x+pi/2). They could also be made global constants that we fill in at
|
||||||
|
// compile time.
|
||||||
|
double costab1[FRAMESAMPLES_HALF];
|
||||||
|
double sintab1[FRAMESAMPLES_HALF];
|
||||||
|
double costab2[FRAMESAMPLES_QUARTER];
|
||||||
|
double sintab2[FRAMESAMPLES_QUARTER];
|
||||||
|
} TransformTables;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// lower-band codec instance
|
// lower-band codec instance
|
||||||
@ -477,6 +487,9 @@ typedef struct {
|
|||||||
uint16_t in_sample_rate_hz;
|
uint16_t in_sample_rate_hz;
|
||||||
/* State for the input-resampler. It is only used for 48 kHz input signals. */
|
/* State for the input-resampler. It is only used for 48 kHz input signals. */
|
||||||
int16_t state_in_resampler[SIZE_RESAMPLER_STATE];
|
int16_t state_in_resampler[SIZE_RESAMPLER_STATE];
|
||||||
|
|
||||||
|
// Trig tables for WebRtcIsac_Time2Spec and WebRtcIsac_Spec2time.
|
||||||
|
TransformTables transform_tables;
|
||||||
} ISACMainStruct;
|
} ISACMainStruct;
|
||||||
|
|
||||||
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_ */
|
#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_SOURCE_STRUCTS_H_ */
|
||||||
|
@ -14,41 +14,33 @@
|
|||||||
#include "os_specific_inline.h"
|
#include "os_specific_inline.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
static double costab1[FRAMESAMPLES_HALF];
|
void WebRtcIsac_InitTransform(TransformTables* tables) {
|
||||||
static double sintab1[FRAMESAMPLES_HALF];
|
|
||||||
static double costab2[FRAMESAMPLES_QUARTER];
|
|
||||||
static double sintab2[FRAMESAMPLES_QUARTER];
|
|
||||||
|
|
||||||
void WebRtcIsac_InitTransform()
|
|
||||||
{
|
|
||||||
int k;
|
int k;
|
||||||
double fact, phase;
|
double fact, phase;
|
||||||
|
|
||||||
fact = PI / (FRAMESAMPLES_HALF);
|
fact = PI / (FRAMESAMPLES_HALF);
|
||||||
phase = 0.0;
|
phase = 0.0;
|
||||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||||
costab1[k] = cos(phase);
|
tables->costab1[k] = cos(phase);
|
||||||
sintab1[k] = sin(phase);
|
tables->sintab1[k] = sin(phase);
|
||||||
phase += fact;
|
phase += fact;
|
||||||
}
|
}
|
||||||
|
|
||||||
fact = PI * ((double) (FRAMESAMPLES_HALF - 1)) / ((double) FRAMESAMPLES_HALF);
|
fact = PI * ((double) (FRAMESAMPLES_HALF - 1)) / ((double) FRAMESAMPLES_HALF);
|
||||||
phase = 0.5 * fact;
|
phase = 0.5 * fact;
|
||||||
for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
|
for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
|
||||||
costab2[k] = cos(phase);
|
tables->costab2[k] = cos(phase);
|
||||||
sintab2[k] = sin(phase);
|
tables->sintab2[k] = sin(phase);
|
||||||
phase += fact;
|
phase += fact;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebRtcIsac_Time2Spec(const TransformTables* tables,
|
||||||
void WebRtcIsac_Time2Spec(double *inre1,
|
double* inre1,
|
||||||
double *inre2,
|
double* inre2,
|
||||||
int16_t *outreQ7,
|
int16_t* outreQ7,
|
||||||
int16_t *outimQ7,
|
int16_t* outimQ7,
|
||||||
FFTstr *fftstr_obj)
|
FFTstr* fftstr_obj) {
|
||||||
{
|
|
||||||
|
|
||||||
int k;
|
int k;
|
||||||
int dims[1];
|
int dims[1];
|
||||||
double tmp1r, tmp1i, xr, xi, yr, yi, fact;
|
double tmp1r, tmp1i, xr, xi, yr, yi, fact;
|
||||||
@ -61,8 +53,8 @@ void WebRtcIsac_Time2Spec(double *inre1,
|
|||||||
/* Multiply with complex exponentials and combine into one complex vector */
|
/* Multiply with complex exponentials and combine into one complex vector */
|
||||||
fact = 0.5 / sqrt(FRAMESAMPLES_HALF);
|
fact = 0.5 / sqrt(FRAMESAMPLES_HALF);
|
||||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||||
tmp1r = costab1[k];
|
tmp1r = tables->costab1[k];
|
||||||
tmp1i = sintab1[k];
|
tmp1i = tables->sintab1[k];
|
||||||
tmpre[k] = (inre1[k] * tmp1r + inre2[k] * tmp1i) * fact;
|
tmpre[k] = (inre1[k] * tmp1r + inre2[k] * tmp1i) * fact;
|
||||||
tmpim[k] = (inre2[k] * tmp1r - inre1[k] * tmp1i) * fact;
|
tmpim[k] = (inre2[k] * tmp1r - inre1[k] * tmp1i) * fact;
|
||||||
}
|
}
|
||||||
@ -78,8 +70,8 @@ void WebRtcIsac_Time2Spec(double *inre1,
|
|||||||
xi = tmpim[k] - tmpim[FRAMESAMPLES_HALF - 1 - k];
|
xi = tmpim[k] - tmpim[FRAMESAMPLES_HALF - 1 - k];
|
||||||
yr = tmpim[k] + tmpim[FRAMESAMPLES_HALF - 1 - k];
|
yr = tmpim[k] + tmpim[FRAMESAMPLES_HALF - 1 - k];
|
||||||
|
|
||||||
tmp1r = costab2[k];
|
tmp1r = tables->costab2[k];
|
||||||
tmp1i = sintab2[k];
|
tmp1i = tables->sintab2[k];
|
||||||
outreQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1r - xi * tmp1i) * 128.0);
|
outreQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1r - xi * tmp1i) * 128.0);
|
||||||
outimQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1i + xi * tmp1r) * 128.0);
|
outimQ7[k] = (int16_t)WebRtcIsac_lrint((xr * tmp1i + xi * tmp1r) * 128.0);
|
||||||
outreQ7[FRAMESAMPLES_HALF - 1 - k] = (int16_t)WebRtcIsac_lrint((-yr * tmp1i - yi * tmp1r) * 128.0);
|
outreQ7[FRAMESAMPLES_HALF - 1 - k] = (int16_t)WebRtcIsac_lrint((-yr * tmp1i - yi * tmp1r) * 128.0);
|
||||||
@ -87,10 +79,12 @@ void WebRtcIsac_Time2Spec(double *inre1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebRtcIsac_Spec2time(const TransformTables* tables,
|
||||||
void WebRtcIsac_Spec2time(double *inre, double *inim, double *outre1, double *outre2, FFTstr *fftstr_obj)
|
double* inre,
|
||||||
{
|
double* inim,
|
||||||
|
double* outre1,
|
||||||
|
double* outre2,
|
||||||
|
FFTstr* fftstr_obj) {
|
||||||
int k;
|
int k;
|
||||||
double tmp1r, tmp1i, xr, xi, yr, yi, fact;
|
double tmp1r, tmp1i, xr, xi, yr, yi, fact;
|
||||||
|
|
||||||
@ -100,8 +94,8 @@ void WebRtcIsac_Spec2time(double *inre, double *inim, double *outre1, double *ou
|
|||||||
|
|
||||||
for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
|
for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
|
||||||
/* Move zero in time to beginning of frames */
|
/* Move zero in time to beginning of frames */
|
||||||
tmp1r = costab2[k];
|
tmp1r = tables->costab2[k];
|
||||||
tmp1i = sintab2[k];
|
tmp1i = tables->sintab2[k];
|
||||||
xr = inre[k] * tmp1r + inim[k] * tmp1i;
|
xr = inre[k] * tmp1r + inim[k] * tmp1i;
|
||||||
xi = inim[k] * tmp1r - inre[k] * tmp1i;
|
xi = inim[k] * tmp1r - inre[k] * tmp1i;
|
||||||
yr = -inim[FRAMESAMPLES_HALF - 1 - k] * tmp1r - inre[FRAMESAMPLES_HALF - 1 - k] * tmp1i;
|
yr = -inim[FRAMESAMPLES_HALF - 1 - k] * tmp1r - inre[FRAMESAMPLES_HALF - 1 - k] * tmp1i;
|
||||||
@ -122,8 +116,8 @@ void WebRtcIsac_Spec2time(double *inre, double *inim, double *outre1, double *ou
|
|||||||
/* Demodulate and separate */
|
/* Demodulate and separate */
|
||||||
fact = sqrt(FRAMESAMPLES_HALF);
|
fact = sqrt(FRAMESAMPLES_HALF);
|
||||||
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
for (k = 0; k < FRAMESAMPLES_HALF; k++) {
|
||||||
tmp1r = costab1[k];
|
tmp1r = tables->costab1[k];
|
||||||
tmp1i = sintab1[k];
|
tmp1i = tables->sintab1[k];
|
||||||
xr = (outre1[k] * tmp1r - outre2[k] * tmp1i) * fact;
|
xr = (outre1[k] * tmp1r - outre2[k] * tmp1i) * fact;
|
||||||
outre2[k] = (outre2[k] * tmp1r + outre1[k] * tmp1i) * fact;
|
outre2[k] = (outre2[k] * tmp1r + outre1[k] * tmp1i) * fact;
|
||||||
outre1[k] = xr;
|
outre1[k] = xr;
|
||||||
|
Reference in New Issue
Block a user