2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* Spa
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-05 17:48:52 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * Copyright © 2018 Wim Taymans
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-05 17:48:52 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * Permission is hereby granted, free of charge, to any person obtaining a
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * copy of this software and associated documentation files (the "Software"),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * to deal in the Software without restriction, including without limitation
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * and/or sell copies of the Software, and to permit persons to whom the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Software is furnished to do so, subject to the following conditions:
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-05 17:48:52 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * The above copyright notice and this permission notice (including the next
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * paragraph) shall be included in all copies or substantial portions of the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Software.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * DEALINGS IN THE SOFTWARE.
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <string.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <stdio.h>
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <math.h>
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <spa/param/audio/format-utils.h>
							 | 
						
					
						
							
								
									
										
										
										
											2018-12-17 13:26:54 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <spa/support/cpu.h>
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <spa/support/log.h>
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <spa/utils/defs.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-07-03 21:34:22 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define VOLUME_MIN 0.0f
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define VOLUME_NORM 1.0f
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-28 21:07:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include "channelmix-ops.h"
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 09:41:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define _M(ch)		(1UL << SPA_AUDIO_CHANNEL_ ## ch)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MASK_MONO	_M(FC)|_M(MONO)|_M(UNKNOWN)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MASK_STEREO	_M(FL)|_M(FR)|_M(UNKNOWN)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MASK_QUAD	_M(FL)|_M(FR)|_M(RL)|_M(RR)|_M(UNKNOWN)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MASK_3_1	_M(FL)|_M(FR)|_M(FC)|_M(LFE)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MASK_5_1	_M(FL)|_M(FR)|_M(FC)|_M(LFE)|_M(SL)|_M(SR)|_M(RL)|_M(RR)
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-18 12:13:55 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define MASK_7_1	_M(FL)|_M(FR)|_M(FC)|_M(LFE)|_M(SL)|_M(SR)|_M(RL)|_M(RR)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-07 15:52:42 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define ANY	((uint32_t)-1)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define EQ	((uint32_t)-2)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								typedef void (*channelmix_func_t) (struct channelmix *mix, uint32_t n_dst, void * SPA_RESTRICT dst[n_dst],
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											uint32_t n_src, const void * SPA_RESTRICT src[n_src], uint32_t n_samples);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static const struct channelmix_info {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									uint32_t src_chan;
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 17:03:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									uint64_t src_mask;
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									uint32_t dst_chan;
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 17:03:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									uint64_t dst_mask;
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									channelmix_func_t process;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									uint32_t cpu_flags;
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									const char *name;
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								} channelmix_table[] =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-28 21:07:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#if defined (HAVE_SSE)
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 2, MASK_MONO, 2, MASK_MONO, channelmix_copy_sse, SPA_CPU_FLAG_SSE, "copy_sse" },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ 2, MASK_STEREO, 2, MASK_STEREO, channelmix_copy_sse, SPA_CPU_FLAG_SSE, "copy_sse" },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ EQ, 0, EQ, 0, channelmix_copy_sse, SPA_CPU_FLAG_SSE, "copy_sse" },
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 17:03:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 2, MASK_MONO, 2, MASK_MONO, channelmix_copy_c, 0, "copy_c" },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ 2, MASK_STEREO, 2, MASK_STEREO, channelmix_copy_c, 0, "copy_c" },
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-28 21:07:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ EQ, 0, EQ, 0, channelmix_copy_c, 0 },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 1, MASK_MONO, 2, MASK_STEREO, channelmix_f32_1_2_c, 0, "f32_1_2_c" },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ 2, MASK_STEREO, 1, MASK_MONO, channelmix_f32_2_1_c, 0, "f32_2_1_c" },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ 4, MASK_QUAD, 1, MASK_MONO, channelmix_f32_4_1_c, 0, "f32_4_1_c" },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ 4, MASK_3_1, 1, MASK_MONO, channelmix_f32_3p1_1_c, 0, "f32_3p1_1_c" },
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-28 21:07:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#if defined (HAVE_SSE)
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 2, MASK_STEREO, 4, MASK_QUAD, channelmix_f32_2_4_sse, SPA_CPU_FLAG_SSE, "f32_2_4_sse" },
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 17:03:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 2, MASK_STEREO, 4, MASK_QUAD, channelmix_f32_2_4_c, 0, "f32_2_4_c" },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ 2, MASK_STEREO, 4, MASK_3_1, channelmix_f32_2_3p1_c, 0, "f32_2_3p1_c" },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ 2, MASK_STEREO, 6, MASK_5_1, channelmix_f32_2_5p1_c, 0, "f32_2_5p1_c" },
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-28 21:07:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#if defined (HAVE_SSE)
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 6, MASK_5_1, 2, MASK_STEREO, channelmix_f32_5p1_2_sse, SPA_CPU_FLAG_SSE, "f32_5p1_2_sse" },
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 17:03:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 6, MASK_5_1, 2, MASK_STEREO, channelmix_f32_5p1_2_c, 0, "f32_5p1_2_c" },
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-28 21:07:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#if defined (HAVE_SSE)
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 6, MASK_5_1, 4, MASK_QUAD, channelmix_f32_5p1_4_sse, SPA_CPU_FLAG_SSE, "f32_5p1_4_sse" },
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 17:03:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 6, MASK_5_1, 4, MASK_QUAD, channelmix_f32_5p1_4_c, 0, "f32_5p1_4_c" },
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-21 16:45:31 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-28 21:07:53 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#if defined (HAVE_SSE)
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 6, MASK_5_1, 4, MASK_3_1, channelmix_f32_5p1_3p1_sse, SPA_CPU_FLAG_SSE, "f32_5p1_3p1_sse" },
							 | 
						
					
						
							
								
									
										
										
										
											2018-11-21 16:45:31 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 6, MASK_5_1, 4, MASK_3_1, channelmix_f32_5p1_3p1_c, 0, "f32_5p1_3p1_c" },
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-18 12:13:55 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ 8, MASK_7_1, 2, MASK_STEREO, channelmix_f32_7p1_2_c, 0, "f32_7p1_2_c" },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ 8, MASK_7_1, 4, MASK_QUAD, channelmix_f32_7p1_4_c, 0, "f32_7p1_4_c" },
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									{ 8, MASK_7_1, 4, MASK_3_1, channelmix_f32_7p1_3p1_c, 0, "f32_7p1_3p1_c" },
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-18 12:13:55 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									{ ANY, 0, ANY, 0, channelmix_f32_n_m_c, 0, "f32_n_m_c" },
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-07 15:52:42 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define MATCH_CHAN(a,b)		((a) == ANY || (a) == (b))
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define MATCH_CPU_FLAGS(a,b)	((a) == 0 || ((a) & (b)) == a)
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-18 12:13:55 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define MATCH_MASK(a,b)		((a) == 0 || ((a) & (b)) == (b))
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 17:03:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static const struct channelmix_info *find_channelmix_info(uint32_t src_chan, uint64_t src_mask,
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										uint32_t dst_chan, uint64_t dst_mask, uint32_t cpu_flags)
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-07 15:52:42 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									size_t i;
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 09:41:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									for (i = 0; i < SPA_N_ELEMENTS(channelmix_table); i++) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (!MATCH_CPU_FLAGS(channelmix_table[i].cpu_flags, cpu_flags))
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 09:41:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											continue;
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 09:41:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (src_chan == dst_chan && src_mask == dst_mask)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return &channelmix_table[i];
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-10 15:54:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (MATCH_CHAN(channelmix_table[i].src_chan, src_chan) &&
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-13 17:03:56 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										    MATCH_CHAN(channelmix_table[i].dst_chan, dst_chan) &&
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 09:41:41 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										    MATCH_MASK(channelmix_table[i].src_mask, src_mask) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										    MATCH_MASK(channelmix_table[i].dst_mask, dst_mask))
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-06 18:39:07 +02:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return &channelmix_table[i];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define SQRT3_2      1.224744871f  /* sqrt(3/2) */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define SQRT1_2      0.707106781f
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define SQRT2	     1.414213562f
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MATRIX_NORMAL	0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MATRIX_DOLBY	1
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MATRIX_DPLII	2
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define _CH(ch)		((SPA_AUDIO_CHANNEL_ ## ch)-3)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define _MASK(ch)	(1ULL << _CH(ch))
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define FRONT		(_MASK(FC))
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define STEREO		(_MASK(FL)|_MASK(FR))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define REAR		(_MASK(RL)|_MASK(RR))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define SIDE		(_MASK(SL)|_MASK(SR))
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static int make_matrix(struct channelmix *mix)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									float matrix[SPA_AUDIO_MAX_CHANNELS][SPA_AUDIO_MAX_CHANNELS] = {{ 0.0f }};
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									uint64_t src_mask = mix->src_mask;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									uint64_t dst_mask = mix->dst_mask;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									uint64_t unassigned;
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-14 14:56:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									uint32_t i, j, ic, jc, matrix_encoding = MATRIX_NORMAL;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									float clev = SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									float slev = SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									float llev = 0.5f;
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 12:00:46 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									float maxsum = 0.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-03 11:47:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									bool do_upmix = SPA_FLAG_IS_SET(mix->options, CHANNELMIX_OPTION_UPMIX);
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define _MATRIX(s,d)	matrix[_CH(s)][_CH(d)]
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-16 15:03:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spa_log_debug(mix->log, "src-mask:%08"PRIx64" dst-mask:%08"PRIx64,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											src_mask, dst_mask);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/* move the MONO mask to FRONT so that the lower bits can be shifted
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									 * away. */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if ((src_mask & (1Ull << SPA_AUDIO_CHANNEL_MONO)) != 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										src_mask |= (1ULL << SPA_AUDIO_CHANNEL_FC);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if ((dst_mask & (1Ull << SPA_AUDIO_CHANNEL_MONO)) != 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										dst_mask |= (1ULL << SPA_AUDIO_CHANNEL_FC);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* shift so that bit 0 is FL */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									src_mask >>= 3;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									dst_mask >>= 3;
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-16 15:03:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-04 13:41:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (src_mask == 0 || dst_mask == 0) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (src_mask == FRONT && mix->src_chan == 1) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											/* one FC/MONO src goes everywhere */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "distribute FC/MONO");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-15 17:51:07 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												matrix[i][0]= 1.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (dst_mask == FRONT && mix->dst_chan == 1) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											/* one FC/MONO dst get average of everything */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "average FC/MONO");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-15 17:51:07 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												matrix[0][i]= 1.0f / mix->src_chan;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											/* just pair channels */
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-28 20:29:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "pairing channels");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
							 | 
						
					
						
							
								
									
										
										
										
											2021-01-15 17:51:07 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												matrix[i][i]= 1.0f;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-04 13:41:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										src_mask = dst_mask = ~0LU;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto done;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										spa_log_debug(mix->log, "matching channels");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if ((src_mask & dst_mask & (1ULL << i))) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												spa_log_debug(mix->log, "matched %u", i);
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-04 13:41:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												matrix[i][i]= 1.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-04 13:41:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									unassigned = src_mask & ~dst_mask;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spa_log_debug(mix->log, "unassigned downmix %08" PRIx64, unassigned);
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (unassigned & FRONT){
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if ((dst_mask & STEREO) == STEREO){
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign FC to STEREO");
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if(src_mask & STEREO) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,FC) += clev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,FC) += clev;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											} else {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,FC) += SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,FC) += SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_warn(mix->log, "can't assign FC");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (unassigned & STEREO){
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (dst_mask & FRONT) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign STEREO to FC");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,FL) += SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,FR) += SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (src_mask & FRONT)
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FC,FC) = clev * SQRT2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_warn(mix->log, "can't assign STEREO");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (unassigned & _MASK(RC)) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (dst_mask & REAR){
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign RC to RL+RR");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RL,RC) += SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RR,RC) += SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (dst_mask & SIDE) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign RC to SL+SR");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(SL,RC) += SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(SR,RC) += SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if(dst_mask & STEREO) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign RC to FL+FR");
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (matrix_encoding == MATRIX_DOLBY ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											    matrix_encoding == MATRIX_DPLII) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												if (unassigned & (_MASK(RL)|_MASK(RR))) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
													_MATRIX(FL,RC) -= slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													_MATRIX(FR,RC) += slev * SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										                } else {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
													_MATRIX(FL,RC) -= slev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													_MATRIX(FR,RC) += slev;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											} else {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,RC) += slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,RC) += slev * SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (dst_mask & FRONT) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign RC to FC");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,RC) += slev * SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_warn(mix->log, "can't assign RC");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (unassigned & REAR) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (dst_mask & _MASK(RC)) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign RL+RR to RC");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RC,RL) += SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RC,RR) += SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (dst_mask & SIDE) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign RL+RR to SL+SR");
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (src_mask & SIDE) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(SL,RL) += SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(SR,RR) += SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											} else {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(SL,RL) += 1.0f;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(SR,RR) += 1.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (dst_mask & STEREO) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign RL+RR to FL+FR %f", slev);
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (matrix_encoding == MATRIX_DOLBY) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,RL) -= slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,RR) -= slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,RL) += slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,RR) += slev * SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											} else if (matrix_encoding == MATRIX_DPLII) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,RL) -= slev * SQRT3_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,RR) -= slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,RL) += slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,RR) += slev * SQRT3_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											} else {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,RL) += slev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,RR) += slev;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (dst_mask & FRONT) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign RL+RR to FC");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,RL)+= slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,RR)+= slev * SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_warn(mix->log, "can't assign RL");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (unassigned & SIDE) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (dst_mask & REAR) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign SL+SR to RL+RR");
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (src_mask & _MASK(RL)) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(RL,SL) += SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(RR,SR) += SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											} else {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(RL,SL) += 1.0f;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(RR,SR) += 1.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else if (dst_mask & _MASK(RC)) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign SL+SR to RC");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RC,SL)+= SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RC,SR)+= SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (dst_mask & STEREO) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign SL+SR to FL+FR");
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (matrix_encoding == MATRIX_DOLBY) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,SL) -= slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,SR) -= slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,SL) += slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,SR) += slev * SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											} else if (matrix_encoding == MATRIX_DPLII) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,SL) -= slev * SQRT3_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,SR) -= slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,SL) += slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,SR) += slev * SQRT3_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											} else {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FL,SL) += slev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												_MATRIX(FR,SR) += slev;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (dst_mask & FRONT) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign SL+SR to FC");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,SL) += slev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,SR) += slev * SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_warn(mix->log, "can't assign SL");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (unassigned & _MASK(FLC)) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (dst_mask & STEREO) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 12:00:13 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign FLC+FRC to FL+FR");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FL,FLC)+= 1.0f;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FR,FRC)+= 1.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if(dst_mask & FRONT) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign FLC+FRC to FC");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,FLC)+= SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,FRC)+= SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_warn(mix->log, "can't assign FLC");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-03 13:20:36 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (unassigned & _MASK(LFE) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    SPA_FLAG_IS_SET(mix->options, CHANNELMIX_OPTION_MIX_LFE)) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (dst_mask & FRONT) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign LFE to FC");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,LFE) += llev;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:29:36 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if (dst_mask & STEREO) {
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "assign LFE to FL+FR");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FL,LFE) += llev * SQRT1_2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FR,LFE) += llev * SQRT1_2;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_warn(mix->log, "can't assign LFE");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:31:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-03 11:47:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (!do_upmix)
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:31:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										goto done;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									unassigned = dst_mask & ~src_mask;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									spa_log_debug(mix->log, "unassigned upmix %08" PRIx64, unassigned);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (unassigned & FRONT) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:31:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if ((src_mask & STEREO) == STEREO) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "produce FC from STEREO");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,FL) += clev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(FC,FR) += clev;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:31:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_warn(mix->log, "can't produce FC");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-17 11:09:19 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (unassigned & _MASK(LFE) && mix->lfe_cutoff > 0.0f) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:31:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if ((src_mask & STEREO) == STEREO) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "produce LFE from STEREO");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(LFE,FL) += llev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(LFE,FR) += llev;
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if ((src_mask & FRONT) == FRONT) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "produce LFE from FC");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(LFE,FC) += llev;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:31:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_warn(mix->log, "can't produce LFE");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (unassigned & SIDE) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if ((src_mask & REAR) == REAR) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "produce SIDE from REAR");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(SL,RL) += 1.0f;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(SR,RR) += 1.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:31:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if ((src_mask & STEREO) == STEREO) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "produce SIDE from STEREO");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(SL,FL) += 1.0f;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(SR,FR) += 1.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if ((src_mask & FRONT) == FRONT) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "produce SIDE from FC");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(SL,FC) += clev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(SR,FC) += clev;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:31:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (unassigned & REAR) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if ((src_mask & SIDE) == SIDE) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "produce REAR from SIDE");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RL,SL) += 1.0f;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RR,SR) += 1.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:31:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if ((src_mask & STEREO) == STEREO) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "produce REAR from STEREO");
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RL,FL) += 1.0f;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RR,FR) += 1.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-27 18:08:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										} else if ((src_mask & FRONT) == FRONT) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "produce REAR from FC");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RL,FC) += clev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											_MATRIX(RR,FC) += clev;
							 | 
						
					
						
							
								
									
										
										
										
											2021-03-06 21:31:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-04 13:41:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								done:
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									for (jc = 0, ic = 0, i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										float sum = 0.0f;
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if ((dst_mask & (1UL << i)) == 0)
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											continue;
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-16 10:56:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										for (jc = 0, j = 0; j < SPA_AUDIO_MAX_CHANNELS; j++) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if ((src_mask & (1UL << j)) == 0)
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												continue;
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-14 14:56:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mix->matrix_orig[ic][jc++] = matrix[i][j];
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sum += fabs(matrix[i][j]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 12:00:46 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										maxsum = SPA_MAX(maxsum, sum);
							 | 
						
					
						
							
								
									
										
										
										
											2021-05-03 11:47:29 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (i == _CH(LFE) && do_upmix && mix->lfe_cutoff > 0.0f) {
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:34:14 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "channel %d is LFE", ic);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											lr4_set(&mix->lr4[ic], BQ_LOWPASS, mix->lfe_cutoff / mix->freq);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											mix->lr4_info[ic] = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											mix->lr4_info[ic] = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-14 14:56:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ic++;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 12:00:46 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (SPA_FLAG_IS_SET(mix->options, CHANNELMIX_OPTION_NORMALIZE) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    maxsum > 1.0f) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										for (i = 0; i < ic; i++)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											for (j = 0; j < jc; j++)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										                mix->matrix_orig[i][j] /= maxsum;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-12 14:47:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void impl_channelmix_set_volume(struct channelmix *mix, float volume, bool mute,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										uint32_t n_channel_volumes, float *channel_volumes)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									float volumes[SPA_AUDIO_MAX_CHANNELS];
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-02 18:36:42 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									float vol = mute ? 0.0f : volume, t;
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-12 14:47:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									uint32_t i, j;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									uint32_t src_chan = mix->src_chan;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									uint32_t dst_chan = mix->dst_chan;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spa_log_debug(mix->log, "volume:%f mute:%d n_volumes:%d", volume, mute, n_channel_volumes);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-12 14:47:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/** apply global volume to channels */
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									for (i = 0; i < n_channel_volumes; i++) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-12 14:47:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										volumes[i] = channel_volumes[i] * vol;
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-29 11:59:44 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										spa_log_debug(mix->log, "%d: %f * %f = %f", i, channel_volumes[i], vol, volumes[i]);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-12 14:47:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-03 13:20:36 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/** apply volumes per channel */
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-12 14:47:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (n_channel_volumes == src_chan) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										for (i = 0; i < dst_chan; i++) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											for (j = 0; j < src_chan; j++) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-14 14:56:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												mix->matrix[i][j] = mix->matrix_orig[i][j] * volumes[j];
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-12 14:47:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else if (n_channel_volumes == dst_chan) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										for (i = 0; i < dst_chan; i++) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											for (j = 0; j < src_chan; j++) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-14 14:56:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												mix->matrix[i][j] = mix->matrix_orig[i][j] * volumes[i];
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-12 14:47:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-03 13:20:36 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									SPA_FLAG_SET(mix->flags, CHANNELMIX_FLAG_ZERO);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									SPA_FLAG_SET(mix->flags, CHANNELMIX_FLAG_EQUAL);
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-04 13:41:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									SPA_FLAG_SET(mix->flags, CHANNELMIX_FLAG_COPY);
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-14 14:56:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-03 13:20:36 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									t = 0.0;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									for (i = 0; i < dst_chan; i++) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										for (j = 0; j < src_chan; j++) {
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-14 14:56:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											float v = mix->matrix[i][j];
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spa_log_debug(mix->log, "%d %d: %f", i, j, v);
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-14 14:56:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (i == 0 && j == 0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												t = v;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											else if (t != v)
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-03 13:20:36 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												SPA_FLAG_CLEAR(mix->flags, CHANNELMIX_FLAG_EQUAL);
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-14 14:56:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (v != 0.0)
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-03 13:20:36 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												SPA_FLAG_CLEAR(mix->flags, CHANNELMIX_FLAG_ZERO);
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if ((i == j && v != 1.0f) ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											    (i != j && v != 0.0f))
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-04 13:41:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												SPA_FLAG_CLEAR(mix->flags, CHANNELMIX_FLAG_COPY);
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-04 13:41:24 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									SPA_FLAG_UPDATE(mix->flags, CHANNELMIX_FLAG_IDENTITY,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											dst_chan == src_chan && SPA_FLAG_IS_SET(mix->flags, CHANNELMIX_FLAG_COPY));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-03 13:20:36 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spa_log_debug(mix->log, "flags:%08x", mix->flags);
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void impl_channelmix_free(struct channelmix *mix)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									mix->process = NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								int channelmix_init(struct channelmix *mix)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									const struct channelmix_info *info;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									info = find_channelmix_info(mix->src_chan, mix->src_mask, mix->dst_chan, mix->dst_mask,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											mix->cpu_flags);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (info == NULL)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return -ENOTSUP;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2021-04-26 17:33:45 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spa_log_debug(mix->log, "selected %s", info->name);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									mix->free = impl_channelmix_free;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									mix->process = info->process;
							 | 
						
					
						
							
								
									
										
										
										
											2019-08-12 14:47:16 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									mix->set_volume = impl_channelmix_set_volume;
							 | 
						
					
						
							
								
									
										
										
										
											2019-03-29 17:39:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									mix->cpu_flags = info->cpu_flags;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return make_matrix(mix);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |