• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "audio/utility/channel_mixing_matrix.h"
12 
13 #include <stddef.h>
14 
15 #include "audio/utility/channel_mixer.h"
16 #include "rtc_base/arraysize.h"
17 #include "rtc_base/logging.h"
18 #include "rtc_base/strings/string_builder.h"
19 #include "test/field_trial.h"
20 #include "test/gtest.h"
21 
22 namespace webrtc {
23 
24 // Test all possible layout conversions can be constructed and mixed.
25 // Also ensure that the channel matrix fulfill certain conditions when remapping
26 // is supported.
TEST(ChannelMixingMatrixTest,ConstructAllPossibleLayouts)27 TEST(ChannelMixingMatrixTest, ConstructAllPossibleLayouts) {
28   for (ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
29        input_layout <= CHANNEL_LAYOUT_MAX;
30        input_layout = static_cast<ChannelLayout>(input_layout + 1)) {
31     for (ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
32          output_layout <= CHANNEL_LAYOUT_MAX;
33          output_layout = static_cast<ChannelLayout>(output_layout + 1)) {
34       // DISCRETE, BITSTREAM can't be tested here based on the current approach.
35       // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC is not mixable.
36       // Stereo down mix should never be the output layout.
37       if (input_layout == CHANNEL_LAYOUT_BITSTREAM ||
38           input_layout == CHANNEL_LAYOUT_DISCRETE ||
39           input_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC ||
40           output_layout == CHANNEL_LAYOUT_BITSTREAM ||
41           output_layout == CHANNEL_LAYOUT_DISCRETE ||
42           output_layout == CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC ||
43           output_layout == CHANNEL_LAYOUT_STEREO_DOWNMIX) {
44         continue;
45       }
46 
47       rtc::StringBuilder ss;
48       ss << "Input Layout: " << input_layout
49          << ", Output Layout: " << output_layout;
50       SCOPED_TRACE(ss.str());
51       ChannelMixingMatrix matrix_builder(
52           input_layout, ChannelLayoutToChannelCount(input_layout),
53           output_layout, ChannelLayoutToChannelCount(output_layout));
54       const int input_channels = ChannelLayoutToChannelCount(input_layout);
55       const int output_channels = ChannelLayoutToChannelCount(output_layout);
56       std::vector<std::vector<float>> matrix;
57       bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
58 
59       if (remapping) {
60         // Also ensure that (when remapping can take place), a maximum of one
61         // input channel is included per output. This knowledge will simplify
62         // the channel mixing algorithm since it allows us to find the only
63         // scale factor which equals 1.0 and copy that input to its
64         // corresponding output. If no such factor can be found, the
65         // corresponding output can be set to zero.
66         for (int i = 0; i < output_channels; i++) {
67           EXPECT_EQ(static_cast<size_t>(input_channels), matrix[i].size());
68           int num_input_channels_accounted_for_per_output = 0;
69           for (int j = 0; j < input_channels; j++) {
70             float scale = matrix[i][j];
71             if (scale > 0) {
72               EXPECT_EQ(scale, 1.0f);
73               num_input_channels_accounted_for_per_output++;
74             }
75           }
76           // Each output channel shall contain contribution from one or less
77           // input channels.
78           EXPECT_LE(num_input_channels_accounted_for_per_output, 1);
79         }
80       }
81     }
82   }
83 }
84 
85 // Verify channels are mixed and scaled correctly.
TEST(ChannelMixingMatrixTest,StereoToMono)86 TEST(ChannelMixingMatrixTest, StereoToMono) {
87   ChannelLayout input_layout = CHANNEL_LAYOUT_STEREO;
88   ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
89   ChannelMixingMatrix matrix_builder(
90       input_layout, ChannelLayoutToChannelCount(input_layout), output_layout,
91       ChannelLayoutToChannelCount(output_layout));
92   std::vector<std::vector<float>> matrix;
93   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
94 
95   //                      Input: stereo
96   //                      LEFT  RIGHT
97   // Output: mono CENTER  0.5   0.5
98   //
99   EXPECT_FALSE(remapping);
100   EXPECT_EQ(1u, matrix.size());
101   EXPECT_EQ(2u, matrix[0].size());
102   EXPECT_EQ(0.5f, matrix[0][0]);
103   EXPECT_EQ(0.5f, matrix[0][1]);
104 }
105 
TEST(ChannelMixingMatrixTest,MonoToStereo)106 TEST(ChannelMixingMatrixTest, MonoToStereo) {
107   ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
108   ChannelLayout output_layout = CHANNEL_LAYOUT_STEREO;
109   ChannelMixingMatrix matrix_builder(
110       input_layout, ChannelLayoutToChannelCount(input_layout), output_layout,
111       ChannelLayoutToChannelCount(output_layout));
112   std::vector<std::vector<float>> matrix;
113   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
114 
115   //                       Input: mono
116   //                       CENTER
117   // Output: stereo LEFT   1
118   //                RIGHT  1
119   //
120   EXPECT_TRUE(remapping);
121   EXPECT_EQ(2u, matrix.size());
122   EXPECT_EQ(1u, matrix[0].size());
123   EXPECT_EQ(1.0f, matrix[0][0]);
124   EXPECT_EQ(1u, matrix[1].size());
125   EXPECT_EQ(1.0f, matrix[1][0]);
126 }
127 
TEST(ChannelMixingMatrixTest,MonoToTwoOneWithoutVoIPAdjustments)128 TEST(ChannelMixingMatrixTest, MonoToTwoOneWithoutVoIPAdjustments) {
129   test::ScopedFieldTrials field_trials(
130       "WebRTC-VoIPChannelRemixingAdjustmentKillSwitch/Enabled/");
131   ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
132   ChannelLayout output_layout = CHANNEL_LAYOUT_2_1;
133   ChannelMixingMatrix matrix_builder(
134       input_layout, ChannelLayoutToChannelCount(input_layout), output_layout,
135       ChannelLayoutToChannelCount(output_layout));
136   std::vector<std::vector<float>> matrix;
137   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
138 
139   //                         Input: mono
140   //                         CENTER
141   // Output: 2.1 FRONT_LEFT  1
142   //             FRONT_RIGHT 1
143   //             BACK_CENTER 0
144   //
145   EXPECT_FALSE(remapping);
146   EXPECT_EQ(3u, matrix.size());
147   EXPECT_EQ(1u, matrix[0].size());
148   EXPECT_EQ(1.0f, matrix[0][0]);
149   EXPECT_EQ(1.0f, matrix[1][0]);
150   EXPECT_EQ(0.0f, matrix[2][0]);
151 }
152 
TEST(ChannelMixingMatrixTest,MonoToTwoOneWithVoIPAdjustments)153 TEST(ChannelMixingMatrixTest, MonoToTwoOneWithVoIPAdjustments) {
154   ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
155   ChannelLayout output_layout = CHANNEL_LAYOUT_2_1;
156   ChannelMixingMatrix matrix_builder(
157       input_layout, ChannelLayoutToChannelCount(input_layout), output_layout,
158       ChannelLayoutToChannelCount(output_layout));
159   std::vector<std::vector<float>> matrix;
160   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
161 
162   //                         Input: mono
163   //                         CENTER
164   // Output: 2.1 FRONT_LEFT  1
165   //             FRONT_RIGHT 1
166   //             BACK_CENTER 0
167   //
168   EXPECT_TRUE(remapping);
169   EXPECT_EQ(3u, matrix.size());
170   EXPECT_EQ(1u, matrix[0].size());
171   EXPECT_EQ(1.0f, matrix[0][0]);
172   EXPECT_EQ(1.0f, matrix[1][0]);
173   EXPECT_EQ(0.0f, matrix[2][0]);
174 }
175 
TEST(ChannelMixingMatrixTest,MonoToFiveOneWithoutVoIPAdjustments)176 TEST(ChannelMixingMatrixTest, MonoToFiveOneWithoutVoIPAdjustments) {
177   test::ScopedFieldTrials field_trials(
178       "WebRTC-VoIPChannelRemixingAdjustmentKillSwitch/Enabled/");
179   ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
180   ChannelLayout output_layout = CHANNEL_LAYOUT_5_1;
181   const int input_channels = ChannelLayoutToChannelCount(input_layout);
182   const int output_channels = ChannelLayoutToChannelCount(output_layout);
183   ChannelMixingMatrix matrix_builder(input_layout, input_channels,
184                                      output_layout, output_channels);
185   std::vector<std::vector<float>> matrix;
186   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
187   //                         Input: mono
188   //                         CENTER
189   // Output: 5.1 LEFT        0
190   //             RIGHT       0
191   //             CENTER      1
192   //             LFE         0
193   //             SIDE_LEFT   0
194   //             SIDE_RIGHT  0
195   //
196   EXPECT_TRUE(remapping);
197   EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
198   for (int n = 0; n < output_channels; n++) {
199     EXPECT_EQ(static_cast<size_t>(input_channels), matrix[n].size());
200     if (n == CENTER) {
201       EXPECT_EQ(1.0f, matrix[CENTER][0]);
202     } else {
203       EXPECT_EQ(0.0f, matrix[n][0]);
204     }
205   }
206 }
207 
TEST(ChannelMixingMatrixTest,MonoToFiveOneWithVoIPAdjustments)208 TEST(ChannelMixingMatrixTest, MonoToFiveOneWithVoIPAdjustments) {
209   ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
210   ChannelLayout output_layout = CHANNEL_LAYOUT_5_1;
211   const int input_channels = ChannelLayoutToChannelCount(input_layout);
212   const int output_channels = ChannelLayoutToChannelCount(output_layout);
213   ChannelMixingMatrix matrix_builder(input_layout, input_channels,
214                                      output_layout, output_channels);
215   std::vector<std::vector<float>> matrix;
216   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
217   //                         Input: mono
218   //                         CENTER
219   // Output: 5.1 LEFT        1
220   //             RIGHT       1
221   //             CENTER      0
222   //             LFE         0
223   //             SIDE_LEFT   0
224   //             SIDE_RIGHT  0
225   //
226   EXPECT_TRUE(remapping);
227   EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
228   for (int n = 0; n < output_channels; n++) {
229     EXPECT_EQ(static_cast<size_t>(input_channels), matrix[n].size());
230     if (n == LEFT || n == RIGHT) {
231       EXPECT_EQ(1.0f, matrix[n][0]);
232     } else {
233       EXPECT_EQ(0.0f, matrix[n][0]);
234     }
235   }
236 }
237 
TEST(ChannelMixingMatrixTest,MonoToSevenOneWithoutVoIPAdjustments)238 TEST(ChannelMixingMatrixTest, MonoToSevenOneWithoutVoIPAdjustments) {
239   test::ScopedFieldTrials field_trials(
240       "WebRTC-VoIPChannelRemixingAdjustmentKillSwitch/Enabled/");
241   ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
242   ChannelLayout output_layout = CHANNEL_LAYOUT_7_1;
243   const int input_channels = ChannelLayoutToChannelCount(input_layout);
244   const int output_channels = ChannelLayoutToChannelCount(output_layout);
245   ChannelMixingMatrix matrix_builder(input_layout, input_channels,
246                                      output_layout, output_channels);
247   std::vector<std::vector<float>> matrix;
248   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
249   //                         Input: mono
250   //                         CENTER
251   // Output: 7.1 LEFT        0
252   //             RIGHT       0
253   //             CENTER      1
254   //             LFE         0
255   //             SIDE_LEFT   0
256   //             SIDE_RIGHT  0
257   //             BACK_LEFT   0
258   //             BACK_RIGHT  0
259   //
260   EXPECT_TRUE(remapping);
261   EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
262   for (int n = 0; n < output_channels; n++) {
263     EXPECT_EQ(static_cast<size_t>(input_channels), matrix[n].size());
264     if (n == CENTER) {
265       EXPECT_EQ(1.0f, matrix[CENTER][0]);
266     } else {
267       EXPECT_EQ(0.0f, matrix[n][0]);
268     }
269   }
270 }
271 
TEST(ChannelMixingMatrixTest,MonoToSevenOneWithVoIPAdjustments)272 TEST(ChannelMixingMatrixTest, MonoToSevenOneWithVoIPAdjustments) {
273   ChannelLayout input_layout = CHANNEL_LAYOUT_MONO;
274   ChannelLayout output_layout = CHANNEL_LAYOUT_7_1;
275   const int input_channels = ChannelLayoutToChannelCount(input_layout);
276   const int output_channels = ChannelLayoutToChannelCount(output_layout);
277   ChannelMixingMatrix matrix_builder(input_layout, input_channels,
278                                      output_layout, output_channels);
279   std::vector<std::vector<float>> matrix;
280   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
281   //                         Input: mono
282   //                         CENTER
283   // Output: 7.1 LEFT        1
284   //             RIGHT       1
285   //             CENTER      0
286   //             LFE         0
287   //             SIDE_LEFT   0
288   //             SIDE_RIGHT  0
289   //             BACK_LEFT   0
290   //             BACK_RIGHT  0
291   //
292   EXPECT_TRUE(remapping);
293   EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
294   for (int n = 0; n < output_channels; n++) {
295     EXPECT_EQ(static_cast<size_t>(input_channels), matrix[n].size());
296     if (n == LEFT || n == RIGHT) {
297       EXPECT_EQ(1.0f, matrix[n][0]);
298     } else {
299       EXPECT_EQ(0.0f, matrix[n][0]);
300     }
301   }
302 }
303 
TEST(ChannelMixingMatrixTest,FiveOneToMono)304 TEST(ChannelMixingMatrixTest, FiveOneToMono) {
305   ChannelLayout input_layout = CHANNEL_LAYOUT_5_1;
306   ChannelLayout output_layout = CHANNEL_LAYOUT_MONO;
307   ChannelMixingMatrix matrix_builder(
308       input_layout, ChannelLayoutToChannelCount(input_layout), output_layout,
309       ChannelLayoutToChannelCount(output_layout));
310   std::vector<std::vector<float>> matrix;
311   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
312 
313   // Note: 1/sqrt(2) is shown as 0.707.
314   //
315   //                      Input: 5.1
316   //                      LEFT   RIGHT  CENTER  LFE    SIDE_LEFT  SIDE_RIGHT
317   // Output: mono CENTER  0.707  0.707  1       0.707  0.707      0.707
318   //
319   EXPECT_FALSE(remapping);
320   EXPECT_EQ(1u, matrix.size());
321   EXPECT_EQ(6u, matrix[0].size());
322   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[0][0]);
323   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[0][1]);
324   // The center channel will be mixed at scale 1.
325   EXPECT_EQ(1.0f, matrix[0][2]);
326   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[0][3]);
327   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[0][4]);
328   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[0][5]);
329 }
330 
TEST(ChannelMixingMatrixTest,FiveOneBackToStereo)331 TEST(ChannelMixingMatrixTest, FiveOneBackToStereo) {
332   // Front L, Front R, Front C, LFE, Back L, Back R
333   ChannelLayout input_layout = CHANNEL_LAYOUT_5_1_BACK;
334   ChannelLayout output_layout = CHANNEL_LAYOUT_STEREO;
335   const int input_channels = ChannelLayoutToChannelCount(input_layout);
336   const int output_channels = ChannelLayoutToChannelCount(output_layout);
337   ChannelMixingMatrix matrix_builder(input_layout, input_channels,
338                                      output_layout, output_channels);
339   std::vector<std::vector<float>> matrix;
340   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
341 
342   // Note: 1/sqrt(2) is shown as 0.707.
343   // Note: The Channels enumerator is given by {LEFT = 0, RIGHT, CENTER, LFE,
344   // BACK_LEFT, BACK_RIGHT,...}, hence we can use the enumerator values as
345   // indexes in the matrix when verifying the scaling factors.
346   //
347   //                      Input: 5.1
348   //                      LEFT   RIGHT  CENTER  LFE    BACK_LEFT  BACK_RIGHT
349   // Output: stereo LEFT  1      0      0.707   0.707  0.707      0
350   //                RIGHT 0      1      0.707   0.707  0          0.707
351   //
352   EXPECT_FALSE(remapping);
353   EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
354   EXPECT_EQ(static_cast<size_t>(input_channels), matrix[LEFT].size());
355   EXPECT_EQ(static_cast<size_t>(input_channels), matrix[RIGHT].size());
356   EXPECT_EQ(1.0f, matrix[LEFT][LEFT]);
357   EXPECT_EQ(1.0f, matrix[RIGHT][RIGHT]);
358   EXPECT_EQ(0.0f, matrix[LEFT][RIGHT]);
359   EXPECT_EQ(0.0f, matrix[RIGHT][LEFT]);
360   EXPECT_EQ(0.0f, matrix[LEFT][BACK_RIGHT]);
361   EXPECT_EQ(0.0f, matrix[RIGHT][BACK_LEFT]);
362   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[LEFT][CENTER]);
363   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[LEFT][LFE]);
364   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[LEFT][BACK_LEFT]);
365   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[RIGHT][CENTER]);
366   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[RIGHT][LFE]);
367   EXPECT_FLOAT_EQ(ChannelMixer::kHalfPower, matrix[RIGHT][BACK_RIGHT]);
368 }
369 
TEST(ChannelMixingMatrixTest,FiveOneToSevenOne)370 TEST(ChannelMixingMatrixTest, FiveOneToSevenOne) {
371   // Front L, Front R, Front C, LFE, Side L, Side R
372   ChannelLayout input_layout = CHANNEL_LAYOUT_5_1;
373   // Front L, Front R, Front C, LFE, Side L, Side R, Back L, Back R
374   ChannelLayout output_layout = CHANNEL_LAYOUT_7_1;
375   const int input_channels = ChannelLayoutToChannelCount(input_layout);
376   const int output_channels = ChannelLayoutToChannelCount(output_layout);
377   ChannelMixingMatrix matrix_builder(input_layout, input_channels,
378                                      output_layout, output_channels);
379   std::vector<std::vector<float>> matrix;
380   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
381 
382   //                        Input: 5.1
383   //                        LEFT   RIGHT  CENTER  LFE    SIDE_LEFT  SIDE_RIGHT
384   // Output: 7.1 LEFT       1      0      0       0      0          0
385   //             RIGHT      0      1      0       0      0          0
386   //             CENTER     0      0      1       0      0          0
387   //             LFE        0      0      0       1      0          0
388   //             SIDE_LEFT  0      0      0       0      1          0
389   //             SIDE_RIGHT 0      0      0       0      0          1
390   //             BACK_LEFT  0      0      0       0      0          0
391   //             BACK_RIGHT 0      0      0       0      0          0
392   //
393   EXPECT_TRUE(remapping);
394   EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
395   for (int i = 0; i < output_channels; i++) {
396     EXPECT_EQ(static_cast<size_t>(input_channels), matrix[i].size());
397     for (int j = 0; j < input_channels; j++) {
398       if (i == j) {
399         EXPECT_EQ(1.0f, matrix[i][j]);
400       } else {
401         EXPECT_EQ(0.0f, matrix[i][j]);
402       }
403     }
404   }
405 }
406 
TEST(ChannelMixingMatrixTest,StereoToFiveOne)407 TEST(ChannelMixingMatrixTest, StereoToFiveOne) {
408   ChannelLayout input_layout = CHANNEL_LAYOUT_STEREO;
409   ChannelLayout output_layout = CHANNEL_LAYOUT_5_1;
410   const int input_channels = ChannelLayoutToChannelCount(input_layout);
411   const int output_channels = ChannelLayoutToChannelCount(output_layout);
412   ChannelMixingMatrix matrix_builder(input_layout, input_channels,
413                                      output_layout, output_channels);
414   std::vector<std::vector<float>> matrix;
415   bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
416 
417   //                         Input: Stereo
418   //                         LEFT   RIGHT
419   // Output: 5.1 LEFT        1      0
420   //             RIGHT       0      1
421   //             CENTER      0      0
422   //             LFE         0      0
423   //             SIDE_LEFT   0      0
424   //             SIDE_RIGHT  0      0
425   //
426   EXPECT_TRUE(remapping);
427   EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
428   for (int n = 0; n < output_channels; n++) {
429     EXPECT_EQ(static_cast<size_t>(input_channels), matrix[n].size());
430     if (n == LEFT) {
431       EXPECT_EQ(1.0f, matrix[LEFT][LEFT]);
432       EXPECT_EQ(0.0f, matrix[LEFT][RIGHT]);
433     } else if (n == RIGHT) {
434       EXPECT_EQ(0.0f, matrix[RIGHT][LEFT]);
435       EXPECT_EQ(1.0f, matrix[RIGHT][RIGHT]);
436     } else {
437       EXPECT_EQ(0.0f, matrix[n][LEFT]);
438       EXPECT_EQ(0.0f, matrix[n][RIGHT]);
439     }
440   }
441 }
442 
TEST(ChannelMixingMatrixTest,DiscreteToDiscrete)443 TEST(ChannelMixingMatrixTest, DiscreteToDiscrete) {
444   const struct {
445     int input_channels;
446     int output_channels;
447   } test_case[] = {
448       {2, 2},
449       {2, 5},
450       {5, 2},
451   };
452 
453   for (size_t n = 0; n < arraysize(test_case); n++) {
454     int input_channels = test_case[n].input_channels;
455     int output_channels = test_case[n].output_channels;
456     ChannelMixingMatrix matrix_builder(CHANNEL_LAYOUT_DISCRETE, input_channels,
457                                        CHANNEL_LAYOUT_DISCRETE,
458                                        output_channels);
459     std::vector<std::vector<float>> matrix;
460     bool remapping = matrix_builder.CreateTransformationMatrix(&matrix);
461     EXPECT_TRUE(remapping);
462     EXPECT_EQ(static_cast<size_t>(output_channels), matrix.size());
463     for (int i = 0; i < output_channels; i++) {
464       EXPECT_EQ(static_cast<size_t>(input_channels), matrix[i].size());
465       for (int j = 0; j < input_channels; j++) {
466         if (i == j) {
467           EXPECT_EQ(1.0f, matrix[i][j]);
468         } else {
469           EXPECT_EQ(0.0f, matrix[i][j]);
470         }
471       }
472     }
473   }
474 }
475 
476 }  // namespace webrtc
477