Added 3-tap pitch predictor by analysis by synthesis
[speexdsp.git] / libspeex / cb_search.c
1 /*-----------------------------------------------------------------------*\
2
3     FILE........: GAINSHAPE.C
4     TYPE........: C Module
5     AUTHOR......: David Rowe
6     COMPANY.....: Voicetronix
7     DATE CREATED: 19/2/02
8
9     General gain-shape codebook search.
10
11 \*-----------------------------------------------------------------------*/
12
13 /* Modified by Jean-Marc Valin 2002 */
14
15
16 #include <stdlib.h>
17 #include <cb_search.h>
18 #include "filters.h"
19
20 #define min(a,b) ((a) < (b) ? (a) : (b))
21
22 /*---------------------------------------------------------------------------*\
23                                                                              
24  void overlap_cb_search()                                                             
25                                                                               
26  Searches a gain/shape codebook consisting of overlapping entries for the    
27  closest vector to the target.  Gives identical results to search() above   
28  buts uses fast end correction algorithm for the synthesis of response       
29  vectors.                                                                     
30                                                                              
31 \*---------------------------------------------------------------------------*/
32
33 void overlap_cb_search(
34 float target[],                 /* target vector */
35 float ak[],                     /* LPCs for this subframe */
36 float awk1[],                   /* Weighted LPCs for this subframe */
37 float awk2[],                   /* Weighted LPCs for this subframe */
38 float codebook[],               /* overlapping codebook */
39 int   entries,                  /* number of overlapping entries to search */
40 float *gain,                    /* gain of optimum entry */
41 int   *index,                   /* index of optimum entry */
42 int   p,                        /* number of LPC coeffs */
43 int   nsf                       /* number of samples in subframe */
44 )
45 {
46   float *resp;                  /* zero state response to current entry */
47   float *h;                     /* impulse response of synthesis filter */
48   float *impulse;               /* excitation vector containing one impulse */
49   float d,e,g,score;            /* codebook searching variables */
50   float bscore;                 /* score of "best" vector so far */
51   int i,k;                      /* loop variables */
52
53   /* Initialise */
54   
55   resp = (float*)malloc(sizeof(float)*nsf);
56   h = (float*)malloc(sizeof(float)*nsf);
57   impulse = (float*)malloc(sizeof(float)*nsf);
58
59   for(i=0; i<nsf; i++)
60     impulse[i] = 0.0;
61    
62   *gain = 0.0;
63   *index = 0;
64   bscore = 0.0;
65   impulse[0] = 1.0;
66
67   /* Calculate impulse response of  A(z/g2) / ( A(z)*(z/g1) ) */
68   residue_zero(impulse, awk1, h, nsf, p);
69   syn_filt_zero(h, ak, h, nsf, p);
70   syn_filt_zero(h, awk2, h, nsf,p);
71   
72   /* Calculate codebook zero-response */
73   residue_zero(&codebook[entries-1],awk1,resp,nsf,p);
74   syn_filt_zero(resp,ak,resp,nsf,p);
75   syn_filt_zero(resp,awk2,resp,nsf,p);
76     
77   /* Search codebook backwards using end correction for synthesis */
78   
79   for(k=entries-1; k>=0; k--) {
80
81     d = 0.0; e = 0.0;
82     for(i=0; i<nsf; i++) {
83       d += target[i]*resp[i];
84       e += resp[i]*resp[i]+1;
85     }
86     g = d/e;
87     score = g*d;
88     /*printf ("score: %f %f %f %f\n", target[0],d,e,score);*/
89     if (score >= bscore) {
90       bscore = score;
91       *gain = g;
92       *index = k;
93     }
94     
95     /* Synthesise next entry */
96     
97     if (k) {
98       for(i=nsf-1; i>=1; i--)
99         resp[i] = resp[i-1] + codebook[k-1]*h[i];
100       resp[0] = codebook[k-1]*h[0];
101     }
102   }
103
104   free(resp);
105   free(h);
106   free(impulse);
107
108 }
109