OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #include "webrtc/modules/audio_coding/codecs/g722/include/audio_decoder_g722.h" |
| 12 |
| 13 #include <string.h> |
| 14 |
| 15 #include "webrtc/base/checks.h" |
| 16 #include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h" |
| 17 |
| 18 namespace webrtc { |
| 19 |
| 20 AudioDecoderG722::AudioDecoderG722() { |
| 21 WebRtcG722_CreateDecoder(&dec_state_); |
| 22 WebRtcG722_DecoderInit(dec_state_); |
| 23 } |
| 24 |
| 25 AudioDecoderG722::~AudioDecoderG722() { |
| 26 WebRtcG722_FreeDecoder(dec_state_); |
| 27 } |
| 28 |
| 29 bool AudioDecoderG722::HasDecodePlc() const { |
| 30 return false; |
| 31 } |
| 32 |
| 33 int AudioDecoderG722::DecodeInternal(const uint8_t* encoded, |
| 34 size_t encoded_len, |
| 35 int sample_rate_hz, |
| 36 int16_t* decoded, |
| 37 SpeechType* speech_type) { |
| 38 RTC_DCHECK_EQ(sample_rate_hz, 16000); |
| 39 int16_t temp_type = 1; // Default is speech. |
| 40 size_t ret = |
| 41 WebRtcG722_Decode(dec_state_, encoded, encoded_len, decoded, &temp_type); |
| 42 *speech_type = ConvertSpeechType(temp_type); |
| 43 return static_cast<int>(ret); |
| 44 } |
| 45 |
| 46 void AudioDecoderG722::Reset() { |
| 47 WebRtcG722_DecoderInit(dec_state_); |
| 48 } |
| 49 |
| 50 int AudioDecoderG722::PacketDuration(const uint8_t* encoded, |
| 51 size_t encoded_len) const { |
| 52 // 1/2 encoded byte per sample per channel. |
| 53 return static_cast<int>(2 * encoded_len / Channels()); |
| 54 } |
| 55 |
| 56 size_t AudioDecoderG722::Channels() const { |
| 57 return 1; |
| 58 } |
| 59 |
| 60 AudioDecoderG722Stereo::AudioDecoderG722Stereo() { |
| 61 WebRtcG722_CreateDecoder(&dec_state_left_); |
| 62 WebRtcG722_CreateDecoder(&dec_state_right_); |
| 63 WebRtcG722_DecoderInit(dec_state_left_); |
| 64 WebRtcG722_DecoderInit(dec_state_right_); |
| 65 } |
| 66 |
| 67 AudioDecoderG722Stereo::~AudioDecoderG722Stereo() { |
| 68 WebRtcG722_FreeDecoder(dec_state_left_); |
| 69 WebRtcG722_FreeDecoder(dec_state_right_); |
| 70 } |
| 71 |
| 72 int AudioDecoderG722Stereo::DecodeInternal(const uint8_t* encoded, |
| 73 size_t encoded_len, |
| 74 int sample_rate_hz, |
| 75 int16_t* decoded, |
| 76 SpeechType* speech_type) { |
| 77 RTC_DCHECK_EQ(sample_rate_hz, 16000); |
| 78 int16_t temp_type = 1; // Default is speech. |
| 79 // De-interleave the bit-stream into two separate payloads. |
| 80 uint8_t* encoded_deinterleaved = new uint8_t[encoded_len]; |
| 81 SplitStereoPacket(encoded, encoded_len, encoded_deinterleaved); |
| 82 // Decode left and right. |
| 83 size_t decoded_len = WebRtcG722_Decode(dec_state_left_, encoded_deinterleaved, |
| 84 encoded_len / 2, decoded, &temp_type); |
| 85 size_t ret = WebRtcG722_Decode( |
| 86 dec_state_right_, &encoded_deinterleaved[encoded_len / 2], |
| 87 encoded_len / 2, &decoded[decoded_len], &temp_type); |
| 88 if (ret == decoded_len) { |
| 89 ret += decoded_len; // Return total number of samples. |
| 90 // Interleave output. |
| 91 for (size_t k = ret / 2; k < ret; k++) { |
| 92 int16_t temp = decoded[k]; |
| 93 memmove(&decoded[2 * k - ret + 2], &decoded[2 * k - ret + 1], |
| 94 (ret - k - 1) * sizeof(int16_t)); |
| 95 decoded[2 * k - ret + 1] = temp; |
| 96 } |
| 97 } |
| 98 *speech_type = ConvertSpeechType(temp_type); |
| 99 delete[] encoded_deinterleaved; |
| 100 return static_cast<int>(ret); |
| 101 } |
| 102 |
| 103 size_t AudioDecoderG722Stereo::Channels() const { |
| 104 return 2; |
| 105 } |
| 106 |
| 107 void AudioDecoderG722Stereo::Reset() { |
| 108 WebRtcG722_DecoderInit(dec_state_left_); |
| 109 WebRtcG722_DecoderInit(dec_state_right_); |
| 110 } |
| 111 |
| 112 // Split the stereo packet and place left and right channel after each other |
| 113 // in the output array. |
| 114 void AudioDecoderG722Stereo::SplitStereoPacket(const uint8_t* encoded, |
| 115 size_t encoded_len, |
| 116 uint8_t* encoded_deinterleaved) { |
| 117 // Regroup the 4 bits/sample so |l1 l2| |r1 r2| |l3 l4| |r3 r4| ..., |
| 118 // where "lx" is 4 bits representing left sample number x, and "rx" right |
| 119 // sample. Two samples fit in one byte, represented with |...|. |
| 120 for (size_t i = 0; i + 1 < encoded_len; i += 2) { |
| 121 uint8_t right_byte = ((encoded[i] & 0x0F) << 4) + (encoded[i + 1] & 0x0F); |
| 122 encoded_deinterleaved[i] = (encoded[i] & 0xF0) + (encoded[i + 1] >> 4); |
| 123 encoded_deinterleaved[i + 1] = right_byte; |
| 124 } |
| 125 |
| 126 // Move one byte representing right channel each loop, and place it at the |
| 127 // end of the bytestream vector. After looping the data is reordered to: |
| 128 // |l1 l2| |l3 l4| ... |l(N-1) lN| |r1 r2| |r3 r4| ... |r(N-1) r(N)|, |
| 129 // where N is the total number of samples. |
| 130 for (size_t i = 0; i < encoded_len / 2; i++) { |
| 131 uint8_t right_byte = encoded_deinterleaved[i + 1]; |
| 132 memmove(&encoded_deinterleaved[i + 1], &encoded_deinterleaved[i + 2], |
| 133 encoded_len - i - 2); |
| 134 encoded_deinterleaved[encoded_len - 1] = right_byte; |
| 135 } |
| 136 } |
| 137 |
| 138 } // namespace webrtc |
OLD | NEW |