⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 downmix.c

📁 关于AC3的解码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	sam1 = samples->channel[1];
	sam2 = samples->channel[2];
	sam3 = samples->channel[3];

	/* AC3 3/1.1 channel downmix, 3 front, 1 rear channel, lfe */
	for ( i=0; i < 256; ++i )
	{
		left = *sam0++ * lrmixgain;
		center= *sam1++ * cmixgain;
		right = *sam2++ * lrmixgain;
		rear = *sam3++ * smixgain * SQRT2_2;

		Acc1 = ( 2 + left + center - rear ) >> 2;
		Acc2 = ( 2 + right+ center + rear ) >> 2;

		*out_samples++ = Acc1;
		*out_samples++ = Acc2;
	}
}


/* AC3 3/0.1 channel downmix, 3 front, LFE */
void
mix301to20( stream_samples_t *samples, sint_16 *out_samples )
{
	int i;

	sint_32 left,	/* source-sample front left */
		center,	/* source-sample front center */
		right,  /* source-sample front right */
		lfe;	/* low frequency effects channel */

	sint_16 Acc1, Acc2; /* accumulators */
	register float *sam0, *sam1, *sam2, *sam5;


	sam0 = samples->channel[0];
	sam1 = samples->channel[1];
	sam2 = samples->channel[2];
	sam5 = samples->channel[5];

	/* AC3 3/0.1 channel downmix, 3 front, lfe */
	for ( i=0; i < 256; ++i )
	{
		left = *sam0++ * lrmixgain;
		center= *sam1++ * cmixgain;
		right = *sam2++ * lrmixgain;
		lfe = *sam5++ * lfemixgain;

		Acc1 = ( 2 + left + center + lfe ) >> 2;
		Acc2 = ( 2 + right+ center + lfe ) >> 2;

		*out_samples++ = Acc1;
		*out_samples++ = Acc2;
	}
}


/* AC3 3/0.0 channel downmix, 3 front */
void
mix300to20( stream_samples_t *samples, sint_16 *out_samples )
{
	int i;

	sint_32 left,	/* source-sample front left */
		center,	/* source-sample front center */
		right;  /* source-sample front right */

	sint_16 Acc1, Acc2; /* accumulators */
	register float *sam0, *sam1, *sam2;


	sam0 = samples->channel[0];
	sam1 = samples->channel[1];
	sam2 = samples->channel[2];

	/* AC3 3/0.0 channel downmix, 3 front */
	for ( i=0; i < 256; ++i )
	{
		left = *sam0++ * lrmixgain;
		center= *sam1++ * cmixgain;
		right = *sam2++ * lrmixgain;

		Acc1 = ( 2 + left + center ) >> 2;
		Acc2 = ( 2 + right+ center ) >> 2;

		*out_samples++ = Acc1;
		*out_samples++ = Acc2;
	}
}


/* AC3 2/1.1 channel downmix, 2 front, 1 rear channel, LFE */
void
mix211to20( stream_samples_t *samples, sint_16 *out_samples )
{
	int i;

	sint_32 left,	/* source-sample front left */
		right,  /* source-sample front right */
		rear,  /* source-sample (mono) rear */
		lfe;	/* low frequency effects channel */

	sint_16 Acc1, Acc2; /* accumulators */
	register float *sam0, *sam1, *sam2, *sam5;


	sam0 = samples->channel[0];
	sam1 = samples->channel[1];
	sam2 = samples->channel[2];
	sam5 = samples->channel[5];

	/* AC3 2/1.1 channel downmix, 2 front, 1 rear channel, lfe */
	for ( i=0; i < 256; ++i )
	{
		left = *sam0++ * lrmixgain;
		right = *sam1++ * lrmixgain;
		rear = *sam2++ * smixgain * SQRT2_2;
		lfe = *sam5++ * lfemixgain;

		Acc1 = ( 2 + left + lfe - rear ) >> 2;
		Acc2 = ( 2 + right+ lfe + rear ) >> 2;

		*out_samples++ = Acc1;
		*out_samples++ = Acc2;
	}
}



