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
|
#include "pv.h"
/* S is a spectrum in rfft format, i.e., it contains N real values
arranged as real followed by imaginary values, except for first
two values, which are real parts of 0 and Nyquist frequencies;
convert first changes these into N/2+1 PAIRS of magnitude and
phase values to be stored in output array C; the phases are then
unwrapped and successive phase differences are used to compute
estimates of the instantaneous frequencies for each phase vocoder
analysis channel; decimation rate D and sampling rate R are used
to render these frequency values directly in Hz. */
void convert(float *S, float *C, int N2, float *lastphase, float fundamental, float factor )
{
float phase, phasediff;
int even,odd;
float a,b;
int i;
for ( i = 0; i <= N2; i++ ) {
odd = ( even = i<<1 ) + 1;
a = ( i == N2 ? S[1] : S[even] );
b = ( i == 0 || i == N2 ? 0. : S[odd] );
C[even] = hypot( a, b );
if ( C[even] == 0. )
phasediff = 0.;
else {
phasediff = ( phase = -atan2( b, a ) ) - lastphase[i];
lastphase[i] = phase;
while ( phasediff > PV_PI ) phasediff -= PV_2PI;
while ( phasediff < -PV_PI ) phasediff += PV_2PI;
}
C[odd] = phasediff*factor + i*fundamental;
}
}
void unconvert(float *C, float *S, int N2, float *lastphase, float fundamental, float factor )
{
int i,even,odd;
float mag,phase;
for ( i = 0; i <= N2; i++ ) {
odd = ( even = i<<1 ) + 1;
mag = C[even];
lastphase[i] += C[odd] - i*fundamental;
phase = lastphase[i]*factor;
if(i != N2) {
S[even] = mag*cos( phase );
S[odd] = -mag*sin( phase );
}
else
S[1] = mag*cos( phase );
}
}
|