📄 downmix.c
字号:
}
}
static void mix32toS (sample_t * samples, sample_t bias)
{
int i;
sample_t common, surround;
for (i = 0; i < 256; i++) {
common = samples[i + 256] + bias;
surround = samples[i + 768] + samples[i + 1024];
samples[i] += common - surround;
samples[i + 256] = samples[i + 512] + common + surround;
}
}
static void move2to1 (sample_t * src, sample_t * dest, sample_t bias)
{
int i;
for (i = 0; i < 256; i++)
dest[i] = src[i] + src[i + 256] + bias;
}
static void zero (sample_t * samples)
{
int i;
for (i = 0; i < 256; i++)
samples[i] = 0;
}
static void downmix_C (sample_t * samples, int acmod, int output, sample_t bias,
sample_t clev, sample_t slev)
{
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
case CONVERT (A52_CHANNEL, A52_CHANNEL2):
memcpy (samples, samples + 256, 256 * sizeof (sample_t));
break;
case CONVERT (A52_CHANNEL, A52_MONO):
case CONVERT (A52_STEREO, A52_MONO):
mix_2to1:
mix2to1 (samples, samples + 256, bias);
break;
case CONVERT (A52_2F1R, A52_MONO):
if (slev == 0)
goto mix_2to1;
case CONVERT (A52_3F, A52_MONO):
mix_3to1:
mix3to1 (samples, bias);
break;
case CONVERT (A52_3F1R, A52_MONO):
if (slev == 0)
goto mix_3to1;
case CONVERT (A52_2F2R, A52_MONO):
if (slev == 0)
goto mix_2to1;
mix4to1 (samples, bias);
break;
case CONVERT (A52_3F2R, A52_MONO):
if (slev == 0)
goto mix_3to1;
mix5to1 (samples, bias);
break;
case CONVERT (A52_MONO, A52_DOLBY):
memcpy (samples + 256, samples, 256 * sizeof (sample_t));
break;
case CONVERT (A52_3F, A52_STEREO):
case CONVERT (A52_3F, A52_DOLBY):
mix_3to2:
mix3to2 (samples, bias);
break;
case CONVERT (A52_2F1R, A52_STEREO):
if (slev == 0)
break;
mix21to2 (samples, samples + 256, bias);
break;
case CONVERT (A52_2F1R, A52_DOLBY):
mix21toS (samples, bias);
break;
case CONVERT (A52_3F1R, A52_STEREO):
if (slev == 0)
goto mix_3to2;
mix31to2 (samples, bias);
break;
case CONVERT (A52_3F1R, A52_DOLBY):
mix31toS (samples, bias);
break;
case CONVERT (A52_2F2R, A52_STEREO):
if (slev == 0)
break;
mix2to1 (samples, samples + 512, bias);
mix2to1 (samples + 256, samples + 768, bias);
break;
case CONVERT (A52_2F2R, A52_DOLBY):
mix22toS (samples, bias);
break;
case CONVERT (A52_3F2R, A52_STEREO):
if (slev == 0)
goto mix_3to2;
mix32to2 (samples, bias);
break;
case CONVERT (A52_3F2R, A52_DOLBY):
mix32toS (samples, bias);
break;
case CONVERT (A52_3F1R, A52_3F):
if (slev == 0)
break;
mix21to2 (samples, samples + 512, bias);
break;
case CONVERT (A52_3F2R, A52_3F):
if (slev == 0)
break;
mix2to1 (samples, samples + 768, bias);
mix2to1 (samples + 512, samples + 1024, bias);
break;
case CONVERT (A52_3F1R, A52_2F1R):
mix3to2 (samples, bias);
memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
break;
case CONVERT (A52_2F2R, A52_2F1R):
mix2to1 (samples + 512, samples + 768, bias);
break;
case CONVERT (A52_3F2R, A52_2F1R):
mix3to2 (samples, bias); //FIXME possible bug? (output doesnt seem to be used)
move2to1 (samples + 768, samples + 512, bias);
break;
case CONVERT (A52_3F2R, A52_3F1R):
mix2to1 (samples + 768, samples + 1024, bias);
break;
case CONVERT (A52_2F1R, A52_2F2R):
memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t));
break;
case CONVERT (A52_3F1R, A52_2F2R):
mix3to2 (samples, bias);
memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
break;
case CONVERT (A52_3F2R, A52_2F2R):
mix3to2 (samples, bias);
memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t));
memcpy (samples + 768, samples + 1024, 256 * sizeof (sample_t));
break;
case CONVERT (A52_3F1R, A52_3F2R):
memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t));
break;
}
}
static void upmix_C (sample_t * samples, int acmod, int output)
{
switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) {
case CONVERT (A52_CHANNEL, A52_CHANNEL2):
memcpy (samples + 256, samples, 256 * sizeof (sample_t));
break;
case CONVERT (A52_3F2R, A52_MONO):
zero (samples + 1024);
case CONVERT (A52_3F1R, A52_MONO):
case CONVERT (A52_2F2R, A52_MONO):
zero (samples + 768);
case CONVERT (A52_3F, A52_MONO):
case CONVERT (A52_2F1R, A52_MONO):
zero (samples + 512);
case CONVERT (A52_CHANNEL, A52_MONO):
case CONVERT (A52_STEREO, A52_MONO):
zero (samples + 256);
break;
case CONVERT (A52_3F2R, A52_STEREO):
case CONVERT (A52_3F2R, A52_DOLBY):
zero (samples + 1024);
case CONVERT (A52_3F1R, A52_STEREO):
case CONVERT (A52_3F1R, A52_DOLBY):
zero (samples + 768);
case CONVERT (A52_3F, A52_STEREO):
case CONVERT (A52_3F, A52_DOLBY):
mix_3to2:
memcpy (samples + 512, samples + 256, 256 * sizeof (sample_t));
zero (samples + 256);
break;
case CONVERT (A52_2F2R, A52_STEREO):
case CONVERT (A52_2F2R, A52_DOLBY):
zero (samples + 768);
case CONVERT (A52_2F1R, A52_STEREO):
case CONVERT (A52_2F1R, A52_DOLBY):
zero (samples + 512);
break;
case CONVERT (A52_3F2R, A52_3F):
zero (samples + 1024);
case CONVERT (A52_3F1R, A52_3F):
case CONVERT (A52_2F2R, A52_2F1R):
zero (samples + 768);
break;
case CONVERT (A52_3F2R, A52_3F1R):
zero (samples + 1024);
break;
case CONVERT (A52_3F2R, A52_2F1R):
zero (samples + 1024);
case CONVERT (A52_3F1R, A52_2F1R):
mix_31to21:
memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t));
goto mix_3to2;
case CONVERT (A52_3F2R, A52_2F2R):
memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t));
goto mix_31to21;
}
}
#if defined(ARCH_X86) && defined(__GNUC__)
static void mix2to1_SSE (sample_t * dest, sample_t * src, sample_t bias)
{
asm volatile(
"movlps %2, %%xmm7 \n\t"
"shufps $0x00, %%xmm7, %%xmm7 \n\t"
"movl $-1024, %%esi \n\t"
".balign 16\n\t"
"1: \n\t"
"movaps (%0, %%esi), %%xmm0 \n\t"
"movaps 16(%0, %%esi), %%xmm1 \n\t"
"addps (%1, %%esi), %%xmm0 \n\t"
"addps 16(%1, %%esi), %%xmm1 \n\t"
"addps %%xmm7, %%xmm0 \n\t"
"addps %%xmm7, %%xmm1 \n\t"
"movaps %%xmm0, (%1, %%esi) \n\t"
"movaps %%xmm1, 16(%1, %%esi) \n\t"
"addl $32, %%esi \n\t"
" jnz 1b \n\t"
:: "r" (src+256), "r" (dest+256), "m" (bias)
: "%esi"
);
}
static void mix3to1_SSE (sample_t * samples, sample_t bias)
{
asm volatile(
"movlps %1, %%xmm7 \n\t"
"shufps $0x00, %%xmm7, %%xmm7 \n\t"
"movl $-1024, %%esi \n\t"
".balign 16\n\t"
"1: \n\t"
"movaps (%0, %%esi), %%xmm0 \n\t"
"movaps 1024(%0, %%esi), %%xmm1 \n\t"
"addps 2048(%0, %%esi), %%xmm0 \n\t"
"addps %%xmm7, %%xmm1 \n\t"
"addps %%xmm1, %%xmm0 \n\t"
"movaps %%xmm0, (%0, %%esi) \n\t"
"addl $16, %%esi \n\t"
" jnz 1b \n\t"
:: "r" (samples+256), "m" (bias)
: "%esi"
);
}
static void mix4to1_SSE (sample_t * samples, sample_t bias)
{
asm volatile(
"movlps %1, %%xmm7 \n\t"
"shufps $0x00, %%xmm7, %%xmm7 \n\t"
"movl $-1024, %%esi \n\t"
".balign 16\n\t"
"1: \n\t"
"movaps (%0, %%esi), %%xmm0 \n\t"
"movaps 1024(%0, %%esi), %%xmm1 \n\t"
"addps 2048(%0, %%esi), %%xmm0 \n\t"
"addps 3072(%0, %%esi), %%xmm1 \n\t"
"addps %%xmm7, %%xmm0 \n\t"
"addps %%xmm1, %%xmm0 \n\t"
"movaps %%xmm0, (%0, %%esi) \n\t"
"addl $16, %%esi \n\t"
" jnz 1b \n\t"
:: "r" (samples+256), "m" (bias)
: "%esi"
);
}
static void mix5to1_SSE (sample_t * samples, sample_t bias)
{
asm volatile(
"movlps %1, %%xmm7 \n\t"
"shufps $0x00, %%xmm7, %%xmm7 \n\t"
"movl $-1024, %%esi \n\t"
".balign 16\n\t"
"1: \n\t"
"movaps (%0, %%esi), %%xmm0 \n\t"
"movaps 1024(%0, %%esi), %%xmm1 \n\t"
"addps 2048(%0, %%esi), %%xmm0 \n\t"
"addps 3072(%0, %%esi), %%xmm1 \n\t"
"addps %%xmm7, %%xmm0 \n\t"
"addps 4096(%0, %%esi), %%xmm1 \n\t"
"addps %%xmm1, %%xmm0 \n\t"
"movaps %%xmm0, (%0, %%esi) \n\t"
"addl $16, %%esi \n\t"
" jnz 1b \n\t"
:: "r" (samples+256), "m" (bias)
: "%esi"
);
}
static void mix3to2_SSE (sample_t * samples, sample_t bias)
{
asm volatile(
"movlps %1, %%xmm7 \n\t"
"shufps $0x00, %%xmm7, %%xmm7 \n\t"
"movl $-1024, %%esi \n\t"
".balign 16\n\t"
"1: \n\t"
"movaps 1024(%0, %%esi), %%xmm0 \n\t"
"addps %%xmm7, %%xmm0 \n\t" //common
"movaps (%0, %%esi), %%xmm1 \n\t"
"movaps 2048(%0, %%esi), %%xmm2 \n\t"
"addps %%xmm0, %%xmm1 \n\t"
"addps %%xmm0, %%xmm2 \n\t"
"movaps %%xmm1, (%0, %%esi) \n\t"
"movaps %%xmm2, 1024(%0, %%esi) \n\t"
"addl $16, %%esi \n\t"
" jnz 1b \n\t"
:: "r" (samples+256), "m" (bias)
: "%esi"
);
}
static void mix21to2_SSE (sample_t * left, sample_t * right, sample_t bias)
{
asm volatile(
"movlps %2, %%xmm7 \n\t"
"shufps $0x00, %%xmm7, %%xmm7 \n\t"
"movl $-1024, %%esi \n\t"
".balign 16\n\t"
"1: \n\t"
"movaps 1024(%1, %%esi), %%xmm0 \n\t"
"addps %%xmm7, %%xmm0 \n\t" //common
"movaps (%0, %%esi), %%xmm1 \n\t"
"movaps (%1, %%esi), %%xmm2 \n\t"
"addps %%xmm0, %%xmm1 \n\t"
"addps %%xmm0, %%xmm2 \n\t"
"movaps %%xmm1, (%0, %%esi) \n\t"
"movaps %%xmm2, (%1, %%esi) \n\t"
"addl $16, %%esi \n\t"
" jnz 1b \n\t"
:: "r" (left+256), "r" (right+256), "m" (bias)
: "%esi"
);
}
static void mix21toS_SSE (sample_t * samples, sample_t bias)
{
asm volatile(
"movlps %1, %%xmm7 \n\t"
"shufps $0x00, %%xmm7, %%xmm7 \n\t"
"movl $-1024, %%esi \n\t"
".balign 16\n\t"
"1: \n\t"
"movaps 2048(%0, %%esi), %%xmm0 \n\t" // surround
"movaps (%0, %%esi), %%xmm1 \n\t"
"movaps 1024(%0, %%esi), %%xmm2 \n\t"
"addps %%xmm7, %%xmm1 \n\t"
"addps %%xmm7, %%xmm2 \n\t"
"subps %%xmm0, %%xmm1 \n\t"
"addps %%xmm0, %%xmm2 \n\t"
"movaps %%xmm1, (%0, %%esi) \n\t"
"movaps %%xmm2, 1024(%0, %%esi) \n\t"
"addl $16, %%esi \n\t"
" jnz 1b \n\t"
:: "r" (samples+256), "m" (bias)
: "%esi"
);
}
static void mix31to2_SSE (sample_t * samples, sample_t bias)
{
asm volatile(
"movlps %1, %%xmm7 \n\t"
"shufps $0x00, %%xmm7, %%xmm7 \n\t"
"movl $-1024, %%esi \n\t"
".balign 16\n\t"
"1: \n\t"
"movaps 1024(%0, %%esi), %%xmm0 \n\t"
"addps 3072(%0, %%esi), %%xmm0 \n\t"
"addps %%xmm7, %%xmm0 \n\t" // common
"movaps (%0, %%esi), %%xmm1 \n\t"
"movaps 2048(%0, %%esi), %%xmm2 \n\t"
"addps %%xmm0, %%xmm1 \n\t"
"addps %%xmm0, %%xmm2 \n\t"
"movaps %%xmm1, (%0, %%esi) \n\t"
"movaps %%xmm2, 1024(%0, %%esi) \n\t"
"addl $16, %%esi \n\t"
" jnz 1b \n\t"
:: "r" (samples+256), "m" (bias)
: "%esi"
);
}
static void mix31toS_SSE (sample_t * samples, sample_t bias)
{
asm volatile(
"movlps %1, %%xmm7 \n\t"
"shufps $0x00, %%xmm7, %%xmm7 \n\t"
"movl $-1024, %%esi \n\t"
".balign 16\n\t"
"1: \n\t"
"movaps 1024(%0, %%esi), %%xmm0 \n\t"
"movaps 3072(%0, %%esi), %%xmm3 \n\t" // surround
"addps %%xmm7, %%xmm0 \n\t" // common
"movaps (%0, %%esi), %%xmm1 \n\t"
"movaps 2048(%0, %%esi), %%xmm2 \n\t"
"addps %%xmm0, %%xmm1 \n\t"
"addps %%xmm0, %%xmm2 \n\t"
"subps %%xmm3, %%xmm1 \n\t"
"addps %%xmm3, %%xmm2 \n\t"
"movaps %%xmm1, (%0, %%esi) \n\t"
"movaps %%xmm2, 1024(%0, %%esi) \n\t"
"addl $16, %%esi \n\t"
" jnz 1b \n\t"
:: "r" (samples+256), "m" (bias)
: "%esi"
);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -