Пример #1
0
        public virtual void initImdct(FFT mdctCtx)
        {
            SineWin.initFfSineWindows();

            // Initialize the MDCT transform
            mdctCtx.mdctInit(8, true, -1.0);
        }
Пример #2
0
        public virtual void ipqf(FFT dctCtx, IPQFChannelContext hist, float[] @in, float[] @out)
        {
            float[] idctIn  = new float[ATRAC3P_SUBBANDS];
            float[] idctOut = new float[ATRAC3P_SUBBANDS];

            Arrays.Fill(@out, 0, ATRAC3P_FRAME_SAMPLES, 0f);

            for (int s = 0; s < ATRAC3P_SUBBAND_SAMPLES; s++)
            {
                // pack up one sample from each subband
                for (int sb = 0; sb < ATRAC3P_SUBBANDS; sb++)
                {
                    idctIn[sb] = @in[sb * ATRAC3P_SUBBAND_SAMPLES + s];
                }

                // Calculate the sine and cosine part of the PQF using IDCT-IV
                dctCtx.imdctHalf(idctOut, 0, idctIn, 0);

                // append the result to the history
                for (int i = 0; i < 8; i++)
                {
                    hist.buf1[hist.pos][i] = idctOut[i + 8];
                    hist.buf2[hist.pos][i] = idctOut[7 - i];
                }

                int posNow  = hist.pos;
                int posNext = mod23_lut[posNow + 2];                 // posNext = (posNow + 1) % 23

                for (int t = 0; t < ATRAC3P_PQF_FIR_LEN; t++)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        @out[s * 16 + i + 0] += hist.buf1[posNow][i] * ipqf_coeffs1[t][i] + hist.buf2[posNext][i] * ipqf_coeffs2[t][i];
                        @out[s * 16 + i + 8] += hist.buf1[posNow][7 - i] * ipqf_coeffs1[t][i + 8] + hist.buf2[posNext][7 - i] * ipqf_coeffs2[t][i + 8];
                    }

                    posNow  = mod23_lut[posNext + 2];                    // posNow = (posNow + 2) % 23;
                    posNext = mod23_lut[posNow + 2];                     // posNext = (posNext + 2) % 23;
                }

                hist.pos = mod23_lut[hist.pos];                 // hist.pos = (hist.pos - 1) % 23;
            }
        }
Пример #3
0
        public virtual void imdct(FFT mdctCtx, float[] @in, int inOffset, float[] @out, int outOffset, int windId, int sb)
        {
            if ((sb & 1) != 0)
            {
                for (int i = 0; i < ATRAC3P_SUBBAND_SAMPLES / 2; i++)
                {
                    float tmp = @in[inOffset + i];
                    @in[inOffset + i] = @in[inOffset + ATRAC3P_SUBBAND_SAMPLES - 1 - i];
                    @in[inOffset + ATRAC3P_SUBBAND_SAMPLES - 1 - i] = tmp;
                }
            }

            mdctCtx.imdctCalc(@out, outOffset, @in, inOffset);

            /* Perform windowing on the output.
             * ATRAC3+ uses two different MDCT windows:
             * - The first one is just the plain sine window of size 256
             * - The 2nd one is the plain sine window of size 128
             *   wrapped into zero (at the start) and one (at the end) regions.
             *   Both regions are 32 samples long. */
            if ((windId & 2) != 0)
            {             // 1st half: steep window
                Arrays.Fill(@out, outOffset, outOffset + 32, 0f);
                vectorFmul(@out, outOffset + 32, @out, outOffset + 32, ff_sine_64, 0, 64);
            }
            else
            {             // 1st halt: simple sine window
                vectorFmul(@out, outOffset, @out, outOffset, ff_sine_128, 0, ATRAC3P_MDCT_SIZE / 2);
            }

            if ((windId & 1) != 0)
            {             // 2nd half: steep window
                vectorFmulReverse(@out, outOffset + 160, @out, outOffset + 160, ff_sine_64, 0, 64);
                Arrays.Fill(@out, outOffset + 224, outOffset + 224 + 32, 0f);
            }
            else
            {             // 2nd half: simple sine window
                vectorFmulReverse(@out, outOffset + 128, @out, outOffset + 128, ff_sine_128, 0, ATRAC3P_MDCT_SIZE / 2);
            }
        }