c@225
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
c@225
|
2
|
c@225
|
3 /*
|
c@225
|
4 QM DSP Library
|
c@225
|
5
|
c@225
|
6 Centre for Digital Music, Queen Mary, University of London.
|
c@225
|
7 This file copyright 2005-2006 Christian Landone.
|
c@225
|
8 All rights reserved.
|
c@225
|
9 */
|
c@225
|
10
|
c@225
|
11 #include "PhaseVocoder.h"
|
c@225
|
12 #include "dsp/transforms/FFT.h"
|
c@225
|
13 #include <math.h>
|
c@225
|
14
|
c@225
|
15 //////////////////////////////////////////////////////////////////////
|
c@225
|
16 // Construction/Destruction
|
c@225
|
17 //////////////////////////////////////////////////////////////////////
|
c@225
|
18
|
c@225
|
19 PhaseVocoder::PhaseVocoder()
|
c@225
|
20 {
|
c@225
|
21
|
c@225
|
22 }
|
c@225
|
23
|
c@225
|
24 PhaseVocoder::~PhaseVocoder()
|
c@225
|
25 {
|
c@225
|
26
|
c@225
|
27 }
|
c@225
|
28
|
c@225
|
29 void PhaseVocoder::FFTShift(unsigned int size, double *src)
|
c@225
|
30 {
|
c@225
|
31 // IN-place Rotation of FFT arrays
|
c@225
|
32 unsigned int i;
|
c@225
|
33
|
c@225
|
34 shiftBuffer = new double[size/2];
|
c@225
|
35
|
c@225
|
36 for( i = 0; i < size/2; i++)
|
c@225
|
37 {
|
c@225
|
38 shiftBuffer[ i ] = src[ i ];
|
c@225
|
39 src[ i ] = src[ i + size/2];
|
c@225
|
40 }
|
c@225
|
41
|
c@225
|
42 for( i =size/2; i < size; i++)
|
c@225
|
43 {
|
c@225
|
44 src[ i ] = shiftBuffer[ i -(size/2)];
|
c@225
|
45 }
|
c@225
|
46
|
c@225
|
47 delete [] shiftBuffer;
|
c@225
|
48
|
c@225
|
49 }
|
c@225
|
50
|
c@225
|
51 void PhaseVocoder::process(unsigned int size, double *src, double *mag, double *theta)
|
c@225
|
52 {
|
c@225
|
53
|
c@225
|
54 // Primary Interface to Phase Vocoder
|
c@225
|
55 realOut = new double[ size ];
|
c@225
|
56 imagOut = new double[ size ];
|
c@225
|
57
|
c@225
|
58 FFTShift( size, src);
|
c@225
|
59
|
c@225
|
60 coreFFT( size, src, 0, realOut, imagOut);
|
c@225
|
61
|
c@225
|
62 getMagnitude( size/2, mag, realOut, imagOut);
|
c@225
|
63 getPhase( size/2, theta, realOut, imagOut);
|
c@225
|
64
|
c@225
|
65 delete [] realOut;
|
c@225
|
66 delete [] imagOut;
|
c@225
|
67 }
|
c@225
|
68
|
c@225
|
69
|
c@225
|
70 void PhaseVocoder::coreFFT( unsigned int NumSamples, double *RealIn, double* ImagIn, double *RealOut, double *ImagOut)
|
c@225
|
71 {
|
c@225
|
72 // This function is taken from a standard freeware implementation defined in FFT.h
|
c@225
|
73 // TODO: Use FFTW
|
c@225
|
74 FFT::process( NumSamples,0, RealIn, ImagIn, RealOut, ImagOut );
|
c@225
|
75 }
|
c@225
|
76
|
c@225
|
77 void PhaseVocoder::getMagnitude(unsigned int size, double *mag, double *real, double *imag)
|
c@225
|
78 {
|
c@225
|
79 unsigned int j;
|
c@225
|
80
|
c@225
|
81 for( j = 0; j < size; j++)
|
c@225
|
82 {
|
c@225
|
83 mag[ j ] = sqrt( real[ j ] * real[ j ] + imag[ j ] * imag[ j ]);
|
c@225
|
84 }
|
c@225
|
85 }
|
c@225
|
86
|
c@225
|
87 void PhaseVocoder::getPhase(unsigned int size, double *theta, double *real, double *imag)
|
c@225
|
88 {
|
c@225
|
89 unsigned int k;
|
c@225
|
90
|
c@225
|
91 // Phase Angle "matlab" style
|
c@225
|
92 //Watch out for quadrant mapping !!!
|
c@225
|
93 for( k = 0; k < size; k++)
|
c@225
|
94 {
|
c@225
|
95 theta[ k ] = atan2( -imag[ k ], real[ k ]);
|
c@225
|
96 }
|
c@225
|
97 }
|