summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/audio_processing/audio_buffer.cc58
-rw-r--r--modules/audio_processing/audio_buffer.h4
-rw-r--r--modules/audio_processing/common.h6
3 files changed, 41 insertions, 27 deletions
diff --git a/modules/audio_processing/audio_buffer.cc b/modules/audio_processing/audio_buffer.cc
index 1ceba383..fb2c200e 100644
--- a/modules/audio_processing/audio_buffer.cc
+++ b/modules/audio_processing/audio_buffer.cc
@@ -70,8 +70,9 @@ void StereoToMono(const int16_t* left, const int16_t* right, int16_t* out,
// One int16_t and one float ChannelBuffer that are kept in sync. The sync is
// broken when someone requests write access to either ChannelBuffer, and
// reestablished when someone requests the outdated ChannelBuffer. It is
-// therefore safe to use the return value of ibuf() and fbuf() until the next
-// call to the other method.
+// therefore safe to use the return value of ibuf_const() and fbuf_const()
+// until the next call to ibuf() or fbuf(), and the return value of ibuf() and
+// fbuf() until the next call to any of the other functions.
class IFChannelBuffer {
public:
IFChannelBuffer(int samples_per_channel, int num_channels)
@@ -80,19 +81,24 @@ class IFChannelBuffer {
fvalid_(true),
fbuf_(samples_per_channel, num_channels) {}
- ChannelBuffer<int16_t>* ibuf() {
+ ChannelBuffer<int16_t>* ibuf() { return ibuf(false); }
+ ChannelBuffer<float>* fbuf() { return fbuf(false); }
+ const ChannelBuffer<int16_t>* ibuf_const() { return ibuf(true); }
+ const ChannelBuffer<float>* fbuf_const() { return fbuf(true); }
+
+ private:
+ ChannelBuffer<int16_t>* ibuf(bool readonly) {
RefreshI();
- fvalid_ = false;
+ fvalid_ = readonly;
return &ibuf_;
}
- ChannelBuffer<float>* fbuf() {
+ ChannelBuffer<float>* fbuf(bool readonly) {
RefreshF();
- ivalid_ = false;
+ ivalid_ = readonly;
return &fbuf_;
}
- private:
void RefreshF() {
if (!fvalid_) {
assert(ivalid_);
@@ -266,69 +272,71 @@ void AudioBuffer::InitForNewData() {
}
const int16_t* AudioBuffer::data(int channel) const {
- return channels_->ibuf()->channel(channel);
+ return channels_->ibuf_const()->channel(channel);
}
int16_t* AudioBuffer::data(int channel) {
mixed_low_pass_valid_ = false;
- const AudioBuffer* t = this;
- return const_cast<int16_t*>(t->data(channel));
+ return channels_->ibuf()->channel(channel);
}
const float* AudioBuffer::data_f(int channel) const {
- return channels_->fbuf()->channel(channel);
+ return channels_->fbuf_const()->channel(channel);
}
float* AudioBuffer::data_f(int channel) {
mixed_low_pass_valid_ = false;
- const AudioBuffer* t = this;
- return const_cast<float*>(t->data_f(channel));
+ return channels_->fbuf()->channel(channel);
}
const int16_t* AudioBuffer::low_pass_split_data(int channel) const {
return split_channels_low_.get()
- ? split_channels_low_->ibuf()->channel(channel)
+ ? split_channels_low_->ibuf_const()->channel(channel)
: data(channel);
}
int16_t* AudioBuffer::low_pass_split_data(int channel) {
mixed_low_pass_valid_ = false;
- const AudioBuffer* t = this;
- return const_cast<int16_t*>(t->low_pass_split_data(channel));
+ return split_channels_low_.get()
+ ? split_channels_low_->ibuf()->channel(channel)
+ : data(channel);
}
const float* AudioBuffer::low_pass_split_data_f(int channel) const {
return split_channels_low_.get()
- ? split_channels_low_->fbuf()->channel(channel)
+ ? split_channels_low_->fbuf_const()->channel(channel)
: data_f(channel);
}
float* AudioBuffer::low_pass_split_data_f(int channel) {
mixed_low_pass_valid_ = false;
- const AudioBuffer* t = this;
- return const_cast<float*>(t->low_pass_split_data_f(channel));
+ return split_channels_low_.get()
+ ? split_channels_low_->fbuf()->channel(channel)
+ : data_f(channel);
}
const int16_t* AudioBuffer::high_pass_split_data(int channel) const {
return split_channels_high_.get()
- ? split_channels_high_->ibuf()->channel(channel)
+ ? split_channels_high_->ibuf_const()->channel(channel)
: NULL;
}
int16_t* AudioBuffer::high_pass_split_data(int channel) {
- const AudioBuffer* t = this;
- return const_cast<int16_t*>(t->high_pass_split_data(channel));
+ return split_channels_high_.get()
+ ? split_channels_high_->ibuf()->channel(channel)
+ : NULL;
}
const float* AudioBuffer::high_pass_split_data_f(int channel) const {
return split_channels_high_.get()
- ? split_channels_high_->fbuf()->channel(channel)
+ ? split_channels_high_->fbuf_const()->channel(channel)
: NULL;
}
float* AudioBuffer::high_pass_split_data_f(int channel) {
- const AudioBuffer* t = this;
- return const_cast<float*>(t->high_pass_split_data_f(channel));
+ return split_channels_high_.get()
+ ? split_channels_high_->fbuf()->channel(channel)
+ : NULL;
}
const int16_t* AudioBuffer::mixed_low_pass_data() {
diff --git a/modules/audio_processing/audio_buffer.h b/modules/audio_processing/audio_buffer.h
index 5c26ae29..acf5753c 100644
--- a/modules/audio_processing/audio_buffer.h
+++ b/modules/audio_processing/audio_buffer.h
@@ -55,7 +55,9 @@ class AudioBuffer {
int samples_per_split_channel() const;
int samples_per_keyboard_channel() const;
- // It can be assumed that channels are stored contiguously.
+ // 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(int channel) const;
int16_t* low_pass_split_data(int channel);
diff --git a/modules/audio_processing/common.h b/modules/audio_processing/common.h
index 10249cc2..98e36cb0 100644
--- a/modules/audio_processing/common.h
+++ b/modules/audio_processing/common.h
@@ -54,10 +54,14 @@ class ChannelBuffer {
}
T* data() { return data_.get(); }
- T* channel(int i) {
+ const T* channel(int i) const {
assert(i >= 0 && i < num_channels_);
return channels_[i];
}
+ T* channel(int i) {
+ const ChannelBuffer<T>* t = this;
+ return const_cast<T*>(t->channel(i));
+ }
T** channels() { return channels_.get(); }
int samples_per_channel() { return samples_per_channel_; }