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@289
|
19 PhaseVocoder::PhaseVocoder(unsigned int n) :
|
c@289
|
20 m_n(n)
|
c@225
|
21 {
|
c@289
|
22 m_fft = new FFTReal(m_n);
|
c@289
|
23 m_realOut = new double[m_n];
|
c@289
|
24 m_imagOut = new double[m_n];
|
c@225
|
25 }
|
c@225
|
26
|
c@225
|
27 PhaseVocoder::~PhaseVocoder()
|
c@225
|
28 {
|
c@289
|
29 delete [] m_realOut;
|
c@289
|
30 delete [] m_imagOut;
|
c@289
|
31 delete m_fft;
|
c@225
|
32 }
|
c@225
|
33
|
c@225
|
34 void PhaseVocoder::FFTShift(unsigned int size, double *src)
|
c@225
|
35 {
|
c@280
|
36 const int hs = size/2;
|
c@280
|
37 for (int i = 0; i < hs; ++i) {
|
c@280
|
38 double tmp = src[i];
|
c@280
|
39 src[i] = src[i + hs];
|
c@280
|
40 src[i + hs] = tmp;
|
c@225
|
41 }
|
c@225
|
42 }
|
c@225
|
43
|
c@289
|
44 void PhaseVocoder::process(double *src, double *mag, double *theta)
|
c@225
|
45 {
|
c@289
|
46 FFTShift( m_n, src);
|
c@289
|
47
|
c@289
|
48 m_fft->process(0, src, m_realOut, m_imagOut);
|
c@225
|
49
|
c@289
|
50 getMagnitude( m_n/2, mag, m_realOut, m_imagOut);
|
c@289
|
51 getPhase( m_n/2, theta, m_realOut, m_imagOut);
|
c@225
|
52 }
|
c@225
|
53
|
c@225
|
54 void PhaseVocoder::getMagnitude(unsigned int size, double *mag, double *real, double *imag)
|
c@225
|
55 {
|
c@225
|
56 unsigned int j;
|
c@225
|
57
|
c@225
|
58 for( j = 0; j < size; j++)
|
c@225
|
59 {
|
c@225
|
60 mag[ j ] = sqrt( real[ j ] * real[ j ] + imag[ j ] * imag[ j ]);
|
c@225
|
61 }
|
c@225
|
62 }
|
c@225
|
63
|
c@225
|
64 void PhaseVocoder::getPhase(unsigned int size, double *theta, double *real, double *imag)
|
c@225
|
65 {
|
c@225
|
66 unsigned int k;
|
c@225
|
67
|
c@225
|
68 // Phase Angle "matlab" style
|
c@225
|
69 //Watch out for quadrant mapping !!!
|
c@225
|
70 for( k = 0; k < size; k++)
|
c@225
|
71 {
|
c@225
|
72 theta[ k ] = atan2( -imag[ k ], real[ k ]);
|
c@225
|
73 }
|
c@225
|
74 }
|