Skip to content

Commit 56821c0

Browse files
committed
Audio: Up_down_mixer: Convert stubs with arithmetic to generic C
This patch adds more conversions those include simple arithmetic operations. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 1eec690 commit 56821c0

1 file changed

Lines changed: 99 additions & 3 deletions

File tree

src/audio/up_down_mixer/up_down_mixer_generic.c

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Author: Bartosz Kokoszko <bartoszx.kokoszko@intel.com>
66
// Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
77

8+
#include <sof/audio/format.h>
89
#include <errno.h>
910
#include <stddef.h>
1011
#include <stdint.h>
@@ -262,7 +263,86 @@ void downmix32bit_5_0_mono(struct up_down_mixer_data *cd, const uint8_t * const
262263
void downmix32bit_5_1(struct up_down_mixer_data *cd, const uint8_t * const in_data,
263264
const uint32_t in_size, uint8_t * const out_data)
264265
{
265-
sof_panic(0);
266+
const uint8_t left_slot = get_channel_location(cd->in_channel_map, CHANNEL_LEFT);
267+
const uint8_t center_slot = get_channel_location(cd->in_channel_map, CHANNEL_CENTER);
268+
const uint8_t right_slot = get_channel_location(cd->in_channel_map, CHANNEL_RIGHT);
269+
uint8_t left_surround_slot = get_channel_location(cd->in_channel_map, CHANNEL_LEFT_SURROUND);
270+
uint8_t right_surround_slot = get_channel_location(cd->in_channel_map, CHANNEL_RIGHT_SURROUND);
271+
const uint8_t lfe_slot = get_channel_location(cd->in_channel_map, CHANNEL_LFE);
272+
273+
/* Must support also 5.1 Surround */
274+
const bool surround_5_1_channel_map = (left_surround_slot == CHANNEL_INVALID) &&
275+
(right_surround_slot == CHANNEL_INVALID);
276+
277+
if (surround_5_1_channel_map) {
278+
left_surround_slot = get_channel_location(cd->in_channel_map, CHANNEL_LEFT_SIDE);
279+
right_surround_slot = get_channel_location(cd->in_channel_map, CHANNEL_RIGHT_SIDE);
280+
}
281+
282+
/* Load the downmix coefficients. */
283+
int32_t P_coefficient_left = cd->downmix_coefficients[CHANNEL_LEFT];
284+
int32_t P_coefficient_center = cd->downmix_coefficients[CHANNEL_CENTER];
285+
int32_t P_coefficient_right = cd->downmix_coefficients[CHANNEL_RIGHT];
286+
int32_t P_coefficient_left_surround = cd->downmix_coefficients[CHANNEL_LEFT_SURROUND];
287+
int32_t P_coefficient_right_surround = cd->downmix_coefficients[CHANNEL_RIGHT_SURROUND];
288+
int32_t P_coefficient_lfe = cd->downmix_coefficients[CHANNEL_LFE];
289+
290+
if (surround_5_1_channel_map) {
291+
P_coefficient_left_surround = cd->downmix_coefficients[CHANNEL_LEFT_SIDE];
292+
P_coefficient_right_surround = cd->downmix_coefficients[CHANNEL_RIGHT_SIDE];
293+
}
294+
295+
const int32_t *input_left = (int32_t *)(in_data + (left_slot << 2));
296+
const int32_t *input_center = (int32_t *)(in_data + (center_slot << 2));
297+
const int32_t *input_right = (int32_t *)(in_data + (right_slot << 2));
298+
const int32_t *input_left_surround = (int32_t *)(in_data + (left_surround_slot << 2));
299+
const int32_t *input_right_surround = (int32_t *)(in_data + (right_surround_slot << 2));
300+
const int32_t *input_lfe = (int32_t *)(in_data + (lfe_slot << 2));
301+
302+
/* Downmixer single store. */
303+
int32_t *output_left = (int32_t *)(out_data);
304+
int32_t *output_right = (int32_t *)(out_data + sizeof(int32_t));
305+
306+
/*
307+
* We don't need to initialize those registers in loop's body.
308+
* Using non accumulating multiplication for the first left,rignt channels
309+
* is more efficient.
310+
* For non 5.1 version we cannot use this optimization, we don't know
311+
* which channel is present and which multiplication should reset output
312+
* accumulators.
313+
*/
314+
int64_t Q_tmp_left;
315+
int64_t Q_tmp_right;
316+
317+
const int32_t *const end_input_left = input_left + (in_size / (sizeof(int32_t)));
318+
319+
while (input_left < end_input_left) {
320+
/* Accumulate as Q1.31 * Q1.31 -> Q2.62 */
321+
Q_tmp_left = (int64_t)P_coefficient_center * *input_center;
322+
input_center += 6;
323+
324+
Q_tmp_left += (int64_t)P_coefficient_lfe * *input_lfe;
325+
input_lfe += 6;
326+
Q_tmp_right = Q_tmp_left;
327+
328+
Q_tmp_left += (int64_t)P_coefficient_left * *input_left;
329+
input_left += 6;
330+
331+
Q_tmp_right += (int64_t)P_coefficient_right * *input_right;
332+
input_right += 6;
333+
334+
Q_tmp_left += (int64_t)P_coefficient_left_surround * *input_left_surround;
335+
input_left_surround += 6;
336+
337+
Q_tmp_right += (int64_t)P_coefficient_right_surround * *input_right_surround;
338+
input_right_surround += 6;
339+
340+
/* Shift with round to Q1.31 and saturate and store output */
341+
*output_left = sat_int32(Q_SHIFT_RND(Q_tmp_left, 62, 31));
342+
*output_right = sat_int32(Q_SHIFT_RND(Q_tmp_right, 62, 31));
343+
output_left += 2;
344+
output_right += 2;
345+
}
266346
}
267347

268348
void downmix32bit_7_1(struct up_down_mixer_data *cd, const uint8_t * const in_data,
@@ -274,7 +354,15 @@ void downmix32bit_7_1(struct up_down_mixer_data *cd, const uint8_t * const in_da
274354
void downmix16bit_stereo(struct up_down_mixer_data *cd, const uint8_t * const in_data,
275355
const uint32_t in_size, uint8_t * const out_data)
276356
{
277-
sof_panic(0);
357+
int32_t sum;
358+
const int16_t *in_data16 = (int16_t *)in_data;
359+
int16_t *out_data16 = (int16_t *)out_data;
360+
int idx;
361+
362+
for (idx = 0; idx < (in_size >> 2); ++idx) {
363+
sum = (int32_t)in_data16[2 * idx] + in_data16[2 * idx + 1];
364+
out_data16[idx] = sat_int16((sum + 1) >> 1);
365+
}
278366
}
279367

280368
void shiftcopy16bit_mono(struct up_down_mixer_data *cd, const uint8_t * const in_data,
@@ -326,7 +414,15 @@ void downmix16bit_4ch_mono(struct up_down_mixer_data *cd, const uint8_t * const
326414
void downmix32bit_stereo(struct up_down_mixer_data *cd, const uint8_t * const in_data,
327415
const uint32_t in_size, uint8_t * const out_data)
328416
{
329-
sof_panic(0);
417+
int64_t sum;
418+
int32_t *in_data32 = (int32_t *)in_data;
419+
int32_t *out_data32 = (int32_t *)out_data;
420+
int idx;
421+
422+
for (idx = 0; idx < (in_size >> 3); idx++) {
423+
sum = (int64_t)in_data32[2 * idx] + in_data32[2 * idx + 1];
424+
out_data32[idx] = sat_int32((sum + 1) >> 1);
425+
}
330426
}
331427

332428
void downmix32bit_3_1_mono(struct up_down_mixer_data *cd, const uint8_t * const in_data,

0 commit comments

Comments
 (0)