diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/mapping_matrix.c')
-rw-r--r-- | lib/rbcodec/codecs/libopus/mapping_matrix.c | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libopus/mapping_matrix.c b/lib/rbcodec/codecs/libopus/mapping_matrix.c new file mode 100644 index 0000000000..31298af057 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/mapping_matrix.c | |||
@@ -0,0 +1,378 @@ | |||
1 | /* Copyright (c) 2017 Google Inc. | ||
2 | Written by Andrew Allen */ | ||
3 | /* | ||
4 | Redistribution and use in source and binary forms, with or without | ||
5 | modification, are permitted provided that the following conditions | ||
6 | are met: | ||
7 | |||
8 | - Redistributions of source code must retain the above copyright | ||
9 | notice, this list of conditions and the following disclaimer. | ||
10 | |||
11 | - Redistributions in binary form must reproduce the above copyright | ||
12 | notice, this list of conditions and the following disclaimer in the | ||
13 | documentation and/or other materials provided with the distribution. | ||
14 | |||
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "arch.h" | ||
33 | #include "float_cast.h" | ||
34 | #include "opus_private.h" | ||
35 | #include "opus_defines.h" | ||
36 | #include "mapping_matrix.h" | ||
37 | |||
38 | #define MATRIX_INDEX(nb_rows, row, col) (nb_rows * col + row) | ||
39 | |||
40 | opus_int32 mapping_matrix_get_size(int rows, int cols) | ||
41 | { | ||
42 | opus_int32 size; | ||
43 | |||
44 | /* Mapping Matrix must only support up to 255 channels in or out. | ||
45 | * Additionally, the total cell count must be <= 65004 octets in order | ||
46 | * for the matrix to be stored in an OGG header. | ||
47 | */ | ||
48 | if (rows > 255 || cols > 255) | ||
49 | return 0; | ||
50 | size = rows * (opus_int32)cols * sizeof(opus_int16); | ||
51 | if (size > 65004) | ||
52 | return 0; | ||
53 | |||
54 | return align(sizeof(MappingMatrix)) + align(size); | ||
55 | } | ||
56 | |||
57 | opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix) | ||
58 | { | ||
59 | /* void* cast avoids clang -Wcast-align warning */ | ||
60 | return (opus_int16*)(void*)((char*)matrix + align(sizeof(MappingMatrix))); | ||
61 | } | ||
62 | |||
63 | void mapping_matrix_init(MappingMatrix * const matrix, | ||
64 | int rows, int cols, int gain, const opus_int16 *data, opus_int32 data_size) | ||
65 | { | ||
66 | int i; | ||
67 | opus_int16 *ptr; | ||
68 | |||
69 | #if !defined(ENABLE_ASSERTIONS) | ||
70 | (void)data_size; | ||
71 | #endif | ||
72 | celt_assert(align(data_size) == align(rows * cols * sizeof(opus_int16))); | ||
73 | |||
74 | matrix->rows = rows; | ||
75 | matrix->cols = cols; | ||
76 | matrix->gain = gain; | ||
77 | ptr = mapping_matrix_get_data(matrix); | ||
78 | for (i = 0; i < rows * cols; i++) | ||
79 | { | ||
80 | ptr[i] = data[i]; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | #ifndef DISABLE_FLOAT_API | ||
85 | void mapping_matrix_multiply_channel_in_float( | ||
86 | const MappingMatrix *matrix, | ||
87 | const float *input, | ||
88 | int input_rows, | ||
89 | opus_val16 *output, | ||
90 | int output_row, | ||
91 | int output_rows, | ||
92 | int frame_size) | ||
93 | { | ||
94 | /* Matrix data is ordered col-wise. */ | ||
95 | opus_int16* matrix_data; | ||
96 | int i, col; | ||
97 | |||
98 | celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); | ||
99 | |||
100 | matrix_data = mapping_matrix_get_data(matrix); | ||
101 | |||
102 | for (i = 0; i < frame_size; i++) | ||
103 | { | ||
104 | float tmp = 0; | ||
105 | for (col = 0; col < input_rows; col++) | ||
106 | { | ||
107 | tmp += | ||
108 | matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] * | ||
109 | input[MATRIX_INDEX(input_rows, col, i)]; | ||
110 | } | ||
111 | #if defined(FIXED_POINT) | ||
112 | output[output_rows * i] = FLOAT2INT16((1/32768.f)*tmp); | ||
113 | #else | ||
114 | output[output_rows * i] = (1/32768.f)*tmp; | ||
115 | #endif | ||
116 | } | ||
117 | } | ||
118 | |||
119 | void mapping_matrix_multiply_channel_out_float( | ||
120 | const MappingMatrix *matrix, | ||
121 | const opus_val16 *input, | ||
122 | int input_row, | ||
123 | int input_rows, | ||
124 | float *output, | ||
125 | int output_rows, | ||
126 | int frame_size | ||
127 | ) | ||
128 | { | ||
129 | /* Matrix data is ordered col-wise. */ | ||
130 | opus_int16* matrix_data; | ||
131 | int i, row; | ||
132 | float input_sample; | ||
133 | |||
134 | celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); | ||
135 | |||
136 | matrix_data = mapping_matrix_get_data(matrix); | ||
137 | |||
138 | for (i = 0; i < frame_size; i++) | ||
139 | { | ||
140 | #if defined(FIXED_POINT) | ||
141 | input_sample = (1/32768.f)*input[input_rows * i]; | ||
142 | #else | ||
143 | input_sample = input[input_rows * i]; | ||
144 | #endif | ||
145 | for (row = 0; row < output_rows; row++) | ||
146 | { | ||
147 | float tmp = | ||
148 | (1/32768.f)*matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] * | ||
149 | input_sample; | ||
150 | output[MATRIX_INDEX(output_rows, row, i)] += tmp; | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | #endif /* DISABLE_FLOAT_API */ | ||
155 | |||
156 | void mapping_matrix_multiply_channel_in_short( | ||
157 | const MappingMatrix *matrix, | ||
158 | const opus_int16 *input, | ||
159 | int input_rows, | ||
160 | opus_val16 *output, | ||
161 | int output_row, | ||
162 | int output_rows, | ||
163 | int frame_size) | ||
164 | { | ||
165 | /* Matrix data is ordered col-wise. */ | ||
166 | opus_int16* matrix_data; | ||
167 | int i, col; | ||
168 | |||
169 | celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); | ||
170 | |||
171 | matrix_data = mapping_matrix_get_data(matrix); | ||
172 | |||
173 | for (i = 0; i < frame_size; i++) | ||
174 | { | ||
175 | opus_val32 tmp = 0; | ||
176 | for (col = 0; col < input_rows; col++) | ||
177 | { | ||
178 | #if defined(FIXED_POINT) | ||
179 | tmp += | ||
180 | ((opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] * | ||
181 | (opus_int32)input[MATRIX_INDEX(input_rows, col, i)]) >> 8; | ||
182 | #else | ||
183 | tmp += | ||
184 | matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] * | ||
185 | input[MATRIX_INDEX(input_rows, col, i)]; | ||
186 | #endif | ||
187 | } | ||
188 | #if defined(FIXED_POINT) | ||
189 | output[output_rows * i] = (opus_int16)((tmp + 64) >> 7); | ||
190 | #else | ||
191 | output[output_rows * i] = (1/(32768.f*32768.f))*tmp; | ||
192 | #endif | ||
193 | } | ||
194 | } | ||
195 | |||
196 | void mapping_matrix_multiply_channel_out_short( | ||
197 | const MappingMatrix *matrix, | ||
198 | const opus_val16 *input, | ||
199 | int input_row, | ||
200 | int input_rows, | ||
201 | opus_int16 *output, | ||
202 | int output_rows, | ||
203 | int frame_size) | ||
204 | { | ||
205 | /* Matrix data is ordered col-wise. */ | ||
206 | opus_int16* matrix_data; | ||
207 | int i, row; | ||
208 | opus_int32 input_sample; | ||
209 | |||
210 | celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows); | ||
211 | |||
212 | matrix_data = mapping_matrix_get_data(matrix); | ||
213 | |||
214 | for (i = 0; i < frame_size; i++) | ||
215 | { | ||
216 | #if defined(FIXED_POINT) | ||
217 | input_sample = (opus_int32)input[input_rows * i]; | ||
218 | #else | ||
219 | input_sample = (opus_int32)FLOAT2INT16(input[input_rows * i]); | ||
220 | #endif | ||
221 | for (row = 0; row < output_rows; row++) | ||
222 | { | ||
223 | opus_int32 tmp = | ||
224 | (opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] * | ||
225 | input_sample; | ||
226 | output[MATRIX_INDEX(output_rows, row, i)] += (tmp + 16384) >> 15; | ||
227 | } | ||
228 | } | ||
229 | } | ||
230 | |||
231 | const MappingMatrix mapping_matrix_foa_mixing = { 6, 6, 0 }; | ||
232 | const opus_int16 mapping_matrix_foa_mixing_data[36] = { | ||
233 | 16384, 0, -16384, 23170, 0, 0, 16384, 23170, | ||
234 | 16384, 0, 0, 0, 16384, 0, -16384, -23170, | ||
235 | 0, 0, 16384, -23170, 16384, 0, 0, 0, | ||
236 | 0, 0, 0, 0, 32767, 0, 0, 0, | ||
237 | 0, 0, 0, 32767 | ||
238 | }; | ||
239 | |||
240 | const MappingMatrix mapping_matrix_soa_mixing = { 11, 11, 0 }; | ||
241 | const opus_int16 mapping_matrix_soa_mixing_data[121] = { | ||
242 | 10923, 7723, 13377, -13377, 11585, 9459, 7723, -16384, | ||
243 | -6689, 0, 0, 10923, 7723, 13377, 13377, -11585, | ||
244 | 9459, 7723, 16384, -6689, 0, 0, 10923, -15447, | ||
245 | 13377, 0, 0, -18919, 7723, 0, 13377, 0, | ||
246 | 0, 10923, 7723, -13377, -13377, 11585, -9459, 7723, | ||
247 | 16384, -6689, 0, 0, 10923, -7723, 0, 13377, | ||
248 | -16384, 0, -15447, 0, 9459, 0, 0, 10923, | ||
249 | -7723, 0, -13377, 16384, 0, -15447, 0, 9459, | ||
250 | 0, 0, 10923, 15447, 0, 0, 0, 0, | ||
251 | -15447, 0, -18919, 0, 0, 10923, 7723, -13377, | ||
252 | 13377, -11585, -9459, 7723, -16384, -6689, 0, 0, | ||
253 | 10923, -15447, -13377, 0, 0, 18919, 7723, 0, | ||
254 | 13377, 0, 0, 0, 0, 0, 0, 0, | ||
255 | 0, 0, 0, 0, 32767, 0, 0, 0, | ||
256 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
257 | 32767 | ||
258 | }; | ||
259 | |||
260 | const MappingMatrix mapping_matrix_toa_mixing = { 18, 18, 0 }; | ||
261 | const opus_int16 mapping_matrix_toa_mixing_data[324] = { | ||
262 | 8208, 0, -881, 14369, 0, 0, -8192, -4163, | ||
263 | 13218, 0, 0, 0, 11095, -8836, -6218, 14833, | ||
264 | 0, 0, 8208, -10161, 881, 10161, -13218, -2944, | ||
265 | -8192, 2944, 0, -10488, -6218, 6248, -11095, -6248, | ||
266 | 0, -10488, 0, 0, 8208, 10161, 881, -10161, | ||
267 | -13218, 2944, -8192, -2944, 0, 10488, -6218, -6248, | ||
268 | -11095, 6248, 0, 10488, 0, 0, 8176, 5566, | ||
269 | -11552, 5566, 9681, -11205, 8192, -11205, 0, 4920, | ||
270 | -15158, 9756, -3334, 9756, 0, -4920, 0, 0, | ||
271 | 8176, 7871, 11552, 0, 0, 15846, 8192, 0, | ||
272 | -9681, -6958, 0, 13797, 3334, 0, -15158, 0, | ||
273 | 0, 0, 8176, 0, 11552, 7871, 0, 0, | ||
274 | 8192, 15846, 9681, 0, 0, 0, 3334, 13797, | ||
275 | 15158, 6958, 0, 0, 8176, 5566, -11552, -5566, | ||
276 | -9681, -11205, 8192, 11205, 0, 4920, 15158, 9756, | ||
277 | -3334, -9756, 0, 4920, 0, 0, 8208, 14369, | ||
278 | -881, 0, 0, -4163, -8192, 0, -13218, -14833, | ||
279 | 0, -8836, 11095, 0, 6218, 0, 0, 0, | ||
280 | 8208, 10161, 881, 10161, 13218, 2944, -8192, 2944, | ||
281 | 0, 10488, 6218, -6248, -11095, -6248, 0, -10488, | ||
282 | 0, 0, 8208, -14369, -881, 0, 0, 4163, | ||
283 | -8192, 0, -13218, 14833, 0, 8836, 11095, 0, | ||
284 | 6218, 0, 0, 0, 8208, 0, -881, -14369, | ||
285 | 0, 0, -8192, 4163, 13218, 0, 0, 0, | ||
286 | 11095, 8836, -6218, -14833, 0, 0, 8176, -5566, | ||
287 | -11552, 5566, -9681, 11205, 8192, -11205, 0, -4920, | ||
288 | 15158, -9756, -3334, 9756, 0, -4920, 0, 0, | ||
289 | 8176, 0, 11552, -7871, 0, 0, 8192, -15846, | ||
290 | 9681, 0, 0, 0, 3334, -13797, 15158, -6958, | ||
291 | 0, 0, 8176, -7871, 11552, 0, 0, -15846, | ||
292 | 8192, 0, -9681, 6958, 0, -13797, 3334, 0, | ||
293 | -15158, 0, 0, 0, 8176, -5566, -11552, -5566, | ||
294 | 9681, 11205, 8192, 11205, 0, -4920, -15158, -9756, | ||
295 | -3334, -9756, 0, 4920, 0, 0, 8208, -10161, | ||
296 | 881, -10161, 13218, -2944, -8192, -2944, 0, -10488, | ||
297 | 6218, 6248, -11095, 6248, 0, 10488, 0, 0, | ||
298 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
299 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
300 | 32767, 0, 0, 0, 0, 0, 0, 0, | ||
301 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
302 | 0, 0, 0, 32767 | ||
303 | }; | ||
304 | |||
305 | const MappingMatrix mapping_matrix_foa_demixing = { 6, 6, 0 }; | ||
306 | const opus_int16 mapping_matrix_foa_demixing_data[36] = { | ||
307 | 16384, 16384, 16384, 16384, 0, 0, 0, 23170, | ||
308 | 0, -23170, 0, 0, -16384, 16384, -16384, 16384, | ||
309 | 0, 0, 23170, 0, -23170, 0, 0, 0, | ||
310 | 0, 0, 0, 0, 32767, 0, 0, 0, | ||
311 | 0, 0, 0, 32767 | ||
312 | }; | ||
313 | |||
314 | const MappingMatrix mapping_matrix_soa_demixing = { 11, 11, 3050 }; | ||
315 | const opus_int16 mapping_matrix_soa_demixing_data[121] = { | ||
316 | 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771, | ||
317 | 2771, 0, 0, 10033, 10033, -20066, 10033, 14189, | ||
318 | 14189, -28378, 10033, -20066, 0, 0, 3393, 3393, | ||
319 | 3393, -3393, 0, 0, 0, -3393, -3393, 0, | ||
320 | 0, -17378, 17378, 0, -17378, -24576, 24576, 0, | ||
321 | 17378, 0, 0, 0, -14189, 14189, 0, -14189, | ||
322 | -28378, 28378, 0, 14189, 0, 0, 0, 2399, | ||
323 | 2399, -4799, -2399, 0, 0, 0, -2399, 4799, | ||
324 | 0, 0, 1959, 1959, 1959, 1959, -3918, -3918, | ||
325 | -3918, 1959, 1959, 0, 0, -4156, 4156, 0, | ||
326 | 4156, 0, 0, 0, -4156, 0, 0, 0, | ||
327 | 8192, 8192, -16384, 8192, 16384, 16384, -32768, 8192, | ||
328 | -16384, 0, 0, 0, 0, 0, 0, 0, | ||
329 | 0, 0, 0, 0, 8312, 0, 0, 0, | ||
330 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
331 | 8312 | ||
332 | }; | ||
333 | |||
334 | const MappingMatrix mapping_matrix_toa_demixing = { 18, 18, 0 }; | ||
335 | const opus_int16 mapping_matrix_toa_demixing_data[324] = { | ||
336 | 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, | ||
337 | 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, | ||
338 | 0, 0, 0, -9779, 9779, 6263, 8857, 0, | ||
339 | 6263, 13829, 9779, -13829, 0, -6263, 0, -8857, | ||
340 | -6263, -9779, 0, 0, -3413, 3413, 3413, -11359, | ||
341 | 11359, 11359, -11359, -3413, 3413, -3413, -3413, -11359, | ||
342 | 11359, 11359, -11359, 3413, 0, 0, 13829, 9779, | ||
343 | -9779, 6263, 0, 8857, -6263, 0, 9779, 0, | ||
344 | -13829, 6263, -8857, 0, -6263, -9779, 0, 0, | ||
345 | 0, -15617, -15617, 6406, 0, 0, -6406, 0, | ||
346 | 15617, 0, 0, -6406, 0, 0, 6406, 15617, | ||
347 | 0, 0, 0, -5003, 5003, -10664, 15081, 0, | ||
348 | -10664, -7075, 5003, 7075, 0, 10664, 0, -15081, | ||
349 | 10664, -5003, 0, 0, -8176, -8176, -8176, 8208, | ||
350 | 8208, 8208, 8208, -8176, -8176, -8176, -8176, 8208, | ||
351 | 8208, 8208, 8208, -8176, 0, 0, -7075, 5003, | ||
352 | -5003, -10664, 0, 15081, 10664, 0, 5003, 0, | ||
353 | 7075, -10664, -15081, 0, 10664, -5003, 0, 0, | ||
354 | 15617, 0, 0, 0, -6406, 6406, 0, -15617, | ||
355 | 0, -15617, 15617, 0, 6406, -6406, 0, 0, | ||
356 | 0, 0, 0, -11393, 11393, 2993, -4233, 0, | ||
357 | 2993, -16112, 11393, 16112, 0, -2993, 0, 4233, | ||
358 | -2993, -11393, 0, 0, 0, -9974, -9974, -13617, | ||
359 | 0, 0, 13617, 0, 9974, 0, 0, 13617, | ||
360 | 0, 0, -13617, 9974, 0, 0, 0, 5579, | ||
361 | -5579, 10185, 14403, 0, 10185, -7890, -5579, 7890, | ||
362 | 0, -10185, 0, -14403, -10185, 5579, 0, 0, | ||
363 | 11826, -11826, -11826, -901, 901, 901, -901, 11826, | ||
364 | -11826, 11826, 11826, -901, 901, 901, -901, -11826, | ||
365 | 0, 0, -7890, -5579, 5579, 10185, 0, 14403, | ||
366 | -10185, 0, -5579, 0, 7890, 10185, -14403, 0, | ||
367 | -10185, 5579, 0, 0, -9974, 0, 0, 0, | ||
368 | -13617, 13617, 0, 9974, 0, 9974, -9974, 0, | ||
369 | 13617, -13617, 0, 0, 0, 0, 16112, -11393, | ||
370 | 11393, -2993, 0, 4233, 2993, 0, -11393, 0, | ||
371 | -16112, -2993, -4233, 0, 2993, 11393, 0, 0, | ||
372 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
373 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
374 | 32767, 0, 0, 0, 0, 0, 0, 0, | ||
375 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
376 | 0, 0, 0, 32767 | ||
377 | }; | ||
378 | |||