Make ChannelBuffer aware of frequency bands
Now the ChannelBuffer has 2 separate arrays, one for the full-band data and one for the splitted one. The corresponding accessors are added to the ChannelBuffer.
This is done to avoid having to refresh the bands pointers in AudioBuffer. It will also allow us to have a general accessor like data()[band][channel][sample].
All the files using the ChannelBuffer needed to be re-factored.
Tested with modules_unittests, common_audio_unittests, audioproc, audioproc_f, voe_cmd_test.
R=andrew@webrtc.org, kwiberg@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/36999004
Cr-Commit-Position: refs/heads/master@{#8318}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8318 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_processing/audio_buffer.cc b/webrtc/modules/audio_processing/audio_buffer.cc
index 7b302cf..c4dff8a 100644
--- a/webrtc/modules/audio_processing/audio_buffer.cc
+++ b/webrtc/modules/audio_processing/audio_buffer.cc
@@ -48,92 +48,90 @@
template <typename T>
void StereoToMono(const T* left, const T* right, T* out,
- int samples_per_channel) {
- for (int i = 0; i < samples_per_channel; ++i)
+ int num_frames) {
+ for (int i = 0; i < num_frames; ++i)
out[i] = (left[i] + right[i]) / 2;
}
+int NumBandsFromSamplesPerChannel(int num_frames) {
+ int num_bands = 1;
+ if (num_frames == kSamplesPer32kHzChannel ||
+ num_frames == kSamplesPer48kHzChannel) {
+ num_bands = rtc::CheckedDivExact(num_frames,
+ static_cast<int>(kSamplesPer16kHzChannel));
+ }
+ return num_bands;
+}
+
} // namespace
-AudioBuffer::AudioBuffer(int input_samples_per_channel,
+AudioBuffer::AudioBuffer(int input_num_frames,
int num_input_channels,
- int process_samples_per_channel,
+ int process_num_frames,
int num_process_channels,
- int output_samples_per_channel)
- : input_samples_per_channel_(input_samples_per_channel),
+ int output_num_frames)
+ : input_num_frames_(input_num_frames),
num_input_channels_(num_input_channels),
- proc_samples_per_channel_(process_samples_per_channel),
+ proc_num_frames_(process_num_frames),
num_proc_channels_(num_process_channels),
- output_samples_per_channel_(output_samples_per_channel),
+ output_num_frames_(output_num_frames),
num_channels_(num_process_channels),
- num_bands_(1),
- samples_per_split_channel_(proc_samples_per_channel_),
+ num_bands_(NumBandsFromSamplesPerChannel(proc_num_frames_)),
+ num_split_frames_(rtc::CheckedDivExact(
+ proc_num_frames_, num_bands_)),
mixed_low_pass_valid_(false),
reference_copied_(false),
activity_(AudioFrame::kVadUnknown),
keyboard_data_(NULL),
- channels_(new IFChannelBuffer(proc_samples_per_channel_,
- num_proc_channels_)) {
- assert(input_samples_per_channel_ > 0);
- assert(proc_samples_per_channel_ > 0);
- assert(output_samples_per_channel_ > 0);
+ data_(new IFChannelBuffer(proc_num_frames_, num_proc_channels_)) {
+ assert(input_num_frames_ > 0);
+ assert(proc_num_frames_ > 0);
+ assert(output_num_frames_ > 0);
assert(num_input_channels_ > 0 && num_input_channels_ <= 2);
- assert(num_proc_channels_ <= num_input_channels_);
+ assert(num_proc_channels_ > 0 && num_proc_channels_ <= num_input_channels_);
if (num_input_channels_ == 2 && num_proc_channels_ == 1) {
- input_buffer_.reset(new ChannelBuffer<float>(input_samples_per_channel_,
+ input_buffer_.reset(new ChannelBuffer<float>(input_num_frames_,
num_proc_channels_));
}
- if (input_samples_per_channel_ != proc_samples_per_channel_ ||
- output_samples_per_channel_ != proc_samples_per_channel_) {
+ if (input_num_frames_ != proc_num_frames_ ||
+ output_num_frames_ != proc_num_frames_) {
// Create an intermediate buffer for resampling.
- process_buffer_.reset(new ChannelBuffer<float>(proc_samples_per_channel_,
+ process_buffer_.reset(new ChannelBuffer<float>(proc_num_frames_,
num_proc_channels_));
- }
- if (input_samples_per_channel_ != proc_samples_per_channel_) {
- input_resamplers_.reserve(num_proc_channels_);
- for (int i = 0; i < num_proc_channels_; ++i) {
- input_resamplers_.push_back(
- new PushSincResampler(input_samples_per_channel_,
- proc_samples_per_channel_));
+ if (input_num_frames_ != proc_num_frames_) {
+ for (int i = 0; i < num_proc_channels_; ++i) {
+ input_resamplers_.push_back(
+ new PushSincResampler(input_num_frames_,
+ proc_num_frames_));
+ }
+ }
+
+ if (output_num_frames_ != proc_num_frames_) {
+ for (int i = 0; i < num_proc_channels_; ++i) {
+ output_resamplers_.push_back(
+ new PushSincResampler(proc_num_frames_,
+ output_num_frames_));
+ }
}
}
- if (output_samples_per_channel_ != proc_samples_per_channel_) {
- output_resamplers_.reserve(num_proc_channels_);
- for (int i = 0; i < num_proc_channels_; ++i) {
- output_resamplers_.push_back(
- new PushSincResampler(proc_samples_per_channel_,
- output_samples_per_channel_));
- }
- }
-
- if (proc_samples_per_channel_ == kSamplesPer32kHzChannel ||
- proc_samples_per_channel_ == kSamplesPer48kHzChannel) {
- samples_per_split_channel_ = kSamplesPer16kHzChannel;
- num_bands_ = proc_samples_per_channel_ / samples_per_split_channel_;
- split_channels_.push_back(new IFChannelBuffer(samples_per_split_channel_,
- num_proc_channels_));
- split_channels_.push_back(new IFChannelBuffer(samples_per_split_channel_,
- num_proc_channels_));
+ if (num_bands_ > 1) {
+ split_data_.reset(new IFChannelBuffer(proc_num_frames_,
+ num_proc_channels_,
+ num_bands_));
splitting_filter_.reset(new SplittingFilter(num_proc_channels_));
- if (proc_samples_per_channel_ == kSamplesPer48kHzChannel) {
- split_channels_.push_back(new IFChannelBuffer(samples_per_split_channel_,
- num_proc_channels_));
- }
}
- bands_.reset(new int16_t*[num_proc_channels_ * kMaxNumBands]);
- bands_f_.reset(new float*[num_proc_channels_ * kMaxNumBands]);
}
AudioBuffer::~AudioBuffer() {}
void AudioBuffer::CopyFrom(const float* const* data,
- int samples_per_channel,
+ int num_frames,
AudioProcessing::ChannelLayout layout) {
- assert(samples_per_channel == input_samples_per_channel_);
+ assert(num_frames == input_num_frames_);
assert(ChannelsFromLayout(layout) == num_input_channels_);
InitForNewData();
@@ -146,53 +144,55 @@
if (num_input_channels_ == 2 && num_proc_channels_ == 1) {
StereoToMono(data[0],
data[1],
- input_buffer_->channel(0),
- input_samples_per_channel_);
+ input_buffer_->channels()[0],
+ input_num_frames_);
data_ptr = input_buffer_->channels();
}
// Resample.
- if (input_samples_per_channel_ != proc_samples_per_channel_) {
+ if (input_num_frames_ != proc_num_frames_) {
for (int i = 0; i < num_proc_channels_; ++i) {
input_resamplers_[i]->Resample(data_ptr[i],
- input_samples_per_channel_,
- process_buffer_->channel(i),
- proc_samples_per_channel_);
+ input_num_frames_,
+ process_buffer_->channels()[i],
+ proc_num_frames_);
}
data_ptr = process_buffer_->channels();
}
// Convert to the S16 range.
for (int i = 0; i < num_proc_channels_; ++i) {
- FloatToFloatS16(data_ptr[i], proc_samples_per_channel_,
- channels_->fbuf()->channel(i));
+ FloatToFloatS16(data_ptr[i],
+ proc_num_frames_,
+ data_->fbuf()->channels()[i]);
}
}
-void AudioBuffer::CopyTo(int samples_per_channel,
+void AudioBuffer::CopyTo(int num_frames,
AudioProcessing::ChannelLayout layout,
float* const* data) {
- assert(samples_per_channel == output_samples_per_channel_);
+ assert(num_frames == output_num_frames_);
assert(ChannelsFromLayout(layout) == num_channels_);
// Convert to the float range.
float* const* data_ptr = data;
- if (output_samples_per_channel_ != proc_samples_per_channel_) {
+ if (output_num_frames_ != proc_num_frames_) {
// Convert to an intermediate buffer for subsequent resampling.
data_ptr = process_buffer_->channels();
}
for (int i = 0; i < num_channels_; ++i) {
- FloatS16ToFloat(channels_->fbuf()->channel(i), proc_samples_per_channel_,
+ FloatS16ToFloat(data_->fbuf()->channels()[i],
+ proc_num_frames_,
data_ptr[i]);
}
// Resample.
- if (output_samples_per_channel_ != proc_samples_per_channel_) {
+ if (output_num_frames_ != proc_num_frames_) {
for (int i = 0; i < num_channels_; ++i) {
output_resamplers_[i]->Resample(data_ptr[i],
- proc_samples_per_channel_,
+ proc_num_frames_,
data[i],
- output_samples_per_channel_);
+ output_num_frames_);
}
}
}
@@ -205,119 +205,81 @@
num_channels_ = num_proc_channels_;
}
-const int16_t* AudioBuffer::data_const(int channel) const {
- return channels_const()[channel];
-}
-
-int16_t* AudioBuffer::data(int channel) {
- return channels()[channel];
-}
-
const int16_t* const* AudioBuffer::channels_const() const {
- return channels_->ibuf_const()->channels();
+ return data_->ibuf_const()->channels();
}
int16_t* const* AudioBuffer::channels() {
mixed_low_pass_valid_ = false;
- return channels_->ibuf()->channels();
+ return data_->ibuf()->channels();
}
const int16_t* const* AudioBuffer::split_bands_const(int channel) const {
- // This is necessary to make sure that the int16_t data is up to date in the
- // IFChannelBuffer.
- // TODO(aluebs): Having to depend on this to get the updated data is bug
- // prone. One solution is to have ChannelBuffer track the bands as well.
- for (int i = 0; i < kMaxNumBands; ++i) {
- int16_t* const* channels =
- const_cast<int16_t* const*>(split_channels_const(static_cast<Band>(i)));
- bands_[kMaxNumBands * channel + i] = channels ? channels[channel] : NULL;
- }
- return &bands_[kMaxNumBands * channel];
+ return split_data_.get() ?
+ split_data_->ibuf_const()->bands(channel) :
+ data_->ibuf_const()->bands(channel);
}
int16_t* const* AudioBuffer::split_bands(int channel) {
mixed_low_pass_valid_ = false;
- // This is necessary to make sure that the int16_t data is up to date and the
- // float data is marked as invalid in the IFChannelBuffer.
- for (int i = 0; i < kMaxNumBands; ++i) {
- int16_t* const* channels = split_channels(static_cast<Band>(i));
- bands_[kMaxNumBands * channel + i] = channels ? channels[channel] : NULL;
- }
- return &bands_[kMaxNumBands * channel];
+ return split_data_.get() ?
+ split_data_->ibuf()->bands(channel) :
+ data_->ibuf()->bands(channel);
}
const int16_t* const* AudioBuffer::split_channels_const(Band band) const {
- if (split_channels_.size() > static_cast<size_t>(band)) {
- return split_channels_[band]->ibuf_const()->channels();
+ if (split_data_.get()) {
+ return split_data_->ibuf_const()->channels(band);
} else {
- return band == kBand0To8kHz ? channels_->ibuf_const()->channels() : NULL;
+ return band == kBand0To8kHz ? data_->ibuf_const()->channels() : nullptr;
}
}
int16_t* const* AudioBuffer::split_channels(Band band) {
mixed_low_pass_valid_ = false;
- if (split_channels_.size() > static_cast<size_t>(band)) {
- return split_channels_[band]->ibuf()->channels();
+ if (split_data_.get()) {
+ return split_data_->ibuf()->channels(band);
} else {
- return band == kBand0To8kHz ? channels_->ibuf()->channels() : NULL;
+ return band == kBand0To8kHz ? data_->ibuf()->channels() : nullptr;
}
}
-const float* AudioBuffer::data_const_f(int channel) const {
- return channels_const_f()[channel];
-}
-
-float* AudioBuffer::data_f(int channel) {
- return channels_f()[channel];
-}
-
const float* const* AudioBuffer::channels_const_f() const {
- return channels_->fbuf_const()->channels();
+ return data_->fbuf_const()->channels();
}
float* const* AudioBuffer::channels_f() {
mixed_low_pass_valid_ = false;
- return channels_->fbuf()->channels();
+ return data_->fbuf()->channels();
}
const float* const* AudioBuffer::split_bands_const_f(int channel) const {
- // This is necessary to make sure that the float data is up to date in the
- // IFChannelBuffer.
- for (int i = 0; i < kMaxNumBands; ++i) {
- float* const* channels =
- const_cast<float* const*>(split_channels_const_f(static_cast<Band>(i)));
- bands_f_[kMaxNumBands * channel + i] = channels ? channels[channel] : NULL;
-
- }
- return &bands_f_[kMaxNumBands * channel];
+ return split_data_.get() ?
+ split_data_->fbuf_const()->bands(channel) :
+ data_->fbuf_const()->bands(channel);
}
float* const* AudioBuffer::split_bands_f(int channel) {
mixed_low_pass_valid_ = false;
- // This is necessary to make sure that the float data is up to date and the
- // int16_t data is marked as invalid in the IFChannelBuffer.
- for (int i = 0; i < kMaxNumBands; ++i) {
- float* const* channels = split_channels_f(static_cast<Band>(i));
- bands_f_[kMaxNumBands * channel + i] = channels ? channels[channel] : NULL;
-
- }
- return &bands_f_[kMaxNumBands * channel];
+ return split_data_.get() ?
+ split_data_->fbuf()->bands(channel) :
+ data_->fbuf()->bands(channel);
}
const float* const* AudioBuffer::split_channels_const_f(Band band) const {
- if (split_channels_.size() > static_cast<size_t>(band)) {
- return split_channels_[band]->fbuf_const()->channels();
+ if (split_data_.get()) {
+ return split_data_->fbuf_const()->channels(band);
} else {
- return band == kBand0To8kHz ? channels_->fbuf_const()->channels() : NULL;
+ return band == kBand0To8kHz ? data_->fbuf_const()->channels() : nullptr;
}
}
float* const* AudioBuffer::split_channels_f(Band band) {
mixed_low_pass_valid_ = false;
- if (split_channels_.size() > static_cast<size_t>(band)) {
- return split_channels_[band]->fbuf()->channels();
+ if (split_data_.get()) {
+ return split_data_->fbuf()->channels(band);
} else {
- return band == kBand0To8kHz ? channels_->fbuf()->channels() : NULL;
+ return band == kBand0To8kHz ? data_->fbuf()->channels() : nullptr;
}
}
@@ -332,15 +294,15 @@
if (!mixed_low_pass_valid_) {
if (!mixed_low_pass_channels_.get()) {
mixed_low_pass_channels_.reset(
- new ChannelBuffer<int16_t>(samples_per_split_channel_, 1));
+ new ChannelBuffer<int16_t>(num_split_frames_, 1));
}
StereoToMono(split_bands_const(0)[kBand0To8kHz],
split_bands_const(1)[kBand0To8kHz],
- mixed_low_pass_channels_->data(),
- samples_per_split_channel_);
+ mixed_low_pass_channels_->channels()[0],
+ num_split_frames_);
mixed_low_pass_valid_ = true;
}
- return mixed_low_pass_channels_->data();
+ return mixed_low_pass_channels_->channels()[0];
}
const int16_t* AudioBuffer::low_pass_reference(int channel) const {
@@ -348,7 +310,7 @@
return NULL;
}
- return low_pass_reference_channels_->channel(channel);
+ return low_pass_reference_channels_->channels()[channel];
}
const float* AudioBuffer::keyboard_data() const {
@@ -371,17 +333,17 @@
num_channels_ = num_channels;
}
-int AudioBuffer::samples_per_channel() const {
- return proc_samples_per_channel_;
+int AudioBuffer::num_frames() const {
+ return proc_num_frames_;
}
-int AudioBuffer::samples_per_split_channel() const {
- return samples_per_split_channel_;
+int AudioBuffer::num_frames_per_band() const {
+ return num_split_frames_;
}
-int AudioBuffer::samples_per_keyboard_channel() const {
+int AudioBuffer::num_keyboard_frames() const {
// We don't resample the keyboard channel.
- return input_samples_per_channel_;
+ return input_num_frames_;
}
int AudioBuffer::num_bands() const {
@@ -390,25 +352,25 @@
// TODO(andrew): Do deinterleaving and mixing in one step?
void AudioBuffer::DeinterleaveFrom(AudioFrame* frame) {
- assert(proc_samples_per_channel_ == input_samples_per_channel_);
+ assert(proc_num_frames_ == input_num_frames_);
assert(frame->num_channels_ == num_input_channels_);
- assert(frame->samples_per_channel_ == proc_samples_per_channel_);
+ assert(frame->samples_per_channel_ == proc_num_frames_);
InitForNewData();
activity_ = frame->vad_activity_;
if (num_input_channels_ == 2 && num_proc_channels_ == 1) {
// Downmix directly; no explicit deinterleaving needed.
- int16_t* downmixed = channels_->ibuf()->channel(0);
- for (int i = 0; i < input_samples_per_channel_; ++i) {
+ int16_t* downmixed = data_->ibuf()->channels()[0];
+ for (int i = 0; i < input_num_frames_; ++i) {
downmixed[i] = (frame->data_[i * 2] + frame->data_[i * 2 + 1]) / 2;
}
} else {
assert(num_proc_channels_ == num_input_channels_);
int16_t* interleaved = frame->data_;
for (int i = 0; i < num_proc_channels_; ++i) {
- int16_t* deinterleaved = channels_->ibuf()->channel(i);
+ int16_t* deinterleaved = data_->ibuf()->channels()[i];
int interleaved_idx = i;
- for (int j = 0; j < proc_samples_per_channel_; ++j) {
+ for (int j = 0; j < proc_num_frames_; ++j) {
deinterleaved[j] = interleaved[interleaved_idx];
interleaved_idx += num_proc_channels_;
}
@@ -417,10 +379,10 @@
}
void AudioBuffer::InterleaveTo(AudioFrame* frame, bool data_changed) const {
- assert(proc_samples_per_channel_ == output_samples_per_channel_);
+ assert(proc_num_frames_ == output_num_frames_);
assert(num_channels_ == num_input_channels_);
assert(frame->num_channels_ == num_channels_);
- assert(frame->samples_per_channel_ == proc_samples_per_channel_);
+ assert(frame->samples_per_channel_ == proc_num_frames_);
frame->vad_activity_ = activity_;
if (!data_changed) {
@@ -429,9 +391,9 @@
int16_t* interleaved = frame->data_;
for (int i = 0; i < num_channels_; i++) {
- int16_t* deinterleaved = channels_->ibuf()->channel(i);
+ int16_t* deinterleaved = data_->ibuf()->channels()[i];
int interleaved_idx = i;
- for (int j = 0; j < proc_samples_per_channel_; j++) {
+ for (int j = 0; j < proc_num_frames_; j++) {
interleaved[interleaved_idx] = deinterleaved[j];
interleaved_idx += num_channels_;
}
@@ -443,23 +405,23 @@
if (!low_pass_reference_channels_.get() ||
low_pass_reference_channels_->num_channels() != num_channels_) {
low_pass_reference_channels_.reset(
- new ChannelBuffer<int16_t>(samples_per_split_channel_,
+ new ChannelBuffer<int16_t>(num_split_frames_,
num_proc_channels_));
}
for (int i = 0; i < num_proc_channels_; i++) {
- low_pass_reference_channels_->CopyFrom(split_bands_const(i)[kBand0To8kHz],
- i);
+ memcpy(low_pass_reference_channels_->channels()[i],
+ split_bands_const(i)[kBand0To8kHz],
+ low_pass_reference_channels_->num_frames_per_band() *
+ sizeof(split_bands_const(i)[kBand0To8kHz][0]));
}
}
void AudioBuffer::SplitIntoFrequencyBands() {
- splitting_filter_->Analysis(channels_.get(),
- split_channels_.get());
+ splitting_filter_->Analysis(data_.get(), split_data_.get());
}
void AudioBuffer::MergeFrequencyBands() {
- splitting_filter_->Synthesis(split_channels_.get(),
- channels_.get());
+ splitting_filter_->Synthesis(split_data_.get(), data_.get());
}
} // namespace webrtc
diff --git a/webrtc/modules/audio_processing/audio_buffer.h b/webrtc/modules/audio_processing/audio_buffer.h
index da4f7e8..a7f7e89 100644
--- a/webrtc/modules/audio_processing/audio_buffer.h
+++ b/webrtc/modules/audio_processing/audio_buffer.h
@@ -27,7 +27,6 @@
class PushSincResampler;
class IFChannelBuffer;
-static const int kMaxNumBands = 3;
enum Band {
kBand0To8kHz = 0,
kBand8To16kHz = 1,
@@ -37,25 +36,23 @@
class AudioBuffer {
public:
// TODO(ajm): Switch to take ChannelLayouts.
- AudioBuffer(int input_samples_per_channel,
+ AudioBuffer(int input_num_frames,
int num_input_channels,
- int process_samples_per_channel,
+ int process_num_frames,
int num_process_channels,
- int output_samples_per_channel);
+ int output_num_frames);
virtual ~AudioBuffer();
int num_channels() const;
void set_num_channels(int num_channels);
- int samples_per_channel() const;
- int samples_per_split_channel() const;
- int samples_per_keyboard_channel() const;
+ int num_frames() const;
+ int num_frames_per_band() const;
+ int num_keyboard_frames() const;
int num_bands() const;
// Sample array accessors. Channels are guaranteed to be stored contiguously
// in memory. Prefer to use the const variants of each accessor when
// possible, since they incur less float<->int16 conversion overhead.
- int16_t* data(int channel);
- const int16_t* data_const(int channel) const;
int16_t* const* channels();
const int16_t* const* channels_const() const;
int16_t* const* split_bands(int channel);
@@ -70,8 +67,6 @@
// Float versions of the accessors, with automatic conversion back and forth
// as necessary. The range of the numbers are the same as for int16_t.
- float* data_f(int channel);
- const float* data_const_f(int channel) const;
float* const* channels_f();
const float* const* channels_const_f() const;
float* const* split_bands_f(int channel);
@@ -92,9 +87,9 @@
// Use for float deinterleaved data.
void CopyFrom(const float* const* data,
- int samples_per_channel,
+ int num_frames,
AudioProcessing::ChannelLayout layout);
- void CopyTo(int samples_per_channel,
+ void CopyTo(int num_frames,
AudioProcessing::ChannelLayout layout,
float* const* data);
void CopyLowPassToReference();
@@ -110,29 +105,27 @@
// The audio is passed into DeinterleaveFrom() or CopyFrom() with input
// format (samples per channel and number of channels).
- const int input_samples_per_channel_;
+ const int input_num_frames_;
const int num_input_channels_;
// The audio is stored by DeinterleaveFrom() or CopyFrom() with processing
// format.
- const int proc_samples_per_channel_;
+ const int proc_num_frames_;
const int num_proc_channels_;
// The audio is returned by InterleaveTo() and CopyTo() with output samples
// per channels and the current number of channels. This last one can be
// changed at any time using set_num_channels().
- const int output_samples_per_channel_;
+ const int output_num_frames_;
int num_channels_;
int num_bands_;
- int samples_per_split_channel_;
+ int num_split_frames_;
bool mixed_low_pass_valid_;
bool reference_copied_;
AudioFrame::VADActivity activity_;
const float* keyboard_data_;
- scoped_ptr<IFChannelBuffer> channels_;
- ScopedVector<IFChannelBuffer> split_channels_;
- scoped_ptr<int16_t*[]> bands_;
- scoped_ptr<float*[]> bands_f_;
+ scoped_ptr<IFChannelBuffer> data_;
+ scoped_ptr<IFChannelBuffer> split_data_;
scoped_ptr<SplittingFilter> splitting_filter_;
scoped_ptr<ChannelBuffer<int16_t> > mixed_low_pass_channels_;
scoped_ptr<ChannelBuffer<int16_t> > low_pass_reference_channels_;
diff --git a/webrtc/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc
index 1319e16..06b6038 100644
--- a/webrtc/modules/audio_processing/audio_processing_impl.cc
+++ b/webrtc/modules/audio_processing/audio_processing_impl.cc
@@ -598,7 +598,7 @@
AudioBuffer* ca = capture_audio_.get(); // For brevity.
if (use_new_agc_ && gain_control_->is_enabled()) {
- agc_manager_->AnalyzePreProcess(ca->data(0),
+ agc_manager_->AnalyzePreProcess(ca->channels()[0],
ca->num_channels(),
fwd_proc_format_.samples_per_channel());
}
@@ -613,7 +613,7 @@
beamformer_->ProcessChunk(ca->split_channels_const_f(kBand0To8kHz),
ca->split_channels_const_f(kBand8To16kHz),
ca->num_channels(),
- ca->samples_per_split_channel(),
+ ca->num_frames_per_band(),
ca->split_channels_f(kBand0To8kHz),
ca->split_channels_f(kBand8To16kHz));
ca->set_num_channels(1);
@@ -636,7 +636,7 @@
gain_control_->is_enabled() &&
(!beamformer_enabled_ || beamformer_->is_target_present())) {
agc_manager_->Process(ca->split_bands_const(0)[kBand0To8kHz],
- ca->samples_per_split_channel(),
+ ca->num_frames_per_band(),
split_rate_);
}
RETURN_ON_ERR(gain_control_->ProcessCaptureAudio(ca));
@@ -651,13 +651,13 @@
float voice_probability =
agc_manager_.get() ? agc_manager_->voice_probability() : 1.f;
- transient_suppressor_->Suppress(ca->data_f(0),
- ca->samples_per_channel(),
+ transient_suppressor_->Suppress(ca->channels_f()[0],
+ ca->num_frames(),
ca->num_channels(),
ca->split_bands_const_f(0)[kBand0To8kHz],
- ca->samples_per_split_channel(),
+ ca->num_frames_per_band(),
ca->keyboard_data(),
- ca->samples_per_keyboard_channel(),
+ ca->num_keyboard_frames(),
voice_probability,
key_pressed_);
}
diff --git a/webrtc/modules/audio_processing/beamformer/pcm_utils.cc b/webrtc/modules/audio_processing/beamformer/pcm_utils.cc
index 14d9742..207a2dc 100644
--- a/webrtc/modules/audio_processing/beamformer/pcm_utils.cc
+++ b/webrtc/modules/audio_processing/beamformer/pcm_utils.cc
@@ -51,7 +51,7 @@
PcmRead(file, length, num_channels, deinterleaved_buffer->channels());
for (int i = 0; i < num_channels; ++i) {
- S16ToFloat(deinterleaved_buffer->channel(i), num_frames, buffer[i]);
+ S16ToFloat(deinterleaved_buffer->channels()[i], num_frames, buffer[i]);
}
return elements_read;
}
@@ -82,7 +82,7 @@
new ChannelBuffer<int16_t>(num_frames, num_channels));
for (int i = 0; i < num_channels; ++i) {
- FloatToS16(buffer[i], num_frames, deinterleaved_buffer->channel(i));
+ FloatToS16(buffer[i], num_frames, deinterleaved_buffer->channels()[i]);
}
PcmWrite(file, length, num_channels, deinterleaved_buffer->channels());
}
diff --git a/webrtc/modules/audio_processing/echo_cancellation_impl.cc b/webrtc/modules/audio_processing/echo_cancellation_impl.cc
index dd3c7f1..245941a 100644
--- a/webrtc/modules/audio_processing/echo_cancellation_impl.cc
+++ b/webrtc/modules/audio_processing/echo_cancellation_impl.cc
@@ -77,7 +77,7 @@
return apm_->kNoError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
assert(audio->num_channels() == apm_->num_reverse_channels());
int err = apm_->kNoError;
@@ -90,7 +90,7 @@
err = WebRtcAec_BufferFarend(
my_handle,
audio->split_bands_const_f(j)[kBand0To8kHz],
- static_cast<int16_t>(audio->samples_per_split_channel()));
+ static_cast<int16_t>(audio->num_frames_per_band()));
if (err != apm_->kNoError) {
return GetHandleError(my_handle); // TODO(ajm): warning possible?
@@ -116,7 +116,7 @@
return apm_->kStreamParameterNotSetError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
assert(audio->num_channels() == apm_->num_output_channels());
int err = apm_->kNoError;
@@ -132,7 +132,7 @@
audio->split_bands_const_f(i),
audio->num_bands(),
audio->split_bands_f(i),
- static_cast<int16_t>(audio->samples_per_split_channel()),
+ static_cast<int16_t>(audio->num_frames_per_band()),
apm_->stream_delay_ms(),
stream_drift_samples_);
diff --git a/webrtc/modules/audio_processing/echo_control_mobile_impl.cc b/webrtc/modules/audio_processing/echo_control_mobile_impl.cc
index 534732e..0f5b4fe 100644
--- a/webrtc/modules/audio_processing/echo_control_mobile_impl.cc
+++ b/webrtc/modules/audio_processing/echo_control_mobile_impl.cc
@@ -83,7 +83,7 @@
return apm_->kNoError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
assert(audio->num_channels() == apm_->num_reverse_channels());
int err = apm_->kNoError;
@@ -96,7 +96,7 @@
err = WebRtcAecm_BufferFarend(
my_handle,
audio->split_bands_const(j)[kBand0To8kHz],
- static_cast<int16_t>(audio->samples_per_split_channel()));
+ static_cast<int16_t>(audio->num_frames_per_band()));
if (err != apm_->kNoError) {
return GetHandleError(my_handle); // TODO(ajm): warning possible?
@@ -118,7 +118,7 @@
return apm_->kStreamParameterNotSetError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
assert(audio->num_channels() == apm_->num_output_channels());
int err = apm_->kNoError;
@@ -141,7 +141,7 @@
noisy,
clean,
audio->split_bands(i)[kBand0To8kHz],
- static_cast<int16_t>(audio->samples_per_split_channel()),
+ static_cast<int16_t>(audio->num_frames_per_band()),
apm_->stream_delay_ms());
if (err != apm_->kNoError) {
diff --git a/webrtc/modules/audio_processing/gain_control_impl.cc b/webrtc/modules/audio_processing/gain_control_impl.cc
index af92b9c..6211c49 100644
--- a/webrtc/modules/audio_processing/gain_control_impl.cc
+++ b/webrtc/modules/audio_processing/gain_control_impl.cc
@@ -57,14 +57,14 @@
return apm_->kNoError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
for (int i = 0; i < num_handles(); i++) {
Handle* my_handle = static_cast<Handle*>(handle(i));
int err = WebRtcAgc_AddFarend(
my_handle,
audio->mixed_low_pass_data(),
- static_cast<int16_t>(audio->samples_per_split_channel()));
+ static_cast<int16_t>(audio->num_frames_per_band()));
if (err != apm_->kNoError) {
return GetHandleError(my_handle);
@@ -79,7 +79,7 @@
return apm_->kNoError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
assert(audio->num_channels() == num_handles());
int err = apm_->kNoError;
@@ -92,7 +92,7 @@
my_handle,
audio->split_bands(i),
audio->num_bands(),
- static_cast<int16_t>(audio->samples_per_split_channel()));
+ static_cast<int16_t>(audio->num_frames_per_band()));
if (err != apm_->kNoError) {
return GetHandleError(my_handle);
@@ -108,7 +108,7 @@
my_handle,
audio->split_bands(i),
audio->num_bands(),
- static_cast<int16_t>(audio->samples_per_split_channel()),
+ static_cast<int16_t>(audio->num_frames_per_band()),
analog_capture_level_,
&capture_level_out);
@@ -133,7 +133,7 @@
return apm_->kStreamParameterNotSetError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
assert(audio->num_channels() == num_handles());
stream_is_saturated_ = false;
@@ -146,7 +146,7 @@
my_handle,
audio->split_bands_const(i),
audio->num_bands(),
- static_cast<int16_t>(audio->samples_per_split_channel()),
+ static_cast<int16_t>(audio->num_frames_per_band()),
audio->split_bands(i),
capture_levels_[i],
&capture_level_out,
diff --git a/webrtc/modules/audio_processing/high_pass_filter_impl.cc b/webrtc/modules/audio_processing/high_pass_filter_impl.cc
index 43c3754..588ba41 100644
--- a/webrtc/modules/audio_processing/high_pass_filter_impl.cc
+++ b/webrtc/modules/audio_processing/high_pass_filter_impl.cc
@@ -114,13 +114,13 @@
return apm_->kNoError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
for (int i = 0; i < num_handles(); i++) {
Handle* my_handle = static_cast<Handle*>(handle(i));
err = Filter(my_handle,
audio->split_bands(i)[kBand0To8kHz],
- audio->samples_per_split_channel());
+ audio->num_frames_per_band());
if (err != apm_->kNoError) {
return GetHandleError(my_handle);
diff --git a/webrtc/modules/audio_processing/level_estimator_impl.cc b/webrtc/modules/audio_processing/level_estimator_impl.cc
index 5fbda83..26a61dc 100644
--- a/webrtc/modules/audio_processing/level_estimator_impl.cc
+++ b/webrtc/modules/audio_processing/level_estimator_impl.cc
@@ -31,8 +31,8 @@
RMSLevel* rms_level = static_cast<RMSLevel*>(handle(0));
for (int i = 0; i < audio->num_channels(); ++i) {
- rms_level->Process(audio->data_const(i),
- audio->samples_per_channel());
+ rms_level->Process(audio->channels_const()[i],
+ audio->num_frames());
}
return AudioProcessing::kNoError;
diff --git a/webrtc/modules/audio_processing/noise_suppression_impl.cc b/webrtc/modules/audio_processing/noise_suppression_impl.cc
index 05ef910..aa37e67 100644
--- a/webrtc/modules/audio_processing/noise_suppression_impl.cc
+++ b/webrtc/modules/audio_processing/noise_suppression_impl.cc
@@ -60,7 +60,7 @@
if (!is_component_enabled()) {
return apm_->kNoError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
assert(audio->num_channels() == num_handles());
for (int i = 0; i < num_handles(); ++i) {
@@ -76,7 +76,7 @@
if (!is_component_enabled()) {
return apm_->kNoError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
assert(audio->num_channels() == num_handles());
for (int i = 0; i < num_handles(); ++i) {
diff --git a/webrtc/modules/audio_processing/splitting_filter.cc b/webrtc/modules/audio_processing/splitting_filter.cc
index f3cbcad..623bb05 100644
--- a/webrtc/modules/audio_processing/splitting_filter.cc
+++ b/webrtc/modules/audio_processing/splitting_filter.cc
@@ -30,59 +30,53 @@
}
}
-void SplittingFilter::Analysis(const IFChannelBuffer* in_data,
- const std::vector<IFChannelBuffer*>& bands) {
- DCHECK(bands.size() == 2 || bands.size() == 3);
- DCHECK_EQ(channels_, in_data->num_channels());
- for (size_t i = 0; i < bands.size(); ++i) {
- DCHECK_EQ(channels_, bands[i]->num_channels());
- DCHECK_EQ(in_data->samples_per_channel(),
- static_cast<int>(bands.size()) * bands[i]->samples_per_channel());
- }
- if (bands.size() == 2) {
- TwoBandsAnalysis(in_data, bands[0], bands[1]);
- } else if (bands.size() == 3) {
- ThreeBandsAnalysis(in_data, bands[0], bands[1], bands[2]);
+void SplittingFilter::Analysis(const IFChannelBuffer* data,
+ IFChannelBuffer* bands) {
+ DCHECK(bands->num_bands() == 2 || bands->num_bands() == 3);
+ DCHECK_EQ(channels_, data->num_channels());
+ DCHECK_EQ(channels_, bands->num_channels());
+ DCHECK_EQ(data->num_frames(),
+ bands->num_frames_per_band() * bands->num_bands());
+ if (bands->num_bands() == 2) {
+ TwoBandsAnalysis(data, bands);
+ } else if (bands->num_bands() == 3) {
+ ThreeBandsAnalysis(data, bands);
}
}
-void SplittingFilter::Synthesis(const std::vector<IFChannelBuffer*>& bands,
- IFChannelBuffer* out_data) {
- DCHECK(bands.size() == 2 || bands.size() == 3);
- DCHECK_EQ(channels_, out_data->num_channels());
- for (size_t i = 0; i < bands.size(); ++i) {
- DCHECK_EQ(channels_, bands[i]->num_channels());
- DCHECK_EQ(out_data->samples_per_channel(),
- static_cast<int>(bands.size()) * bands[i]->samples_per_channel());
- }
- if (bands.size() == 2) {
- TwoBandsSynthesis(bands[0], bands[1], out_data);
- } else if (bands.size() == 3) {
- ThreeBandsSynthesis(bands[0], bands[1], bands[2], out_data);
+void SplittingFilter::Synthesis(const IFChannelBuffer* bands,
+ IFChannelBuffer* data) {
+ DCHECK(bands->num_bands() == 2 || bands->num_bands() == 3);
+ DCHECK_EQ(channels_, data->num_channels());
+ DCHECK_EQ(channels_, bands->num_channels());
+ DCHECK_EQ(data->num_frames(),
+ bands->num_frames_per_band() * bands->num_bands());
+ if (bands->num_bands() == 2) {
+ TwoBandsSynthesis(bands, data);
+ } else if (bands->num_bands() == 3) {
+ ThreeBandsSynthesis(bands, data);
}
}
-void SplittingFilter::TwoBandsAnalysis(const IFChannelBuffer* in_data,
- IFChannelBuffer* band1,
- IFChannelBuffer* band2) {
+void SplittingFilter::TwoBandsAnalysis(const IFChannelBuffer* data,
+ IFChannelBuffer* bands) {
for (int i = 0; i < channels_; ++i) {
- WebRtcSpl_AnalysisQMF(in_data->ibuf_const()->channel(i),
- in_data->samples_per_channel(),
- band1->ibuf()->channel(i),
- band2->ibuf()->channel(i),
+ WebRtcSpl_AnalysisQMF(data->ibuf_const()->channels()[i],
+ data->num_frames(),
+ bands->ibuf()->channels(0)[i],
+ bands->ibuf()->channels(1)[i],
two_bands_states_[i].analysis_state1,
two_bands_states_[i].analysis_state2);
}
}
-void SplittingFilter::TwoBandsSynthesis(const IFChannelBuffer* band1,
- const IFChannelBuffer* band2,
- IFChannelBuffer* out_data) {
+void SplittingFilter::TwoBandsSynthesis(const IFChannelBuffer* bands,
+ IFChannelBuffer* data) {
for (int i = 0; i < channels_; ++i) {
- WebRtcSpl_SynthesisQMF(band1->ibuf_const()->channel(i),
- band2->ibuf_const()->channel(i),
- band1->samples_per_channel(),
- out_data->ibuf()->channel(i),
+ WebRtcSpl_SynthesisQMF(bands->ibuf_const()->channels(0)[i],
+ bands->ibuf_const()->channels(1)[i],
+ bands->num_frames_per_band(),
+ data->ibuf()->channels()[i],
two_bands_states_[i].synthesis_state1,
two_bands_states_[i].synthesis_state2);
}
@@ -92,15 +86,13 @@
// by a proper 3 band filter bank.
// It up-samples from 48kHz to 64kHz, splits twice into 2 bands and discards the
// uppermost band, because it is empty anyway.
-void SplittingFilter::ThreeBandsAnalysis(const IFChannelBuffer* in_data,
- IFChannelBuffer* band1,
- IFChannelBuffer* band2,
- IFChannelBuffer* band3) {
+void SplittingFilter::ThreeBandsAnalysis(const IFChannelBuffer* data,
+ IFChannelBuffer* bands) {
DCHECK_EQ(kSamplesPer48kHzChannel,
- in_data->samples_per_channel());
+ data->num_frames());
InitBuffers();
for (int i = 0; i < channels_; ++i) {
- analysis_resamplers_[i]->Resample(in_data->ibuf_const()->channel(i),
+ analysis_resamplers_[i]->Resample(data->ibuf_const()->channels()[i],
kSamplesPer48kHzChannel,
int_buffer_.get(),
kSamplesPer64kHzChannel);
@@ -112,14 +104,14 @@
two_bands_states_[i].analysis_state2);
WebRtcSpl_AnalysisQMF(int_buffer_.get(),
kSamplesPer32kHzChannel,
- band1->ibuf()->channel(i),
- band2->ibuf()->channel(i),
+ bands->ibuf()->channels(0)[i],
+ bands->ibuf()->channels(1)[i],
band1_states_[i].analysis_state1,
band1_states_[i].analysis_state2);
WebRtcSpl_AnalysisQMF(int_buffer_.get() + kSamplesPer32kHzChannel,
kSamplesPer32kHzChannel,
int_buffer_.get(),
- band3->ibuf()->channel(i),
+ bands->ibuf()->channels(2)[i],
band2_states_[i].analysis_state1,
band2_states_[i].analysis_state2);
}
@@ -129,25 +121,23 @@
// by a proper 3 band filter bank.
// Using an empty uppermost band, it merges the 4 bands in 2 steps and
// down-samples from 64kHz to 48kHz.
-void SplittingFilter::ThreeBandsSynthesis(const IFChannelBuffer* band1,
- const IFChannelBuffer* band2,
- const IFChannelBuffer* band3,
- IFChannelBuffer* out_data) {
+void SplittingFilter::ThreeBandsSynthesis(const IFChannelBuffer* bands,
+ IFChannelBuffer* data) {
DCHECK_EQ(kSamplesPer48kHzChannel,
- out_data->samples_per_channel());
+ data->num_frames());
InitBuffers();
for (int i = 0; i < channels_; ++i) {
memset(int_buffer_.get(),
0,
kSamplesPer64kHzChannel * sizeof(int_buffer_[0]));
- WebRtcSpl_SynthesisQMF(band1->ibuf_const()->channel(i),
- band2->ibuf_const()->channel(i),
+ WebRtcSpl_SynthesisQMF(bands->ibuf_const()->channels(0)[i],
+ bands->ibuf_const()->channels(1)[i],
kSamplesPer16kHzChannel,
int_buffer_.get(),
band1_states_[i].synthesis_state1,
band1_states_[i].synthesis_state2);
WebRtcSpl_SynthesisQMF(int_buffer_.get() + kSamplesPer32kHzChannel,
- band3->ibuf_const()->channel(i),
+ bands->ibuf_const()->channels(2)[i],
kSamplesPer16kHzChannel,
int_buffer_.get() + kSamplesPer32kHzChannel,
band2_states_[i].synthesis_state1,
@@ -160,7 +150,7 @@
two_bands_states_[i].synthesis_state2);
synthesis_resamplers_[i]->Resample(int_buffer_.get(),
kSamplesPer64kHzChannel,
- out_data->ibuf()->channel(i),
+ data->ibuf()->channels()[i],
kSamplesPer48kHzChannel);
}
}
diff --git a/webrtc/modules/audio_processing/splitting_filter.h b/webrtc/modules/audio_processing/splitting_filter.h
index 119375b..16387a8 100644
--- a/webrtc/modules/audio_processing/splitting_filter.h
+++ b/webrtc/modules/audio_processing/splitting_filter.h
@@ -56,28 +56,16 @@
public:
SplittingFilter(int channels);
- void Analysis(const IFChannelBuffer* in_data,
- const std::vector<IFChannelBuffer*>& bands);
- void Synthesis(const std::vector<IFChannelBuffer*>& bands,
- IFChannelBuffer* out_data);
+ void Analysis(const IFChannelBuffer* data, IFChannelBuffer* bands);
+ void Synthesis(const IFChannelBuffer* bands, IFChannelBuffer* data);
private:
// These work for 640 samples or less.
- void TwoBandsAnalysis(const IFChannelBuffer* in_data,
- IFChannelBuffer* band1,
- IFChannelBuffer* band2);
- void TwoBandsSynthesis(const IFChannelBuffer* band1,
- const IFChannelBuffer* band2,
- IFChannelBuffer* out_data);
+ void TwoBandsAnalysis(const IFChannelBuffer* data, IFChannelBuffer* bands);
+ void TwoBandsSynthesis(const IFChannelBuffer* bands, IFChannelBuffer* data);
// These only work for 480 samples at the moment.
- void ThreeBandsAnalysis(const IFChannelBuffer* in_data,
- IFChannelBuffer* band1,
- IFChannelBuffer* band2,
- IFChannelBuffer* band3);
- void ThreeBandsSynthesis(const IFChannelBuffer* band1,
- const IFChannelBuffer* band2,
- const IFChannelBuffer* band3,
- IFChannelBuffer* out_data);
+ void ThreeBandsAnalysis(const IFChannelBuffer* data, IFChannelBuffer* bands);
+ void ThreeBandsSynthesis(const IFChannelBuffer* bands, IFChannelBuffer* data);
void InitBuffers();
int channels_;
diff --git a/webrtc/modules/audio_processing/splitting_filter_unittest.cc b/webrtc/modules/audio_processing/splitting_filter_unittest.cc
index 105392d..598057f 100644
--- a/webrtc/modules/audio_processing/splitting_filter_unittest.cc
+++ b/webrtc/modules/audio_processing/splitting_filter_unittest.cc
@@ -35,36 +35,32 @@
static const float kAmplitude = 8192;
static const int kChunks = 8;
SplittingFilter splitting_filter(kChannels);
- IFChannelBuffer in_data(kSamplesPer48kHzChannel, kChannels);
- IFChannelBuffer out_data(kSamplesPer48kHzChannel, kChannels);
- ScopedVector<IFChannelBuffer> bands;
- for (int i = 0; i < kNumBands; ++i) {
- bands.push_back(new IFChannelBuffer(kSamplesPer16kHzChannel, kChannels));
- }
+ IFChannelBuffer in_data(kSamplesPer48kHzChannel, kChannels, kNumBands);
+ IFChannelBuffer out_data(kSamplesPer48kHzChannel, kChannels, kNumBands);
for (int i = 0; i < kChunks; ++i) {
// Input signal generation.
bool is_present[kNumBands];
- memset(in_data.fbuf()->channel(0),
+ memset(in_data.fbuf()->channels()[0],
0,
- kSamplesPer48kHzChannel * sizeof(in_data.fbuf()->channel(0)[0]));
+ kSamplesPer48kHzChannel * sizeof(in_data.fbuf()->channels()[0][0]));
for (int j = 0; j < kNumBands; ++j) {
is_present[j] = i & (1 << j);
float amplitude = is_present[j] ? kAmplitude : 0;
for (int k = 0; k < kSamplesPer48kHzChannel; ++k) {
- in_data.fbuf()->channel(0)[k] +=
+ in_data.fbuf()->channels()[0][k] +=
amplitude * sin(2 * M_PI * kFrequenciesHz[j] *
(i * kSamplesPer48kHzChannel + k) / kSampleRateHz);
}
}
// Three band splitting filter.
- splitting_filter.Analysis(&in_data, bands.get());
+ splitting_filter.Analysis(&in_data, &out_data);
// Energy calculation.
float energy[kNumBands];
for (int j = 0; j < kNumBands; ++j) {
energy[j] = 0;
for (int k = 0; k < kSamplesPer16kHzChannel; ++k) {
- energy[j] += bands[j]->fbuf_const()->channel(0)[k] *
- bands[j]->fbuf_const()->channel(0)[k];
+ energy[j] += out_data.fbuf_const()->channels(j)[0][k] *
+ out_data.fbuf_const()->channels(j)[0][k];
}
energy[j] /= kSamplesPer16kHzChannel;
if (is_present[j]) {
@@ -74,14 +70,14 @@
}
}
// Three band merge.
- splitting_filter.Synthesis(bands.get(), &out_data);
+ splitting_filter.Synthesis(&out_data, &out_data);
// Delay and cross correlation estimation.
float xcorr = 0;
for (int delay = 0; delay < kSamplesPer48kHzChannel; ++delay) {
float tmpcorr = 0;
for (int j = delay; j < kSamplesPer48kHzChannel; ++j) {
- tmpcorr += in_data.fbuf_const()->channel(0)[j] *
- out_data.fbuf_const()->channel(0)[j - delay];
+ tmpcorr += in_data.fbuf_const()->channels()[0][j] *
+ out_data.fbuf_const()->channels()[0][j - delay];
}
tmpcorr /= kSamplesPer48kHzChannel;
if (tmpcorr > xcorr) {
diff --git a/webrtc/modules/audio_processing/test/audio_processing_unittest.cc b/webrtc/modules/audio_processing/test/audio_processing_unittest.cc
index d9ebe8e..0c90758 100644
--- a/webrtc/modules/audio_processing/test/audio_processing_unittest.cc
+++ b/webrtc/modules/audio_processing/test/audio_processing_unittest.cc
@@ -62,15 +62,17 @@
sizeof(*kProcessSampleRates);
void ConvertToFloat(const int16_t* int_data, ChannelBuffer<float>* cb) {
- ChannelBuffer<int16_t> cb_int(cb->samples_per_channel(),
+ ChannelBuffer<int16_t> cb_int(cb->num_frames(),
cb->num_channels());
Deinterleave(int_data,
- cb->samples_per_channel(),
+ cb->num_frames(),
cb->num_channels(),
cb_int.channels());
- S16ToFloat(cb_int.data(),
- cb->samples_per_channel() * cb->num_channels(),
- cb->data());
+ for (int i = 0; i < cb->num_channels(); ++i) {
+ S16ToFloat(cb_int.channels()[i],
+ cb->num_frames(),
+ cb->channels()[i]);
+ }
}
void ConvertToFloat(const AudioFrame& frame, ChannelBuffer<float>* cb) {
@@ -294,7 +296,7 @@
bool ReadChunk(FILE* file, int16_t* int_data, float* float_data,
ChannelBuffer<float>* cb) {
// The files always contain stereo audio.
- size_t frame_size = cb->samples_per_channel() * 2;
+ size_t frame_size = cb->num_frames() * 2;
size_t read_count = fread(int_data, sizeof(int16_t), frame_size, file);
if (read_count != frame_size) {
// Check that the file really ended.
@@ -304,9 +306,9 @@
S16ToFloat(int_data, frame_size, float_data);
if (cb->num_channels() == 1) {
- MixStereoToMono(float_data, cb->data(), cb->samples_per_channel());
+ MixStereoToMono(float_data, cb->channels()[0], cb->num_frames());
} else {
- Deinterleave(float_data, cb->samples_per_channel(), 2,
+ Deinterleave(float_data, cb->num_frames(), 2,
cb->channels());
}
@@ -1250,12 +1252,14 @@
int_data.get(),
float_data.get(),
&src_buf));
- for (int j = 0; j < kNumInputChannels * kSamplesPerChannel; ++j) {
- src_buf.data()[j] *= kScaleFactor;
+ for (int j = 0; j < kNumInputChannels; ++j) {
+ for (int k = 0; k < kSamplesPerChannel; ++k) {
+ src_buf.channels()[j][k] *= kScaleFactor;
+ }
}
EXPECT_EQ(kNoErr,
apm->ProcessStream(src_buf.channels(),
- src_buf.samples_per_channel(),
+ src_buf.num_frames(),
kSampleRateHz,
LayoutFromChannels(src_buf.num_channels()),
kSampleRateHz,
@@ -1273,12 +1277,14 @@
int_data.get(),
float_data.get(),
&src_buf));
- for (int j = 0; j < kNumInputChannels * kSamplesPerChannel; ++j) {
- src_buf.data()[j] *= kScaleFactor;
+ for (int j = 0; j < kNumInputChannels; ++j) {
+ for (int k = 0; k < kSamplesPerChannel; ++k) {
+ src_buf.channels()[j][k] *= kScaleFactor;
+ }
}
EXPECT_EQ(kNoErr,
apm->ProcessStream(src_buf.channels(),
- src_buf.samples_per_channel(),
+ src_buf.num_frames(),
kSampleRateHz,
LayoutFromChannels(src_buf.num_channels()),
kSampleRateHz,
@@ -1648,7 +1654,8 @@
if (msg.channel_size() > 0) {
ASSERT_EQ(revframe_->num_channels_, msg.channel_size());
for (int i = 0; i < msg.channel_size(); ++i) {
- memcpy(revfloat_cb_->channel(i), msg.channel(i).data(),
+ memcpy(revfloat_cb_->channels()[i],
+ msg.channel(i).data(),
msg.channel(i).size());
}
} else {
@@ -1677,7 +1684,8 @@
if (msg.input_channel_size() > 0) {
ASSERT_EQ(frame_->num_channels_, msg.input_channel_size());
for (int i = 0; i < msg.input_channel_size(); ++i) {
- memcpy(float_cb_->channel(i), msg.input_channel(i).data(),
+ memcpy(float_cb_->channels()[i],
+ msg.input_channel(i).data(),
msg.input_channel(i).size());
}
} else {
@@ -1835,7 +1843,6 @@
const int num_output_channels = test->num_output_channels();
const int samples_per_channel = test->sample_rate() *
AudioProcessing::kChunkSizeMs / 1000;
- const int output_length = samples_per_channel * num_output_channels;
Init(test->sample_rate(), test->sample_rate(), test->sample_rate(),
num_input_channels, num_output_channels, num_render_channels, true);
@@ -1876,11 +1883,13 @@
test->sample_rate(),
LayoutFromChannels(num_output_channels),
float_cb_->channels()));
-
- FloatToS16(float_cb_->data(), output_length, output_cb.data());
for (int j = 0; j < num_output_channels; ++j) {
+ FloatToS16(float_cb_->channels()[j],
+ samples_per_channel,
+ output_cb.channels()[j]);
float variance = 0;
- float snr = ComputeSNR(output_int16.channel(j), output_cb.channel(j),
+ float snr = ComputeSNR(output_int16.channels()[j],
+ output_cb.channels()[j],
samples_per_channel, &variance);
#if defined(WEBRTC_AUDIOPROC_FIXED_PROFILE)
// There are a few chunks in the fixed-point profile that give low SNR.
@@ -2171,7 +2180,7 @@
for (int j = 0; j < 10; ++j) {
EXPECT_NOERR(ap->ProcessStream(
in_cb.channels(),
- in_cb.samples_per_channel(),
+ in_cb.num_frames(),
in_rate,
cf[i].in_layout,
out_rate,
@@ -2313,9 +2322,9 @@
// Temporary buffers.
const int max_length =
- 2 * std::max(out_cb.samples_per_channel(),
- std::max(fwd_cb.samples_per_channel(),
- rev_cb.samples_per_channel()));
+ 2 * std::max(out_cb.num_frames(),
+ std::max(fwd_cb.num_frames(),
+ rev_cb.num_frames()));
scoped_ptr<float[]> float_data(new float[max_length]);
scoped_ptr<int16_t[]> int_data(new int16_t[max_length]);
@@ -2324,7 +2333,7 @@
ReadChunk(near_file, int_data.get(), float_data.get(), &fwd_cb)) {
EXPECT_NOERR(ap->AnalyzeReverseStream(
rev_cb.channels(),
- rev_cb.samples_per_channel(),
+ rev_cb.num_frames(),
reverse_rate,
LayoutFromChannels(num_reverse_channels)));
@@ -2334,7 +2343,7 @@
EXPECT_NOERR(ap->ProcessStream(
fwd_cb.channels(),
- fwd_cb.samples_per_channel(),
+ fwd_cb.num_frames(),
input_rate,
LayoutFromChannels(num_input_channels),
output_rate,
@@ -2342,13 +2351,14 @@
out_cb.channels()));
Interleave(out_cb.channels(),
- out_cb.samples_per_channel(),
+ out_cb.num_frames(),
out_cb.num_channels(),
float_data.get());
// Dump output to file.
- ASSERT_EQ(static_cast<size_t>(out_cb.length()),
+ int out_length = out_cb.num_channels() * out_cb.num_frames();
+ ASSERT_EQ(static_cast<size_t>(out_length),
fwrite(float_data.get(), sizeof(float_data[0]),
- out_cb.length(), out_file));
+ out_length, out_file));
analog_level = ap->gain_control()->stream_analog_level();
}
diff --git a/webrtc/modules/audio_processing/test/audioproc_float.cc b/webrtc/modules/audio_processing/test/audioproc_float.cc
index bbac9f1..e1418e9 100644
--- a/webrtc/modules/audio_processing/test/audioproc_float.cc
+++ b/webrtc/modules/audio_processing/test/audioproc_float.cc
@@ -177,27 +177,30 @@
ChannelBuffer<float> o_buf(o_file.sample_rate() / kChunksPerSecond,
o_file.num_channels());
- const size_t c_length = static_cast<size_t>(c_buf.length());
+ const size_t c_length =
+ static_cast<size_t>(c_buf.num_channels() * c_buf.num_frames());
+ const size_t o_length =
+ static_cast<size_t>(o_buf.num_channels() * o_buf.num_frames());
scoped_ptr<float[]> c_interleaved(new float[c_length]);
- scoped_ptr<float[]> o_interleaved(new float[o_buf.length()]);
+ scoped_ptr<float[]> o_interleaved(new float[o_length]);
while (c_file.ReadSamples(c_length, c_interleaved.get()) == c_length) {
FloatS16ToFloat(c_interleaved.get(), c_length, c_interleaved.get());
- Deinterleave(c_interleaved.get(), c_buf.samples_per_channel(),
+ Deinterleave(c_interleaved.get(), c_buf.num_frames(),
c_buf.num_channels(), c_buf.channels());
CHECK_EQ(kNoErr,
ap->ProcessStream(c_buf.channels(),
- c_buf.samples_per_channel(),
+ c_buf.num_frames(),
c_file.sample_rate(),
LayoutFromChannels(c_buf.num_channels()),
o_file.sample_rate(),
LayoutFromChannels(o_buf.num_channels()),
o_buf.channels()));
- Interleave(o_buf.channels(), o_buf.samples_per_channel(),
+ Interleave(o_buf.channels(), o_buf.num_frames(),
o_buf.num_channels(), o_interleaved.get());
- FloatToFloatS16(o_interleaved.get(), o_buf.length(), o_interleaved.get());
- o_file.WriteSamples(o_interleaved.get(), o_buf.length());
+ FloatToFloatS16(o_interleaved.get(), o_length, o_interleaved.get());
+ o_file.WriteSamples(o_interleaved.get(), o_length);
}
return 0;
diff --git a/webrtc/modules/audio_processing/test/process_test.cc b/webrtc/modules/audio_processing/test/process_test.cc
index 3af495c..d1fa032 100644
--- a/webrtc/modules/audio_processing/test/process_test.cc
+++ b/webrtc/modules/audio_processing/test/process_test.cc
@@ -654,7 +654,10 @@
memcpy(far_frame.data_, msg.data().data(), msg.data().size());
} else {
for (int i = 0; i < msg.channel_size(); ++i) {
- reverse_cb->CopyFrom(msg.channel(i).data(), i);
+ memcpy(reverse_cb->channels()[i],
+ msg.channel(i).data(),
+ reverse_cb->num_frames() *
+ sizeof(reverse_cb->channels()[i][0]));
}
}
@@ -704,7 +707,10 @@
near_read_bytes += msg.input_data().size();
} else {
for (int i = 0; i < msg.input_channel_size(); ++i) {
- primary_cb->CopyFrom(msg.input_channel(i).data(), i);
+ memcpy(primary_cb->channels()[i],
+ msg.input_channel(i).data(),
+ primary_cb->num_frames() *
+ sizeof(primary_cb->channels()[i][0]));
near_read_bytes += msg.input_channel(i).size();
}
}
diff --git a/webrtc/modules/audio_processing/voice_detection_impl.cc b/webrtc/modules/audio_processing/voice_detection_impl.cc
index 31336b4..da51a10 100644
--- a/webrtc/modules/audio_processing/voice_detection_impl.cc
+++ b/webrtc/modules/audio_processing/voice_detection_impl.cc
@@ -59,7 +59,7 @@
using_external_vad_ = false;
return apm_->kNoError;
}
- assert(audio->samples_per_split_channel() <= 160);
+ assert(audio->num_frames_per_band() <= 160);
// TODO(ajm): concatenate data in frame buffer here.