/* AC3 2/1.0 channel downmix, 2 front, 1 rear channel */
void mix210to20( stream_samples_t *samples, sint_16 *out_samples )
{
	int i;

	sint_32 left,	/* source-sample front left */
		right,  /* source-sample front right */
		rear;  /* source-sample (mono) rear */

	register sint_16 Acc1, Acc2; /* accumulators */
	register float *sam0, *sam1, *sam2;


	sam0 = samples->channel[0];
	sam1 = samples->channel[1];
	sam2 = samples->channel[2];

	/* AC3 2/1.1 channel downmix, 2 front, 1 rear channel */
	for ( i=0; i < 256; ++i )
	{
		left = *sam0++ * lrmixgain;
		right = *sam1++ * lrmixgain;
		rear = *sam2++ * smixgain * SQRT2_2;

		Acc1 = ( 2 + left  - rear ) >> 2;
		Acc2 = ( 2 + right + rear ) >> 2;

		*out_samples++ = Acc1;
		*out_samples++ = Acc2;
	}
}


/* AC3 2 channel downmix, LFE */
void mix201to20( stream_samples_t *samples, sint_16 *out_samples )
{
	int i;
	register float *lsam, *rsam, *lfesam;
	register sint_32 left,	/* source-sample front left */
		right,  /* source-sample front right */
		lfe;	/* low frequency effects channel */

	sint_16 Acc1, Acc2; /* accumulators */

	lsam = samples->channel[0];
	rsam = samples->channel[1];
	lfesam = samples->channel[5];

	/* AC3 2/0.1 or 1/1.1 channel downmix, 2 front, lfe */
	for ( i=0; i < 256; ++i )
	{
		left = *lsam++ * lrmixgain;
		right = *rsam++ * lrmixgain;
		lfe = *lfesam++ * lfemixgain;

		lfe += 2;

		Acc1 = ( left + lfe ) >> 2;
		Acc2 = ( right+ lfe ) >> 2;

		*out_samples++ = Acc1;
		*out_samples++ = Acc2;

	}
}

void mix200to20( stream_samples_t *samples, sint_16 *out_samples )
{
	int i;
	register float *lsam, *rsam;

	lsam = samples->channel[0];
	rsam = samples->channel[1];

	/* AC3 2/0.0 or 1/1.0 channel downmix, 2 front */
	for ( i=0; i < 256; ++i ){
		*out_samples++ = (sint_16) (*lsam++ * lrmixgain);		//left = samples->channel[0][i] * lrmixgain;
		*out_samples++ = (sint_16) (*rsam++ * lrmixgain);		//right = samples->channel[1][i] * lrmixgain;
	}
}



/* AC3 1 channel downmix */
void
mix101to20( stream_samples_t *samples, sint_16 *out_samples )
{
	int i;

	sint_32 center,	/* front center */
		lfe;	/* low frequency effects channel */

	sint_16 Acc1; /* accumulators */
	register float *sam0, *sam5;


	sam0 = samples->channel[0];
	sam5 = samples->channel[5];

	/* AC3 1/0.1 channel downmix, 2 front, lfe */
	for ( i=0; i < 256; ++i )
	{
		center = *sam0++ * cmixgain;
		lfe = *sam5++ * lfemixgain;

		Acc1 = ( 2 + center+ lfe ) >> 2;
		*out_samples++ = Acc1;
		*out_samples++ = Acc1;
	}
}


/* AC3 1 channel downmix */
void
mix100to20( stream_samples_t *samples, sint_16 *out_samples )
{
	int i;

	sint_16 center;	/* front center */
	register float *sam0;

	sam0 = samples->channel[0];
	/* AC3 1/0.0 channel downmix, 1 front */
	for ( i=0; i < 256; ++i )
	{
		center = *sam0++ * cmixgain;
		*out_samples++ = center;
		*out_samples++ = center;
	}
}




//Pre-scaled downmix coefficients
static float cmixlev_lut[4] = { 0.2928, 0.2468, 0.2071, 0.2468 };
static float smixlev_lut[4] = { 0.2928, 0.2071, 0.0   , 0.2071 };



