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,
|
kResamplerMode1To3,
|
||||||
kResamplerMode1To4,
|
kResamplerMode1To4,
|
||||||
kResamplerMode1To6,
|
kResamplerMode1To6,
|
||||||
|
kResamplerMode1To12,
|
||||||
kResamplerMode2To3,
|
kResamplerMode2To3,
|
||||||
kResamplerMode2To11,
|
kResamplerMode2To11,
|
||||||
kResamplerMode4To11,
|
kResamplerMode4To11,
|
||||||
@ -53,6 +54,7 @@ enum ResamplerMode
|
|||||||
kResamplerMode3To1,
|
kResamplerMode3To1,
|
||||||
kResamplerMode4To1,
|
kResamplerMode4To1,
|
||||||
kResamplerMode6To1,
|
kResamplerMode6To1,
|
||||||
|
kResamplerMode12To1,
|
||||||
kResamplerMode3To2,
|
kResamplerMode3To2,
|
||||||
kResamplerMode11To2,
|
kResamplerMode11To2,
|
||||||
kResamplerMode11To4,
|
kResamplerMode11To4,
|
||||||
|
@ -209,6 +209,9 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
|
|||||||
case 6:
|
case 6:
|
||||||
my_mode_ = kResamplerMode1To6;
|
my_mode_ = kResamplerMode1To6;
|
||||||
break;
|
break;
|
||||||
|
case 12:
|
||||||
|
my_mode_ = kResamplerMode1To12;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
my_type_ = kResamplerInvalid;
|
my_type_ = kResamplerInvalid;
|
||||||
return -1;
|
return -1;
|
||||||
@ -229,6 +232,9 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
|
|||||||
case 6:
|
case 6:
|
||||||
my_mode_ = kResamplerMode6To1;
|
my_mode_ = kResamplerMode6To1;
|
||||||
break;
|
break;
|
||||||
|
case 12:
|
||||||
|
my_mode_ = kResamplerMode12To1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
my_type_ = kResamplerInvalid;
|
my_type_ = kResamplerInvalid;
|
||||||
return -1;
|
return -1;
|
||||||
@ -299,6 +305,18 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
|
|||||||
state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
|
state2_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
|
||||||
WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state2_);
|
WebRtcSpl_ResetResample16khzTo48khz((WebRtcSpl_State16khzTo48khz *)state2_);
|
||||||
break;
|
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:
|
case kResamplerMode2To3:
|
||||||
// 2:6
|
// 2:6
|
||||||
state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
|
state1_ = malloc(sizeof(WebRtcSpl_State16khzTo48khz));
|
||||||
@ -367,6 +385,18 @@ int Resampler::Reset(int inFreq, int outFreq, ResamplerType type)
|
|||||||
state2_ = malloc(8 * sizeof(WebRtc_Word32));
|
state2_ = malloc(8 * sizeof(WebRtc_Word32));
|
||||||
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
|
memset(state2_, 0, 8 * sizeof(WebRtc_Word32));
|
||||||
break;
|
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:
|
case kResamplerMode3To2:
|
||||||
// 3:6
|
// 3:6
|
||||||
state1_ = malloc(8 * sizeof(WebRtc_Word32));
|
state1_ = malloc(8 * sizeof(WebRtc_Word32));
|
||||||
@ -458,8 +488,9 @@ int Resampler::Push(const WebRtc_Word16 * samplesIn, int lengthIn, WebRtc_Word16
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container for temp samples
|
// Containers for temp samples
|
||||||
WebRtc_Word16* tmp;
|
WebRtc_Word16* tmp;
|
||||||
|
WebRtc_Word16* tmp_2;
|
||||||
// tmp data for resampling routines
|
// tmp data for resampling routines
|
||||||
WebRtc_Word32* tmp_mem;
|
WebRtc_Word32* tmp_mem;
|
||||||
|
|
||||||
@ -544,6 +575,41 @@ int Resampler::Push(const WebRtc_Word16 * samplesIn, int lengthIn, WebRtc_Word16
|
|||||||
free(tmp_mem);
|
free(tmp_mem);
|
||||||
free(tmp);
|
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;
|
return 0;
|
||||||
case kResamplerMode2To3:
|
case kResamplerMode2To3:
|
||||||
if (maxLen < (lengthIn * 3 / 2))
|
if (maxLen < (lengthIn * 3 / 2))
|
||||||
@ -783,6 +849,43 @@ int Resampler::Push(const WebRtc_Word16 * samplesIn, int lengthIn, WebRtc_Word16
|
|||||||
free(tmp);
|
free(tmp);
|
||||||
outLen = outLen / 2;
|
outLen = outLen / 2;
|
||||||
return 0;
|
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:
|
case kResamplerMode3To2:
|
||||||
if (maxLen < (lengthIn * 2 / 3))
|
if (maxLen < (lengthIn * 2 / 3))
|
||||||
{
|
{
|
||||||
|
@ -42,9 +42,7 @@ const size_t kDataSize = kMaxRate / 100;
|
|||||||
bool ValidRates(int in_rate, int out_rate) {
|
bool ValidRates(int in_rate, int out_rate) {
|
||||||
// Not the most compact notation, for clarity.
|
// Not the most compact notation, for clarity.
|
||||||
if ((in_rate == 44000 && (out_rate == 48000 || out_rate == 96000)) ||
|
if ((in_rate == 44000 && (out_rate == 48000 || out_rate == 96000)) ||
|
||||||
(out_rate == 44000 && (in_rate == 48000 || in_rate == 96000)) ||
|
(out_rate == 44000 && (in_rate == 48000 || in_rate == 96000))) {
|
||||||
(in_rate == 8000 && out_rate == 96000) ||
|
|
||||||
(in_rate == 96000 && out_rate == 8000)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,14 +60,11 @@ class ResamplerTest : public testing::Test {
|
|||||||
int16_t data_out_[kDataSize];
|
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) {
|
TEST_F(ResamplerTest, Reset) {
|
||||||
// The only failure mode for the constructor is if Reset() fails. For the
|
// The only failure mode for the constructor is if Reset() fails. For the
|
||||||
|
Loading…
Reference in New Issue
Block a user