summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/audio/utility/channel_mixer.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/audio/utility/channel_mixer.h')
-rw-r--r--third_party/libwebrtc/audio/utility/channel_mixer.h86
1 files changed, 86 insertions, 0 deletions
diff --git a/third_party/libwebrtc/audio/utility/channel_mixer.h b/third_party/libwebrtc/audio/utility/channel_mixer.h
new file mode 100644
index 0000000000..2dea8eb45b
--- /dev/null
+++ b/third_party/libwebrtc/audio/utility/channel_mixer.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef AUDIO_UTILITY_CHANNEL_MIXER_H_
+#define AUDIO_UTILITY_CHANNEL_MIXER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include "api/audio/audio_frame.h"
+#include "api/audio/channel_layout.h"
+
+namespace webrtc {
+
+// ChannelMixer is for converting audio between channel layouts. The conversion
+// matrix is built upon construction and used during each Transform() call. The
+// algorithm works by generating a conversion matrix mapping each output channel
+// to list of input channels. The transform renders all of the output channels,
+// with each output channel rendered according to a weighted sum of the relevant
+// input channels as defined in the matrix.
+// This file is derived from Chromium's media/base/channel_mixer.h.
+class ChannelMixer {
+ public:
+ // To mix two channels into one and preserve loudness, we must apply
+ // (1 / sqrt(2)) gain to each.
+ static constexpr float kHalfPower = 0.707106781186547524401f;
+
+ ChannelMixer(ChannelLayout input_layout, ChannelLayout output_layout);
+ ~ChannelMixer();
+
+ // Transforms all input channels corresponding to the selected `input_layout`
+ // to the number of channels in the selected `output_layout`.
+ // Example usage (downmix from stereo to mono):
+ //
+ // ChannelMixer mixer(CHANNEL_LAYOUT_STEREO, CHANNEL_LAYOUT_MONO);
+ // AudioFrame frame;
+ // frame.samples_per_channel_ = 160;
+ // frame.num_channels_ = 2;
+ // EXPECT_EQ(2u, frame.channels());
+ // mixer.Transform(&frame);
+ // EXPECT_EQ(1u, frame.channels());
+ //
+ void Transform(AudioFrame* frame);
+
+ private:
+ bool IsUpMixing() const { return output_channels_ > input_channels_; }
+
+ // Selected channel layouts.
+ const ChannelLayout input_layout_;
+ const ChannelLayout output_layout_;
+
+ // Channel counts for input and output.
+ const size_t input_channels_;
+ const size_t output_channels_;
+
+ // 2D matrix of output channels to input channels.
+ std::vector<std::vector<float> > matrix_;
+
+ // 1D array used as temporary storage during the transformation.
+ std::unique_ptr<int16_t[]> audio_vector_;
+
+ // Number of elements allocated for `audio_vector_`.
+ size_t audio_vector_size_ = 0;
+
+ // Optimization case for when we can simply remap the input channels to output
+ // channels, i.e., when all scaling factors in `matrix_` equals 1.0.
+ bool remapping_;
+
+ // Delete the copy constructor and assignment operator.
+ ChannelMixer(const ChannelMixer& other) = delete;
+ ChannelMixer& operator=(const ChannelMixer& other) = delete;
+};
+
+} // namespace webrtc
+
+#endif // AUDIO_UTILITY_CHANNEL_MIXER_H_