📄 ac3_dec_downmixing.c
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2002-2006 Intel Corporation. All Rights Reserved.
//
*/
#include "ac3_dec.h"
#include "ac3_dec_own_fp.h"
/********************************************************************/
#define DB11 7509 * 256
#define COMP_CUSTOM_A 0
#define COMP_CUSTOM_D 1
#define COMP_LINE 2
#define COMP_RF 3
static const Ipp16s NFRONT[8] = { 2, 1, 2, 3, 2, 3, 2, 3 };
static const Ipp16s NREAR[8] = { 0, 0, 0, 0, 1, 1, 2, 2 };
//#define m6dB 0.5000345f /* -6.0 dB */
//#define m3dB 0.7071312f /* -3.0 dB */
//#define m45dB 0.594292158f /* -4.5 dB */
#define m6dB 0.5f /* -6.0 dB */
#define m3dB 0.707106781f /* -3.0 dB */
#define m45dB 0.594603557f /* -4.5 dB */
const Ipp32f cmixlev_lut[4] = {
m3dB, m45dB, m6dB, m45dB
};
const Ipp32f smixlev_lut[4] = {
m3dB, m6dB, 0, m6dB
};
static const Ipp32f karaokeTable[4][18] = {
{1.00000000f, 0.00000000f, 0.00000000f, 0.70710677f,
0.70710677f, 0.00000000f, 0.00000000f, 0.00000000f,
0.00000000f, 1.00000000f, 1.00000000f, 1.00000000f,
0.00000000f, 0.00000000f, 0.00000000f, 1.00000000f,
0.00000000f, 0.00000000f},
{1.00000000f, 0.70713121f, 0.00000000f, 0.70710677f,
0.70710677f, 0.70710677f, 0.70710677f, 0.00000000f,
0.00000000f, 1.00000000f, 1.00000000f, 1.00000000f,
0.00000000f, 0.00000000f, 0.00000000f, 1.00000000f,
1.00000000f, 0.00000000f},
{1.00000000f, 0.00000000f, 0.70713121f, 0.70710677f,
0.70710677f, 0.00000000f, 0.00000000f, 0.70710677f,
0.70710677f, 1.00000000f, 1.00000000f, 1.00000000f,
0.00000000f, 0.00000000f, 0.00000000f, 1.00000000f,
0.00000000f, 1.00000000f},
{1.00000000f, 0.70713121f, 0.70713121f, 0.70710677f,
0.70710677f, 1.00000000f, 0.00000000f, 0.00000000f,
1.00000000f, 1.00000000f, 1.00000000f, -1.00000000f,
0.00000000f, 1.00000000f, 1.00000000f, 1.00000000f,
0.00000000f, 0.00000000f},
};
/********************************************************************/
static Ipp32f drc(Ipp32s compre,
Ipp32s compr,
Ipp32s dynrng,
Ipp32s downmix,
Ipp32f dialnorm,
AC3Dec *state)
{
Ipp32s tmp;
Ipp32f gain;
if (state->out_compmod == COMP_RF) {
if (compre) {
if (compr) gain = (Ipp32f)compr + DB11;
else gain = (Ipp32f)dynrng + DB11;
} else if (downmix) gain = (Ipp32f)dynrng - DB11;
else gain = (Ipp32f)dynrng;
} else if (state->out_compmod == COMP_LINE) {
if (dynrng > 0) gain = (Ipp32f)dynrng * state->drc_scaleLow;
else if (downmix) gain = (Ipp32f)dynrng;
else gain = (Ipp32f)dynrng * state->drc_scaleHigh;
} else {
if (dynrng > 0) gain = (Ipp32f)dynrng * state->drc_scaleLow;
else gain = (Ipp32f)dynrng * state->drc_scaleHigh;
if (downmix) gain = gain - DB11;
}
tmp = (Ipp32s)(gain);
gain = ((Ipp32f)((tmp & 0xFFFFF) + 1048576)) /
((Ipp32f)(1 << (20 - (tmp >> 20))));
if (state->out_compmod != COMP_CUSTOM_A)
gain *= dialnorm;
return gain;
}
/********************************************************************/
void Downmix(Ipp32s dynrng,
Ipp32s dynrng2,
Ipp32s before_imdct,
AC3Dec *state)
{
Ipp32s downmix, i;
Ipp32f cmixgain; /* center channel mix gain */
Ipp32f smixgain; /* surround channel mix gain */
Ipp32f gain = .0f;
Ipp16s infront, inrear, outfront, outrear;
Ipp32f *samples[7];
Ipp32f *samL = NULL;
Ipp32f *samC = NULL;
Ipp32f *samR = NULL;
Ipp32f *samSL = NULL ;
Ipp32f *samSR = NULL;
Ipp32f *samS = NULL;
Ipp32f *samLFE= NULL;
Ipp32f *karaokeSL= NULL;
if (before_imdct) {
for (i = 0; i < 7; i++) {
samples[i] = state->coeffs[i];
}
} else {
for (i = 0; i < 7; i++) {
samples[i] = state->samples[i];
}
}
/* init in_channel */
switch (state->bsi.acmod) {
case ACMOD_0:
samL = samples[0];
samR = samples[1];
samC = samples[2];
samSL = samples[3];
samSR = samples[4];
samS = samples[6];
break;
case ACMOD_10:
samC = samples[0];
samL = samples[1];
samR = samples[2];
samSL = samples[3];
samSR = samples[4];
samS = samples[6];
break;
case ACMOD_20:
samL = samples[0];
samR = samples[1];
samC = samples[2];
samSL = samples[3];
samSR = samples[4];
samS = samples[6];
break;
case ACMOD_30:
samL = samples[0];
samC = samples[1];
samR = samples[2];
samSL = samples[3];
samSR = samples[4];
samS = samples[6];
break;
case ACMOD_21:
samL = samples[0];
samR = samples[1];
samS = samples[2];
samC = samples[3];
samSL = samples[4];
samSR = samples[6];
break;
case ACMOD_31:
samL = samples[0];
samC = samples[1];
samR = samples[2];
samS = samples[3];
samSL = samples[4];
samSR = samples[6];
break;
case ACMOD_22:
samL = samples[0];
samR = samples[1];
samSL = samples[2];
samSR = samples[3];
samC = samples[4];
samS = samples[6];
break;
case ACMOD_32:
samL = samples[0];
samC = samples[1];
samR = samples[2];
samSL = samples[3];
samSR = samples[4];
samS = samples[6];
break;
default:
break;
}
samLFE = samples[5];
/*
* Set up downmix parameters
*/
infront = NFRONT[state->bsi.acmod];
inrear = NREAR[state->bsi.acmod];
outfront = NFRONT[state->out_acmod];
outrear = NREAR[state->out_acmod];
cmixgain = cmixlev_lut[state->bsi.cmixlev];
smixgain = smixlev_lut[state->bsi.surmixlev];
downmix = 0;
if (inrear == 1) {
karaokeSL = samS;
} else {
karaokeSL = samSL;
}
if (before_imdct) {
if (state->bsi.acmod == ACMOD_10) {
ippsZero_32f(samL, 256);
ippsZero_32f(samR, 256);
}
if ((infront == 2) && (outfront != 2)) {
ippsZero_32f(samC, 256);
}
if (inrear == 0) {
if (outrear == 2) {
ippsZero_32f(samSL, 256);
ippsZero_32f(samSR, 256);
} else if (outrear == 1) {
ippsZero_32f(samS, 256);
}
} else if (inrear == 1) {
if (outrear == 2) {
ippsZero_32f(samSL, 256);
ippsZero_32f(samSR, 256);
}
}
if (state->bsi.acmod == ACMOD_0) { /* 1+1 mode, dual independent mono channels present */
gain = drc(state->bsi.compre, state->bsi.compr, dynrng, 0,
state->bsi.dialnorm, state);
ippsMulC_32f_I(gain, samL, 256);
gain = drc(state->bsi.compr2e, state->bsi.compr2, dynrng2, 0,
state->bsi.dialnorm2, state);
ippsMulC_32f_I(gain, samR, 256);
if (outfront == 1) { /* 1 front loudspeaker (center) */
if (state->dualmonomode == DUAL_LEFTMONO) {
ippsCopy_32f(samL, samC, 256);
} else if (state->dualmonomode == DUAL_RGHTMONO) {
ippsCopy_32f(samR, samC, 256);
} else {
ippsAdd_32f(samL, samR, samC, 256);
ippsMulC_32f_I(m6dB, samC, 256); /* 0.501187233 = -6dB */
}
} else if (outfront == 2) {
if (state->dualmonomode == DUAL_LEFTMONO) {
ippsMulC_32f_I(m3dB, samL, 256); /* 0.707945 = -3dB */
ippsCopy_32f(samL, samR, 256);
} else if (state->dualmonomode == DUAL_RGHTMONO) {
ippsMulC_32f_I(m3dB, samR, 256); /* 0.707945 = -3dB */
ippsCopy_32f(samR, samL, 256);
} else if (state->dualmonomode == DUAL_MIXMONO) {
ippsAdd_32f_I(samR, samL, 256);
ippsMulC_32f_I(m6dB, samL, 256); /* 0.501187233 = -6dB */
ippsCopy_32f(samL, samR, 256);
}
} else {
if (state->dualmonomode == DUAL_LEFTMONO) {
ippsCopy_32f(samL, samC, 256);
ippsZero_32f(samL, 256);
ippsZero_32f(samR, 256);
} else if (state->dualmonomode == DUAL_RGHTMONO) {
ippsCopy_32f(samR, samC, 256);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -