OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 // MSVC++ requires this to be set before any other includes to get M_SQRT1_2. | |
6 #define _USE_MATH_DEFINES | |
7 | |
8 #include <cmath> | |
9 | |
10 #include "base/stringprintf.h" | |
11 #include "media/base/audio_bus.h" | |
12 #include "media/base/channel_mixer.h" | |
13 #include "testing/gtest/include/gtest/gtest.h" | |
14 | |
15 namespace media { | |
16 | |
17 // Number of frames to test with. | |
18 enum { kFrames = 16 }; | |
19 | |
20 // Test all possible layout conversions can be constructed and mixed. | |
21 TEST(ChannelMixerTest, ConstructAllPossibleLayouts) { | |
22 for (ChannelLayout input_layout = CHANNEL_LAYOUT_MONO; | |
23 input_layout < CHANNEL_LAYOUT_MAX; | |
24 input_layout = static_cast<ChannelLayout>(input_layout + 1)) { | |
25 for (ChannelLayout output_layout = CHANNEL_LAYOUT_MONO; | |
26 output_layout < CHANNEL_LAYOUT_STEREO_DOWNMIX; | |
27 output_layout = static_cast<ChannelLayout>(output_layout + 1)) { | |
28 SCOPED_TRACE(base::StringPrintf( | |
29 "Input Layout: %d, Output Layout: %d", input_layout, output_layout)); | |
30 ChannelMixer mixer(input_layout, output_layout); | |
31 scoped_ptr<AudioBus> input_bus = AudioBus::Create( | |
32 ChannelLayoutToChannelCount(input_layout), kFrames); | |
33 scoped_ptr<AudioBus> output_bus = AudioBus::Create( | |
34 ChannelLayoutToChannelCount(output_layout), kFrames); | |
35 for (int ch = 0; ch < input_bus->channels(); ++ch) | |
36 std::fill(input_bus->channel(ch), input_bus->channel(ch) + kFrames, 1); | |
37 | |
38 mixer.Rematrix(input_bus.get(), output_bus.get()); | |
39 } | |
40 } | |
41 } | |
42 | |
43 struct ChannelMixerTestData { | |
44 ChannelMixerTestData(ChannelLayout input_layout, ChannelLayout output_layout, | |
scherkus (not reviewing)
2012/10/18 16:50:20
perhaps you have to use regular struct initializer
DaleCurtis
2012/10/18 20:42:20
Didn't like the const setting on variables below,
| |
45 float* channel_values, int num_channel_values, | |
46 float scale) | |
47 : input_layout(input_layout), | |
48 output_layout(output_layout), | |
49 channel_values(channel_values), | |
50 num_channel_values(num_channel_values), | |
51 scale(scale) { | |
52 } | |
53 | |
54 std::string DebugString() const { | |
55 return base::StringPrintf( | |
56 "Input Layout: %d, Output Layout %d, Scale: %f", input_layout, | |
57 output_layout, scale); | |
58 } | |
59 | |
60 const ChannelLayout input_layout; | |
61 const ChannelLayout output_layout; | |
62 const float* channel_values; | |
63 const int num_channel_values; | |
64 const float scale; | |
65 }; | |
66 | |
67 std::ostream& operator<<(std::ostream& os, const ChannelMixerTestData& data) { | |
68 return os << data.DebugString(); | |
69 } | |
70 | |
71 class ChannelMixerTest : public testing::TestWithParam<ChannelMixerTestData> {}; | |
72 | |
73 // Verify channels are mixed and scaled correctly. The test only works if all | |
74 // output channels have the same value. | |
75 TEST_P(ChannelMixerTest, Mixing) { | |
76 ChannelLayout input_layout = GetParam().input_layout; | |
77 ChannelLayout output_layout = GetParam().output_layout; | |
78 | |
79 ChannelMixer mixer(input_layout, output_layout); | |
80 scoped_ptr<AudioBus> input_bus = AudioBus::Create( | |
81 ChannelLayoutToChannelCount(input_layout), kFrames); | |
82 scoped_ptr<AudioBus> output_bus = AudioBus::Create( | |
83 ChannelLayoutToChannelCount(output_layout), kFrames); | |
84 | |
85 const float* channel_values = GetParam().channel_values; | |
86 ASSERT_EQ(input_bus->channels(), GetParam().num_channel_values); | |
87 | |
88 float expected_value = 0; | |
89 float scale = GetParam().scale; | |
90 for (int ch = 0; ch < input_bus->channels(); ++ch) { | |
91 std::fill(input_bus->channel(ch), input_bus->channel(ch) + kFrames, | |
92 channel_values[ch]); | |
93 expected_value += channel_values[ch] * scale; | |
94 } | |
95 | |
96 mixer.Rematrix(input_bus.get(), output_bus.get()); | |
97 | |
98 for (int ch = 0; ch < output_bus->channels(); ++ch) { | |
99 for (int frame = 0; frame < output_bus->frames(); ++frame) { | |
100 ASSERT_FLOAT_EQ(output_bus->channel(ch)[frame], expected_value); | |
101 } | |
102 } | |
103 } | |
104 | |
105 static float kStereoToMonoValues[] = { 0.5f, 0.75f }; | |
106 static float kMonoToStereoValues[] = { 0.5f }; | |
107 // Zero the center channel since it will be mixed at scale 1 vs M_SQRT1_2. | |
108 static float kFiveOneToMonoValues[] = { 0.1f, 0.2f, 0.0f, 0.4f, 0.5f, 0.6f }; | |
109 | |
110 // Run through basic sanity tests for some common conversions. | |
111 INSTANTIATE_TEST_CASE_P(ChannelMixerTest, ChannelMixerTest, testing::Values( | |
112 ChannelMixerTestData(CHANNEL_LAYOUT_STEREO, CHANNEL_LAYOUT_MONO, | |
113 kStereoToMonoValues, arraysize(kStereoToMonoValues), | |
114 0.5f), | |
115 ChannelMixerTestData(CHANNEL_LAYOUT_MONO, CHANNEL_LAYOUT_STEREO, | |
116 kMonoToStereoValues, arraysize(kMonoToStereoValues), | |
117 1.0f), | |
118 ChannelMixerTestData(CHANNEL_LAYOUT_5_1, CHANNEL_LAYOUT_MONO, | |
119 kFiveOneToMonoValues, arraysize(kFiveOneToMonoValues), | |
120 static_cast<float>(M_SQRT1_2)) | |
121 )); | |
122 | |
123 } // namespace media | |
OLD | NEW |