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:
parent
4257790d2d
commit
48b68c0c24
@ -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,
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user