diff options
author | andrew@webrtc.org <andrew@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d> | 2014-04-19 00:32:07 +0000 |
---|---|---|
committer | andrew@webrtc.org <andrew@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d> | 2014-04-19 00:32:07 +0000 |
commit | 708ff4d93770d863cdea26fd496ae71414eb8a53 (patch) | |
tree | db558a6a81de3882829fd913b76ab4d71013e682 | |
parent | 74658f6b1fff3e69c2b16b8600d9e2051e505c1c (diff) | |
download | webrtc-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.h | 15 | ||||
-rw-r--r-- | common_audio/resampler/push_resampler.cc | 40 | ||||
-rw-r--r-- | common_audio/resampler/push_resampler_unittest.cc | 2 | ||||
-rw-r--r-- | common_audio/resampler/push_sinc_resampler.h | 3 | ||||
-rw-r--r-- | modules/audio_coding/main/acm2/acm_resampler.h | 2 | ||||
-rw-r--r-- | modules/audio_coding/main/source/acm_resampler.h | 4 | ||||
-rw-r--r-- | voice_engine/channel.h | 4 | ||||
-rw-r--r-- | voice_engine/output_mixer.h | 6 | ||||
-rw-r--r-- | voice_engine/transmit_mixer.h | 2 | ||||
-rw-r--r-- | voice_engine/utility.cc | 4 | ||||
-rw-r--r-- | voice_engine/utility.h | 6 | ||||
-rw-r--r-- | voice_engine/utility_unittest.cc | 12 |
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) / |