コード例 #1
0
        /**
         * Function enc_lag3()
         * Encoding of fractional pitch lag with 1/3 resolution.
         * <pre>
         * The pitch range for the first subframe is divided as follows:
         *   19 1/3  to   84 2/3   resolution 1/3
         *   85      to   143      resolution 1
         *
         * The period in the first subframe is encoded with 8 bits.
         * For the range with fractions:
         *   index = (T-19)*3 + frac - 1;   where T=[19..85] and frac=[-1,0,1]
         * and for the integer only range
         *   index = (T - 85) + 197;        where T=[86..143]
         *----------------------------------------------------------------------
         * For the second subframe a resolution of 1/3 is always used, and the
         * search range is relative to the lag in the first subframe.
         * If t0 is the lag in the first subframe then
         *  t_min=t0-5   and  t_max=t0+4   and  the range is given by
         *       t_min - 2/3   to  t_max + 2/3
         *
         * The period in the 2nd subframe is encoded with 5 bits:
         *   index = (T-(t_min-1))*3 + frac - 1;    where T[t_min-1 .. t_max+1]
         * </pre>
         *
         * @param T0            input : Pitch delay
         * @param T0_frac       input : Fractional pitch delay
         * @param T0_min        in/out: Minimum search delay
         * @param T0_max        in/out: Maximum search delay
         * @param pit_min       input : Minimum pitch delay
         * @param pit_max       input : Maximum pitch delay
         * @param pit_flag      input : Flag for 1st subframe
         * @return              Return index of encoding
         */

        public static int enc_lag3(
            int T0,
            int T0_frac,
            IntReference T0_min,
            IntReference T0_max,
            int pit_min,
            int pit_max,
            int pit_flag
            )
        {
            int index;
            int _T0_min = T0_min.value, _T0_max = T0_max.value;

            if (pit_flag == 0) /* if 1st subframe */
            {
                /* encode pitch delay (with fraction) */

                if (T0 <= 85)
                {
                    index = T0 * 3 - 58 + T0_frac;
                }
                else
                {
                    index = T0 + 112;
                }

                /* find T0_min and T0_max for second subframe */

                _T0_min = T0 - 5;
                if (_T0_min < pit_min)
                {
                    _T0_min = pit_min;
                }
                _T0_max = _T0_min + 9;
                if (_T0_max > pit_max)
                {
                    _T0_max = pit_max;
                    _T0_min = _T0_max - 9;
                }
            }

            else /* second subframe */
            {
                index = T0 - _T0_min;
                index = index * 3 + 2 + T0_frac;
            }

            T0_min.value = _T0_min;
            T0_max.value = _T0_max;
            return(index);
        }
