File: lpanal.c

package info (click to toggle)
audacity 2.0.6-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 80,076 kB
  • sloc: cpp: 192,859; ansic: 158,072; sh: 34,021; python: 24,248; lisp: 7,495; makefile: 3,667; xml: 573; perl: 31; sed: 16
file content (177 lines) | stat: -rw-r--r-- 3,801 bytes parent folder | download | duplicates (14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/* lpc.c -- implement LPC analysis */

#include <math.h>

#ifndef mips
#include "stdlib.h"
#endif
#include "xlisp.h"


void abs_max(double *x, long desde, long hasta, double *x_maxptr, long *indptr)
{
              /*  use:
	                  abs_max(s,0,10,&mimax,&miind);
	          */

	double x_max = x[desde];
	long ind = desde;
	long i;
	for(i = desde+1; i<hasta; i++)
		if (fabs(x[i]) > x_max)
		{
			x_max = fabs(x[i]);
            ind = i;
		}
	*x_maxptr = x_max;
	*indptr = ind;

}

void xcorr(double *s, double *rxx, long N)
{
	/* use:
	xcorr(s,rxx,N);
	*/
	long i,j;
	for(i=0; i < N; i++)
	{
		rxx[i] = 0.0;
		for(j=0; j < N-i; j++)
			rxx[i] += s[j]*s[j+i]; 
    }
}




// SOUND PARAMETERS
// w         Lisp vector containinig signal values
// P         number of poles
// N         length of sound

// AUTOCORRELEATION PARAMETERS
// rxx       array containing autocorrelation coefs
// max_rxx   temporal maximun value of rxx
// i_max     index of max_rxx

// LPC PARAMETERS
// alpha     array of filter coefs
// k         reflection coef
// E         residual energy
// rms1      energy of input signal (not RMS)
// rms2      residual energy = E    
// unv       voiced/unvoiced parameter = ERR = rms2/rms1

// PITCH DETECTION ALGORITHM: Implemented separately



LVAL snd_lpanal(LVAL w, long P)
{
    
	double *s, *rxx;
	long N;
	double *alpha;
	// double *k, *E; THIS ONLY FOR VECTORIZED k AND E
	double k, E;
	double rms1; // rms2=E;
	double unv;
	double suma, alphatemp; // help variables
	

	long i,j;
	LVAL result;

	xlsave1(result);



	//// end vars /////////////



	//// allocate memory ///////
    N = getsize(w);
	s   = calloc(sizeof(double),N); //signal
    rxx = calloc(sizeof(double),N); //autocorrelation
	alpha = calloc(sizeof(double), P); // filter coefs
	//k = calloc(sizeof(double), P); // reflection coefs
	//E = calloc(sizeof(double), P); // residual energy
    

	//////   copy Lisp array sound data to array of double ///////
	for(i=0; i<N; i++)
		s[i] = getflonum(getelement(w,i));

    /////   autocorrelation  ////////////////

	xcorr(s,rxx,N); // this may be optimized as only P autocorr factors are needed (not N)


	////////     LPC   analysis    //////////////////////////////////
    
	/// Durbin algorithm

	/// inicialization
    //for(i=0; i<P;i++)
	//	alpha[i]=k[i]=E[i]=0.0; // don't need this. Done by default.
	
	//E[0] = rxx[0] - pow(rxx[1],2)/rxx[0];	
	//k[0] = rxx[1]/rxx[0];
	//alpha[0] = k[0];
	E = rxx[0] - pow(rxx[1],2)/rxx[0]; // NO VECTORS k OR E	
	k = rxx[1]/rxx[0];                 //
	alpha[0] = k;                      //

	/// recursive solve
	for(i=1;i<P;i++)
	{
		suma=0.0;
		for(j=0;j<i;j++)
			suma += alpha[j] * rxx[i-j];
		//k[i] = (rxx[i+1]-suma)/E[i-1];
		//alpha[i]=k[i];
		k = (rxx[i+1]-suma)/E;
        alpha[i]=k;
		for(j=0; j <= ((i-1) >> 1); j++)
		{
			//alphatemp = alpha[j] - k[i] * alpha[i-j-1];
			//alpha[i-j-1] -= k[i] * alpha[j];
			//alpha[j] = alphatemp;
			alphatemp = alpha[j] - k * alpha[i-j-1];
			alpha[i-j-1] -= k * alpha[j];
			alpha[j] = alphatemp;

		}
		//E[i] = E[i-1] * (1 - pow(k[i],2));
		E *= (1 - pow(k,2));

	}

	// input signal energy = rxx[0];
	rms1 = rxx[0];

    // voiced/unvoiced
	unv= sqrt(E/rms1); 

    ///// HERE: CHECK STABILITY AND MODIFY COEFS  /////////////
    /////       not implemented

	

	// prepare output result
     result = newvector(P);
     for (i = 0; i < P; i++) setelement(result, i, cvflonum(alpha[P-i-1])); // alpoles format
     
	xlpop();	
	
	// free memory
	free(s); free(rxx); free(alpha);

	return (cons  (cvflonum(rms1),                    // input signal energy
		          cons(cvflonum(E),                   // residual energy
		          cons(cvflonum(unv),                 // ERR, voiced/unvoiced
				  cons(result,  NULL)))));           // coefs

}