⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psearch.c

📁 HawkVoiceDI Project created and maintained by Phil Frisbie, Jr. <phil@hawksoft.com> HawkVoiceD
💻 C
字号:
/*
  CELP voice codec, part of the HawkVoice Direct Interface (HVDI)
  cross platform network voice library
  Copyright (C) 2001-2003 Phil Frisbie, Jr. (phil@hawksoft.com)

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.
    
  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA  02111-1307, USA.
      
  Or go to http://www.gnu.org/copyleft/lgpl.html
*/

#include <memory.h>
#include "celpint.h"

#define LEN		30  /* *length of truncated impulse response	 */
#define MAXBUFPTR	MMAX + MAXNO + 2  * MAXLP + MAXNP - 1

static int submult[MAXPD][4] = 
{
#include "submult.h"      /* *load pitch submultiple delay table   	 */
    
};
extern float h[MAXLP], pdelay[MAXPD];

extern float pitchencode(float input, int *index);
extern float pgain(float *ex, int l, int first, int m, int len, float *match, celp_encoder_state *st);

static void movefr(int n, float *a, float *b)
{
    int i;
    
    for (i = 0; i < n; i++)
        *b++ = *a++;
}

void psearch(int l, int *pindex, celp_encoder_state *st, int *tauptr, int *minptr, float *d1b)
{
    int i, m, lag, start;
    int first, bigptr, subptr, topptr, maxptr, bufptr;
    float g[MAXPD], match[MAXPD], emax;
    
    /*	See warning below ----------------  \/ max (MAXL, MAXLP)	*/
    
    float v0[MAXBUFPTR], v0shift[MAXLP], frac;
    
    /* *initialize arrays							 */
    memset(v0, 0, sizeof(v0));
    memset(v0shift, 0, sizeof(v0shift));
    memset(g, 0, sizeof(g));
    memset(match, 0, sizeof(match));
    
    bufptr = MMAX + 10 + 2*l + MAXNP - 1;
    
    /* *update adaptive code book (pitch memory)				 */
    
    movefr(st->idb, d1b, &v0[bufptr - st->idb - l]);
    
    /* *initial conditions						 */
    
    if (st->nseg == 1)
    {
        st->bb[2] = 0.0;
        st->bb[0] = MMIN;
    }
    else
    {
        
        /*		*find allowable pointer range (minptr to maxptr)	 */
        
        if ((st->nseg % 2) == 0)
        {
            
            /* *delta delay coding on even subframes		 		 */
            
            *minptr = st->oldptr - (st->plevel2/2 - 1);
            maxptr = st->oldptr + (st->plevel2/2);
            if (*minptr < 0)
            {
                *minptr = 0;
                maxptr = st->plevel2 - 1;
            }
            if (maxptr > st->plevel1 - 1)
            {
                maxptr = st->plevel1 - 1;
                *minptr = st->plevel1 - st->plevel2;
            }
        }
        else
        {
            
            /* *full range coding on odd subframes				 */
            
            *minptr = 0;
            maxptr = st->plevel1 - 1;
        }
        
        start = bufptr - l + 1;
        
        
        /* *find gain and match score for integer pitch delays		 */
        /* *(using end-point correction on unity spaced delays)		 */
        
        first = TRUE;
        for (i = *minptr; i <= maxptr; i++)
        {
            m = (int) pdelay[i];
            frac = pdelay[i] - m;
            if (frac < 1.e-4f && frac > -1.e-4f)
            {
                lag = start - m;
                g[i] = pgain(&v0[lag-1], l, first, m, LEN, &match[i], st);
                first = FALSE;
            }
            else
                match[i] = 0.0f;
        }
        
        /* *find pointer to top (MSPE) match score (topptr)			 */
        /* *search for best match score (max -error term)			 */
        
        topptr = *minptr;
        emax = match[topptr];
        for (i = *minptr; i <= maxptr; i++)
        {
            if (match[i] > emax)
            {
                topptr = i;
                emax = match[topptr];
            }
        }
        
        /* *for full search (odd) subframes:				 */
        /* *select shortest delay of 2, 3, or 4 submultiples. if its match   */
        /* *is within 1 dB of MSPE to favor smooth "pitch"			 */
        
        *tauptr = topptr;
        if ((st->nseg % 2) != 0)
        {
            
            /* *for each submultiple {2, 3 & 4}				 */
            
            for (i = 1; i <= submult[topptr][0]; i++)
            {
                
                /* *find best neighborhood match for given submultiple	 */
                
                bigptr = submult[topptr][i];
                for (subptr = mmax(submult[topptr][i] - 8, *minptr); subptr <= 
                    mmin(submult[topptr][i] + 8, maxptr); subptr++)
                {
                    if (match[subptr] > match[bigptr])
                        bigptr = subptr;
                }
                
                /* *select submultiple match if within 1 dB MSPE match	 */
                
                if (match[bigptr] >= 0.88f * match[topptr])
                {
                    *tauptr = bigptr;
                }
            }
        }
        
        /* *place pitch parameters in common bb "structure"			 */
        
        st->bb[2] = g[*tauptr];
        st->bb[0] = pdelay[*tauptr];
        
        /* *save pitch pointer to determine delta delay			 */
        
        st->oldptr = *tauptr;
        
  }
  
  /* *pitch quantization bb[2]						 */
  
  st->bb[2] = pitchencode(st->bb[2], pindex);
}

⌨️ 快捷键说明

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