15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSVC++ requires this to be set before any other includes to get M_SQRT1_2.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _USE_MATH_DEFINES
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "media/audio/audio_parameters.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_bus.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/channel_mixer.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Number of frames to test with.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { kFrames = 16 };
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test all possible layout conversions can be constructed and mixed.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ChannelMixerTest, ConstructAllPossibleLayouts) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       input_layout <= CHANNEL_LAYOUT_MAX;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       input_layout = static_cast<ChannelLayout>(input_layout + 1)) {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         output_layout < CHANNEL_LAYOUT_STEREO_DOWNMIX;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         output_layout = static_cast<ChannelLayout>(output_layout + 1)) {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // DISCRETE can't be tested here based on the current approach.
3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC is not mixable.
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (input_layout == CHANNEL_LAYOUT_DISCRETE ||
3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          input_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC ||
3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          output_layout == CHANNEL_LAYOUT_DISCRETE ||
3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          output_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SCOPED_TRACE(base::StringPrintf(
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Input Layout: %d, Output Layout: %d", input_layout, output_layout));
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ChannelMixer mixer(input_layout, output_layout);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<AudioBus> input_bus = AudioBus::Create(
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ChannelLayoutToChannelCount(input_layout), kFrames);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<AudioBus> output_bus = AudioBus::Create(
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ChannelLayoutToChannelCount(output_layout), kFrames);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int ch = 0; ch < input_bus->channels(); ++ch)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::fill(input_bus->channel(ch), input_bus->channel(ch) + kFrames, 1);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mixer.Transform(input_bus.get(), output_bus.get());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChannelMixerTestData {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChannelMixerTestData(ChannelLayout input_layout, ChannelLayout output_layout,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       float* channel_values, int num_channel_values,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       float scale)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : input_layout(input_layout),
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output_layout(output_layout),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        channel_values(channel_values),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        num_channel_values(num_channel_values),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        scale(scale) {
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    input_channels = ChannelLayoutToChannelCount(input_layout);
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    output_channels = ChannelLayoutToChannelCount(output_layout);
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ChannelMixerTestData(ChannelLayout input_layout, int input_channels,
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       ChannelLayout output_layout, int output_channels,
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       float* channel_values, int num_channel_values)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : input_layout(input_layout),
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        input_channels(input_channels),
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        output_layout(output_layout),
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        output_channels(output_channels),
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        channel_values(channel_values),
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        num_channel_values(num_channel_values),
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        scale(1.0f) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string DebugString() const {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::StringPrintf(
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Input Layout: %d, Output Layout %d, Scale: %f", input_layout,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        output_layout, scale);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChannelLayout input_layout;
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int input_channels;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChannelLayout output_layout;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int output_channels;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float* channel_values;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_channel_values;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float scale;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::ostream& operator<<(std::ostream& os, const ChannelMixerTestData& data) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return os << data.DebugString();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChannelMixerTest : public testing::TestWithParam<ChannelMixerTestData> {};
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify channels are mixed and scaled correctly.  The test only works if all
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// output channels have the same value.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(ChannelMixerTest, Mixing) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChannelLayout input_layout = GetParam().input_layout;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int input_channels = GetParam().input_channels;
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<AudioBus> input_bus = AudioBus::Create(input_channels, kFrames);
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AudioParameters input_audio(AudioParameters::AUDIO_PCM_LINEAR,
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              input_layout,
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              input_layout == CHANNEL_LAYOUT_DISCRETE ?
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  input_channels :
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  ChannelLayoutToChannelCount(input_layout),
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              AudioParameters::kAudioCDSampleRate, 16,
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              kFrames,
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              AudioParameters::NO_EFFECTS);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ChannelLayout output_layout = GetParam().output_layout;
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int output_channels = GetParam().output_channels;
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<AudioBus> output_bus = AudioBus::Create(output_channels, kFrames);
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AudioParameters output_audio(AudioParameters::AUDIO_PCM_LINEAR,
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               output_layout,
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               output_layout == CHANNEL_LAYOUT_DISCRETE ?
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                   output_channels :
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                   ChannelLayoutToChannelCount(output_layout),
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               AudioParameters::kAudioCDSampleRate, 16,
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               kFrames,
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               AudioParameters::NO_EFFECTS);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const float* channel_values = GetParam().channel_values;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(input_bus->channels(), GetParam().num_channel_values);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float expected_value = 0;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float scale = GetParam().scale;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int ch = 0; ch < input_bus->channels(); ++ch) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::fill(input_bus->channel(ch), input_bus->channel(ch) + kFrames,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              channel_values[ch]);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expected_value += channel_values[ch] * scale;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ChannelMixer mixer(input_audio, output_audio);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mixer.Transform(input_bus.get(), output_bus.get());
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Validate the output channel
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (input_layout != CHANNEL_LAYOUT_DISCRETE) {
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (int ch = 0; ch < output_bus->channels(); ++ch) {
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (int frame = 0; frame < output_bus->frames(); ++frame) {
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ASSERT_FLOAT_EQ(output_bus->channel(ch)[frame], expected_value);
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Processing discrete mixing. If there is a matching input channel,
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // then the output channel should be set. If no input channel,
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // output channel should be 0
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (int ch = 0; ch < output_bus->channels(); ++ch) {
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      expected_value = (ch < input_channels) ? channel_values[ch] : 0;
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (int frame = 0; frame < output_bus->frames(); ++frame) {
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ASSERT_FLOAT_EQ(output_bus->channel(ch)[frame], expected_value);
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static float kStereoToMonoValues[] = { 0.5f, 0.75f };
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static float kMonoToStereoValues[] = { 0.5f };
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Zero the center channel since it will be mixed at scale 1 vs M_SQRT1_2.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static float kFiveOneToMonoValues[] = { 0.1f, 0.2f, 0.0f, 0.4f, 0.5f, 0.6f };
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static float kFiveDiscreteValues[] = { 0.1f, 0.2f, 0.3f, 0.4f, 0.5f };
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Run through basic sanity tests for some common conversions.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(ChannelMixerTest, ChannelMixerTest, testing::Values(
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChannelMixerTestData(CHANNEL_LAYOUT_STEREO, CHANNEL_LAYOUT_MONO,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         kStereoToMonoValues, arraysize(kStereoToMonoValues),
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         0.5f),
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChannelMixerTestData(CHANNEL_LAYOUT_MONO, CHANNEL_LAYOUT_STEREO,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         kMonoToStereoValues, arraysize(kMonoToStereoValues),
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         1.0f),
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChannelMixerTestData(CHANNEL_LAYOUT_5_1, CHANNEL_LAYOUT_MONO,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         kFiveOneToMonoValues, arraysize(kFiveOneToMonoValues),
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         static_cast<float>(M_SQRT1_2)),
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ChannelMixerTestData(CHANNEL_LAYOUT_DISCRETE, 2,
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         CHANNEL_LAYOUT_DISCRETE, 2,
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         kStereoToMonoValues, arraysize(kStereoToMonoValues)),
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ChannelMixerTestData(CHANNEL_LAYOUT_DISCRETE, 2,
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         CHANNEL_LAYOUT_DISCRETE, 5,
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         kStereoToMonoValues, arraysize(kStereoToMonoValues)),
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ChannelMixerTestData(CHANNEL_LAYOUT_DISCRETE, 5,
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         CHANNEL_LAYOUT_DISCRETE, 2,
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         kFiveDiscreteValues, arraysize(kFiveDiscreteValues))
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
189