Add tests and modify tools for new float deinterleaved interface.
- Add an Initialize() overload to allow specification of format
parameters. This is mainly useful for testing, but could be used in
the cases where a consumer knows the format before the streams arrive.
- Add a reverse_sample_rate_hz_ parameter to prepare for mismatched
capture and render rates. There is no functional change as it is
currently constrained to match the capture rate.
- Fix a bug in the float dump: we need to use add_ rather than set_.
- Add a debug dump test for both int and float interfaces.
- Enable unpacking of float dumps.
- Enable audioproc to read float dumps.
- Move more shared functionality to test_utils.h, and generally tidy up
a bit by consolidating repeated code.
BUG=2894
TESTED=Verified that the output produced by the float debug dump test is
correct. Processed the resulting debug dump file with audioproc and
ensured that we get identical output. (This is crucial, as we need to
be able to exactly reproduce online results offline.)
R=aluebs@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/9489004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@5676 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc
index 272c786..e19cfec 100644
--- a/webrtc/modules/audio_processing/audio_processing_impl.cc
+++ b/webrtc/modules/audio_processing/audio_processing_impl.cc
@@ -104,8 +104,11 @@
event_msg_(new audioproc::Event()),
#endif
sample_rate_hz_(kSampleRate16kHz),
+ reverse_sample_rate_hz_(kSampleRate16kHz),
split_sample_rate_hz_(kSampleRate16kHz),
samples_per_channel_(kChunkSizeMs * sample_rate_hz_ / 1000),
+ reverse_samples_per_channel_(
+ kChunkSizeMs * reverse_sample_rate_hz_ / 1000),
stream_delay_ms_(0),
delay_offset_ms_(0),
was_stream_delay_set_(false),
@@ -178,6 +181,19 @@
return InitializeLocked();
}
+int AudioProcessingImpl::Initialize(int sample_rate_hz,
+ int reverse_sample_rate_hz,
+ int num_input_channels,
+ int num_output_channels,
+ int num_reverse_channels) {
+ CriticalSectionScoped crit_scoped(crit_);
+ return InitializeLocked(sample_rate_hz,
+ reverse_sample_rate_hz,
+ num_input_channels,
+ num_output_channels,
+ num_reverse_channels);
+}
+
int AudioProcessingImpl::InitializeLocked() {
if (render_audio_ != NULL) {
delete render_audio_;
@@ -190,7 +206,7 @@
}
render_audio_ = new AudioBuffer(num_reverse_channels_,
- samples_per_channel_);
+ reverse_samples_per_channel_);
capture_audio_ = new AudioBuffer(num_input_channels_,
samples_per_channel_);
@@ -215,6 +231,79 @@
return kNoError;
}
+int AudioProcessingImpl::InitializeLocked(int sample_rate_hz,
+ int reverse_sample_rate_hz,
+ int num_input_channels,
+ int num_output_channels,
+ int num_reverse_channels) {
+ if (sample_rate_hz != kSampleRate8kHz &&
+ sample_rate_hz != kSampleRate16kHz &&
+ sample_rate_hz != kSampleRate32kHz) {
+ return kBadSampleRateError;
+ }
+ if (reverse_sample_rate_hz != kSampleRate8kHz &&
+ reverse_sample_rate_hz != kSampleRate16kHz &&
+ reverse_sample_rate_hz != kSampleRate32kHz) {
+ return kBadSampleRateError;
+ }
+ // TODO(ajm): The reverse sample rate is constrained to be identical to the
+ // forward rate for now.
+ if (reverse_sample_rate_hz != sample_rate_hz) {
+ return kBadSampleRateError;
+ }
+ if (num_output_channels > num_input_channels) {
+ return kBadNumberChannelsError;
+ }
+ // Only mono and stereo supported currently.
+ if (num_input_channels > 2 || num_input_channels < 1 ||
+ num_output_channels > 2 || num_output_channels < 1 ||
+ num_reverse_channels > 2 || num_reverse_channels < 1) {
+ return kBadNumberChannelsError;
+ }
+ if (echo_control_mobile_->is_enabled() && sample_rate_hz > kSampleRate16kHz) {
+ LOG(LS_ERROR) << "AECM only supports 16 or 8 kHz sample rates";
+ return kUnsupportedComponentError;
+ }
+
+ sample_rate_hz_ = sample_rate_hz;
+ reverse_sample_rate_hz_ = reverse_sample_rate_hz;
+ reverse_samples_per_channel_ = kChunkSizeMs * reverse_sample_rate_hz / 1000;
+ samples_per_channel_ = kChunkSizeMs * sample_rate_hz / 1000;
+ num_input_channels_ = num_input_channels;
+ num_output_channels_ = num_output_channels;
+ num_reverse_channels_ = num_reverse_channels;
+
+ if (sample_rate_hz_ == kSampleRate32kHz) {
+ split_sample_rate_hz_ = kSampleRate16kHz;
+ } else {
+ split_sample_rate_hz_ = sample_rate_hz_;
+ }
+
+ return InitializeLocked();
+}
+
+// Calls InitializeLocked() if any of the audio parameters have changed from
+// their current values.
+int AudioProcessingImpl::MaybeInitializeLocked(int sample_rate_hz,
+ int reverse_sample_rate_hz,
+ int num_input_channels,
+ int num_output_channels,
+ int num_reverse_channels) {
+ if (sample_rate_hz == sample_rate_hz_ &&
+ reverse_sample_rate_hz == reverse_sample_rate_hz_ &&
+ num_input_channels == num_input_channels_ &&
+ num_output_channels == num_output_channels_ &&
+ num_reverse_channels == num_reverse_channels_) {
+ return kNoError;
+ }
+
+ return InitializeLocked(sample_rate_hz,
+ reverse_sample_rate_hz,
+ num_input_channels,
+ num_output_channels,
+ num_reverse_channels);
+}
+
void AudioProcessingImpl::SetExtraOptions(const Config& config) {
CriticalSectionScoped crit_scoped(crit_);
std::list<ProcessingComponent*>::iterator it;
@@ -316,51 +405,6 @@
return output_will_be_muted_;
}
-// Calls InitializeLocked() if any of the audio parameters have changed from
-// their current values.
-int AudioProcessingImpl::MaybeInitializeLocked(int sample_rate_hz,
- int num_input_channels, int num_output_channels, int num_reverse_channels) {
- if (sample_rate_hz == sample_rate_hz_ &&
- num_input_channels == num_input_channels_ &&
- num_output_channels == num_output_channels_ &&
- num_reverse_channels == num_reverse_channels_) {
- return kNoError;
- }
-
- if (sample_rate_hz != kSampleRate8kHz &&
- sample_rate_hz != kSampleRate16kHz &&
- sample_rate_hz != kSampleRate32kHz) {
- return kBadSampleRateError;
- }
- if (num_output_channels > num_input_channels) {
- return kBadNumberChannelsError;
- }
- // Only mono and stereo supported currently.
- if (num_input_channels > 2 || num_input_channels < 1 ||
- num_output_channels > 2 || num_output_channels < 1 ||
- num_reverse_channels > 2 || num_reverse_channels < 1) {
- return kBadNumberChannelsError;
- }
- if (echo_control_mobile_->is_enabled() && sample_rate_hz > kSampleRate16kHz) {
- LOG(LS_ERROR) << "AECM only supports 16 or 8 kHz sample rates";
- return kUnsupportedComponentError;
- }
-
- sample_rate_hz_ = sample_rate_hz;
- samples_per_channel_ = kChunkSizeMs * sample_rate_hz / 1000;
- num_input_channels_ = num_input_channels;
- num_output_channels_ = num_output_channels;
- num_reverse_channels_ = num_reverse_channels;
-
- if (sample_rate_hz_ == kSampleRate32kHz) {
- split_sample_rate_hz_ = kSampleRate16kHz;
- } else {
- split_sample_rate_hz_ = sample_rate_hz_;
- }
-
- return InitializeLocked();
-}
-
int AudioProcessingImpl::ProcessStream(float* const* data,
int samples_per_channel,
int sample_rate_hz,
@@ -374,7 +418,9 @@
const int num_input_channels = ChannelsFromLayout(input_layout);
// TODO(ajm): We now always set the output channels equal to the input
// channels here. Restore the ability to downmix.
- RETURN_ON_ERR(MaybeInitializeLocked(sample_rate_hz,
+ // TODO(ajm): The reverse sample rate is constrained to be identical to the
+ // forward rate for now.
+ RETURN_ON_ERR(MaybeInitializeLocked(sample_rate_hz, sample_rate_hz,
num_input_channels, num_input_channels, num_reverse_channels_));
if (samples_per_channel != samples_per_channel_) {
return kBadDataLengthError;
@@ -386,7 +432,7 @@
audioproc::Stream* msg = event_msg_->mutable_stream();
const size_t channel_size = sizeof(float) * samples_per_channel;
for (int i = 0; i < num_input_channels; ++i)
- msg->set_input_channel(i, data[i], channel_size);
+ msg->add_input_channel(data[i], channel_size);
}
#endif
@@ -401,7 +447,7 @@
audioproc::Stream* msg = event_msg_->mutable_stream();
const size_t channel_size = sizeof(float) * samples_per_channel;
for (int i = 0; i < num_output_channels_; ++i)
- msg->set_output_channel(i, data[i], channel_size);
+ msg->add_output_channel(data[i], channel_size);
RETURN_ON_ERR(WriteMessageToDebugFile());
}
#endif
@@ -417,8 +463,11 @@
// TODO(ajm): We now always set the output channels equal to the input
// channels here. Restore the ability to downmix.
+ // TODO(ajm): The reverse sample rate is constrained to be identical to the
+ // forward rate for now.
RETURN_ON_ERR(MaybeInitializeLocked(frame->sample_rate_hz_,
- frame->num_channels_, frame->num_channels_, num_reverse_channels_));
+ frame->sample_rate_hz_, frame->num_channels_, frame->num_channels_,
+ num_reverse_channels_));
if (frame->samples_per_channel_ != samples_per_channel_) {
return kBadDataLengthError;
}
@@ -526,9 +575,11 @@
}
const int num_channels = ChannelsFromLayout(layout);
- RETURN_ON_ERR(MaybeInitializeLocked(sample_rate_hz_, num_input_channels_,
- num_output_channels_, num_channels));
- if (samples_per_channel != samples_per_channel_) {
+ // TODO(ajm): The reverse sample rate is constrained to be identical to the
+ // forward rate for now.
+ RETURN_ON_ERR(MaybeInitializeLocked(sample_rate_hz_, sample_rate_hz_,
+ num_input_channels_, num_output_channels_, num_channels));
+ if (samples_per_channel != reverse_samples_per_channel_) {
return kBadDataLengthError;
}
@@ -538,7 +589,7 @@
audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream();
const size_t channel_size = sizeof(float) * samples_per_channel;
for (int i = 0; i < num_channels; ++i)
- msg->set_channel(i, data[i], channel_size);
+ msg->add_channel(data[i], channel_size);
RETURN_ON_ERR(WriteMessageToDebugFile());
}
#endif
@@ -555,9 +606,12 @@
if (frame->sample_rate_hz_ != sample_rate_hz_) {
return kBadSampleRateError;
}
- RETURN_ON_ERR(MaybeInitializeLocked(sample_rate_hz_, num_input_channels_,
- num_output_channels_, frame->num_channels_));
- if (frame->samples_per_channel_ != samples_per_channel_) {
+
+ // TODO(ajm): The reverse sample rate is constrained to be identical to the
+ // forward rate for now.
+ RETURN_ON_ERR(MaybeInitializeLocked(sample_rate_hz_, sample_rate_hz_,
+ num_input_channels_, num_output_channels_, frame->num_channels_));
+ if (frame->samples_per_channel_ != reverse_samples_per_channel_) {
return kBadDataLengthError;
}
@@ -832,6 +886,7 @@
msg->set_num_input_channels(num_input_channels_);
msg->set_num_output_channels(num_output_channels_);
msg->set_num_reverse_channels(num_reverse_channels_);
+ msg->set_reverse_sample_rate(reverse_sample_rate_hz_);
int err = WriteMessageToDebugFile();
if (err != kNoError) {