synth_filter.c

来自「这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔」· C语言 代码 · 共 443 行 · 第 1/2 页

C
443
字号
    B04 =  A04 + A11;
    B05 =  A05 + A10;
    B06 =  A06 + A09;
    B07 =  A07 + A08;
    B08 = MPC_SCALE_CONST((A00 - A15) , 0.5024192929f , 31);
    B09 = MPC_SCALE_CONST((A01 - A14) , 0.5224986076f , 31);
    B10 = MPC_SCALE_CONST((A02 - A13) , 0.5669440627f , 31);
    B11 = MPC_SCALE_CONST((A03 - A12) , 0.6468217969f , 31);
    B12 = MPC_SCALE_CONST((A04 - A11) , 0.7881546021f , 31);
    B13 = MPC_SCALE_CONST((A05 - A10) , 1.0606776476f , 30);
    B14 = MPC_SCALE_CONST((A06 - A09) , 1.7224471569f , 30);
    B15 = MPC_SCALE_CONST((A07 - A08) , 5.1011486053f , 28);

    A00 =  B00 + B07;
    A01 =  B01 + B06;
    A02 =  B02 + B05;
    A03 =  B03 + B04;
    A04 = MPC_SCALE_CONST((B00 - B07) , 0.5097956061f , 31);
    A05 = MPC_SCALE_CONST((B01 - B06) , 0.6013448834f , 31);
    A06 = MPC_SCALE_CONST((B02 - B05) , 0.8999761939f , 31);
    A07 = MPC_SCALE_CONST((B03 - B04) , 2.5629155636f , 29);
    A08 =  B08 + B15;
    A09 =  B09 + B14;
    A10 =  B10 + B13;
    A11 =  B11 + B12;
    A12 = MPC_SCALE_CONST((B08 - B15) , 0.5097956061f , 31);
    A13 = MPC_SCALE_CONST((B09 - B14) , 0.6013448834f , 31);
    A14 = MPC_SCALE_CONST((B10 - B13) , 0.8999761939f , 31);
    A15 = MPC_SCALE_CONST((B11 - B12) , 2.5629155636f , 29);

    B00 =  A00 + A03;
    B01 =  A01 + A02;
    B02 = MPC_SCALE_CONST((A00 - A03) , 0.5411961079f , 31);
    B03 = MPC_SCALE_CONST((A01 - A02) , 1.3065630198f , 30);
    B04 =  A04 + A07;
    B05 =  A05 + A06;
    B06 = MPC_SCALE_CONST((A04 - A07) , 0.5411961079f , 31);
    B07 = MPC_SCALE_CONST((A05 - A06) , 1.3065630198f , 30);
    B08 =  A08 + A11;
    B09 =  A09 + A10;
    B10 = MPC_SCALE_CONST((A08 - A11) , 0.5411961079f , 31);
    B11 = MPC_SCALE_CONST((A09 - A10) , 1.3065630198f , 30);
    B12 =  A12 + A15;
    B13 =  A13 + A14;
    B14 = MPC_SCALE_CONST((A12 - A15) , 0.5411961079f , 31);
    B15 = MPC_SCALE_CONST((A13 - A14) , 1.3065630198f , 30);

    A00 = MPC_SHL(B00 + B01, MPC_FIXED_POINT_SYNTH_FIX);
    A01 = MPC_SCALE_CONST_SHL((B00 - B01) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX);
    A02 = MPC_SHL(B02 + B03, MPC_FIXED_POINT_SYNTH_FIX);
    A03 = MPC_SCALE_CONST_SHL((B02 - B03) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX);
    A04 = MPC_SHL(B04 + B05, MPC_FIXED_POINT_SYNTH_FIX);
    A05 = MPC_SCALE_CONST_SHL((B04 - B05) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX);
    A06 = MPC_SHL(B06 + B07, MPC_FIXED_POINT_SYNTH_FIX);
    A07 = MPC_SCALE_CONST_SHL((B06 - B07) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX);
    A08 = MPC_SHL(B08 + B09, MPC_FIXED_POINT_SYNTH_FIX);
    A09 = MPC_SCALE_CONST_SHL((B08 - B09) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX);
    A10 = MPC_SHL(B10 + B11, MPC_FIXED_POINT_SYNTH_FIX);
    A11 = MPC_SCALE_CONST_SHL((B10 - B11) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX);
    A12 = MPC_SHL(B12 + B13, MPC_FIXED_POINT_SYNTH_FIX);
    A13 = MPC_SCALE_CONST_SHL((B12 - B13) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX);
    A14 = MPC_SHL(B14 + B15, MPC_FIXED_POINT_SYNTH_FIX);
    A15 = MPC_SCALE_CONST_SHL((B14 - B15) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX);

    // mehrfach verwendete Ausdr點ke: A04+A06+A07, A09+A13+A15
    V[ 5] = (V[11] = (V[13] = A07 + (V[15] = A15)) + A11) + A05 + A13;
    V[ 7] = (V[ 9] = A03 + A11 + A15) + A13;
    V[33] = -(V[ 1] = A01 + A09 + A13 + A15) - A14;
    V[35] = -(V[ 3] = A05 + A07 + A09 + A13 + A15) - A06 - A14;
    V[37] = (tmp = -(A10 + A11 + A13 + A14 + A15)) - A05 - A06 - A07;
    V[39] = tmp - A02 - A03;                      // abh鋘gig vom Befehl dr黚er
    V[41] = (tmp += A13 - A12) - A02 - A03;       // abh鋘gig vom Befehl 2 dr黚er
    V[43] = tmp - A04 - A06 - A07;                // abh鋘gig von Befehlen 1 und 3 dr黚er
    V[47] = (tmp = -(A08 + A12 + A14 + A15)) - A00;
    V[45] = tmp - A04 - A06 - A07;                // abh鋘gig vom Befehl dr黚er

    V[32] = -V[ 0];
    V[31] = -V[ 1];
    V[30] = -V[ 2];
    V[29] = -V[ 3];
    V[28] = -V[ 4];
    V[27] = -V[ 5];
    V[26] = -V[ 6];
    V[25] = -V[ 7];
    V[24] = -V[ 8];
    V[23] = -V[ 9];
    V[22] = -V[10];
    V[21] = -V[11];
    V[20] = -V[12];
    V[19] = -V[13];
    V[18] = -V[14];
    V[17] = -V[15];

    V[63] =  V[33];
    V[62] =  V[34];
    V[61] =  V[35];
    V[60] =  V[36];
    V[59] =  V[37];
    V[58] =  V[38];
    V[57] =  V[39];
    V[56] =  V[40];
    V[55] =  V[41];
    V[54] =  V[42];
    V[53] =  V[43];
    V[52] =  V[44];
    V[51] =  V[45];
    V[50] =  V[46];
    V[49] =  V[47];
}

