summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandrew@webrtc.org <andrew@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2014-04-19 00:32:07 +0000
committerandrew@webrtc.org <andrew@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2014-04-19 00:32:07 +0000
commit708ff4d93770d863cdea26fd496ae71414eb8a53 (patch)
treedb558a6a81de3882829fd913b76ab4d71013e682
parent74658f6b1fff3e69c2b16b8600d9e2051e505c1c (diff)
downloadwebrtc-708ff4d93770d863cdea26fd496ae71414eb8a53.tar.gz
Resampler modifications in preparation for arbitrary audioproc rates.
- Templatize PushResampler to support int16 and float. - Add a helper method to PushSincResampler to compute the algorithmic delay. This is a prerequisite of: http://review.webrtc.org/9919004/ BUG=2894 R=turaj@webrtc.org Review URL: https://webrtc-codereview.appspot.com/12169004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@5943 4adac7df-926f-26a2-2b94-8c16560cd09d
-rw-r--r--common_audio/resampler/include/push_resampler.h15
-rw-r--r--common_audio/resampler/push_resampler.cc40
-rw-r--r--common_audio/resampler/push_resampler_unittest.cc2
-rw-r--r--common_audio/resampler/push_sinc_resampler.h3
-rw-r--r--modules/audio_coding/main/acm2/acm_resampler.h2
-rw-r--r--modules/audio_coding/main/source/acm_resampler.h4
-rw-r--r--voice_engine/channel.h4
-rw-r--r--voice_engine/output_mixer.h6
-rw-r--r--voice_engine/transmit_mixer.h2
-rw-r--r--voice_engine/utility.cc4
-rw-r--r--voice_engine/utility.h6
-rw-r--r--voice_engine/utility_unittest.cc12
12 files changed, 52 insertions, 48 deletions
diff --git a/common_audio/resampler/include/push_resampler.h b/common_audio/resampler/include/push_resampler.h
index 770a9926..f04dc0f3 100644
--- a/common_audio/resampler/include/push_resampler.h
+++ b/common_audio/resampler/include/push_resampler.h
@@ -20,6 +20,7 @@ class PushSincResampler;
// Wraps PushSincResampler to provide stereo support.
// TODO(ajm): add support for an arbitrary number of channels.
+template <typename T>
class PushResampler {
public:
PushResampler();
@@ -32,22 +33,18 @@ class PushResampler {
// Returns the total number of samples provided in destination (e.g. 32 kHz,
// 2 channel audio gives 640 samples).
- int Resample(const int16_t* src, int src_length, int16_t* dst,
- int dst_capacity);
+ int Resample(const T* src, int src_length, T* dst, int dst_capacity);
private:
- int ResampleSinc(const int16_t* src, int src_length, int16_t* dst,
- int dst_capacity);
-
scoped_ptr<PushSincResampler> sinc_resampler_;
scoped_ptr<PushSincResampler> sinc_resampler_right_;
int src_sample_rate_hz_;
int dst_sample_rate_hz_;
int num_channels_;
- scoped_array<int16_t> src_left_;
- scoped_array<int16_t> src_right_;
- scoped_array<int16_t> dst_left_;
- scoped_array<int16_t> dst_right_;
+ scoped_ptr<T[]> src_left_;
+ scoped_ptr<T[]> src_right_;
+ scoped_ptr<T[]> dst_left_;
+ scoped_ptr<T[]> dst_right_;
};
} // namespace webrtc
diff --git a/common_audio/resampler/push_resampler.cc b/common_audio/resampler/push_resampler.cc
index 29944187..973c8f74 100644
--- a/common_audio/resampler/push_resampler.cc
+++ b/common_audio/resampler/push_resampler.cc
@@ -18,22 +18,21 @@
namespace webrtc {
-PushResampler::PushResampler()
+template <typename T>
+PushResampler<T>::PushResampler()
: src_sample_rate_hz_(0),
dst_sample_rate_hz_(0),
- num_channels_(0),
- src_left_(NULL),
- src_right_(NULL),
- dst_left_(NULL),
- dst_right_(NULL) {
+ num_channels_(0) {
}
-PushResampler::~PushResampler() {
+template <typename T>
+PushResampler<T>::~PushResampler() {
}
-int PushResampler::InitializeIfNeeded(int src_sample_rate_hz,
- int dst_sample_rate_hz,
- int num_channels) {
+template <typename T>
+int PushResampler<T>::InitializeIfNeeded(int src_sample_rate_hz,
+ int dst_sample_rate_hz,
+ int num_channels) {
if (src_sample_rate_hz == src_sample_rate_hz_ &&
dst_sample_rate_hz == dst_sample_rate_hz_ &&
num_channels == num_channels_)
@@ -53,10 +52,10 @@ int PushResampler::InitializeIfNeeded(int src_sample_rate_hz,
sinc_resampler_.reset(new PushSincResampler(src_size_10ms_mono,
dst_size_10ms_mono));
if (num_channels_ == 2) {
- src_left_.reset(new int16_t[src_size_10ms_mono]);
- src_right_.reset(new int16_t[src_size_10ms_mono]);
- dst_left_.reset(new int16_t[dst_size_10ms_mono]);
- dst_right_.reset(new int16_t[dst_size_10ms_mono]);
+ src_left_.reset(new T[src_size_10ms_mono]);
+ src_right_.reset(new T[src_size_10ms_mono]);
+ dst_left_.reset(new T[dst_size_10ms_mono]);
+ dst_right_.reset(new T[dst_size_10ms_mono]);
sinc_resampler_right_.reset(new PushSincResampler(src_size_10ms_mono,
dst_size_10ms_mono));
}
@@ -64,8 +63,9 @@ int PushResampler::InitializeIfNeeded(int src_sample_rate_hz,
return 0;
}
-int PushResampler::Resample(const int16_t* src, int src_length,
- int16_t* dst, int dst_capacity) {
+template <typename T>
+int PushResampler<T>::Resample(const T* src, int src_length, T* dst,
+ int dst_capacity) {
const int src_size_10ms = src_sample_rate_hz_ * num_channels_ / 100;
const int dst_size_10ms = dst_sample_rate_hz_ * num_channels_ / 100;
if (src_length != src_size_10ms || dst_capacity < dst_size_10ms)
@@ -74,13 +74,13 @@ int PushResampler::Resample(const int16_t* src, int src_length,
if (src_sample_rate_hz_ == dst_sample_rate_hz_) {
// The old resampler provides this memcpy facility in the case of matching
// sample rates, so reproduce it here for the sinc resampler.
- memcpy(dst, src, src_length * sizeof(int16_t));
+ memcpy(dst, src, src_length * sizeof(T));
return src_length;
}
if (num_channels_ == 2) {
const int src_length_mono = src_length / num_channels_;
const int dst_capacity_mono = dst_capacity / num_channels_;
- int16_t* deinterleaved[] = {src_left_.get(), src_right_.get()};
+ T* deinterleaved[] = {src_left_.get(), src_right_.get()};
Deinterleave(src, src_length_mono, num_channels_, deinterleaved);
int dst_length_mono =
@@ -98,4 +98,8 @@ int PushResampler::Resample(const int16_t* src, int src_length,
}
}
+// Explictly generate required instantiations.
+template class PushResampler<int16_t>;
+template class PushResampler<float>;
+
} // namespace webrtc
diff --git a/common_audio/resampler/push_resampler_unittest.cc b/common_audio/resampler/push_resampler_unittest.cc
index c40923bf..4449f4c6 100644
--- a/common_audio/resampler/push_resampler_unittest.cc
+++ b/common_audio/resampler/push_resampler_unittest.cc
@@ -16,7 +16,7 @@
namespace webrtc {
TEST(PushResamplerTest, VerifiesInputParameters) {
- PushResampler resampler;
+ PushResampler<int16_t> resampler;
EXPECT_EQ(-1, resampler.InitializeIfNeeded(-1, 16000, 1));
EXPECT_EQ(-1, resampler.InitializeIfNeeded(16000, -1, 1));
EXPECT_EQ(-1, resampler.InitializeIfNeeded(16000, 16000, 0));
diff --git a/common_audio/resampler/push_sinc_resampler.h b/common_audio/resampler/push_sinc_resampler.h
index fa1bb3e7..7c804fea 100644
--- a/common_audio/resampler/push_sinc_resampler.h
+++ b/common_audio/resampler/push_sinc_resampler.h
@@ -44,6 +44,9 @@ class PushSincResampler : public SincResamplerCallback {
virtual void Run(int frames, float* destination) OVERRIDE;
SincResampler* get_resampler_for_testing() { return resampler_.get(); }
+ static float AlgorithmicDelaySeconds(int source_rate_hz) {
+ return 1.f / source_rate_hz * SincResampler::kKernelSize / 2;
+ }
private:
scoped_ptr<SincResampler> resampler_;
diff --git a/modules/audio_coding/main/acm2/acm_resampler.h b/modules/audio_coding/main/acm2/acm_resampler.h
index 5d952e54..644a32f0 100644
--- a/modules/audio_coding/main/acm2/acm_resampler.h
+++ b/modules/audio_coding/main/acm2/acm_resampler.h
@@ -29,7 +29,7 @@ class ACMResampler {
int16_t* out_audio);
private:
- PushResampler resampler_;
+ PushResampler<int16_t> resampler_;
};
} // namespace acm2
diff --git a/modules/audio_coding/main/source/acm_resampler.h b/modules/audio_coding/main/source/acm_resampler.h
index b50e722c..ceeae05f 100644
--- a/modules/audio_coding/main/source/acm_resampler.h
+++ b/modules/audio_coding/main/source/acm_resampler.h
@@ -15,7 +15,6 @@
#include "webrtc/typedefs.h"
namespace webrtc {
-
namespace acm1 {
class ACMResampler {
@@ -30,11 +29,10 @@ class ACMResampler {
uint8_t num_audio_channels);
private:
- PushResampler resampler_;
+ PushResampler<int16_t> resampler_;
};
} // namespace acm1
-
} // namespace webrtc
#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_SOURCE_ACM_RESAMPLER_H_
diff --git a/voice_engine/channel.h b/voice_engine/channel.h
index 3377be0e..8f47b48c 100644
--- a/voice_engine/channel.h
+++ b/voice_engine/channel.h
@@ -519,8 +519,8 @@ private:
bool _externalTransport;
AudioFrame _audioFrame;
scoped_ptr<int16_t[]> mono_recording_audio_;
- // Resampler is used when input data is stereo while codec is mono.
- PushResampler input_resampler_;
+ // Downsamples to the codec rate if necessary.
+ PushResampler<int16_t> input_resampler_;
uint8_t _audioLevel_dBov;
FilePlayer* _inputFilePlayerPtr;
FilePlayer* _outputFilePlayerPtr;
diff --git a/voice_engine/output_mixer.h b/voice_engine/output_mixer.h
index bd17c3be..859ce64b 100644
--- a/voice_engine/output_mixer.h
+++ b/voice_engine/output_mixer.h
@@ -133,8 +133,10 @@ private:
CriticalSectionWrapper& _fileCritSect;
AudioConferenceMixer& _mixerModule;
AudioFrame _audioFrame;
- PushResampler resampler_; // converts mixed audio to fit ADM format
- PushResampler audioproc_resampler_; // converts mixed audio to fit APM rate
+ // Converts mixed audio to the audio device output rate.
+ PushResampler<int16_t> resampler_;
+ // Converts mixed audio to the audio processing rate.
+ PushResampler<int16_t> audioproc_resampler_;
AudioLevel _audioLevel; // measures audio level for the combined signal
DtmfInband _dtmfGenerator;
int _instanceId;
diff --git a/voice_engine/transmit_mixer.h b/voice_engine/transmit_mixer.h
index b408614a..cc611308 100644
--- a/voice_engine/transmit_mixer.h
+++ b/voice_engine/transmit_mixer.h
@@ -200,7 +200,7 @@ private:
// owns
MonitorModule _monitorModule;
AudioFrame _audioFrame;
- PushResampler resampler_; // ADM sample rate -> mixing rate
+ PushResampler<int16_t> resampler_; // ADM sample rate -> mixing rate
FilePlayer* _filePlayerPtr;
FileRecorder* _fileRecorderPtr;
FileRecorder* _fileCallRecorderPtr;
diff --git a/voice_engine/utility.cc b/voice_engine/utility.cc
index 5058aa32..b7eb885c 100644
--- a/voice_engine/utility.cc
+++ b/voice_engine/utility.cc
@@ -25,7 +25,7 @@ namespace voe {
// ConvertToCodecFormat, but if we're to consolidate we should probably make a
// real converter class.
void RemixAndResample(const AudioFrame& src_frame,
- PushResampler* resampler,
+ PushResampler<int16_t>* resampler,
AudioFrame* dst_frame) {
const int16_t* audio_ptr = src_frame.data_;
int audio_ptr_num_channels = src_frame.num_channels_;
@@ -76,7 +76,7 @@ void DownConvertToCodecFormat(const int16_t* src_data,
int codec_num_channels,
int codec_rate_hz,
int16_t* mono_buffer,
- PushResampler* resampler,
+ PushResampler<int16_t>* resampler,
AudioFrame* dst_af) {
assert(samples_per_channel <= kMaxMonoDataSizeSamples);
assert(num_channels == 1 || num_channels == 2);
diff --git a/voice_engine/utility.h b/voice_engine/utility.h
index f6fa35bf..127bdba0 100644
--- a/voice_engine/utility.h
+++ b/voice_engine/utility.h
@@ -15,12 +15,12 @@
#ifndef WEBRTC_VOICE_ENGINE_UTILITY_H_
#define WEBRTC_VOICE_ENGINE_UTILITY_H_
+#include "webrtc/common_audio/resampler/include/push_resampler.h"
#include "webrtc/typedefs.h"
namespace webrtc {
class AudioFrame;
-class PushResampler;
namespace voe {
@@ -30,7 +30,7 @@ namespace voe {
//
// On failure, returns -1 and copies |src_frame| to |dst_frame|.
void RemixAndResample(const AudioFrame& src_frame,
- PushResampler* resampler,
+ PushResampler<int16_t>* resampler,
AudioFrame* dst_frame);
// Downmix and downsample the audio in |src_data| to |dst_af| as necessary,
@@ -44,7 +44,7 @@ void DownConvertToCodecFormat(const int16_t* src_data,
int codec_num_channels,
int codec_rate_hz,
int16_t* mono_buffer,
- PushResampler* resampler,
+ PushResampler<int16_t>* resampler,
AudioFrame* dst_af);
void MixWithSat(int16_t target[],
diff --git a/voice_engine/utility_unittest.cc b/voice_engine/utility_unittest.cc
index a5d0bcd8..8f7efa87 100644
--- a/voice_engine/utility_unittest.cc
+++ b/voice_engine/utility_unittest.cc
@@ -39,7 +39,7 @@ class UtilityTest : public ::testing::Test {
int dst_channels, int dst_sample_rate_hz,
FunctionToTest function);
- PushResampler resampler_;
+ PushResampler<int16_t> resampler_;
AudioFrame src_frame_;
AudioFrame dst_frame_;
AudioFrame golden_frame_;
@@ -127,11 +127,11 @@ void VerifyFramesAreEqual(const AudioFrame& ref_frame,
}
void UtilityTest::RunResampleTest(int src_channels,
- int src_sample_rate_hz,
- int dst_channels,
- int dst_sample_rate_hz,
- FunctionToTest function) {
- PushResampler resampler; // Create a new one with every test.
+ int src_sample_rate_hz,
+ int dst_channels,
+ int dst_sample_rate_hz,
+ FunctionToTest function) {
+ PushResampler<int16_t> resampler; // Create a new one with every test.
const int16_t kSrcLeft = 30; // Shouldn't overflow for any used sample rate.
const int16_t kSrcRight = 15;
const float resampling_factor = (1.0 * src_sample_rate_hz) /