コード例 #2
0
ファイル: Postfil.cs プロジェクト: starburst997/GroovyCodecs
        /**
         * Computes best (shortest) integer LTP delay + fine search
         *
         * @param t0                input : pitch delay given by coder
         * @param ptr_sig_in        input : input signal (with delay line)
         * @param ptr_sig_in_offset input : input signal offset
         * @param ltpdel            output: delay = *ltpdel - *phase / f_up
         * @param phase             output: phase
         * @param num_gltp          output: numerator of LTP gain
         * @param den_gltp          output: denominator of LTP gain
         * @param y_up
         * @param off_yup
         */
        private void search_del(
            int t0,
            float[] ptr_sig_in,
            int ptr_sig_in_offset,
            IntReference ltpdel,
            IntReference phase,
            FloatReference num_gltp,
            FloatReference den_gltp,
            float[] y_up,
            IntReference off_yup
            )
        {
            var tab_hup_s = TabLd8k.tab_hup_s;

            /* pointers on tables of constants */
            int ptr_h;

            /* Variables and local arrays */
            float[] tab_den0 = new float[F_UP_PST - 1], tab_den1 = new float[F_UP_PST - 1];
            int     ptr_den0, ptr_den1;
            int     ptr_sig_past, ptr_sig_past0;
            int     ptr1;

            int   i, n, ioff, i_max;
            float ener, num, numsq, den0, den1;
            float den_int, num_int;
            float den_max, num_max, numsq_max;
            int   phi_max;
            int   lambda, phi;
            float temp0, temp1;
            int   ptr_y_up;

            /* Compute current signal energy         */
            ener = 0.0f;
            for (i = 0; i < L_SUBFR; i++)
            {
                ener += ptr_sig_in[ptr_sig_in_offset + i] * ptr_sig_in[ptr_sig_in_offset + i];
            }
            if (ener < 0.1f)
            {
                num_gltp.value = 0.0f;
                den_gltp.value = 1.0f;
                ltpdel.value   = 0;
                phase.value    = 0;
                return;
            }

            /* Selects best of 3 integer delays  */
            /* Maximum of 3 numerators around t0 */
            /* coder LTP delay                   */

            lambda = t0 - 1;

            ptr_sig_past = ptr_sig_in_offset - lambda;

            num_int = -1.0e30f;

            /* initialization used only to suppress Microsoft Visual C++ warnings */
            i_max = 0;
            for (i = 0; i < 3; i++)
            {
                num = 0.0f;
                for (n = 0; n < L_SUBFR; n++)
                {
                    num += ptr_sig_in[ptr_sig_in_offset + n] * ptr_sig_in[ptr_sig_past + n];
                }
                if (num > num_int)
                {
                    i_max   = i;
                    num_int = num;
                }

                ptr_sig_past--;
            }

            if (num_int <= 0.0f)
            {
                num_gltp.value = 0.0f;
                den_gltp.value = 1.0f;
                ltpdel.value   = 0;
                phase.value    = 0;
                return;
            }

            /* Calculates denominator for lambda_max */
            lambda      += i_max;
            ptr_sig_past = ptr_sig_in_offset - lambda;
            den_int      = 0.0f;
            for (n = 0; n < L_SUBFR; n++)
            {
                den_int += ptr_sig_in[ptr_sig_past + n] * ptr_sig_in[ptr_sig_past + n];
            }
            if (den_int < 0.1f)
            {
                num_gltp.value = 0.0f;
                den_gltp.value = 1.0f;
                ltpdel.value   = 0;
                phase.value    = 0;
                return;
            }
            /* Select best phase around lambda */

            /* Compute y_up & denominators */
            ptr_y_up      = 0;
            den_max       = den_int;
            ptr_den0      = 0;
            ptr_den1      = 0;
            ptr_h         = 0;
            ptr_sig_past0 = ptr_sig_in_offset + LH_UP_S - 1 - lambda; /* points on lambda_max+1 */

            /* loop on phase  */
            for (phi = 1; phi < F_UP_PST; phi++)
            {
                /* Computes criterion for (lambda_max+1) - phi/F_UP_PST     */
                /* and lambda_max - phi/F_UP_PST                            */
                ptr_sig_past = ptr_sig_past0;
                /* computes y_up[n] */
                for (n = 0; n <= L_SUBFR; n++)
                {
                    ptr1  = ptr_sig_past++;
                    temp0 = 0.0f;
                    for (i = 0; i < LH2_S; i++)
                    {
                        temp0 += tab_hup_s[ptr_h + i] * ptr_sig_in[ptr1 - i];
                    }
                    y_up[ptr_y_up + n] = temp0;
                }

                /* recursive computation of den0 (lambda_max+1) and den1 (lambda_max) */

                /* common part to den0 and den1 */
                temp0 = 0.0f;
                for (n = 1; n < L_SUBFR; n++)
                {
                    temp0 += y_up[ptr_y_up + n] * y_up[ptr_y_up + n];
                }

                /* den0 */
                den0 = temp0 + y_up[ptr_y_up + 0] * y_up[ptr_y_up + 0];
                tab_den0[ptr_den0] = den0;
                ptr_den0++;

                /* den1 */
                den1 = temp0 + y_up[ptr_y_up + L_SUBFR] * y_up[ptr_y_up + L_SUBFR];
                tab_den1[ptr_den1] = den1;
                ptr_den1++;

                if (Math.Abs(y_up[ptr_y_up + 0]) > Math.Abs(y_up[ptr_y_up + L_SUBFR]))
                {
                    if (den0 > den_max)
                    {
                        den_max = den0;
                    }
                }
                else
                {
                    if (den1 > den_max)
                    {
                        den_max = den1;
                    }
                }

                ptr_y_up += L_SUBFRP1;
                ptr_h    += LH2_S;
            }

            if (den_max < 0.1f)
            {
                num_gltp.value = 0.0f;
                den_gltp.value = 1.0f;
                ltpdel.value   = 0;
                phase.value    = 0;
                return;
            }
            /* Computation of the numerators                */
            /* and selection of best num*num/den            */
            /* for non null phases                          */

            /* Initialize with null phase */
            num_max   = num_int;
            den_max   = den_int;
            numsq_max = num_max * num_max;
            phi_max   = 0;
            ioff      = 1;

            ptr_den0 = 0;
            ptr_den1 = 0;
            ptr_y_up = 0;

            /* if den_max = 0 : will be selected and declared unvoiced */
            /* if num!=0 & den=0 : will be selected and declared unvoiced */
            /* degenerated seldom cases, switch off LT is OK */

            /* Loop on phase */
            for (phi = 1; phi < F_UP_PST; phi++)
            {
                /* computes num for lambda_max+1 - phi/F_UP_PST */
                num = 0.0f;
                for (n = 0; n < L_SUBFR; n++)
                {
                    num += ptr_sig_in[n] * y_up[ptr_y_up + n];
                }
                if (num < 0.0f)
                {
                    num = 0.0f;
                }
                numsq = num * num;

                /* selection if num/sqrt(den0) max */
                den0 = tab_den0[ptr_den0];
                ptr_den0++;
                temp0 = numsq * den_max;
                temp1 = numsq_max * den0;
                if (temp0 > temp1)
                {
                    num_max   = num;
                    numsq_max = numsq;
                    den_max   = den0;
                    ioff      = 0;
                    phi_max   = phi;
                }

                /* computes num for lambda_max - phi/F_UP_PST */
                ptr_y_up++;
                num = 0.0f;
                for (n = 0; n < L_SUBFR; n++)
                {
                    num += ptr_sig_in[n] * y_up[ptr_y_up + n];
                }
                if (num < 0.0f)
                {
                    num = 0.0f;
                }
                numsq = num * num;

                /* selection if num/sqrt(den1) max */
                den1 = tab_den1[ptr_den1];
                ptr_den1++;
                temp0 = numsq * den_max;
                temp1 = numsq_max * den1;
                if (temp0 > temp1)
                {
                    num_max   = num;
                    numsq_max = numsq;
                    den_max   = den1;
                    ioff      = 1;
                    phi_max   = phi;
                }

                ptr_y_up += L_SUBFR;
            }

            /* test if normalised crit0[iopt] > THRESCRIT  */

            if (num_max == 0.0f || den_max <= 0.1f)
            {
                num_gltp.value = 0.0f;
                den_gltp.value = 1.0f;
                ltpdel.value   = 0;
                phase.value    = 0;
                return;
            }

            /* comparison num * num            */
            /* with ener * den x THRESCRIT      */
            temp1 = den_max * ener * THRESCRIT;
            if (numsq_max >= temp1)
            {
                ltpdel.value   = lambda + 1 - ioff;
                off_yup.value  = ioff;
                phase.value    = phi_max;
                num_gltp.value = num_max;
                den_gltp.value = den_max;
            }
            else
            {
                num_gltp.value = 0.0f;
                den_gltp.value = 1.0f;
                ltpdel.value   = 0;
                phase.value    = 0;
            }
        }
