Reland r8476 "Set decoder output frequency in AudioDecoder::Decode call"

This should be safe to land now that issue 4143 was resolved (in r8492).
This change effectively reverts 8488.

TBR=kwiberg@webrtc.org

Original commit message:
This CL changes the way the decoder sample rate is set and updated. In
practice, it only concerns the iSAC (float) codec.

One single iSAC decoder instance is used for both wideband and
super-wideband decoding, and the instance must be told to switch
output frequency if the payload type changes. This used to be done
through a call to UpdateDecoderSampleRate, but is now instead done in
the Decode call as an extra parameter.

Review URL: https://webrtc-codereview.appspot.com/39289004

Cr-Commit-Position: refs/heads/master@{#8496}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8496 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrik.lundin@webrtc.org
2015-02-25 10:02:29 +00:00
parent 1e64263b90
commit 1eda4e3db6
20 changed files with 201 additions and 184 deletions

View File

@ -38,8 +38,12 @@
namespace webrtc {
// PCMu
int AudioDecoderPcmU::Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int AudioDecoderPcmU::Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type) {
DCHECK_EQ(sample_rate_hz, 8000);
int16_t temp_type = 1; // Default is speech.
int16_t ret = WebRtcG711_DecodeU(encoded, static_cast<int16_t>(encoded_len),
decoded, &temp_type);
@ -54,8 +58,12 @@ int AudioDecoderPcmU::PacketDuration(const uint8_t* encoded,
}
// PCMa
int AudioDecoderPcmA::Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int AudioDecoderPcmA::Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type) {
DCHECK_EQ(sample_rate_hz, 8000);
int16_t temp_type = 1; // Default is speech.
int16_t ret = WebRtcG711_DecodeA(encoded, static_cast<int16_t>(encoded_len),
decoded, &temp_type);
@ -73,8 +81,14 @@ int AudioDecoderPcmA::PacketDuration(const uint8_t* encoded,
#ifdef WEBRTC_CODEC_PCM16
AudioDecoderPcm16B::AudioDecoderPcm16B() {}
int AudioDecoderPcm16B::Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int AudioDecoderPcm16B::Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type) {
DCHECK(sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
sample_rate_hz == 32000 || sample_rate_hz == 48000)
<< "Unsupported sample rate " << sample_rate_hz;
int16_t ret =
WebRtcPcm16b_Decode(encoded, static_cast<int16_t>(encoded_len), decoded);
*speech_type = ConvertSpeechType(1);
@ -103,8 +117,12 @@ AudioDecoderIlbc::~AudioDecoderIlbc() {
WebRtcIlbcfix_DecoderFree(dec_state_);
}
int AudioDecoderIlbc::Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int AudioDecoderIlbc::Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type) {
DCHECK_EQ(sample_rate_hz, 8000);
int16_t temp_type = 1; // Default is speech.
int16_t ret = WebRtcIlbcfix_Decode(dec_state_, encoded,
static_cast<int16_t>(encoded_len), decoded,
@ -132,8 +150,12 @@ AudioDecoderG722::~AudioDecoderG722() {
WebRtcG722_FreeDecoder(dec_state_);
}
int AudioDecoderG722::Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int AudioDecoderG722::Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type) {
DCHECK_EQ(sample_rate_hz, 16000);
int16_t temp_type = 1; // Default is speech.
int16_t ret =
WebRtcG722_Decode(dec_state_, encoded, static_cast<int16_t>(encoded_len),
@ -163,8 +185,12 @@ AudioDecoderG722Stereo::~AudioDecoderG722Stereo() {
WebRtcG722_FreeDecoder(dec_state_right_);
}
int AudioDecoderG722Stereo::Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int AudioDecoderG722Stereo::Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type) {
DCHECK_EQ(sample_rate_hz, 16000);
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];
@ -244,8 +270,12 @@ AudioDecoderOpus::~AudioDecoderOpus() {
WebRtcOpus_DecoderFree(dec_state_);
}
int AudioDecoderOpus::Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
int AudioDecoderOpus::Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type) {
DCHECK_EQ(sample_rate_hz, 48000);
int16_t temp_type = 1; // Default is speech.
int16_t ret = WebRtcOpus_Decode(dec_state_, encoded,
static_cast<int16_t>(encoded_len), decoded,
@ -257,11 +287,13 @@ int AudioDecoderOpus::Decode(const uint8_t* encoded, size_t encoded_len,
}
int AudioDecoderOpus::DecodeRedundant(const uint8_t* encoded,
size_t encoded_len, int16_t* decoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type) {
if (!PacketHasFec(encoded, encoded_len)) {
// This packet is a RED packet.
return Decode(encoded, encoded_len, decoded, speech_type);
return Decode(encoded, encoded_len, sample_rate_hz, decoded, speech_type);
}
int16_t temp_type = 1; // Default is speech.

View File

@ -37,8 +37,11 @@ namespace webrtc {
class AudioDecoderPcmU : public AudioDecoder {
public:
AudioDecoderPcmU() {}
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type);
virtual int Init() { return 0; }
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
@ -49,8 +52,11 @@ class AudioDecoderPcmU : public AudioDecoder {
class AudioDecoderPcmA : public AudioDecoder {
public:
AudioDecoderPcmA() {}
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type);
virtual int Init() { return 0; }
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
@ -86,8 +92,11 @@ class AudioDecoderPcmAMultiCh : public AudioDecoderPcmA {
class AudioDecoderPcm16B : public AudioDecoder {
public:
AudioDecoderPcm16B();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type);
virtual int Init() { return 0; }
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
@ -112,8 +121,11 @@ class AudioDecoderIlbc : public AudioDecoder {
public:
AudioDecoderIlbc();
virtual ~AudioDecoderIlbc();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type);
virtual bool HasDecodePlc() const { return true; }
virtual int DecodePlc(int num_frames, int16_t* decoded);
virtual int Init();
@ -129,8 +141,11 @@ class AudioDecoderG722 : public AudioDecoder {
public:
AudioDecoderG722();
virtual ~AudioDecoderG722();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type);
virtual bool HasDecodePlc() const { return false; }
virtual int Init();
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
@ -144,8 +159,11 @@ class AudioDecoderG722Stereo : public AudioDecoder {
public:
AudioDecoderG722Stereo();
virtual ~AudioDecoderG722Stereo();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type);
virtual int Init();
private:
@ -169,10 +187,16 @@ class AudioDecoderOpus : public AudioDecoder {
public:
explicit AudioDecoderOpus(int num_channels);
virtual ~AudioDecoderOpus();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type);
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type);
virtual int DecodeRedundant(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type);
virtual int Init();
virtual int PacketDuration(const uint8_t* encoded, size_t encoded_len) const;
virtual int PacketDurationRedundant(const uint8_t* encoded,
@ -195,8 +219,13 @@ class AudioDecoderCng : public AudioDecoder {
public:
explicit AudioDecoderCng();
virtual ~AudioDecoderCng();
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) { return -1; }
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int /*sample_rate_hz*/,
int16_t* decoded,
SpeechType* speech_type) {
return -1;
}
virtual int Init();
virtual int IncomingPacket(const uint8_t* payload,
size_t payload_len,

View File

@ -186,10 +186,9 @@ class AudioDecoderTest : public ::testing::Test {
// Make sure that frame_size_ * channels_ samples are allocated and free.
decoded.resize((processed_samples + frame_size_) * channels_, 0);
AudioDecoder::SpeechType speech_type;
size_t dec_len = decoder_->Decode(&encoded_[encoded_bytes_],
enc_len,
&decoded[processed_samples * channels_],
&speech_type);
size_t dec_len = decoder_->Decode(
&encoded_[encoded_bytes_], enc_len, codec_input_rate_hz_,
&decoded[processed_samples * channels_], &speech_type);
EXPECT_EQ(frame_size_ * channels_, dec_len);
encoded_bytes_ += enc_len;
processed_samples += frame_size_;
@ -222,13 +221,15 @@ class AudioDecoderTest : public ::testing::Test {
AudioDecoder::SpeechType speech_type1, speech_type2;
EXPECT_EQ(0, decoder_->Init());
scoped_ptr<int16_t[]> output1(new int16_t[frame_size_ * channels_]);
dec_len = decoder_->Decode(encoded_, enc_len, output1.get(), &speech_type1);
dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
output1.get(), &speech_type1);
ASSERT_LE(dec_len, frame_size_ * channels_);
EXPECT_EQ(frame_size_ * channels_, dec_len);
// Re-init decoder and decode again.
EXPECT_EQ(0, decoder_->Init());
scoped_ptr<int16_t[]> output2(new int16_t[frame_size_ * channels_]);
dec_len = decoder_->Decode(encoded_, enc_len, output2.get(), &speech_type2);
dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
output2.get(), &speech_type2);
ASSERT_LE(dec_len, frame_size_ * channels_);
EXPECT_EQ(frame_size_ * channels_, dec_len);
for (unsigned int n = 0; n < frame_size_; ++n) {
@ -247,8 +248,8 @@ class AudioDecoderTest : public ::testing::Test {
AudioDecoder::SpeechType speech_type;
EXPECT_EQ(0, decoder_->Init());
scoped_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
size_t dec_len =
decoder_->Decode(encoded_, enc_len, output.get(), &speech_type);
size_t dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
output.get(), &speech_type);
EXPECT_EQ(frame_size_ * channels_, dec_len);
// Call DecodePlc and verify that we get one frame of data.
// (Overwrite the output from the above Decode call, but that does not
@ -338,8 +339,8 @@ class AudioDecoderIlbcTest : public AudioDecoderTest {
AudioDecoder::SpeechType speech_type;
EXPECT_EQ(0, decoder_->Init());
scoped_ptr<int16_t[]> output(new int16_t[frame_size_ * channels_]);
size_t dec_len =
decoder_->Decode(encoded_, enc_len, output.get(), &speech_type);
size_t dec_len = decoder_->Decode(encoded_, enc_len, codec_input_rate_hz_,
output.get(), &speech_type);
EXPECT_EQ(frame_size_, dec_len);
// Simply call DecodePlc and verify that we get 0 as return value.
EXPECT_EQ(0, decoder_->DecodePlc(1, output.get()));

View File

@ -22,8 +22,9 @@ class MockAudioDecoder : public AudioDecoder {
MockAudioDecoder() {}
virtual ~MockAudioDecoder() { Die(); }
MOCK_METHOD0(Die, void());
MOCK_METHOD4(Decode, int(const uint8_t*, size_t, int16_t*,
AudioDecoder::SpeechType*));
MOCK_METHOD5(
Decode,
int(const uint8_t*, size_t, int, int16_t*, AudioDecoder::SpeechType*));
MOCK_CONST_METHOD0(HasDecodePlc, bool());
MOCK_METHOD2(DecodePlc, int(int, int16_t*));
MOCK_METHOD0(Init, int());

View File

@ -29,8 +29,11 @@ class ExternalPcm16B : public AudioDecoder {
public:
ExternalPcm16B() {}
virtual int Decode(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) {
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type) {
int16_t ret = WebRtcPcm16b_Decode(
encoded, static_cast<int16_t>(encoded_len), decoded);
*speech_type = ConvertSpeechType(1);
@ -49,7 +52,7 @@ class MockExternalPcm16B : public ExternalPcm16B {
public:
MockExternalPcm16B() {
// By default, all calls are delegated to the real object.
ON_CALL(*this, Decode(_, _, _, _))
ON_CALL(*this, Decode(_, _, _, _, _))
.WillByDefault(Invoke(&real_, &ExternalPcm16B::Decode));
ON_CALL(*this, HasDecodePlc())
.WillByDefault(Invoke(&real_, &ExternalPcm16B::HasDecodePlc));
@ -65,9 +68,12 @@ class MockExternalPcm16B : public ExternalPcm16B {
virtual ~MockExternalPcm16B() { Die(); }
MOCK_METHOD0(Die, void());
MOCK_METHOD4(Decode,
int(const uint8_t* encoded, size_t encoded_len, int16_t* decoded,
SpeechType* speech_type));
MOCK_METHOD5(Decode,
int(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type));
MOCK_CONST_METHOD0(HasDecodePlc,
bool());
MOCK_METHOD2(DecodePlc,

View File

@ -100,7 +100,8 @@ class NetEqExternalDecoderUnitTest : public test::NetEqExternalDecoderTest {
next_arrival_time = GetArrivalTime(next_send_time);
} while (Lost()); // If lost, immediately read the next packet.
EXPECT_CALL(*external_decoder_, Decode(_, payload_size_bytes_, _, _))
EXPECT_CALL(*external_decoder_,
Decode(_, payload_size_bytes_, 1000 * samples_per_ms_, _, _))
.Times(NumExpectedDecodeCalls(num_loops));
uint32_t time_now = 0;

View File

@ -1266,7 +1266,7 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, Operations* operation,
", ssrc=" << packet->header.ssrc <<
", len=" << packet->payload_length;
decode_length = decoder->DecodeRedundant(
packet->payload, packet->payload_length,
packet->payload, packet->payload_length, fs_hz_,
&decoded_buffer_[*decoded_length], speech_type);
} else {
LOG(LS_VERBOSE) << "Decoding packet: ts=" << packet->header.timestamp <<
@ -1274,10 +1274,9 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, Operations* operation,
", pt=" << static_cast<int>(packet->header.payloadType) <<
", ssrc=" << packet->header.ssrc <<
", len=" << packet->payload_length;
decode_length = decoder->Decode(packet->payload,
packet->payload_length,
&decoded_buffer_[*decoded_length],
speech_type);
decode_length =
decoder->Decode(packet->payload, packet->payload_length, fs_hz_,
&decoded_buffer_[*decoded_length], speech_type);
}
delete[] packet->payload;
@ -1607,7 +1606,8 @@ void NetEqImpl::DoCodecInternalCng() {
if (decoder) {
const uint8_t* dummy_payload = NULL;
AudioDecoder::SpeechType speech_type;
length = decoder->Decode(dummy_payload, 0, decoded_buffer, &speech_type);
length =
decoder->Decode(dummy_payload, 0, fs_hz_, decoded_buffer, &speech_type);
}
assert(mute_factor_array_.get());
normal_->Process(decoded_buffer, length, last_mode_, mute_factor_array_.get(),

View File

@ -430,6 +430,7 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) {
// Produce as many samples as input bytes (|encoded_len|).
virtual int Decode(const uint8_t* encoded,
size_t encoded_len,
int /*sample_rate_hz*/,
int16_t* decoded,
SpeechType* speech_type) {
for (size_t i = 0; i < encoded_len; ++i) {
@ -521,10 +522,11 @@ TEST_F(NetEqImplTest, ReorderedPacket) {
int16_t dummy_output[kPayloadLengthSamples] = {0};
// The below expectation will make the mock decoder write
// |kPayloadLengthSamples| zeros to the output array, and mark it as speech.
EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes, _, _))
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
EXPECT_CALL(mock_decoder,
Decode(Pointee(0), kPayloadLengthBytes, kSampleRateHz, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<3>(AudioDecoder::kSpeech),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kPayloadLengthSamples)));
EXPECT_EQ(NetEq::kOK,
neteq_->RegisterExternalDecoder(
@ -566,10 +568,11 @@ TEST_F(NetEqImplTest, ReorderedPacket) {
// Expect only the second packet to be decoded (the one with "2" as the first
// payload byte).
EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes, _, _))
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
EXPECT_CALL(mock_decoder,
Decode(Pointee(2), kPayloadLengthBytes, kSampleRateHz, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<3>(AudioDecoder::kSpeech),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kPayloadLengthSamples)));
// Pull audio once.
@ -682,28 +685,31 @@ TEST_F(NetEqImplTest, CodecInternalCng) {
// Pointee(x) verifies that first byte of the payload equals x, this makes it
// possible to verify that the correct payload is fed to Decode().
EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes, _, _))
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes,
kSampleRateKhz * 1000, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<3>(AudioDecoder::kSpeech),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kPayloadLengthSamples)));
EXPECT_CALL(mock_decoder, Decode(Pointee(1), kPayloadLengthBytes, _, _))
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
EXPECT_CALL(mock_decoder, Decode(Pointee(1), kPayloadLengthBytes,
kSampleRateKhz * 1000, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<3>(AudioDecoder::kComfortNoise),
SetArgPointee<4>(AudioDecoder::kComfortNoise),
Return(kPayloadLengthSamples)));
EXPECT_CALL(mock_decoder, Decode(IsNull(), 0, _, _))
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
EXPECT_CALL(mock_decoder, Decode(IsNull(), 0, kSampleRateKhz * 1000, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<3>(AudioDecoder::kComfortNoise),
SetArgPointee<4>(AudioDecoder::kComfortNoise),
Return(kPayloadLengthSamples)));
EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes, _, _))
.WillOnce(DoAll(SetArrayArgument<2>(dummy_output,
EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes,
kSampleRateKhz * 1000, _, _))
.WillOnce(DoAll(SetArrayArgument<3>(dummy_output,
dummy_output + kPayloadLengthSamples),
SetArgPointee<3>(AudioDecoder::kSpeech),
SetArgPointee<4>(AudioDecoder::kSpeech),
Return(kPayloadLengthSamples)));
EXPECT_EQ(NetEq::kOK,

View File

@ -36,16 +36,22 @@ class MockAudioDecoderOpus : public AudioDecoderOpus {
MOCK_METHOD0(Init, int());
// Override the following methods such that no actual payload is needed.
int Decode(const uint8_t* encoded, size_t encoded_len, int16_t* decoded,
int Decode(const uint8_t* encoded,
size_t encoded_len,
int /*sample_rate_hz*/,
int16_t* decoded,
SpeechType* speech_type) override {
*speech_type = kSpeech;
memset(decoded, 0, sizeof(int16_t) * kPacketDuration * channels_);
return kPacketDuration * channels_;
}
int DecodeRedundant(const uint8_t* encoded, size_t encoded_len,
int16_t* decoded, SpeechType* speech_type) override {
return Decode(encoded, encoded_len, decoded, speech_type);
int DecodeRedundant(const uint8_t* encoded,
size_t encoded_len,
int sample_rate_hz,
int16_t* decoded,
SpeechType* speech_type) override {
return Decode(encoded, encoded_len, sample_rate_hz, decoded, speech_type);
}
int PacketDuration(const uint8_t* encoded,