Added support for 96 kHz sampling frequency.
Updated resampler_unittests with the new valid combinations.
Verified audio quality on files.
TEST=resampler_unittests, voe_auto_test
BUILDTYPE=Debug, Release
PLATFORM=Linux
Review URL: http://webrtc-codereview.appspot.com/294001
git-svn-id: http://webrtc.googlecode.com/svn/trunk@1002 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/src/common_audio/resampler/include/resampler.h b/src/common_audio/resampler/include/resampler.h
index 41f1a87..38e6bd3 100644
--- a/src/common_audio/resampler/include/resampler.h
+++ b/src/common_audio/resampler/include/resampler.h
@@ -43,6 +43,7 @@
kResamplerMode1To3,
kResamplerMode1To4,
kResamplerMode1To6,
+ kResamplerMode1To12,
kResamplerMode2To3,
kResamplerMode2To11,
kResamplerMode4To11,
@@ -53,6 +54,7 @@
kResamplerMode3To1,
kResamplerMode4To1,
kResamplerMode6To1,
+ kResamplerMode12To1,
kResamplerMode3To2,
kResamplerMode11To2,
kResamplerMode11To4,
diff --git a/src/common_audio/resampler/resampler.cc b/src/common_audio/resampler/resampler.cc
index b175e27..2db27b1 100644
--- a/src/common_audio/resampler/resampler.cc
+++ b/src/common_audio/resampler/resampler.cc
@@ -209,6 +209,9 @@
case 6:
my_mode_ = kResamplerMode1To6;
break;
+ case 12:
+ my_mode_ = kResamplerMode1To12;
+ break;
default:
my_type_ = kResamplerInvalid;
return -1;
@@ -229,6 +232,9 @@
case 6:
my_mode_ = kResamplerMode6To1;
break;
+ case 12:
+ my_mode_ = kResamplerMode12To1;
+ break;
default:
my_type_ = kResamplerInvalid;
return -1;
@@ -299,6 +305,18 @@
state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state2_);
break;
+ case kResamplerMode1To12:
+ // 1:2
+ state1_ = malloc(8 * sizeof(WebRtc_Word32));
+ memset(state1_, 0, 8 * sizeof(WebRtc_Word32));
+ // 2:4
+ state2_ = malloc(8 * sizeof(WebRtc_Word32));
+ memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
+ // 4:12
+ state3_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
+ WebRtcSpl_ResetResample16khzTo48khz(
+ (WebRtcSpl_State16khzTo48khz*) state3_);
+ break;
case kResamplerMode2To3:
// 2:6
state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
@@ -367,6 +385,18 @@
state2_ = malloc(8 * sizeof(WebRtc_Word32));
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
break;
+ case kResamplerMode12To1:
+ // 12:4
+ state1_ = malloc(sizeof(WebRtcSpl_State48khzTo16khz));
+ WebRtcSpl_ResetResample48khzTo16khz(
+ (WebRtcSpl_State48khzTo16khz*) state1_);
+ // 4:2
+ state2_ = malloc(8 * sizeof(WebRtc_Word32));
+ memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
+ // 2:1
+ state3_ = malloc(8 * sizeof(WebRtc_Word32));
+ memset(state3_, 0, 8 * sizeof(WebRtc_Word32));
+ break;
case kResamplerMode3To2:
// 3:6
state1_ = malloc(8 * sizeof(WebRtc_Word32));
@@ -458,8 +488,9 @@
return 0;
}
- // Container for temp samples
+ // Containers for temp samples
WebRtc_Word16* tmp;
+ WebRtc_Word16* tmp_2;
// tmp data for resampling routines
WebRtc_Word32* tmp_mem;
@@ -545,6 +576,41 @@
free(tmp);
return 0;
+ case kResamplerMode1To12:
+ // We can only handle blocks of 40 samples
+ // Can be fixed, but I don't think it's needed
+ if ((lengthIn % 40) != 0) {
+ return -1;
+ }
+ if (maxLen < (lengthIn * 12)) {
+ return -1;
+ }
+
+ tmp_mem = (WebRtc_Word32*) malloc(336 * sizeof(WebRtc_Word32));
+ tmp = (WebRtc_Word16*) malloc(sizeof(WebRtc_Word16) * 4 * lengthIn);
+ //1:2
+ WebRtcSpl_UpsampleBy2(samplesIn, lengthIn, samplesOut,
+ (WebRtc_Word32*) state1_);
+ outLen = lengthIn * 2;
+ //2:4
+ WebRtcSpl_UpsampleBy2(samplesOut, outLen, tmp, (WebRtc_Word32*) state2_);
+ outLen = outLen * 2;
+ // 4:12
+ for (int i = 0; i < outLen; i += 160) {
+ // WebRtcSpl_Resample16khzTo48khz() takes a block of 160 samples
+ // as input and outputs a resampled block of 480 samples. The
+ // data is now actually in 32 kHz sampling rate, despite the
+ // function name, and with a resampling factor of three becomes
+ // 96 kHz.
+ WebRtcSpl_Resample16khzTo48khz(tmp + i, samplesOut + i * 3,
+ (WebRtcSpl_State16khzTo48khz*) state3_,
+ tmp_mem);
+ }
+ outLen = outLen * 3;
+ free(tmp_mem);
+ free(tmp);
+
+ return 0;
case kResamplerMode2To3:
if (maxLen < (lengthIn * 3 / 2))
{
@@ -783,6 +849,43 @@
free(tmp);
outLen = outLen / 2;
return 0;
+ case kResamplerMode12To1:
+ // We can only handle blocks of 480 samples
+ // Can be fixed, but I don't think it's needed
+ if ((lengthIn % 480) != 0) {
+ return -1;
+ }
+ if (maxLen < (lengthIn / 12)) {
+ return -1;
+ }
+
+ tmp_mem = (WebRtc_Word32*) malloc(496 * sizeof(WebRtc_Word32));
+ tmp = (WebRtc_Word16*) malloc((sizeof(WebRtc_Word16) * lengthIn) / 3);
+ tmp_2 = (WebRtc_Word16*) malloc((sizeof(WebRtc_Word16) * lengthIn) / 6);
+ // 12:4
+ for (int i = 0; i < lengthIn; i += 480) {
+ // WebRtcSpl_Resample48khzTo16khz() takes a block of 480 samples
+ // as input and outputs a resampled block of 160 samples. The
+ // data is now actually in 96 kHz sampling rate, despite the
+ // function name, and with a resampling factor of 1/3 becomes
+ // 32 kHz.
+ WebRtcSpl_Resample48khzTo16khz(samplesIn + i, tmp + i / 3,
+ (WebRtcSpl_State48khzTo16khz*) state1_,
+ tmp_mem);
+ }
+ outLen = lengthIn / 3;
+ free(tmp_mem);
+ // 4:2
+ WebRtcSpl_DownsampleBy2(tmp, outLen, tmp_2,
+ (WebRtc_Word32*) state2_);
+ outLen = outLen / 2;
+ free(tmp);
+ // 2:1
+ WebRtcSpl_DownsampleBy2(tmp_2, outLen, samplesOut,
+ (WebRtc_Word32*) state3_);
+ free(tmp_2);
+ outLen = outLen / 2;
+ return 0;
case kResamplerMode3To2:
if (maxLen < (lengthIn * 2 / 3))
{
diff --git a/src/common_audio/resampler/resampler_unittest.cc b/src/common_audio/resampler/resampler_unittest.cc
index c0cd418..f50034d 100644
--- a/src/common_audio/resampler/resampler_unittest.cc
+++ b/src/common_audio/resampler/resampler_unittest.cc
@@ -42,9 +42,7 @@
bool ValidRates(int in_rate, int out_rate) {
// Not the most compact notation, for clarity.
if ((in_rate == 44000 && (out_rate == 48000 || out_rate == 96000)) ||
- (out_rate == 44000 && (in_rate == 48000 || in_rate == 96000)) ||
- (in_rate == 8000 && out_rate == 96000) ||
- (in_rate == 96000 && out_rate == 8000)) {
+ (out_rate == 44000 && (in_rate == 48000 || in_rate == 96000))) {
return false;
}
@@ -62,14 +60,11 @@
int16_t data_out_[kDataSize];
};
-ResamplerTest::ResamplerTest() {
-}
+ResamplerTest::ResamplerTest() {}
-void ResamplerTest::SetUp() {
-}
+void ResamplerTest::SetUp() {}
-void ResamplerTest::TearDown() {
-}
+void ResamplerTest::TearDown() {}
TEST_F(ResamplerTest, Reset) {
// The only failure mode for the constructor is if Reset() fails. For the