コード例 #3
0
        /**
         * Find the pitch period  with 1/3 subsample resolution
         *
         * @param exc           input : excitation buffer
         * @param exc_offset    input : excitation buffer offset
         * @param xn            input : target vector
         * @param h             input : impulse response of filters.
         * @param l_subfr       input : Length of frame to compute pitch
         * @param t0_min        input : minimum value in the searched range
         * @param t0_max        input : maximum value in the searched range
         * @param i_subfr       input : indicator for first subframe
         * @param pit_frac      output: chosen fraction
         * @return          integer part of pitch period
         */

        public static int pitch_fr3(
            float[] exc,          /*                  */
            int exc_offset,
            float[] xn,           /*                        */
            float[] h,            /*        */
            int l_subfr,          /*     */
            int t0_min,           /*  */
            int t0_max,           /*  */
            int i_subfr,          /*         */
            IntReference pit_frac /*                      */
            )
        {
            var L_INTER4 = Ld8k.L_INTER4;

            int   i, frac;
            int   lag, t_min, t_max;
            float max;
            float corr_int;
            var   corr_v = new float[10 + 2 * L_INTER4]; /* size: 2*L_INTER4+t0_max-t0_min+1 */

            float[] corr;
            int     corr_offset;

            /* Find interval to compute normalized correlation */

            t_min = t0_min - L_INTER4;
            t_max = t0_max + L_INTER4;

            corr        = corr_v; /* corr[t_min:t_max] */
            corr_offset = -t_min;

            /* Compute normalized correlation between target and filtered excitation */

            norm_corr(exc, exc_offset, xn, h, l_subfr, t_min, t_max, corr, corr_offset);

            /* find integer pitch */

            max = corr[corr_offset + t0_min];
            lag = t0_min;

            for (i = t0_min + 1; i <= t0_max; i++)
            {
                if (corr[corr_offset + i] >= max)
                {
                    max = corr[corr_offset + i];
                    lag = i;
                }
            }

            /* If first subframe and lag > 84 do not search fractionnal pitch */

            if (i_subfr == 0 && lag > 84)
            {
                pit_frac.value = 0;
                return(lag);
            }

            /* test the fractions around lag and choose the one which maximizes
             * the interpolated normalized correlation */
            corr_offset += lag;
            max          = interpol_3(corr, corr_offset, -2);
            frac         = -2;

            for (i = -1; i <= 2; i++)
            {
                corr_int = interpol_3(corr, corr_offset, i);
                if (corr_int > max)
                {
                    max  = corr_int;
                    frac = i;
                }
            }

            /* limit the fraction value in the interval [-1,0,1] */

            if (frac == -2)
            {
                frac = 1;
                lag -= 1;
            }

            if (frac == 2)
            {
                frac = -1;
                lag += 1;
            }

            pit_frac.value = frac;

            return(lag);
        }
