Retry aa3219ce27ef5471c19670fe5145b136925cbc89:
[chromium-blink-merge.git] / media / base / channel_mixer.cc
blob54b59a891794942c6b494265a2aa36bce59806ff
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/base/channel_mixer.h"
7 #include "base/logging.h"
8 #include "media/audio/audio_parameters.h"
9 #include "media/base/audio_bus.h"
10 #include "media/base/channel_mixing_matrix.h"
11 #include "media/base/vector_math.h"
13 namespace media {
15 ChannelMixer::ChannelMixer(ChannelLayout input_layout,
16 ChannelLayout output_layout) {
17 Initialize(input_layout,
18 ChannelLayoutToChannelCount(input_layout),
19 output_layout,
20 ChannelLayoutToChannelCount(output_layout));
23 ChannelMixer::ChannelMixer(
24 const AudioParameters& input, const AudioParameters& output) {
25 Initialize(input.channel_layout(),
26 input.channels(),
27 output.channel_layout(),
28 output.channels());
31 void ChannelMixer::Initialize(
32 ChannelLayout input_layout, int input_channels,
33 ChannelLayout output_layout, int output_channels) {
34 // Create the transformation matrix
35 ChannelMixingMatrix matrix_builder(input_layout, input_channels,
36 output_layout, output_channels);
37 remapping_ = matrix_builder.CreateTransformationMatrix(&matrix_);
40 ChannelMixer::~ChannelMixer() {}
42 void ChannelMixer::Transform(const AudioBus* input, AudioBus* output) {
43 CHECK_EQ(matrix_.size(), static_cast<size_t>(output->channels()));
44 CHECK_EQ(matrix_[0].size(), static_cast<size_t>(input->channels()));
45 CHECK_EQ(input->frames(), output->frames());
47 // Zero initialize |output| so we're accumulating from zero.
48 output->Zero();
50 // If we're just remapping we can simply copy the correct input to output.
51 if (remapping_) {
52 for (int output_ch = 0; output_ch < output->channels(); ++output_ch) {
53 for (int input_ch = 0; input_ch < input->channels(); ++input_ch) {
54 float scale = matrix_[output_ch][input_ch];
55 if (scale > 0) {
56 DCHECK_EQ(scale, 1.0f);
57 memcpy(output->channel(output_ch), input->channel(input_ch),
58 sizeof(*output->channel(output_ch)) * output->frames());
59 break;
63 return;
66 for (int output_ch = 0; output_ch < output->channels(); ++output_ch) {
67 for (int input_ch = 0; input_ch < input->channels(); ++input_ch) {
68 float scale = matrix_[output_ch][input_ch];
69 // Scale should always be positive. Don't bother scaling by zero.
70 DCHECK_GE(scale, 0);
71 if (scale > 0) {
72 vector_math::FMAC(input->channel(input_ch), scale, output->frames(),
73 output->channel(output_ch));
79 } // namespace media