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
This commit is contained in:
bjornv@webrtc.org 2011-11-23 13:50:41 +00:00
parent 4257790d2d
commit 48b68c0c24
3 changed files with 110 additions and 10 deletions

View File

@ -43,6 +43,7 @@ enum ResamplerMode
kResamplerMode1To3,
kResamplerMode1To4,
kResamplerMode1To6,
kResamplerMode1To12,
kResamplerMode2To3,
kResamplerMode2To11,
kResamplerMode4To11,
@ -53,6 +54,7 @@ enum ResamplerMode
kResamplerMode3To1,
kResamplerMode4To1,
kResamplerMode6To1,
kResamplerMode12To1,
kResamplerMode3To2,
kResamplerMode11To2,
kResamplerMode11To4,

View File

@ -209,6 +209,9 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
case 6:
my_mode_ = kResamplerMode1To6;
break;
case 12:
my_mode_ = kResamplerMode1To12;
break;
default:
my_type_ = kResamplerInvalid;
return -1;
@ -229,6 +232,9 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
case 6:
my_mode_ = kResamplerMode6To1;
break;
case 12:
my_mode_ = kResamplerMode12To1;
break;
default:
my_type_ = kResamplerInvalid;
return -1;
@ -299,6 +305,18 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
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 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
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 @@ int Resampler::Push(const WebRtc_Word16 * samplesIn, int lengthIn, WebRtc_Word16
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;
@ -544,6 +575,41 @@ int Resampler::Push(const WebRtc_Word16 * samplesIn, int lengthIn, WebRtc_Word16
free(tmp_mem);
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 @@ int Resampler::Push(const WebRtc_Word16 * samplesIn, int lengthIn, WebRtc_Word16
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))
{

View File

@ -42,9 +42,7 @@ const size_t kDataSize = kMaxRate / 100;
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 @@ class ResamplerTest : public testing::Test {
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