/* * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "modules/audio_coding/codecs/g722/audio_decoder_g722.h" #include #include #include "modules/audio_coding/codecs/g722/g722_interface.h" #include "modules/audio_coding/codecs/legacy_encoded_audio_frame.h" #include "rtc_base/checks.h" namespace webrtc { AudioDecoderG722Impl::AudioDecoderG722Impl() { WebRtcG722_CreateDecoder(&dec_state_); WebRtcG722_DecoderInit(dec_state_); } AudioDecoderG722Impl::~AudioDecoderG722Impl() { WebRtcG722_FreeDecoder(dec_state_); } bool AudioDecoderG722Impl::HasDecodePlc() const { return false; } int AudioDecoderG722Impl::DecodeInternal(const uint8_t* encoded, size_t encoded_len, int sample_rate_hz, int16_t* decoded, SpeechType* speech_type) { RTC_DCHECK_EQ(SampleRateHz(), sample_rate_hz); int16_t temp_type = 1; // Default is speech. size_t ret = WebRtcG722_Decode(dec_state_, encoded, encoded_len, decoded, &temp_type); *speech_type = ConvertSpeechType(temp_type); return static_cast(ret); } void AudioDecoderG722Impl::Reset() { WebRtcG722_DecoderInit(dec_state_); } std::vector AudioDecoderG722Impl::ParsePayload( rtc::Buffer&& payload, uint32_t timestamp) { return LegacyEncodedAudioFrame::SplitBySamples(this, std::move(payload), timestamp, 8, 16); } int AudioDecoderG722Impl::PacketDuration(const uint8_t* encoded, size_t encoded_len) const { // 1/2 encoded byte per sample per channel. return static_cast(2 * encoded_len / Channels()); } int AudioDecoderG722Impl::SampleRateHz() const { return 16000; } size_t AudioDecoderG722Impl::Channels() const { return 1; } AudioDecoderG722StereoImpl::AudioDecoderG722StereoImpl() { WebRtcG722_CreateDecoder(&dec_state_left_); WebRtcG722_CreateDecoder(&dec_state_right_); WebRtcG722_DecoderInit(dec_state_left_); WebRtcG722_DecoderInit(dec_state_right_); } AudioDecoderG722StereoImpl::~AudioDecoderG722StereoImpl() { WebRtcG722_FreeDecoder(dec_state_left_); WebRtcG722_FreeDecoder(dec_state_right_); } int AudioDecoderG722StereoImpl::DecodeInternal(const uint8_t* encoded, size_t encoded_len, int sample_rate_hz, int16_t* decoded, SpeechType* speech_type) { RTC_DCHECK_EQ(SampleRateHz(), sample_rate_hz); // Adjust the encoded length down to ensure the same number of samples in each // channel. const size_t encoded_len_adjusted = PacketDuration(encoded, encoded_len) * Channels() / 2; // 1/2 byte per sample per channel int16_t temp_type = 1; // Default is speech. // De-interleave the bit-stream into two separate payloads. uint8_t* encoded_deinterleaved = new uint8_t[encoded_len_adjusted]; SplitStereoPacket(encoded, encoded_len_adjusted, encoded_deinterleaved); // Decode left and right. size_t decoded_len = WebRtcG722_Decode(dec_state_left_, encoded_deinterleaved, encoded_len_adjusted / 2, decoded, &temp_type); size_t ret = WebRtcG722_Decode( dec_state_right_, &encoded_deinterleaved[encoded_len_adjusted / 2], encoded_len_adjusted / 2, &decoded[decoded_len], &temp_type); if (ret == decoded_len) { ret += decoded_len; // Return total number of samples. // Interleave output. for (size_t k = ret / 2; k < ret; k++) { int16_t temp = decoded[k]; memmove(&decoded[2 * k - ret + 2], &decoded[2 * k - ret + 1], (ret - k - 1) * sizeof(int16_t)); decoded[2 * k - ret + 1] = temp; } } *speech_type = ConvertSpeechType(temp_type); delete[] encoded_deinterleaved; return static_cast(ret); } int AudioDecoderG722StereoImpl::PacketDuration(const uint8_t* encoded, size_t encoded_len) const { // 1/2 encoded byte per sample per channel. Make sure the length represents // an equal number of bytes per channel. Otherwise, we cannot de-interleave // the encoded data later. return static_cast(2 * (encoded_len / Channels())); } int AudioDecoderG722StereoImpl::SampleRateHz() const { return 16000; } size_t AudioDecoderG722StereoImpl::Channels() const { return 2; } void AudioDecoderG722StereoImpl::Reset() { WebRtcG722_DecoderInit(dec_state_left_); WebRtcG722_DecoderInit(dec_state_right_); } std::vector AudioDecoderG722StereoImpl::ParsePayload( rtc::Buffer&& payload, uint32_t timestamp) { return LegacyEncodedAudioFrame::SplitBySamples(this, std::move(payload), timestamp, 2 * 8, 16); } // Split the stereo packet and place left and right channel after each other // in the output array. void AudioDecoderG722StereoImpl::SplitStereoPacket( const uint8_t* encoded, size_t encoded_len, uint8_t* encoded_deinterleaved) { // Regroup the 4 bits/sample so |l1 l2| |r1 r2| |l3 l4| |r3 r4| ..., // where "lx" is 4 bits representing left sample number x, and "rx" right // sample. Two samples fit in one byte, represented with |...|. for (size_t i = 0; i + 1 < encoded_len; i += 2) { uint8_t right_byte = ((encoded[i] & 0x0F) << 4) + (encoded[i + 1] & 0x0F); encoded_deinterleaved[i] = (encoded[i] & 0xF0) + (encoded[i + 1] >> 4); encoded_deinterleaved[i + 1] = right_byte; } // Move one byte representing right channel each loop, and place it at the // end of the bytestream vector. After looping the data is reordered to: // |l1 l2| |l3 l4| ... |l(N-1) lN| |r1 r2| |r3 r4| ... |r(N-1) r(N)|, // where N is the total number of samples. for (size_t i = 0; i < encoded_len / 2; i++) { uint8_t right_byte = encoded_deinterleaved[i + 1]; memmove(&encoded_deinterleaved[i + 1], &encoded_deinterleaved[i + 2], encoded_len - i - 2); encoded_deinterleaved[encoded_len - 1] = right_byte; } } } // namespace webrtc