コード例 #4
0
ファイル: Postfil.cs プロジェクト: starburst997/GroovyCodecs
        /**
         * Harmonic postfilter
         *
         * @param t0                    input : pitch delay given by coder
         * @param ptr_sig_in            input : postfilter input filter (residu2)
         * @param ptr_sig_in_offset     input : postfilter input filter offset
         * @param ptr_sig_pst0          output: harmonic postfilter output
         * @param ptr_sig_pst0_offset   input: harmonic postfilter offset
         * @return                      voicing decision 0 = uv,  > 0 delay
         */
        private int pst_ltp(
            int t0,
            float[] ptr_sig_in,
            int ptr_sig_in_offset,
            float[] ptr_sig_pst0,
            int ptr_sig_pst0_offset
            )
        {
            int vo;

            /* Declare variables                                 */
            int   ltpdel, phase;
            float num_gltp, den_gltp;
            float num2_gltp, den2_gltp;
            float gain_plt;
            var   y_up = new float[SIZ_Y_UP];

            float[] ptr_y_up;
            int     ptr_y_up_offset;
            int     off_yup;

            /* Sub optimal delay search */
            var _ltpdel   = new IntReference();
            var _phase    = new IntReference();
            var _num_gltp = new FloatReference();
            var _den_gltp = new FloatReference();
            var _off_yup  = new IntReference();

            search_del(
                t0,
                ptr_sig_in,
                ptr_sig_in_offset,
                _ltpdel,
                _phase,
                _num_gltp,
                _den_gltp,
                y_up,
                _off_yup);
            ltpdel   = _ltpdel.value;
            phase    = _phase.value;
            num_gltp = _num_gltp.value;
            den_gltp = _den_gltp.value;
            off_yup  = _off_yup.value;

            vo = ltpdel;

            if (num_gltp == 0.0f)
            {
                Util.copy(ptr_sig_in, ptr_sig_in_offset, ptr_sig_pst0, ptr_sig_pst0_offset, L_SUBFR);
            }
            else
            {
                if (phase == 0)
                {
                    ptr_y_up        = ptr_sig_in;
                    ptr_y_up_offset = ptr_sig_in_offset - ltpdel;
                }

                else
                {
                    /* Filtering with long filter */
                    var _num2_gltp = new FloatReference();
                    var _den2_gltp = new FloatReference();
                    compute_ltp_l(
                        ptr_sig_in,
                        ptr_sig_in_offset,
                        ltpdel,
                        phase,
                        ptr_sig_pst0,
                        ptr_sig_pst0_offset,
                        _num2_gltp,
                        _den2_gltp);
                    num2_gltp = _num2_gltp.value;
                    den2_gltp = _den2_gltp.value;

                    if (select_ltp(num_gltp, den_gltp, num2_gltp, den2_gltp) == 1)
                    {
                        /* select short filter */
                        ptr_y_up        = y_up;
                        ptr_y_up_offset = (phase - 1) * L_SUBFRP1 + off_yup;
                    }
                    else
                    {
                        /* select long filter */
                        num_gltp        = num2_gltp;
                        den_gltp        = den2_gltp;
                        ptr_y_up        = ptr_sig_pst0;
                        ptr_y_up_offset = ptr_sig_pst0_offset;
                    }
                }

                if (num_gltp > den_gltp)
                {
                    gain_plt = MIN_GPLT;
                }
                else
                {
                    gain_plt = den_gltp / (den_gltp + GAMMA_G * num_gltp);
                }

                /* filtering by H0(z) (harmonic filter) */
                filt_plt(
                    ptr_sig_in,
                    ptr_sig_in_offset,
                    ptr_y_up,
                    ptr_y_up_offset,
                    ptr_sig_pst0,
                    ptr_sig_pst0_offset,
                    gain_plt);
            }

            return(vo);
        }