// 48 -> 8 resampler void WebRtcSpl_Resample48khzTo8khz(const WebRtc_Word16* in, WebRtc_Word16* out, WebRtcSpl_State48khzTo8khz* state, WebRtc_Word32* tmpmem) { ///// 48 --> 24 ///// // WebRtc_Word16 in[480] // WebRtc_Word32 out[240] ///// WebRtcSpl_DownBy2ShortToInt(in, 480, tmpmem + 256, state->S_48_24); ///// 24 --> 24(LP) ///// // WebRtc_Word32 in[240] // WebRtc_Word32 out[240] ///// WebRtcSpl_LPBy2IntToInt(tmpmem + 256, 240, tmpmem + 16, state->S_24_24); ///// 24 --> 16 ///// // WebRtc_Word32 in[240] // WebRtc_Word32 out[160] ///// // copy state to and from input array memcpy(tmpmem + 8, state->S_24_16, 8 * sizeof(WebRtc_Word32)); memcpy(state->S_24_16, tmpmem + 248, 8 * sizeof(WebRtc_Word32)); WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 80); ///// 16 --> 8 ///// // WebRtc_Word32 in[160] // WebRtc_Word16 out[80] ///// WebRtcSpl_DownBy2IntToShort(tmpmem, 160, out, state->S_16_8); }
int16_t WebRtcOpus_Decode(OpusDecInst* inst, int16_t* encoded, int16_t encoded_bytes, int16_t* decoded, int16_t* audio_type) { /* Enough for 120 ms (the largest Opus packet size) of mono audio at 48 kHz * and resampler overlap. This will need to be enlarged for stereo decoding. */ int16_t buffer16[kWebRtcOpusMaxFrameSize]; int32_t buffer32[kWebRtcOpusMaxFrameSize + 7]; int decoded_samples; int blocks; int16_t output_samples; int i; /* If mono case, just do a regular call to the decoder. * If stereo, call to WebRtcOpus_Decode() gives left channel as output, and * calls to WebRtcOpus_Decode_slave() give right channel as output. * This is to make stereo work with the current setup of NetEQ, which * requires two calls to the decoder to produce stereo. */ /* Decode to a temporary buffer. */ decoded_samples = DecodeNative(inst->decoder_left, encoded, encoded_bytes, buffer16, audio_type); if (decoded_samples < 0) { return -1; } if (inst->channels == 2) { /* The parameter |decoded_samples| holds the number of samples pairs, in * case of stereo. Number of samples in |buffer16| equals |decoded_samples| * times 2. */ for (i = 0; i < decoded_samples; i++) { /* Take every second sample, starting at the first sample. This gives * the left channel. */ buffer16[i] = buffer16[i * 2]; } } /* Resample from 48 kHz to 32 kHz. */ for (i = 0; i < 7; i++) { buffer32[i] = inst->state_48_32_left[i]; inst->state_48_32_left[i] = buffer16[decoded_samples - 7 + i]; } for (i = 0; i < decoded_samples; i++) { buffer32[7 + i] = buffer16[i]; } /* Resampling 3 samples to 2. Function divides the input in |blocks| number * of 3-sample groups, and output is |blocks| number of 2-sample groups. * When this is removed, the compensation in WebRtcOpus_DurationEst should be * removed too. */ blocks = decoded_samples / 3; WebRtcSpl_Resample48khzTo32khz(buffer32, buffer32, blocks); output_samples = (int16_t) (blocks * 2); WebRtcSpl_VectorBitShiftW32ToW16(decoded, output_samples, buffer32, 15); return output_samples; }
int16_t WebRtcOpus_DecodeSlave(OpusDecInst* inst, int16_t* encoded, int16_t encoded_bytes, int16_t* decoded, int16_t* audio_type) { /* Enough for 120 ms (the largest Opus packet size) of mono audio at 48 kHz * and resampler overlap. This will need to be enlarged for stereo decoding. */ int16_t buffer16[kWebRtcOpusMaxFrameSize]; int32_t buffer32[kWebRtcOpusMaxFrameSize + 7]; int decoded_samples; int blocks; int16_t output_samples; int i; /* Decode to a temporary buffer. */ decoded_samples = DecodeNative(inst->decoder_right, encoded, encoded_bytes, buffer16, audio_type); if (decoded_samples < 0) { return -1; } if (inst->channels == 2) { /* The parameter |decoded_samples| holds the number of samples pairs, in * case of stereo. Number of samples in |buffer16| equals |decoded_samples| * times 2. */ for (i = 0; i < decoded_samples; i++) { /* Take every second sample, starting at the second sample. This gives * the right channel. */ buffer16[i] = buffer16[i * 2 + 1]; } } else { /* Decode slave should never be called for mono packets. */ return -1; } /* Resample from 48 kHz to 32 kHz. */ for (i = 0; i < 7; i++) { buffer32[i] = inst->state_48_32_right[i]; inst->state_48_32_right[i] = buffer16[decoded_samples - 7 + i]; } for (i = 0; i < decoded_samples; i++) { buffer32[7 + i] = buffer16[i]; } /* Resampling 3 samples to 2. Function divides the input in |blocks| number * of 3-sample groups, and output is |blocks| number of 2-sample groups. */ blocks = decoded_samples / 3; WebRtcSpl_Resample48khzTo32khz(buffer32, buffer32, blocks); output_samples = (int16_t) (blocks * 2); WebRtcSpl_VectorBitShiftW32ToW16(decoded, output_samples, buffer32, 15); return output_samples; }
int16_t WebRtcOpus_Decode(OpusDecInst *inst, int16_t *encoded, int16_t len, int16_t *decoded, int16_t *audioType) { /* Enough for 120 ms (the largest Opus packet size) of mono audio at 48 kHz. * This will need to be enlarged for stereo decoding. */ int16_t buffer16[WEBRTC_OPUS_MAX_FRAME_SIZE]; int32_t buffer32[WEBRTC_OPUS_MAX_FRAME_SIZE+7]; int decodedSamples; int blocks; int16_t outputSamples; int i; /* Decode to a temporary buffer. */ decodedSamples = WebRtcOpus_DecodeNative(inst, encoded, len, buffer16, audioType); if (decodedSamples < 0) { return -1; } /* Resample from 48 kHz to 32 kHz. */ for (i = 0; i < 7; i++) { buffer32[i] = inst->state_48_32[i]; } for (i = 0; i < decodedSamples; i++) { buffer32[7+i] = buffer16[i]; } for (i = 0; i < 7; i++) { inst->state_48_32[i] = (int16_t)buffer32[decodedSamples+i]; } blocks = decodedSamples/3; WebRtcSpl_Resample48khzTo32khz(buffer32, buffer32, blocks); outputSamples = (int16_t)(blocks*2); WebRtcSpl_VectorBitShiftW32ToW16(decoded, outputSamples, buffer32, 15); return outputSamples; }
// 48 -> 16 resampler void WebRtcSpl_Resample48khzTo16khz(const WebRtc_Word16* in, WebRtc_Word16* out, WebRtcSpl_State48khzTo16khz* state, WebRtc_Word32* tmpmem) { ///// 48 --> 48(LP) ///// // WebRtc_Word16 in[480] // WebRtc_Word32 out[480] ///// WebRtcSpl_LPBy2ShortToInt(in, 480, tmpmem + 16, state->S_48_48); ///// 48 --> 32 ///// // WebRtc_Word32 in[480] // WebRtc_Word32 out[320] ///// // copy state to and from input array memcpy(tmpmem + 8, state->S_48_32, 8 * sizeof(WebRtc_Word32)); memcpy(state->S_48_32, tmpmem + 488, 8 * sizeof(WebRtc_Word32)); WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 160); ///// 32 --> 16 ///// // WebRtc_Word32 in[320] // WebRtc_Word16 out[160] ///// WebRtcSpl_DownBy2IntToShort(tmpmem, 320, out, state->S_32_16); }
int16_t WebRtcOpus_Decode(OpusDecInst* inst, int16_t* encoded, int16_t encoded_bytes, int16_t* decoded, int16_t* audio_type) { /* Enough for 120 ms (the largest Opus packet size) of mono audio at 48 kHz * and resampler overlap. This will need to be enlarged for stereo decoding. */ int16_t buffer16[kWebRtcOpusMaxFrameSize]; int32_t buffer32[kWebRtcOpusMaxFrameSize + 7]; int decoded_samples; int blocks; int16_t output_samples; int i; /* Decode to a temporary buffer. */ decoded_samples = DecodeNative(inst, encoded, encoded_bytes, buffer16, audio_type); if (decoded_samples < 0) { return -1; } /* Resample from 48 kHz to 32 kHz. */ for (i = 0; i < 7; i++) { buffer32[i] = inst->state_48_32[i]; inst->state_48_32[i] = buffer16[decoded_samples -7 + i]; } for (i = 0; i < decoded_samples; i++) { buffer32[7 + i] = buffer16[i]; } /* Resampling 3 samples to 2. Function divides the input in |blocks| number * of 3-sample groups, and output is |blocks| number of 2-sample groups. */ blocks = decoded_samples / 3; WebRtcSpl_Resample48khzTo32khz(buffer32, buffer32, blocks); output_samples = (int16_t) (blocks * 2); WebRtcSpl_VectorBitShiftW32ToW16(decoded, output_samples, buffer32, 15); return output_samples; }