static void Synthese_Filter_float_internal(MPC_SAMPLE_FORMAT * OutData,MPC_SAMPLE_FORMAT * V,const MPC_SAMPLE_FORMAT * Y)
{
    mpc_uint32_t n;
    for ( n = 0; n < 36; n++, Y += 32 ) {
        V -= 64;
        Calculate_New_V ( Y, V );
        {
            MPC_SAMPLE_FORMAT * Data = OutData;
            const MPC_SAMPLE_FORMAT *  D = (const MPC_SAMPLE_FORMAT *) &Di_opt;
            mpc_int32_t           k;
            //mpc_int32_t           tmp;

            
            
            for ( k = 0; k < 32; k++, D += 16, V++ ) {
                *Data = MPC_SHL(
                    MPC_MULTIPLY_FRACT(V[  0],D[ 0]) + MPC_MULTIPLY_FRACT(V[ 96],D[ 1]) + MPC_MULTIPLY_FRACT(V[128],D[ 2]) + MPC_MULTIPLY_FRACT(V[224],D[ 3])
                    + MPC_MULTIPLY_FRACT(V[256],D[ 4]) + MPC_MULTIPLY_FRACT(V[352],D[ 5]) + MPC_MULTIPLY_FRACT(V[384],D[ 6]) + MPC_MULTIPLY_FRACT(V[480],D[ 7])
                    + MPC_MULTIPLY_FRACT(V[512],D[ 8]) + MPC_MULTIPLY_FRACT(V[608],D[ 9]) + MPC_MULTIPLY_FRACT(V[640],D[10]) + MPC_MULTIPLY_FRACT(V[736],D[11])
                    + MPC_MULTIPLY_FRACT(V[768],D[12]) + MPC_MULTIPLY_FRACT(V[864],D[13]) + MPC_MULTIPLY_FRACT(V[896],D[14]) + MPC_MULTIPLY_FRACT(V[992],D[15])
                    , 2);
                
                Data += 2;
            }
            V -= 32;//bleh
            OutData+=64;
        }
    }
}

