Index: webrtc/modules/audio_processing/audio_buffer.h |
diff --git a/webrtc/modules/audio_processing/audio_buffer.h b/webrtc/modules/audio_processing/audio_buffer.h |
index 4291fb3eb99832a416d691cecab9c8b8ff9a041e..0ecda828791defa26f586f40fc8c1cf262af0218 100644 |
--- a/webrtc/modules/audio_processing/audio_buffer.h |
+++ b/webrtc/modules/audio_processing/audio_buffer.h |
@@ -30,6 +30,72 @@ enum Band { |
kBand16To24kHz = 2 |
}; |
+template <typename T, typename Intermediate> |
aluebs-webrtc
2015/07/14 23:12:43
What do you think about adding these to audio_util
mgraczyk
2015/07/15 01:12:46
Done.
|
+void DownmixStereoToMono(int num_frames, |
aluebs-webrtc
2015/07/14 23:12:42
Is it worth it to specialize for the stereo case?
mgraczyk
2015/07/15 01:12:46
Probably, although I didn't benchmark it. I figure
aluebs-webrtc
2015/07/15 18:04:05
Yes, common, but do you gain anything? It definiti
mgraczyk
2015/07/15 20:03:19
The if statement is basically free because it's at
|
+ T* out, |
+ const T* left, |
+ const T* right) { |
aluebs-webrtc
2015/07/14 23:12:42
Inputs before outputs?
mgraczyk
2015/07/15 01:12:46
Done.
|
+ for (int i = 0; i < num_frames; ++i) { |
+ out[i] = (static_cast<Intermediate>(left[i]) + right[i]) / 2; |
+ } |
+} |
+ |
+template <typename T, typename Intermediate> |
+void DownmixToMono(int num_frames, |
+ T* out, |
+ const T* const* input_channels, |
+ int num_channels) { |
aluebs-webrtc
2015/07/14 23:12:42
Inputs before outputs?
mgraczyk
2015/07/15 01:12:46
Done.
|
+ if (num_channels == 2) { |
+ DownmixStereoToMono<T, Intermediate>(num_frames, out, input_channels[0], |
+ input_channels[1]); |
+ } else { |
+ for (int i = 0; i < num_frames; ++i) { |
+ Intermediate value = input_channels[0][i]; |
+ for (int j = 1; j < num_channels; ++j) { |
+ value += input_channels[j][i]; |
+ } |
+ out[i] = value / num_channels; |
+ } |
+ } |
+} |
+ |
+// Downmixes an interleaved multichannel signal to a single channel by averaging |
+// all channels. |
+template <typename T, typename Intermediate> |
+void DownmixInterleavedToMonoImpl(const T* interleaved, |
+ T* deinterleaved, |
+ int num_multichannel_frames, |
+ int num_channels) { |
aluebs-webrtc
2015/07/14 23:12:43
Inputs before outputs?
mgraczyk
2015/07/15 01:12:46
Done.
|
+ assert(num_channels > 0); |
+ assert(num_multichannel_frames > 0); |
+ |
+ const T* const end = interleaved + num_multichannel_frames * num_channels; |
+ |
+ if (num_channels == 1) { |
+ std::memmove( |
+ deinterleaved, interleaved, |
+ num_channels * num_multichannel_frames * sizeof(*deinterleaved)); |
aluebs-webrtc
2015/07/14 23:12:42
You don't need to multiply by num_channels since y
mgraczyk
2015/07/15 01:12:46
Done.
|
+ } else if (num_channels == 2) { |
aluebs-webrtc
2015/07/14 23:12:42
Is it worth it to specialize for the stereo case?
mgraczyk
2015/07/15 01:12:46
Same answer, although here the savings is not goin
aluebs-webrtc
2015/07/15 21:29:16
So, should this be removed as well following the s
mgraczyk
2015/07/15 21:53:55
Done.
|
+ // Explicitly unroll for the common stereo case. |
+ while (interleaved < end) { |
+ *deinterleaved++ = |
+ (static_cast<Intermediate>(*interleaved) + *(interleaved + 1)) / 2; |
+ interleaved += 2; |
+ } |
+ } else { |
+ while (interleaved < end) { |
aluebs-webrtc
2015/07/14 23:12:43
I find for with indexes easier to follow, but I le
mgraczyk
2015/07/15 01:12:46
Acknowledged.
|
+ const T* const frame_end = interleaved + num_channels; |
+ |
+ Intermediate value = *interleaved++; |
+ while (interleaved < frame_end) { |
+ value += *interleaved++; |
+ } |
+ |
+ *deinterleaved++ = value / num_channels; |
+ } |
+ } |
+} |
+ |
class AudioBuffer { |
public: |
// TODO(ajm): Switch to take ChannelLayouts. |
@@ -112,12 +178,8 @@ class AudioBuffer { |
void InterleaveTo(AudioFrame* frame, bool data_changed) const; |
// Use for float deinterleaved data. |
- void CopyFrom(const float* const* data, |
- int num_frames, |
- AudioProcessing::ChannelLayout layout); |
- void CopyTo(int num_frames, |
- AudioProcessing::ChannelLayout layout, |
- float* const* data); |
+ void CopyFrom(const float* const* data, const StreamConfig& stream_config); |
+ void CopyTo(const StreamConfig& stream_config, float* const* data); |
void CopyLowPassToReference(); |
// Splits the signal into different bands. |