Exemplo n.º 1
0
        /// <summary>
        /// Resampler: convert from one sampling rate to another
        /// Input and output sampling rate are at most 48000 Hz
        /// </summary>
        /// <param name="S">I/O  Resampler state</param>
        /// <param name="output">O    Output signal</param>
        /// <param name="output_ptr"></param>
        /// <param name="input">I    Input signal</param>
        /// <param name="input_ptr"></param>
        /// <param name="inLen">I    Number of input samples</param>
        /// <returns></returns>
        internal static int silk_resampler(
            SilkResamplerState S,
            short[] output,
            int output_ptr,
            short[] input,
            int input_ptr,
            int inLen)
        {
            int nSamples;

            /* Need at least 1 ms of input data */
            Inlines.OpusAssert(inLen >= S.Fs_in_kHz);
            /* Delay can't exceed the 1 ms of buffering */
            Inlines.OpusAssert(S.inputDelay <= S.Fs_in_kHz);

            nSamples = S.Fs_in_kHz - S.inputDelay;

            short[] delayBufPtr = S.delayBuf;

            /* Copy to delay buffer */
            Array.Copy(input, input_ptr, delayBufPtr, S.inputDelay, nSamples);

            switch (S.resampler_function)
            {
            case USE_silk_resampler_private_up2_HQ_wrapper:
                silk_resampler_private_up2_HQ(S.sIIR, output, output_ptr, delayBufPtr, 0, S.Fs_in_kHz);
                silk_resampler_private_up2_HQ(S.sIIR, output, output_ptr + S.Fs_out_kHz, input, input_ptr + nSamples, inLen - S.Fs_in_kHz);
                break;

            case USE_silk_resampler_private_IIR_FIR:
                silk_resampler_private_IIR_FIR(S, output, output_ptr, delayBufPtr, 0, S.Fs_in_kHz);
                silk_resampler_private_IIR_FIR(S, output, output_ptr + S.Fs_out_kHz, input, input_ptr + nSamples, inLen - S.Fs_in_kHz);
                break;

            case USE_silk_resampler_private_down_FIR:
                silk_resampler_private_down_FIR(S, output, output_ptr, delayBufPtr, 0, S.Fs_in_kHz);
                silk_resampler_private_down_FIR(S, output, output_ptr + S.Fs_out_kHz, input, input_ptr + nSamples, inLen - S.Fs_in_kHz);
                break;

            default:
                Array.Copy(delayBufPtr, 0, output, output_ptr, S.Fs_in_kHz);
                Array.Copy(input, input_ptr + nSamples, output, output_ptr + S.Fs_out_kHz, inLen - S.Fs_in_kHz);
                break;
            }

            /* Copy to delay buffer */
            Array.Copy(input, input_ptr + inLen - S.inputDelay, delayBufPtr, 0, S.inputDelay);

            return(SilkError.SILK_NO_ERROR);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Resample with a 2nd order AR filter followed by FIR interpolation
        /// </summary>
        /// <param name="S">I/O  Resampler state</param>
        /// <param name="output">O    Output signal</param>
        /// <param name="output_ptr"></param>
        /// <param name="input">I    Input signal</param>
        /// <param name="input_ptr"></param>
        /// <param name="inLen">I    Number of input samples</param>
        internal static void silk_resampler_private_down_FIR(
            SilkResamplerState S,
            short[] output,
            int output_ptr,
            short[] input,
            int input_ptr,
            int inLen)
        {
            int nSamplesIn;
            int max_index_Q16, index_increment_Q16;

            int[] buf = new int[S.batchSize + S.FIR_Order];

            /* Copy buffered samples to start of buffer */
            Array.Copy(S.sFIR_i32, buf, S.FIR_Order);

            /* Iterate over blocks of frameSizeIn input samples */
            index_increment_Q16 = S.invRatio_Q16;
            while (true)
            {
                nSamplesIn = Inlines.silk_min(inLen, S.batchSize);

                /* Second-order AR filter (output in Q8) */
                silk_resampler_private_AR2(S.sIIR, 0, buf, S.FIR_Order, input, input_ptr, S.Coefs, nSamplesIn);

                max_index_Q16 = Inlines.silk_LSHIFT32(nSamplesIn, 16);

                /* Interpolate filtered signal */
                output_ptr = silk_resampler_private_down_FIR_INTERPOL(output, output_ptr, buf, S.Coefs, 2, S.FIR_Order,
                                                                      S.FIR_Fracs, max_index_Q16, index_increment_Q16);

                input_ptr += nSamplesIn;
                inLen     -= nSamplesIn;

                if (inLen > 1)
                {
                    /* More iterations to do; copy last part of filtered signal to beginning of buffer */
                    Array.Copy(buf, nSamplesIn, buf, 0, S.FIR_Order);
                }
                else
                {
                    break;
                }
            }

            /* Copy last part of filtered signal to the state for the next call */
            Array.Copy(buf, nSamplesIn, S.sFIR_i32, 0, S.FIR_Order);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Upsample using a combination of allpass-based 2x upsampling and FIR interpolation
        /// </summary>
        /// <param name="S">I/O  Resampler state</param>
        /// <param name="output">O    Output signal</param>
        /// <param name="output_ptr"></param>
        /// <param name="input">I    Input signal</param>
        /// <param name="input_ptr"></param>
        /// <param name="inLen">I    Number of input samples</param>
        internal static void silk_resampler_private_IIR_FIR(
            SilkResamplerState S,
            short[] output,
            int output_ptr,
            short[] input,
            int input_ptr,
            int inLen)
        {
            int nSamplesIn;
            int max_index_Q16, index_increment_Q16;

            short[] buf = new short[2 * S.batchSize + SilkConstants.RESAMPLER_ORDER_FIR_12];

            /* Copy buffered samples to start of buffer */
            Array.Copy(S.sFIR_i16, 0, buf, 0, SilkConstants.RESAMPLER_ORDER_FIR_12);

            /* Iterate over blocks of frameSizeIn input samples */
            index_increment_Q16 = S.invRatio_Q16;
            while (true)
            {
                nSamplesIn = Inlines.silk_min(inLen, S.batchSize);

                /* Upsample 2x */
                silk_resampler_private_up2_HQ(S.sIIR, buf, SilkConstants.RESAMPLER_ORDER_FIR_12, input, input_ptr, nSamplesIn);

                max_index_Q16 = Inlines.silk_LSHIFT32(nSamplesIn, 16 + 1);         /* + 1 because 2x upsampling */
                output_ptr    = silk_resampler_private_IIR_FIR_INTERPOL(output, output_ptr, buf, max_index_Q16, index_increment_Q16);
                input_ptr    += nSamplesIn;
                inLen        -= nSamplesIn;

                if (inLen > 0)
                {
                    /* More iterations to do; copy last part of filtered signal to beginning of buffer */
                    Array.Copy(buf, nSamplesIn << 1, buf, 0, SilkConstants.RESAMPLER_ORDER_FIR_12);
                }
                else
                {
                    break;
                }
            }

            /* Copy last part of filtered signal to the state for the next call */
            Array.Copy(buf, nSamplesIn << 1, S.sFIR_i16, 0, SilkConstants.RESAMPLER_ORDER_FIR_12);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Initialize/reset the resampler state for a given pair of input/output sampling rates
        /// </summary>
        /// <param name="S">I/O  Resampler state</param>
        /// <param name="Fs_Hz_in">I    Input sampling rate (Hz)</param>
        /// <param name="Fs_Hz_out">I    Output sampling rate (Hz)</param>
        /// <param name="forEnc">I    If 1: encoder; if 0: decoder</param>
        /// <returns></returns>
        internal static int silk_resampler_init(
            SilkResamplerState S,
            int Fs_Hz_in,
            int Fs_Hz_out,
            int forEnc)
        {
            int up2x;

            /* Clear state */
            S.Reset();

            /* Input checking */
            if (forEnc != 0)
            {
                if ((Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000) ||
                    (Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000))
                {
                    Inlines.OpusAssert(false);
                    return(-1);
                }
                S.inputDelay = Tables.delay_matrix_enc[rateID(Fs_Hz_in), rateID(Fs_Hz_out)];
            }
            else
            {
                if ((Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000) ||
                    (Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000))
                {
                    Inlines.OpusAssert(false);
                    return(-1);
                }
                S.inputDelay = Tables.delay_matrix_dec[rateID(Fs_Hz_in), rateID(Fs_Hz_out)];
            }

            S.Fs_in_kHz  = Inlines.silk_DIV32_16(Fs_Hz_in, 1000);
            S.Fs_out_kHz = Inlines.silk_DIV32_16(Fs_Hz_out, 1000);

            /* Number of samples processed per batch */
            S.batchSize = S.Fs_in_kHz * SilkConstants.RESAMPLER_MAX_BATCH_SIZE_MS;

            /* Find resampler with the right sampling ratio */
            up2x = 0;
            if (Fs_Hz_out > Fs_Hz_in)
            {
                /* Upsample */
                if (Fs_Hz_out == Inlines.silk_MUL(Fs_Hz_in, 2))
                {                            /* Fs_out : Fs_in = 2 : 1 */
                                             /* Special case: directly use 2x upsampler */
                    S.resampler_function = USE_silk_resampler_private_up2_HQ_wrapper;
                }
                else
                {
                    /* Default resampler */
                    S.resampler_function = USE_silk_resampler_private_IIR_FIR;
                    up2x = 1;
                }
            }
            else if (Fs_Hz_out < Fs_Hz_in)
            {
                /* Downsample */
                S.resampler_function = USE_silk_resampler_private_down_FIR;
                if (Inlines.silk_MUL(Fs_Hz_out, 4) == Inlines.silk_MUL(Fs_Hz_in, 3))
                {             /* Fs_out : Fs_in = 3 : 4 */
                    S.FIR_Fracs = 3;
                    S.FIR_Order = SilkConstants.RESAMPLER_DOWN_ORDER_FIR0;
                    S.Coefs     = Tables.silk_Resampler_3_4_COEFS;
                }
                else if (Inlines.silk_MUL(Fs_Hz_out, 3) == Inlines.silk_MUL(Fs_Hz_in, 2))
                {      /* Fs_out : Fs_in = 2 : 3 */
                    S.FIR_Fracs = 2;
                    S.FIR_Order = SilkConstants.RESAMPLER_DOWN_ORDER_FIR0;
                    S.Coefs     = Tables.silk_Resampler_2_3_COEFS;
                }
                else if (Inlines.silk_MUL(Fs_Hz_out, 2) == Fs_Hz_in)
                {                     /* Fs_out : Fs_in = 1 : 2 */
                    S.FIR_Fracs = 1;
                    S.FIR_Order = SilkConstants.RESAMPLER_DOWN_ORDER_FIR1;
                    S.Coefs     = Tables.silk_Resampler_1_2_COEFS;
                }
                else if (Inlines.silk_MUL(Fs_Hz_out, 3) == Fs_Hz_in)
                {                     /* Fs_out : Fs_in = 1 : 3 */
                    S.FIR_Fracs = 1;
                    S.FIR_Order = SilkConstants.RESAMPLER_DOWN_ORDER_FIR2;
                    S.Coefs     = Tables.silk_Resampler_1_3_COEFS;
                }
                else if (Inlines.silk_MUL(Fs_Hz_out, 4) == Fs_Hz_in)
                {                     /* Fs_out : Fs_in = 1 : 4 */
                    S.FIR_Fracs = 1;
                    S.FIR_Order = SilkConstants.RESAMPLER_DOWN_ORDER_FIR2;
                    S.Coefs     = Tables.silk_Resampler_1_4_COEFS;
                }
                else if (Inlines.silk_MUL(Fs_Hz_out, 6) == Fs_Hz_in)
                {                     /* Fs_out : Fs_in = 1 : 6 */
                    S.FIR_Fracs = 1;
                    S.FIR_Order = SilkConstants.RESAMPLER_DOWN_ORDER_FIR2;
                    S.Coefs     = Tables.silk_Resampler_1_6_COEFS;
                }
                else
                {
                    /* None available */
                    Inlines.OpusAssert(false);
                    return(-1);
                }
            }
            else
            {
                /* Input and output sampling rates are equal: copy */
                S.resampler_function = USE_silk_resampler_copy;
            }

            /* Ratio of input/output samples */
            S.invRatio_Q16 = Inlines.silk_LSHIFT32(Inlines.silk_DIV32(Inlines.silk_LSHIFT32(Fs_Hz_in, 14 + up2x), Fs_Hz_out), 2);

            /* Make sure the ratio is rounded up */
            while (Inlines.silk_SMULWW(S.invRatio_Q16, Fs_Hz_out) < Inlines.silk_LSHIFT32(Fs_Hz_in, up2x))
            {
                S.invRatio_Q16++;
            }

            return(0);
        }