Adding iSAC-fb support

Adding tests, too.

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3440 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrik.lundin@webrtc.org 2013-01-31 09:55:24 +00:00
parent 3d13d9f0a0
commit ac59dba3f7
8 changed files with 103 additions and 0 deletions

View File

@ -30,6 +30,7 @@ bool AudioDecoder::CodecSupported(NetEqDecoder codec_type) {
#endif
#ifdef WEBRTC_CODEC_ISAC
case kDecoderISACswb:
case kDecoderISACfb:
#endif
#ifdef WEBRTC_CODEC_PCM16
case kDecoderPCM16B:
@ -96,6 +97,7 @@ int AudioDecoder::CodecSampleRateHz(NetEqDecoder codec_type) {
}
#ifdef WEBRTC_CODEC_ISAC
case kDecoderISACswb:
case kDecoderISACfb:
#endif
#ifdef WEBRTC_CODEC_PCM16
case kDecoderPCM16Bswb32kHz:
@ -153,6 +155,8 @@ AudioDecoder* AudioDecoder::CreateAudioDecoder(NetEqDecoder codec_type) {
#ifdef WEBRTC_CODEC_ISAC
case kDecoderISACswb:
return new AudioDecoderIsacSwb;
case kDecoderISACfb:
return new AudioDecoderIsacFb;
#endif
#ifdef WEBRTC_CODEC_PCM16
case kDecoderPCM16B:

View File

@ -209,6 +209,11 @@ AudioDecoderIsacSwb::AudioDecoderIsacSwb() : AudioDecoderIsac() {
codec_type_ = kDecoderISACswb;
WebRtcIsac_SetDecSampRate(static_cast<ISACStruct*>(state_), 32000);
}
// iSAC FB
AudioDecoderIsacFb::AudioDecoderIsacFb() : AudioDecoderIsacSwb() {
codec_type_ = kDecoderISACfb;
}
#endif
// iSAC fix

View File

@ -143,6 +143,14 @@ class AudioDecoderIsacSwb : public AudioDecoderIsac {
private:
DISALLOW_COPY_AND_ASSIGN(AudioDecoderIsacSwb);
};
class AudioDecoderIsacFb : public AudioDecoderIsacSwb {
public:
AudioDecoderIsacFb();
private:
DISALLOW_COPY_AND_ASSIGN(AudioDecoderIsacFb);
};
#endif
#ifdef WEBRTC_CODEC_ISACFX

View File

@ -377,6 +377,19 @@ class AudioDecoderIsacSwbTest : public AudioDecoderTest {
int input_size_;
};
// This test is identical to AudioDecoderIsacSwbTest, except that it creates
// an AudioDecoderIsacFb decoder object.
class AudioDecoderIsacFbTest : public AudioDecoderIsacSwbTest {
protected:
AudioDecoderIsacFbTest() : AudioDecoderIsacSwbTest() {
// Delete the |decoder_| that was created by AudioDecoderIsacSwbTest and
// create an AudioDecoderIsacFb object instead.
delete decoder_;
decoder_ = new AudioDecoderIsacFb;
assert(decoder_);
}
};
class AudioDecoderIsacFixTest : public AudioDecoderTest {
protected:
AudioDecoderIsacFixTest() : AudioDecoderTest() {
@ -549,6 +562,17 @@ TEST_F(AudioDecoderIsacSwbTest, EncodeDecode) {
DecodePlcTest();
}
TEST_F(AudioDecoderIsacFbTest, 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, DISABLED_EncodeDecode) {
int tolerance = 11034;
double mse = 3.46e6;
@ -587,6 +611,7 @@ TEST(AudioDecoder, CodecSampleRateHz) {
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderILBC));
EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderISAC));
EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderISACswb));
EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderISACfb));
EXPECT_EQ(8000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16B));
EXPECT_EQ(16000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bwb));
EXPECT_EQ(32000, AudioDecoder::CodecSampleRateHz(kDecoderPCM16Bswb32kHz));
@ -620,6 +645,7 @@ TEST(AudioDecoder, CodecSupported) {
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderILBC));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISAC));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISACswb));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderISACfb));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16B));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bwb));
EXPECT_TRUE(AudioDecoder::CodecSupported(kDecoderPCM16Bswb32kHz));

