| 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 } |