annotate dsp/phasevocoder/PhaseVocoder.cpp @ 289:befe5aa6b450

* Refactor FFT a little bit so as to separate construction and processing rather than have a single static method -- will make it easier to use a different implementation * pull in KissFFT implementation (not hooked up yet)
author Chris Cannam <c.cannam@qmul.ac.uk>
date Wed, 13 May 2009 09:19:12 +0000
parents 9c403afdd9e9
children e5907ae6de17
rev   line source
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 }