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"
15 ChannelMixer::ChannelMixer(ChannelLayout input_layout
,
16 ChannelLayout output_layout
) {
17 Initialize(input_layout
,
18 ChannelLayoutToChannelCount(input_layout
),
20 ChannelLayoutToChannelCount(output_layout
));
23 ChannelMixer::ChannelMixer(
24 const AudioParameters
& input
, const AudioParameters
& output
) {
25 Initialize(input
.channel_layout(),
27 output
.channel_layout(),
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.
50 // If we're just remapping we can simply copy the correct input to output.
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
];
56 DCHECK_EQ(scale
, 1.0f
);
57 memcpy(output
->channel(output_ch
), input
->channel(input_ch
),
58 sizeof(*output
->channel(output_ch
)) * output
->frames());
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.
72 vector_math::FMAC(input
->channel(input_ch
), scale
, output
->frames(),
73 output
->channel(output_ch
));