comparison dsp/phasevocoder/PhaseVocoder.cpp @ 119:2020c73dc997 pvoc

Phase vocoder: provide time-domain and freq-domain inputs separately; update tests etc
author Chris Cannam
date Thu, 03 Oct 2013 12:58:36 +0100
parents f3c69325cca2
children be6d811fd81f
comparison
equal deleted inserted replaced
118:4920d100b290 119:2020c73dc997
16 #include "PhaseVocoder.h" 16 #include "PhaseVocoder.h"
17 #include "dsp/transforms/FFT.h" 17 #include "dsp/transforms/FFT.h"
18 #include "maths/MathUtilities.h" 18 #include "maths/MathUtilities.h"
19 #include <math.h> 19 #include <math.h>
20 20
21 #include <cassert>
22
21 #include <iostream> 23 #include <iostream>
22 using std::cerr; 24 using std::cerr;
23 using std::endl; 25 using std::endl;
24 26
25 PhaseVocoder::PhaseVocoder(int n, int hop) : 27 PhaseVocoder::PhaseVocoder(int n, int hop) :
26 m_n(n), 28 m_n(n),
27 m_hop(hop) 29 m_hop(hop)
28 { 30 {
29 m_fft = new FFTReal(m_n); 31 m_fft = new FFTReal(m_n);
32 m_time = new double[m_n];
30 m_real = new double[m_n]; 33 m_real = new double[m_n];
31 m_imag = new double[m_n]; 34 m_imag = new double[m_n];
32 m_phase = new double[m_n/2 + 1]; 35 m_phase = new double[m_n/2 + 1];
33 m_unwrapped = new double[m_n/2 + 1]; 36 m_unwrapped = new double[m_n/2 + 1];
34 37
40 reset(); 43 reset();
41 } 44 }
42 45
43 PhaseVocoder::~PhaseVocoder() 46 PhaseVocoder::~PhaseVocoder()
44 { 47 {
45 delete [] m_unwrapped; 48 delete[] m_unwrapped;
46 delete [] m_phase; 49 delete[] m_phase;
47 delete [] m_real; 50 delete[] m_real;
48 delete [] m_imag; 51 delete[] m_imag;
52 delete[] m_time;
49 delete m_fft; 53 delete m_fft;
50 } 54 }
51 55
52 void PhaseVocoder::FFTShift(double *src) 56 void PhaseVocoder::FFTShift(double *src)
53 { 57 {
57 src[i] = src[i + hs]; 61 src[i] = src[i + hs];
58 src[i + hs] = tmp; 62 src[i + hs] = tmp;
59 } 63 }
60 } 64 }
61 65
62 void PhaseVocoder::process(double *src, double *mag, double *theta, 66 void PhaseVocoder::processTimeDomain(const double *src,
63 double *unwrapped) 67 double *mag, double *theta,
68 double *unwrapped)
64 { 69 {
65 FFTShift(src); 70 for (int i = 0; i < m_n; ++i) {
66 71 m_time[i] = src[i];
67 m_fft->forward(src, m_real, m_imag); 72 }
73 FFTShift(m_time);
74 m_fft->forward(m_time, m_real, m_imag);
75 getMagnitudes(mag);
76 getPhases(theta);
77 unwrapPhases(theta, unwrapped);
78 }
68 79
80 void PhaseVocoder::processFrequencyDomain(const double *reals,
81 const double *imags,
82 double *mag, double *theta,
83 double *unwrapped)
84 {
85 for (int i = 0; i < m_n/2 + 1; ++i) {
86 m_real[i] = reals[i];
87 m_imag[i] = imags[i];
88 }
69 getMagnitudes(mag); 89 getMagnitudes(mag);
70 getPhases(theta); 90 getPhases(theta);
71 unwrapPhases(theta, unwrapped); 91 unwrapPhases(theta, unwrapped);
72 } 92 }
73 93
100 120
101 void PhaseVocoder::unwrapPhases(double *theta, double *unwrapped) 121 void PhaseVocoder::unwrapPhases(double *theta, double *unwrapped)
102 { 122 {
103 cerr << "PhaseVocoder::unwrapPhases" << endl; 123 cerr << "PhaseVocoder::unwrapPhases" << endl;
104 124
125 //!!! if magnitude in a bin below a threshold, reset stored unwrapped phase angle for that bin
126
105 for (int i = 0; i < m_n/2 + 1; ++i) { 127 for (int i = 0; i < m_n/2 + 1; ++i) {
106 128
107 double omega = (2 * M_PI * m_hop * i) / m_n; 129 double omega = (2 * M_PI * m_hop * i) / m_n;
108 double expected = m_phase[i] + omega; 130 double expected = m_phase[i] + omega;
109 double error = MathUtilities::princarg(theta[i] - expected); 131 double error = MathUtilities::princarg(theta[i] - expected);
110 132
111 unwrapped[i] = m_unwrapped[i] + omega + error; 133 unwrapped[i] = m_unwrapped[i] + omega + error;
112 134
113 cerr << "i = " << i << ", instantaneous phase = " << theta[i] << ", prev phase = " << m_phase[i] << ", omega = " << omega << ", expected = " << expected << ", error = " << error << ", unwrapped = " << unwrapped[i] << endl; 135 cerr << "i = " << i << ", (" << m_real[i] << "," << m_imag[i] << "), instantaneous phase = " << theta[i] << ", prev phase = " << m_phase[i] << ", omega = " << omega << ", expected = " << expected << ", error = " << error << ", unwrapped = " << unwrapped[i] << endl;
114 136
115 m_phase[i] = theta[i]; 137 m_phase[i] = theta[i];
116 m_unwrapped[i] = unwrapped[i]; 138 m_unwrapped[i] = unwrapped[i];
117 } 139 }
118 } 140 }