PhaseVocoder.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  QM DSP Library
5 
6  Centre for Digital Music, Queen Mary, University of London.
7  This file 2005-2006 Christian Landone, copyright 2013 QMUL.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "PhaseVocoder.h"
17 #include "dsp/transforms/FFT.h"
18 #include "maths/MathUtilities.h"
19 #include <math.h>
20 
21 #include <cassert>
22 
23 #include <iostream>
24 using std::cerr;
25 using std::endl;
26 
27 PhaseVocoder::PhaseVocoder(int n, int hop) :
28  m_n(n),
29  m_hop(hop)
30 {
31  m_fft = new FFTReal(m_n);
32  m_time = new double[m_n];
33  m_real = new double[m_n];
34  m_imag = new double[m_n];
35  m_phase = new double[m_n/2 + 1];
36  m_unwrapped = new double[m_n/2 + 1];
37 
38  for (int i = 0; i < m_n/2 + 1; ++i) {
39  m_phase[i] = 0.0;
40  m_unwrapped[i] = 0.0;
41  }
42 
43  reset();
44 }
45 
47 {
48  delete[] m_unwrapped;
49  delete[] m_phase;
50  delete[] m_real;
51  delete[] m_imag;
52  delete[] m_time;
53  delete m_fft;
54 }
55 
56 void PhaseVocoder::FFTShift(double *src)
57 {
58  const int hs = m_n/2;
59  for (int i = 0; i < hs; ++i) {
60  double tmp = src[i];
61  src[i] = src[i + hs];
62  src[i + hs] = tmp;
63  }
64 }
65 
66 void PhaseVocoder::processTimeDomain(const double *src,
67  double *mag, double *theta,
68  double *unwrapped)
69 {
70  for (int i = 0; i < m_n; ++i) {
71  m_time[i] = src[i];
72  }
75  getMagnitudes(mag);
76  getPhases(theta);
77  unwrapPhases(theta, unwrapped);
78 }
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  }
89  getMagnitudes(mag);
90  getPhases(theta);
91  unwrapPhases(theta, unwrapped);
92 }
93 
95 {
96  for (int i = 0; i < m_n/2 + 1; ++i) {
97  // m_phase stores the "previous" phase, so set to one step
98  // behind so that a signal with initial phase at zero matches
99  // the expected values. This is completely unnecessary for any
100  // analytical purpose, it's just tidier.
101  double omega = (2 * M_PI * m_hop * i) / m_n;
102  m_phase[i] = -omega;
103  m_unwrapped[i] = -omega;
104  }
105 }
106 
108 {
109  for (int i = 0; i < m_n/2 + 1; i++) {
110  mag[i] = sqrt(m_real[i] * m_real[i] + m_imag[i] * m_imag[i]);
111  }
112 }
113 
114 void PhaseVocoder::getPhases(double *theta)
115 {
116  for (int i = 0; i < m_n/2 + 1; i++) {
117  theta[i] = atan2(m_imag[i], m_real[i]);
118  }
119 }
120 
121 void PhaseVocoder::unwrapPhases(double *theta, double *unwrapped)
122 {
123  for (int i = 0; i < m_n/2 + 1; ++i) {
124 
125  double omega = (2 * M_PI * m_hop * i) / m_n;
126  double expected = m_phase[i] + omega;
127  double error = MathUtilities::princarg(theta[i] - expected);
128 
129  unwrapped[i] = m_unwrapped[i] + omega + error;
130 
131  m_phase[i] = theta[i];
132  m_unwrapped[i] = unwrapped[i];
133  }
134 }
135 
FFTReal * m_fft
Definition: PhaseVocoder.h:72
double * m_phase
Definition: PhaseVocoder.h:76
double * m_real
Definition: PhaseVocoder.h:75
void reset()
Reset the stored phases to zero.
double * m_time
Definition: PhaseVocoder.h:73
double * m_unwrapped
Definition: PhaseVocoder.h:77
void processTimeDomain(const double *src, double *mag, double *phase, double *unwrapped)
Given one frame of time-domain samples, FFT and return the magnitudes, instantaneous phases...
PhaseVocoder(int size, int hop)
void getMagnitudes(double *mag)
double * m_imag
Definition: PhaseVocoder.h:74
void forward(const double *realIn, double *realOut, double *imagOut)
Carry out a forward real-to-complex transform of size nsamples, where nsamples is the value provided ...
Definition: FFT.cpp:184
static double princarg(double ang)
The principle argument function.
void getPhases(double *theta)
Definition: FFT.h:52
virtual ~PhaseVocoder()
void unwrapPhases(double *theta, double *unwrapped)
void processFrequencyDomain(const double *reals, const double *imags, double *mag, double *phase, double *unwrapped)
Given one frame of frequency-domain samples, return the magnitudes, instantaneous phases...
void FFTShift(double *src)