void
mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData) 
{
    /********* left channel ********/
    memmove(d->V_L + MPC_V_MEM, d->V_L, 960 * sizeof(MPC_SAMPLE_FORMAT) );

    Synthese_Filter_float_internal(
        OutData,
        (MPC_SAMPLE_FORMAT *)(d->V_L + MPC_V_MEM),
        (MPC_SAMPLE_FORMAT *)(d->Y_L [0]));

    /******** right channel ********/
    memmove(d->V_R + MPC_V_MEM, d->V_R, 960 * sizeof(MPC_SAMPLE_FORMAT) );

    Synthese_Filter_float_internal(
        OutData + 1,
        (MPC_SAMPLE_FORMAT *)(d->V_R + MPC_V_MEM),
        (MPC_SAMPLE_FORMAT *)(d->Y_R [0]));
}

/*******************************************/
/*                                         */
/*            dithered synthesis           */
/*                                         */
/*******************************************/

static const unsigned char    Parity [256] = {  // parity
    0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
    1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
    1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
    0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
    1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
    0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
    0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
    1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0
};

/*
 *  This is a simple random number generator with good quality for audio purposes.
 *  It consists of two polycounters with opposite rotation direction and different
 *  periods. The periods are coprime, so the total period is the product of both.
 *
 *     -------------------------------------------------------------------------------------------------
 * +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0|
 * |   -------------------------------------------------------------------------------------------------
 * |                                                                          |  |  |  |     |        |
 * |                                                                          +--+--+--+-XOR-+--------+
 * |                                                                                      |
 * +--------------------------------------------------------------------------------------+
 *
 *     -------------------------------------------------------------------------------------------------
 *     |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+
 *     -------------------------------------------------------------------------------------------------   |
 *       |  |           |  |                                                                               |
 *       +--+----XOR----+--+                                                                               |
 *                |                                                                                        |
 *                +----------------------------------------------------------------------------------------+
 *
 *
 *  The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481,
 *  which gives a period of 18.410.713.077.675.721.215. The result is the
 *  XORed values of both generators.
 */
mpc_uint32_t
random_int(mpc_decoder *d) 
{
#if 1
    mpc_uint32_t  t1, t2, t3, t4;

    t3   = t1 = d->__r1;   t4   = t2 = d->__r2;  // Parity calculation is done via table lookup, this is also available
    t1  &= 0xF5;        t2 >>= 25;               // on CPUs without parity, can be implemented in C and avoid unpredictable
    t1   = Parity [t1]; t2  &= 0x63;             // jumps and slow rotate through the carry flag operations.
    t1 <<= 31;          t2   = Parity [t2];

    return (d->__r1 = (t3 >> 1) | t1 ) ^ (d->__r2 = (t4 + t4) | t2 );
#else
    return (d->__r1 = (d->__r1 >> 1) | ((mpc_uint32_t)Parity [d->__r1 & 0xF5] << 31) ) ^
        (d->__r2 = (d->__r2 << 1) |  (mpc_uint32_t)Parity [(d->__r2 >> 25) & 0x63] );
#endif
}

⌨️ 快捷键说明

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