mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	audioconvert: fix mono channel mix test
When we have a single MONO channel, distribute and average. Otherwise, use the logic to do proper mixing. Adjust the unit test accordingly.
This commit is contained in:
		
							parent
							
								
									ce02c7d435
								
							
						
					
					
						commit
						6b34b8c44e
					
				
					 4 changed files with 43 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -36,6 +36,10 @@
 | 
			
		|||
 | 
			
		||||
#include "channelmix-ops.h"
 | 
			
		||||
 | 
			
		||||
#undef SPA_LOG_TOPIC_DEFAULT
 | 
			
		||||
#define SPA_LOG_TOPIC_DEFAULT log_topic
 | 
			
		||||
struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.channelmix");
 | 
			
		||||
 | 
			
		||||
#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)
 | 
			
		||||
| 
						 | 
				
			
			@ -159,24 +163,30 @@ static int make_matrix(struct channelmix *mix)
 | 
			
		|||
 | 
			
		||||
	/* move the MONO mask to FRONT so that the lower bits can be shifted
 | 
			
		||||
	 * 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)
 | 
			
		||||
	if ((src_mask & (1Ull << SPA_AUDIO_CHANNEL_MONO)) != 0) {
 | 
			
		||||
		if (mix->src_chan == 1)
 | 
			
		||||
			src_mask = 0;
 | 
			
		||||
		else
 | 
			
		||||
			src_mask |= (1ULL << SPA_AUDIO_CHANNEL_FC);
 | 
			
		||||
	}
 | 
			
		||||
	if ((dst_mask & (1Ull << SPA_AUDIO_CHANNEL_MONO)) != 0) {
 | 
			
		||||
		if (mix->dst_chan == 1)
 | 
			
		||||
			dst_mask = 0;
 | 
			
		||||
		dst_mask |= (1ULL << SPA_AUDIO_CHANNEL_FC);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* shift so that bit 0 is FL */
 | 
			
		||||
	src_mask >>= 3;
 | 
			
		||||
	dst_mask >>= 3;
 | 
			
		||||
 | 
			
		||||
	/* unknown channels or just 1 channel */
 | 
			
		||||
	if (src_mask == 0 || mix->src_chan == 1 ||
 | 
			
		||||
	    dst_mask == 0 || mix->dst_chan == 1) {
 | 
			
		||||
		if (src_mask == FRONT && mix->src_chan == 1) {
 | 
			
		||||
	if (src_mask == 0 || dst_mask == 0) {
 | 
			
		||||
		if (mix->src_chan == 1) {
 | 
			
		||||
			/* one FC/MONO src goes everywhere */
 | 
			
		||||
			spa_log_debug(mix->log, "distribute FC/MONO");
 | 
			
		||||
			for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
 | 
			
		||||
				matrix[i][0]= 1.0f;
 | 
			
		||||
		} else if (dst_mask == FRONT && mix->dst_chan == 1) {
 | 
			
		||||
		} else if (mix->dst_chan == 1) {
 | 
			
		||||
			/* 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++)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,10 @@
 | 
			
		|||
#include <spa/utils/defs.h>
 | 
			
		||||
#include <spa/param/audio/raw.h>
 | 
			
		||||
 | 
			
		||||
#undef SPA_LOG_TOPIC_DEFAULT
 | 
			
		||||
#define SPA_LOG_TOPIC_DEFAULT log_topic
 | 
			
		||||
extern struct spa_log_topic *log_topic;
 | 
			
		||||
 | 
			
		||||
#include "crossover.h"
 | 
			
		||||
 | 
			
		||||
#define VOLUME_MIN 0.0f
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,9 +44,6 @@
 | 
			
		|||
 | 
			
		||||
#include "channelmix-ops.h"
 | 
			
		||||
 | 
			
		||||
#undef SPA_LOG_TOPIC_DEFAULT
 | 
			
		||||
#define SPA_LOG_TOPIC_DEFAULT log_topic
 | 
			
		||||
static struct spa_log_topic *log_topic = &SPA_LOG_TOPIC(0, "spa.channelmix");
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_RATE		48000
 | 
			
		||||
#define DEFAULT_CHANNELS	2
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,21 +68,36 @@ static void test_mix(uint32_t src_chan, uint32_t src_mask, uint32_t dst_chan, ui
 | 
			
		|||
	dump_matrix(&mix, coeff);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_1_N(void)
 | 
			
		||||
static void test_1_N_MONO(void)
 | 
			
		||||
{
 | 
			
		||||
	test_mix(1, _M(MONO), 2, _M(FL)|_M(FR),
 | 
			
		||||
			MATRIX(0.707107, 0.707107));
 | 
			
		||||
			MATRIX(1.0, 1.0));
 | 
			
		||||
	test_mix(1, _M(MONO), 3, _M(FL)|_M(FR)|_M(LFE),
 | 
			
		||||
			MATRIX(0.707107, 0.707107, 0.0));
 | 
			
		||||
			MATRIX(1.0, 1.0, 1.0));
 | 
			
		||||
	test_mix(1, _M(MONO), 4, _M(FL)|_M(FR)|_M(LFE)|_M(FC),
 | 
			
		||||
			MATRIX(0.0, 0.0, 1.0, 0.0));
 | 
			
		||||
			MATRIX(1.0, 1.0, 1.0, 1.0));
 | 
			
		||||
	test_mix(1, _M(MONO), 4, _M(FL)|_M(FR)|_M(RL)|_M(RR),
 | 
			
		||||
			MATRIX(0.707107, 0.707107, 0.0, 0.0));
 | 
			
		||||
			MATRIX(1.0, 1.0, 1.0, 1.0));
 | 
			
		||||
	test_mix(1, _M(MONO), 12, 0,
 | 
			
		||||
			MATRIX(1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
 | 
			
		||||
			       1.0, 1.0, 1.0, 1.0, 1.0, 1.0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_1_N_FC(void)
 | 
			
		||||
{
 | 
			
		||||
	test_mix(1, _M(FC), 2, _M(FL)|_M(FR),
 | 
			
		||||
			MATRIX(0.707107, 0.707107));
 | 
			
		||||
	test_mix(1, _M(FC), 3, _M(FL)|_M(FR)|_M(LFE),
 | 
			
		||||
			MATRIX(0.707107, 0.707107, 0.0));
 | 
			
		||||
	test_mix(1, _M(FC), 4, _M(FL)|_M(FR)|_M(LFE)|_M(FC),
 | 
			
		||||
			MATRIX(0.0, 0.0, 1.0, 0.0));
 | 
			
		||||
	test_mix(1, _M(FC), 4, _M(FL)|_M(FR)|_M(RL)|_M(RR),
 | 
			
		||||
			MATRIX(0.707107, 0.707107, 0.0, 0.0));
 | 
			
		||||
	test_mix(1, _M(FC), 12, 0,
 | 
			
		||||
			MATRIX(1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
 | 
			
		||||
			       1.0, 1.0, 1.0, 1.0, 1.0, 1.0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void test_N_1(void)
 | 
			
		||||
{
 | 
			
		||||
	test_mix(1, _M(MONO), 1, _M(MONO),
 | 
			
		||||
| 
						 | 
				
			
			@ -203,7 +218,8 @@ int main(int argc, char *argv[])
 | 
			
		|||
{
 | 
			
		||||
	logger.log.level = SPA_LOG_LEVEL_TRACE;
 | 
			
		||||
 | 
			
		||||
	test_1_N();
 | 
			
		||||
	test_1_N_MONO();
 | 
			
		||||
	test_1_N_FC();
 | 
			
		||||
	test_N_1();
 | 
			
		||||
	test_3p1_N();
 | 
			
		||||
	test_4_N();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue