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
diff --git a/webrtc/modules/audio_coding/neteq4/audio_decoder.cc b/webrtc/modules/audio_coding/neteq4/audio_decoder.cc
index 3e9b464..5a745ff 100644
--- a/webrtc/modules/audio_coding/neteq4/audio_decoder.cc
+++ b/webrtc/modules/audio_coding/neteq4/audio_decoder.cc
@@ -30,6 +30,7 @@
#endif
#ifdef WEBRTC_CODEC_ISAC
case kDecoderISACswb:
+ case kDecoderISACfb:
#endif
#ifdef WEBRTC_CODEC_PCM16
case kDecoderPCM16B:
@@ -96,6 +97,7 @@
}
#ifdef WEBRTC_CODEC_ISAC
case kDecoderISACswb:
+ case kDecoderISACfb:
#endif
#ifdef WEBRTC_CODEC_PCM16
case kDecoderPCM16Bswb32kHz:
@@ -153,6 +155,8 @@
#ifdef WEBRTC_CODEC_ISAC
case kDecoderISACswb:
return new AudioDecoderIsacSwb;
+ case kDecoderISACfb:
+ return new AudioDecoderIsacFb;
#endif
#ifdef WEBRTC_CODEC_PCM16
case kDecoderPCM16B:
diff --git a/webrtc/modules/audio_coding/neteq4/audio_decoder_impl.cc b/webrtc/modules/audio_coding/neteq4/audio_decoder_impl.cc
index 4ab7984..1d000ff 100644
--- a/webrtc/modules/audio_coding/neteq4/audio_decoder_impl.cc
+++ b/webrtc/modules/audio_coding/neteq4/audio_decoder_impl.cc
@@ -209,6 +209,11 @@
codec_type_ = kDecoderISACswb;
WebRtcIsac_SetDecSampRate(static_cast<ISACStruct*>(state_), 32000);
}
+
+// iSAC FB
+AudioDecoderIsacFb::AudioDecoderIsacFb() : AudioDecoderIsacSwb() {
+ codec_type_ = kDecoderISACfb;
+}
#endif
// iSAC fix
diff --git a/webrtc/modules/audio_coding/neteq4/audio_decoder_impl.h b/webrtc/modules/audio_coding/neteq4/audio_decoder_impl.h
index 1776a39..7aaa69a 100644
--- a/webrtc/modules/audio_coding/neteq4/audio_decoder_impl.h
+++ b/webrtc/modules/audio_coding/neteq4/audio_decoder_impl.h
@@ -143,6 +143,14 @@
private:
DISALLOW_COPY_AND_ASSIGN(AudioDecoderIsacSwb);
};
+
+class AudioDecoderIsacFb : public AudioDecoderIsacSwb {
+ public:
+ AudioDecoderIsacFb();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AudioDecoderIsacFb);
+};
#endif
#ifdef WEBRTC_CODEC_ISACFX
diff --git a/webrtc/modules/audio_coding/neteq4/audio_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq4/audio_decoder_unittest.cc
index b7e3286..f91438f 100644
--- a/webrtc/modules/audio_coding/neteq4/audio_decoder_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq4/audio_decoder_unittest.cc
@@ -377,6 +377,19 @@
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 @@
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 @@
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 @@
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));
diff --git a/webrtc/modules/audio_coding/neteq4/interface/audio_decoder.h b/webrtc/modules/audio_coding/neteq4/interface/audio_decoder.h
index 0b23c76..7668f33 100644
--- a/webrtc/modules/audio_coding/neteq4/interface/audio_decoder.h
+++ b/webrtc/modules/audio_coding/neteq4/interface/audio_decoder.h
@@ -26,6 +26,7 @@
kDecoderILBC,
kDecoderISAC,
kDecoderISACswb,
+ kDecoderISACfb,
kDecoderPCM16B,
kDecoderPCM16Bwb,
kDecoderPCM16Bswb32kHz,
diff --git a/webrtc/modules/audio_coding/neteq4/neteq_unittest.cc b/webrtc/modules/audio_coding/neteq4/neteq_unittest.cc
index 65cc393..250ca0e 100644
--- a/webrtc/modules/audio_coding/neteq4/neteq_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq4/neteq_unittest.cc
@@ -235,6 +235,8 @@
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.
diff --git a/webrtc/modules/audio_coding/neteq4/timestamp_scaler.cc b/webrtc/modules/audio_coding/neteq4/timestamp_scaler.cc
index 6bb22d5..d58d5dd 100644
--- a/webrtc/modules/audio_coding/neteq4/timestamp_scaler.cc
+++ b/webrtc/modules/audio_coding/neteq4/timestamp_scaler.cc
@@ -49,6 +49,7 @@
}
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).
diff --git a/webrtc/modules/audio_coding/neteq4/timestamp_scaler_unittest.cc b/webrtc/modules/audio_coding/neteq4/timestamp_scaler_unittest.cc
index ecbed98..c676094 100644
--- a/webrtc/modules/audio_coding/neteq4/timestamp_scaler_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq4/timestamp_scaler_unittest.cc
@@ -252,6 +252,62 @@
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;