summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorkwiberg@webrtc.org <kwiberg@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2014-07-18 07:50:29 +0000
committerkwiberg@webrtc.org <kwiberg@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2014-07-18 07:50:29 +0000
commit84649c022683027d6c1765fad1d7b447a8e8b03a (patch)
tree70cfcf3b5afe84069fe28259479791a3d612df6e /modules
parent8bd216f982a7ecd65fef95db7a40bc034d2062bd (diff)
downloadwebrtc-84649c022683027d6c1765fad1d7b447a8e8b03a.tar.gz
AudioBuffer: Optimize const accesses to arrays that autoconvert int16<->float
Specifically, when someone asks for a const pointer to the int16 version of the array, there's no need to invalidate the float version of that array, and vice versa. (But obviously, invalidation still has to happen when someone asks for a non-const pointer.) R=aluebs@webrtc.org, andrew@webrtc.org, minyue@webrtc.org Review URL: https://webrtc-codereview.appspot.com/18809004 git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@6725 4adac7df-926f-26a2-2b94-8c16560cd09d
Diffstat (limited to 'modules')
-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_; }