webrtc_m130/webrtc/modules/audio_coding/neteq4/audio_decoder_unittest.cc
henrik.lundin@webrtc.org d94659dc27 Initial upload of NetEq4
This is the first public upload of the new NetEq, version 4.

It has been through extensive internal review during the course of
the project.

TEST=trybots

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3425 4adac7df-926f-26a2-2b94-8c16560cd09d
2013-01-29 12:09:21 +00:00

648 lines
23 KiB
C++

/*
* Copyright (c) 2012 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 "webrtc/modules/audio_coding/neteq4/audio_decoder_impl.h"
#include <assert.h>
#include <stdlib.h>
#include <string>
#include "gtest/gtest.h"
#include "webrtc/common_audio/resampler/include/resampler.h"
#include "webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h"
#include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h"
#include "webrtc/modules/audio_coding/codecs/ilbc/interface/ilbc.h"
#include "webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h"
#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h"
#include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h"
#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h"
#include "webrtc/system_wrappers/interface/data_log.h"
#include "webrtc/test/testsupport/fileutils.h"
namespace webrtc {
class AudioDecoderTest : public ::testing::Test {
protected:
AudioDecoderTest()
: input_fp_(NULL),
input_(NULL),
encoded_(NULL),
decoded_(NULL),
frame_size_(0),
data_length_(0),
encoded_bytes_(0),
decoder_(NULL) {
input_file_ = webrtc::test::ProjectRootPath() +
"resources/audio_coding/testfile32kHz.pcm";
}
virtual ~AudioDecoderTest() {}
virtual void SetUp() {
// Create arrays.
ASSERT_GT(data_length_, 0u) << "The test must set data_length_ > 0";
input_ = new int16_t[data_length_];
encoded_ = new uint8_t[data_length_ * 2];
decoded_ = new int16_t[data_length_];
// Open input file.
input_fp_ = fopen(input_file_.c_str(), "rb");
ASSERT_TRUE(input_fp_ != NULL) << "Failed to open file " << input_file_;
// Read data to |input_|.
ASSERT_EQ(data_length_,
fread(input_, sizeof(int16_t), data_length_, input_fp_)) <<
"Could not read enough data from file";
// Logging to view input and output in Matlab.
// Use 'gyp -Denable_data_logging=1' to enable logging.
DataLog::CreateLog();
DataLog::AddTable("CodecTest");
DataLog::AddColumn("CodecTest", "input", 1);
DataLog::AddColumn("CodecTest", "output", 1);
}
virtual void TearDown() {
delete decoder_;
decoder_ = NULL;
// Close input file.
fclose(input_fp_);
// Delete arrays.
delete [] input_;
input_ = NULL;
delete [] encoded_;
encoded_ = NULL;
delete [] decoded_;
decoded_ = NULL;
// Close log.
DataLog::ReturnLog();
}
virtual void InitEncoder() { }
// This method must be implemented for all tests derived from this class.
virtual int EncodeFrame(const int16_t* input, size_t input_len,
uint8_t* output) = 0;
// Encodes and decodes audio. The absolute difference between the input and
// output is compared vs |tolerance|, and the mean-squared error is compared
// with |mse|. The encoded stream should contain |expected_bytes|.
void EncodeDecodeTest(size_t expected_bytes, int tolerance, double mse,
int delay = 0) {
ASSERT_GE(tolerance, 0) << "Test must define a tolerance >= 0";
size_t processed_samples = 0u;
encoded_bytes_ = 0u;
InitEncoder();
EXPECT_EQ(0, decoder_->Init());
while (processed_samples + frame_size_ <= data_length_) {
size_t enc_len = EncodeFrame(&input_[processed_samples], frame_size_,
&encoded_[encoded_bytes_]);
AudioDecoder::SpeechType speech_type;
size_t dec_len = decoder_->Decode(&encoded_[encoded_bytes_], enc_len,
&decoded_[processed_samples],
&speech_type);
EXPECT_EQ(frame_size_, dec_len);
encoded_bytes_ += enc_len;
processed_samples += frame_size_;
}
EXPECT_EQ(expected_bytes, encoded_bytes_);
CompareInputOutput(processed_samples, tolerance, delay);
EXPECT_LE(MseInputOutput(processed_samples, delay), mse);
}
// The absolute difference between the input and output is compared vs
// |tolerance|. The parameter |delay| is used to correct for codec delays.
void CompareInputOutput(size_t num_samples, int tolerance, int delay) const {
assert(num_samples <= data_length_);
for (unsigned int n = 0; n < num_samples - delay; ++n) {
ASSERT_NEAR(input_[n], decoded_[n + delay], tolerance) <<
"Exit test on first diff; n = " << n;
DataLog::InsertCell("CodecTest", "input", input_[n]);
DataLog::InsertCell("CodecTest", "output", decoded_[n]);
DataLog::NextRow("CodecTest");
}
}
// Calculates mean-squared error between input and output. The parameter
// |delay| is used to correct for codec delays.
double MseInputOutput(size_t num_samples, int delay) const {
assert(num_samples <= data_length_);
if (num_samples == 0) return 0.0;
double squared_sum = 0.0;
for (unsigned int n = 0; n < num_samples - delay; ++n) {
squared_sum += (input_[n] - decoded_[n + delay]) *
(input_[n] - decoded_[n + delay]);
}
return squared_sum / (num_samples - delay);
}
// Encodes a payload and decodes it twice with decoder re-init before each
// decode. Verifies that the decoded result is the same.
void ReInitTest() {
uint8_t* encoded = encoded_;
uint8_t* encoded_copy = encoded_ + 2 * frame_size_;
int16_t* output1 = decoded_;
int16_t* output2 = decoded_ + frame_size_;
InitEncoder();
size_t enc_len = EncodeFrame(input_, frame_size_, encoded);
// Copy payload since iSAC fix destroys it during decode.
// Issue: http://code.google.com/p/webrtc/issues/detail?id=845.
// TODO(hlundin): Remove if the iSAC bug gets fixed.
memcpy(encoded_copy, encoded, enc_len);
AudioDecoder::SpeechType speech_type1, speech_type2;
EXPECT_EQ(0, decoder_->Init());
size_t dec_len = decoder_->Decode(encoded, enc_len, output1, &speech_type1);
EXPECT_EQ(frame_size_, dec_len);
// Re-init decoder and decode again.
EXPECT_EQ(0, decoder_->Init());
dec_len = decoder_->Decode(encoded_copy, enc_len, output2, &speech_type2);
EXPECT_EQ(frame_size_, dec_len);
for (unsigned int n = 0; n < frame_size_; ++n) {
ASSERT_EQ(output1[n], output2[n]) << "Exit test on first diff; n = " << n;
}
EXPECT_EQ(speech_type1, speech_type2);
}
// Call DecodePlc and verify that the correct number of samples is produced.
void DecodePlcTest() {
InitEncoder();
size_t enc_len = EncodeFrame(input_, frame_size_, encoded_);
AudioDecoder::SpeechType speech_type;
EXPECT_EQ(0, decoder_->Init());
size_t dec_len =
decoder_->Decode(encoded_, enc_len, decoded_, &speech_type);
EXPECT_EQ(frame_size_, 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
// matter.)
dec_len = decoder_->DecodePlc(1, decoded_);
EXPECT_EQ(frame_size_, dec_len);
}
std::string input_file_;
FILE* input_fp_;
int16_t* input_;
uint8_t* encoded_;
int16_t* decoded_;
size_t frame_size_;
size_t data_length_;
size_t encoded_bytes_;
AudioDecoder* decoder_;
};
class AudioDecoderPcmUTest : public AudioDecoderTest {
protected:
AudioDecoderPcmUTest() : AudioDecoderTest() {
frame_size_ = 160;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderPcmU;
assert(decoder_);
}
virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
uint8_t* output) {
int enc_len_bytes =
WebRtcG711_EncodeU(NULL, const_cast<int16_t*>(input), input_len_samples,
reinterpret_cast<int16_t*>(output));
EXPECT_EQ(input_len_samples, static_cast<size_t>(enc_len_bytes));
return enc_len_bytes;
}
};
class AudioDecoderPcmATest : public AudioDecoderTest {
protected:
AudioDecoderPcmATest() : AudioDecoderTest() {
frame_size_ = 160;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderPcmA;
assert(decoder_);
}
virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
uint8_t* output) {
int enc_len_bytes =
WebRtcG711_EncodeA(NULL, const_cast<int16_t*>(input), input_len_samples,
reinterpret_cast<int16_t*>(output));
EXPECT_EQ(input_len_samples, static_cast<size_t>(enc_len_bytes));
return enc_len_bytes;
}
};
class AudioDecoderPcm16BTest : public AudioDecoderTest {
protected:
AudioDecoderPcm16BTest() : AudioDecoderTest() {
frame_size_ = 160;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderPcm16B(kDecoderPCM16B);
assert(decoder_);
}
virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
uint8_t* output) {
int enc_len_bytes = WebRtcPcm16b_EncodeW16(
const_cast<int16_t*>(input), input_len_samples,
reinterpret_cast<int16_t*>(output));
EXPECT_EQ(2 * input_len_samples, static_cast<size_t>(enc_len_bytes));
return enc_len_bytes;
}
};
class AudioDecoderIlbcTest : public AudioDecoderTest {
protected:
AudioDecoderIlbcTest() : AudioDecoderTest() {
frame_size_ = 240;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderIlbc;
assert(decoder_);
assert(WebRtcIlbcfix_EncoderCreate(&encoder_) == 0);
}
~AudioDecoderIlbcTest() {
WebRtcIlbcfix_EncoderFree(encoder_);
}
virtual void InitEncoder() {
ASSERT_EQ(0, WebRtcIlbcfix_EncoderInit(encoder_, 30)); // 30 ms.
}
virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
uint8_t* output) {
int enc_len_bytes =
WebRtcIlbcfix_Encode(encoder_, input, input_len_samples,
reinterpret_cast<int16_t*>(output));
EXPECT_EQ(50, enc_len_bytes);
return enc_len_bytes;
}
// Overload the default test since iLBC's function WebRtcIlbcfix_NetEqPlc does
// not return any data. It simply resets a few states and returns 0.
void DecodePlcTest() {
InitEncoder();
size_t enc_len = EncodeFrame(input_, frame_size_, encoded_);
AudioDecoder::SpeechType speech_type;
EXPECT_EQ(0, decoder_->Init());
size_t dec_len =
decoder_->Decode(encoded_, enc_len, decoded_, &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, decoded_));
}
iLBC_encinst_t* encoder_;
};
class AudioDecoderIsacFloatTest : public AudioDecoderTest {
protected:
AudioDecoderIsacFloatTest() : AudioDecoderTest() {
input_size_ = 160;
frame_size_ = 480;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderIsac;
assert(decoder_);
assert(WebRtcIsac_Create(&encoder_) == 0);
assert(WebRtcIsac_SetEncSampRate(encoder_, 16000) == 0);
}
~AudioDecoderIsacFloatTest() {
WebRtcIsac_Free(encoder_);
}
virtual void InitEncoder() {
ASSERT_EQ(0, WebRtcIsac_EncoderInit(encoder_, 1)); // Fixed mode.
ASSERT_EQ(0, WebRtcIsac_Control(encoder_, 32000, 30)); // 32 kbps, 30 ms.
}
virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
uint8_t* output) {
// Insert 3 * 10 ms. Expect non-zero output on third call.
EXPECT_EQ(0, WebRtcIsac_Encode(encoder_, input,
reinterpret_cast<int16_t*>(output)));
input += input_size_;
EXPECT_EQ(0, WebRtcIsac_Encode(encoder_, input,
reinterpret_cast<int16_t*>(output)));
input += input_size_;
int enc_len_bytes =
WebRtcIsac_Encode(encoder_, input, reinterpret_cast<int16_t*>(output));
EXPECT_GT(enc_len_bytes, 0);
return enc_len_bytes;
}
ISACStruct* encoder_;
int input_size_;
};
class AudioDecoderIsacSwbTest : public AudioDecoderTest {
protected:
AudioDecoderIsacSwbTest() : AudioDecoderTest() {
input_size_ = 320;
frame_size_ = 960;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderIsacSwb;
assert(decoder_);
assert(WebRtcIsac_Create(&encoder_) == 0);
assert(WebRtcIsac_SetEncSampRate(encoder_, 32000) == 0);
}
~AudioDecoderIsacSwbTest() {
WebRtcIsac_Free(encoder_);
}
virtual void InitEncoder() {
ASSERT_EQ(0, WebRtcIsac_EncoderInit(encoder_, 1)); // Fixed mode.
ASSERT_EQ(0, WebRtcIsac_Control(encoder_, 32000, 30)); // 32 kbps, 30 ms.
}
virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
uint8_t* output) {
// Insert 3 * 10 ms. Expect non-zero output on third call.
EXPECT_EQ(0, WebRtcIsac_Encode(encoder_, input,
reinterpret_cast<int16_t*>(output)));
input += input_size_;
EXPECT_EQ(0, WebRtcIsac_Encode(encoder_, input,
reinterpret_cast<int16_t*>(output)));
input += input_size_;
int enc_len_bytes =
WebRtcIsac_Encode(encoder_, input, reinterpret_cast<int16_t*>(output));
EXPECT_GT(enc_len_bytes, 0);
return enc_len_bytes;
}
ISACStruct* encoder_;
int input_size_;
};
class AudioDecoderIsacFixTest : public AudioDecoderTest {
protected:
AudioDecoderIsacFixTest() : AudioDecoderTest() {
input_size_ = 160;
frame_size_ = 480;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderIsacFix;
assert(decoder_);
assert(WebRtcIsacfix_Create(&encoder_) == 0);
}
~AudioDecoderIsacFixTest() {
WebRtcIsacfix_Free(encoder_);
}
virtual void InitEncoder() {
ASSERT_EQ(0, WebRtcIsacfix_EncoderInit(encoder_, 1)); // Fixed mode.
ASSERT_EQ(0,
WebRtcIsacfix_Control(encoder_, 32000, 30)); // 32 kbps, 30 ms.
}
virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
uint8_t* output) {
// Insert 3 * 10 ms. Expect non-zero output on third call.
EXPECT_EQ(0, WebRtcIsacfix_Encode(encoder_, input,
reinterpret_cast<int16_t*>(output)));
input += input_size_;
EXPECT_EQ(0, WebRtcIsacfix_Encode(encoder_, input,
reinterpret_cast<int16_t*>(output)));
input += input_size_;
int enc_len_bytes = WebRtcIsacfix_Encode(
encoder_, input, reinterpret_cast<int16_t*>(output));
EXPECT_GT(enc_len_bytes, 0);
return enc_len_bytes;
}
ISACFIX_MainStruct* encoder_;
int input_size_;
};
class AudioDecoderG722Test : public AudioDecoderTest {
protected:
AudioDecoderG722Test() : AudioDecoderTest() {
frame_size_ = 160;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderG722;
assert(decoder_);
assert(WebRtcG722_CreateEncoder(&encoder_) == 0);
}
~AudioDecoderG722Test() {
WebRtcG722_FreeEncoder(encoder_);
}
virtual void InitEncoder() {
ASSERT_EQ(0, WebRtcG722_EncoderInit(encoder_));
}
virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
uint8_t* output) {
int enc_len_bytes =
WebRtcG722_Encode(encoder_, const_cast<int16_t*>(input),
input_len_samples,
reinterpret_cast<int16_t*>(output));
EXPECT_EQ(80, enc_len_bytes);
return enc_len_bytes;
}
G722EncInst* encoder_;
};
class AudioDecoderOpusTest : public AudioDecoderTest {
protected:
AudioDecoderOpusTest() : AudioDecoderTest() {
frame_size_ = 320;
data_length_ = 10 * frame_size_;
decoder_ = new AudioDecoderOpus(kDecoderOpus);
assert(decoder_);
assert(WebRtcOpus_EncoderCreate(&encoder_, 1) == 0);
}
~AudioDecoderOpusTest() {
WebRtcOpus_EncoderFree(encoder_);
}
virtual void InitEncoder() {}
virtual int EncodeFrame(const int16_t* input, size_t input_len_samples,
uint8_t* output) {
// Upsample from 32 to 48 kHz.
Resampler rs;
rs.Reset(32000, 48000, kResamplerSynchronous);
const int max_resamp_len_samples = input_len_samples * 3 / 2;
int16_t* resamp_input = new int16_t[max_resamp_len_samples];
int resamp_len_samples;
EXPECT_EQ(0, rs.Push(input, input_len_samples, resamp_input,
max_resamp_len_samples, resamp_len_samples));
EXPECT_EQ(max_resamp_len_samples, resamp_len_samples);
int enc_len_bytes =
WebRtcOpus_Encode(encoder_, resamp_input,
resamp_len_samples, data_length_, output);
EXPECT_GT(enc_len_bytes, 0);
delete [] resamp_input;
return enc_len_bytes;
}
OpusEncInst* encoder_;
};
TEST_F(AudioDecoderPcmUTest, EncodeDecode) {
int tolerance = 251;
double mse = 1734.0;
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMu));
EncodeDecodeTest(data_length_, tolerance, mse);
ReInitTest();
EXPECT_FALSE(decoder_->HasDecodePlc());
}
TEST_F(AudioDecoderPcmATest, EncodeDecode) {
int tolerance = 308;
double mse = 1931.0;
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMa));
EncodeDecodeTest(data_length_, tolerance, mse);
ReInitTest();
EXPECT_FALSE(decoder_->HasDecodePlc());
}
TEST_F(AudioDecoderPcm16BTest, EncodeDecode) {
int tolerance = 0;
double mse = 0.0;
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16B));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bwb));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb32kHz));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb48kHz));
EncodeDecodeTest(2 * data_length_, tolerance, mse);
ReInitTest();
EXPECT_FALSE(decoder_->HasDecodePlc());
}
TEST_F(AudioDecoderIlbcTest, EncodeDecode) {
int tolerance = 6808;
double mse = 2.13e6;
int delay = 80; // Delay from input to output.
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderILBC));
EncodeDecodeTest(500, tolerance, mse, delay);
ReInitTest();
EXPECT_TRUE(decoder_->HasDecodePlc());
DecodePlcTest();
}
TEST_F(AudioDecoderIsacFloatTest, EncodeDecode) {
int tolerance = 3399;
double mse = 434951.0;
int delay = 48; // Delay from input to output.
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISAC));
EncodeDecodeTest(883, tolerance, mse, delay);
ReInitTest();
EXPECT_TRUE(decoder_->HasDecodePlc());
DecodePlcTest();
}
TEST_F(AudioDecoderIsacSwbTest, EncodeDecode) {
int tolerance = 19757;
double mse = 8.18e6;
int delay = 160; // Delay from input to output.
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISACswb));
EncodeDecodeTest(853, tolerance, mse, delay);
ReInitTest();
EXPECT_TRUE(decoder_->HasDecodePlc());
DecodePlcTest();
}
TEST_F(AudioDecoderIsacFixTest, EncodeDecode) {
int tolerance = 11034;
double mse = 3.46e6;
int delay = 54; // Delay from input to output.
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISAC));
EncodeDecodeTest(735, tolerance, mse, delay);
ReInitTest();
EXPECT_FALSE(decoder_->HasDecodePlc());
}
TEST_F(AudioDecoderG722Test, EncodeDecode) {
int tolerance = 6176;
double mse = 238630.0;
int delay = 22; // Delay from input to output.
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderG722));
EncodeDecodeTest(data_length_ / 2, tolerance, mse, delay);
ReInitTest();
EXPECT_FALSE(decoder_->HasDecodePlc());
}
TEST_F(AudioDecoderOpusTest, EncodeDecode) {
int tolerance = 6176;
double mse = 238630.0;
int delay = 22; // Delay from input to output.
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderOpus));
EncodeDecodeTest(731, tolerance, mse, delay);
ReInitTest();
EXPECT_FALSE(decoder_->HasDecodePlc());
}
TEST(AudioDecoder, CodecSampleRateHz) {
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCMu));
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCMa));
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCMu_2ch));
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCMa_2ch));
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderILBC));
EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderISAC));
EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderISACswb));
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16B));
EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bwb));
EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bswb32kHz));
EXPECT_EQ(48000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bswb48kHz));
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16B_2ch));
EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bwb_2ch));
EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bswb32kHz_2ch));
EXPECT_EQ(48000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bswb48kHz_2ch));
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16B_5ch));
EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderG722));
EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderG722_2ch));
EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderRED));
EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderAVT));
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderCNGnb));
EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderCNGwb));
EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderCNGswb32kHz));
// TODO(tlegrand): Change 32000 to 48000 below once ACM has 48 kHz support.
EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderCNGswb48kHz));
EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderArbitrary));
EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderOpus));
EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderOpus_2ch));
EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderCELT_32));
EXPECT_EQ(-1, AudioDecoder::CodecSampleRateHz(kDecoderCELT_32_2ch));
}
TEST(AudioDecoder, CodecSupported) {
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMu));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMa));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMu_2ch));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCMa_2ch));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderILBC));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISAC));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISACswb));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16B));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bwb));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb32kHz));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb48kHz));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16B_2ch));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bwb_2ch));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb32kHz_2ch));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb48kHz_2ch));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16B_5ch));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderG722));
EXPECT_FALSE(AudioDecoder::CodecSupported(kDecoderG722_2ch));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderRED));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderAVT));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCNGnb));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCNGwb));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCNGswb32kHz));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderCNGswb48kHz));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderArbitrary));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderOpus));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderOpus_2ch));
EXPECT_FALSE(AudioDecoder::CodecSupported(kDecoderCELT_32));
EXPECT_FALSE(AudioDecoder::CodecSupported(kDecoderCELT_32_2ch));
}
} // namespace webrtc