/* master downmix function */
void
downmix( stream_samples_t *samples, sint_16 *out_samples, bsi_t *bsi, int keep51output )
{
	/* process the bsi mixlevel directives.  These directives influence
	   the decoder. */

	clev = cmixlev_lut[bsi->cmixlev];
	slev = smixlev_lut[bsi->surmixlev];
	
	
	switch( bsi->cmixlev )
	{
		case 0 : // -3.0dB
			cmixgain = SQRT2_2;
			break;
		case 1 : // -4.5dB
			cmixgain = 0.595662143;
			break;
		case 2 : // -6.0dB
			cmixgain = 0.5;
			break;
		case 3 : // reserved, use -4.5dB
			cmixgain = 0.595662143;
			break;
		default :
			fprintf( stderr, "\ndownmix.c : unknown bsi.cmixlev ( %u )", bsi->cmixlev );
	}

	switch( bsi->surmixlev )
	{
		case 0 : // -3.0dB
			smixgain = SQRT2_2;
			break;
		case 1 : // -6.0dB
			smixgain = 0.5;
			break;
		case 2 : // +0.0 dB
			smixgain = 1;
			break;
		case 3 : // reserved, use +0.0 dB
			smixgain = 1;
			break;
		default :
			fprintf( stderr, "\ndownmix.c : unknown bsi.surmixlev ( %u )", bsi->surmixlev );
	}

	PerformPreSampleGain( samples );

	lfemixgain = 3.16227766; /* +10dB */
	lrmixgain = 1.0; /* +0.0dB */

	lrmixgain *= GAINSCALE;
	cmixgain *= GAINSCALE;
	smixgain *= GAINSCALE;
	lfemixgain *= SQRT2_2 * GAINSCALE;

	if ( bsi->lfeon )
	{	// lfe on, "X.1"
		//printf( "Doing bsi->acmod=%d\n", bsi->acmod );
		switch ( bsi->acmod )
		{
			case 0:  // 1 + 1, dual-mono, lfe
				lrmixgain = cmixgain * GAINSCALE;
				mix201to20( samples, out_samples );
				break;
			case 1:  // 1, mono, lfe
				cmixgain *= SQRT2_2 * GAINSCALE;
				mix101to20( samples, out_samples );
				break;
			case 2:  // 2-channel stereo, lfe
				mix201to20( samples, out_samples );
				break;
			case 3:  // 3-front, lfe
				mix301to20( samples, out_samples );
				break;
			case 4:  // 2-front, 1-rear, lfe
				mix211to20( samples, out_samples );
				break;
			case 5:  // 3-front, 1-rear, lfe
				mix311to20( samples, out_samples );
				break;
			case 6:  // 2-front, 2-rear, lfe
				mix221to20( samples, out_samples );
				break;
			case 7:  // 3-front, 2-rear, lfe
				mix321to20( samples, out_samples, keep51output );
				//downmix_3f_2r_to_2ch( samples, out_samples );
				break;
			default :
			;
		}	// endswitch ( bsi->acmod )
	} // endif ( bsi->lfeon )
	else
	{ // lfe off, "X.0" 
		//printf( "Doing bsi->acmod=%d\n", bsi->acmod );
		switch ( bsi->acmod )
		{
			case 0:  // 1 + 1, dual-mono
				lrmixgain = cmixgain * GAINSCALE;
				mix200to20( samples, out_samples );
				break;
			case 1:  // 1, mono,
				cmixgain *= SQRT2_2 * GAINSCALE;
				mix100to20( samples, out_samples );
				break;
			case 2:  // 2-channel stereo,
				mix200to20( samples, out_samples );
				break;
			case 3:  // 3-front
				mix300to20( samples, out_samples );
				break;
			case 4:  // 2-front, 1-rear
				mix210to20( samples, out_samples );
				break;
			case 5:  // 3-front, 1-rear
				mix310to20( samples, out_samples );
				break;
			case 6:  // 2-front, 2-rear
				mix220to20( samples, out_samples );
				break;
			case 7:  // 3-front, 2-rear
				mix320to20( samples, out_samples );
				break;
			default :
				;
		}	// endswitch ( bsi->acmod )
	} // endif ( bsi->lfeon )

	// only gain on 2.0 output
	if ( !keep51output ){
		PerformGlobalGain( out_samples );
		PerformCurvedGlobalGain( out_samples );
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -