Esempio n. 1
0
        /**
         * Find the lag that has maximum correlation
         *
         * @param signal            input : Signal to compute the open loop pitch
         *                          signal[-142:-1] should be known.
         * @param signal_offset     input : signal offset
         * @param l_frame           input : Length of frame to compute pitch
         * @param lagmax            input : maximum lag
         * @param lagmin            input : minimum lag
         * @param cor_max           input : normalized correlation of selected lag
         * @return lag found
         */
        private static int lag_max(
            float[] signal,
            int signal_offset,
            int l_frame,
            int lagmax,
            int lagmin,
            FloatReference cor_max
            )
        {
            var FLT_MIN_G729 = Ld8k.FLT_MIN_G729;

            int   i, j;
            int   p, p1;
            float max, t0;
            var   p_max = 0;

            max = FLT_MIN_G729;

            for (i = lagmax; i >= lagmin; i--)
            {
                p  = signal_offset;
                p1 = signal_offset - i;
                t0 = 0.0f;

                for (j = 0; j < l_frame; j++, p++, p1++)
                {
                    t0 += signal[p] * signal[p1];
                }

                if (t0 >= max)
                {
                    max   = t0;
                    p_max = i;
                }
            }

            /* compute energy */

            t0 = 0.01f; /* to avoid division by zero */
            p  = signal_offset - p_max;
            for (i = 0; i < l_frame; i++, p++)
            {
                t0 += signal[p] * signal[p];
            }
            t0 = inv_sqrt(t0);        /* 1/sqrt(energy)    */

            cor_max.value = max * t0; /* max/sqrt(energy)  */

            return(p_max);
        }
Esempio n. 2
0
        /**
         * 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;
            }
        }
Esempio n. 3
0
        /**
         * Compute delayed signal,
         * num & den of gain for fractional delay
         * with long interpolation filter
         *
         * @param s_in           input signal with past
         * @param s_in_offset    input signal with past
         * @param ltpdel         delay factor
         * @param phase          phase factor
         * @param y_up           delayed signal
         * @param y_up_offset    delayed signal offset
         * @param num            numerator of LTP gain
         * @param den            denominator of LTP gain
         */
        private void compute_ltp_l(
            float[] s_in,
            int s_in_offset,
            int ltpdel,
            int phase,
            float[] y_up,
            int y_up_offset,
            FloatReference num,
            FloatReference den
            )
        {
            var tab_hup_l = TabLd8k.tab_hup_l;

            /* Pointer on table of constants */
            int ptr_h;

            /* Local variables */
            int   i;
            int   ptr2;
            float temp;

            /* Filtering with long filter */
            ptr_h = (phase - 1) * LH2_L;
            ptr2  = s_in_offset - ltpdel + LH_UP_L;

            /* Compute y_up */
            for (int n = y_up_offset, toIndex = y_up_offset + L_SUBFR; n < toIndex; n++)
            {
                temp = 0.0f;
                for (i = 0; i < LH2_L; i++)
                {
                    temp += tab_hup_l[ptr_h + i] * s_in[ptr2];
                    ptr2--;
                }

                y_up[n] = temp;
                ptr2   += LH2_L_P1;
            }

            var _num = 0.0f;

            /* Compute num */
            for (var n = 0; n < L_SUBFR; n++)
            {
                _num += y_up[y_up_offset + n] * s_in[s_in_offset + n];
            }
            if (_num < 0.0f)
            {
                _num = 0.0f;
            }
            num.value = _num;

            var _den = 0.0f;

            /* Compute den */
            for (int n = y_up_offset, toIndex = y_up_offset + L_SUBFR; n < toIndex; n++)
            {
                _den += y_up[n] * y_up[n];
            }
            den.value = _den;
        }
Esempio n. 4
0
        /**
         * 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);
        }