View File

@ -26,6 +26,7 @@ enum NetEqDecoder {
kDecoderILBC,
kDecoderISAC,
kDecoderISACswb,
kDecoderISACfb,
kDecoderPCM16B,
kDecoderPCM16Bwb,
kDecoderPCM16Bswb32kHz,

View File

@ -235,6 +235,8 @@ void NetEqDecodingTest::LoadDecoders() {
ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderISAC, 103));
// Load iSAC SWB.
ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderISACswb, 104));
// Load iSAC FB.
ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderISACfb, 105));
// Load PCM16B nb.
ASSERT_EQ(0, neteq_->RegisterPayloadType(kDecoderPCM16B, 93));
// Load PCM16B wb.

View File

@ -49,6 +49,7 @@ uint32_t TimestampScaler::ToInternal(uint32_t external_timestamp,
}
case kDecoderOpus:
case kDecoderOpus_2ch:
case kDecoderISACfb:
case kDecoderCNGswb48kHz: {
// Use timestamp scaling with factor 2/3 (32 kHz sample rate, but RTP
// timestamps run on 48 kHz).

View File

@ -252,6 +252,62 @@ TEST(TimestampScaler, TestG722Reset) {
EXPECT_CALL(db, Die()); // Called when database object is deleted.
}
TEST(TimestampScaler, TestOpusLargeStep) {
MockDecoderDatabase db;
DecoderDatabase::DecoderInfo info;
info.codec_type = kDecoderOpus; // Uses a factor 2/3 scaling.
static const uint8_t kRtpPayloadType = 17;
EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
.WillRepeatedly(Return(&info));
TimestampScaler scaler(db);
// Test both sides of the timestamp wrap-around.
static const uint32_t kStep = 960;
uint32_t external_timestamp = 0;
// |external_timestamp| will be a large positive value.
external_timestamp = external_timestamp - 5 * kStep;
uint32_t internal_timestamp = external_timestamp;
for (; external_timestamp != 5 * kStep; external_timestamp += kStep) {
// Scale to internal timestamp.
EXPECT_EQ(internal_timestamp,
scaler.ToInternal(external_timestamp, kRtpPayloadType));
// Scale back.
EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
// Internal timestamp should be incremented with twice the step.
internal_timestamp += 2 * kStep / 3;
}
EXPECT_CALL(db, Die()); // Called when database object is deleted.
}
TEST(TimestampScaler, TestIsacFbLargeStep) {
MockDecoderDatabase db;
DecoderDatabase::DecoderInfo info;
info.codec_type = kDecoderISACfb; // Uses a factor 2/3 scaling.
static const uint8_t kRtpPayloadType = 17;
EXPECT_CALL(db, GetDecoderInfo(kRtpPayloadType))
.WillRepeatedly(Return(&info));
TimestampScaler scaler(db);
// Test both sides of the timestamp wrap-around.
static const uint32_t kStep = 960;
uint32_t external_timestamp = 0;
// |external_timestamp| will be a large positive value.
external_timestamp = external_timestamp - 5 * kStep;
uint32_t internal_timestamp = external_timestamp;
for (; external_timestamp != 5 * kStep; external_timestamp += kStep) {
// Scale to internal timestamp.
EXPECT_EQ(internal_timestamp,
scaler.ToInternal(external_timestamp, kRtpPayloadType));
// Scale back.
EXPECT_EQ(external_timestamp, scaler.ToExternal(internal_timestamp));
// Internal timestamp should be incremented with twice the step.
internal_timestamp += 2 * kStep / 3;
}
EXPECT_CALL(db, Die()); // Called when database object is deleted.
}
TEST(TimestampScaler, Failures) {
static const uint8_t kRtpPayloadType = 17;
MockDecoderDatabase db;