summaryrefslogtreecommitdiff
path: root/src/loris/ReassignedSpectrum.h
blob: cd8ae69c2ab0095e061aaeccda42335e2a21254f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#ifndef INCLUDE_REASSIGNEDSPECTRUM_H
#define INCLUDE_REASSIGNEDSPECTRUM_H
/*
 * This is the Loris C++ Class Library, implementing analysis, 
 * manipulation, and synthesis of digitized sounds using the Reassigned 
 * Bandwidth-Enhanced Additive Sound Model.
 *
 * Loris is Copyright (c) 1999-2010 by Kelly Fitz and Lippold Haken
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY, without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 * ReassignedSpectrum.h
 *
 * Definition of class Loris::ReassignedSpectrum.
 *
 * Kelly Fitz, 7 Dec 1999
 * loris@cerlsoundgroup.org
 *
 * http://www.cerlsoundgroup.org/Loris/
 *
 */

#include "FourierTransform.h"
#include <vector>

//	begin namespace
namespace Loris {

// ---------------------------------------------------------------------------
//	class ReassignedSpectrum
//
//!	Computes a reassigned short-time Fourier spectrum using the transform
//! method of Auger and Flandrin. 
//	
class ReassignedSpectrum
{
//	-- public interface --
public:
    //! An unsigned integral type large enough
    //! to represent the length of any transform.
    typedef FourierTransform::size_type size_type;

//	--- lifecycle ---

    //! Construct a new instance using the specified short-time window.
    //!	Transform lengths are the smallest power of two greater than twice the
    //!	window length.
	ReassignedSpectrum( const std::vector< double > & window );

    //! Construct a new instance using the specified short-time window and
    //! its time derivative.
    //!	Transform lengths are the smallest power of two greater than twice the
    //!	window length.
	ReassignedSpectrum( const std::vector< double > & window,
                        const std::vector< double > & windowDerivative );
    
	// compiler-generated copy, assign, and destroy are sufficient

//	--- operations ---

    //!	Compute the reassigned Fourier transform of the samples on the half open
    //!	range [sampsBegin, sampsEnd), aligning sampCenter with the center of
    //!	the analysis window.
    //!
    //! \param  sampsBegin pointer representing the beginning of 
    //!         the (half-open) range of samples to transform
    //! \param  sampCenter the sample in the range that is to be 
    //!         aligned with the center of the analysis window
    //! \param  sampsEnd pointer representing the end of 
    //!         the (half-open) range of samples to transform
    //!
    //! \pre    sampsBegin must not be past sampCenter
    //! \pre    sampsEnd must be past sampCenter
    //! \post   the transform buffers store the reassigned 
    //!         short-time transform data for the specified 
    //!         samples
	void transform( const double * sampsBegin, const double * pos, const double * sampsEnd );
	
//	--- inquiry ---

    //! Return the length of the Fourier transforms.
	size_type size( void ) const;	

    //! Return read access to the short-time window samples.
    //!	(Peers may need to know about the analysis window
    //!	or about the scale factors in introduces.)
	const std::vector< double > & window( void ) const;
	

//	--- reassigned transform access ---
        
	//! Compute and return the convergence indicator, computed from the 
	//!	mixed partial derivative of spectral phase, optionally used in 
	//!	BW enhanced analysis as a convergence indicator. The convergence
	//!	value is on the range [0,1], 0 for a sinusoid, and 1 for an impulse.
    //!
    //! \param  idx the frequency sample at which to evaluate the
    //!         transform
	double convergence( long idx ) const;

    //! Return the reassigned frequency in fractional frequency 
    //! samples computed at the specified transform index.
    //!
    //! \param  idx the frequency sample at which to evaluate the
    //!         transform
	double reassignedFrequency( long idx ) const;

    //! Return the spectrum magnitude (absolute)
    //! computed at the specified transform index.
    //!
    //! \param  idx the frequency sample at which to evaluate the
    //!         transform
	double reassignedMagnitude( long idx ) const;

    //! Return the phase in radians computed at the specified transform index.
    //!	The reassigned phase is shifted to account for the time
    //!	correction according to the corrected frequency.
    //!
    //!
    //! \param  idx the frequency sample at which to evaluate the
    //!         transform
	double reassignedPhase( long idx ) const;	

    //! Return the reassigned time in fractional samples
    //! computed at the specified transform index.
    //!
    //! \param  idx the frequency sample at which to evaluate the
    //!         transform
	double reassignedTime( long idx ) const;

//	--- reassignment operations ---
	
    //!	Compute the frequency correction at the specified frequency sample
    //! using the method of Auger and Flandrin to evaluate the partial
    //! derivative of spectrum phase w.r.t. time.
    //!
    //!	Correction is computed in fractional frequency samples, because
    //!	that's the kind of frequency domain ramp we used on our window.
    //!	sample is the frequency sample index, the nominal component 
    //!	frequency in samples. 
	double frequencyCorrection( long sample ) const;

    //!	Compute the time correction at the specified frequency sample
    //! using the method of Auger and Flandrin to evaluate the partial
    //! derivative of spectrum phase w.r.t. frequency.
    //!
    //!	Correction is computed in fractional samples, because
    //!	that's the kind of ramp we used on our window.
	double timeCorrection( long sample ) const;

//	--- legacy support ---

    //  These members are deprecated, and included only
    //  to support old code. New code should use the
    //  corresponding documented members.
    //  All of these members are deprecated.
    
    double reassignedPhase( long idx, double, double ) const
        { return reassignedPhase( idx ); }
    double reassignedMagnitude( double, long intBinNumber ) const
        { return reassignedMagnitude( intBinNumber ); }
    
    //  subscript operator
    //  The signature has changed, can no longer return a reference,
    //  but since the reference returned was const, this version should 
    //  keep most old code working, if not all.
    std::complex< double > operator[]( unsigned long idx ) const;
	
private:

//	-- window building helpers --

    //	Build a pair of complex-valued windows, one having the frequency-ramp 
    //  (time-derivative) window in the real part and the time-ramp window in the 
    //  imagnary part, and the other having the unmodified window in the real part
    //  and, if computing mixed deriviatives, the time-ramp time-derivative window
    //  in the imaginary part.
    //
    //  Input is the unmodified window function.
    void buildReassignmentWindows( const std::vector< double > & window );
    
    //	Build a pair of complex-valued windows, one having the frequency-ramp 
    //  (time-derivative) window in the real part and the time-ramp window in the 
    //  imagnary part, and the other having the unmodified window in the real part
    //  and, if computing mixed deriviatives, the time-ramp time-derivative window
    //  in the imaginary part.
    //
    //  Input is the unmodified window function and its time derivative, so the
    //  DFT kludge is unnecessary.
    void buildReassignmentWindows( const std::vector< double > & window,
                                   const std::vector< double > & windowDerivative );    

//	-- instance variables --

	//! the FourierTransform for computing magnitude and phase
	FourierTransform mMagnitudeTransform;
	
	//! the FourierTransform for computing time and frequency corrections
	FourierTransform mCorrectionTransform;
	
	//! the original short-time analysis window samples
	std::vector< double > mWindow;                          //  W(n)
	
	//! the complex window used to compute the 
    //! magnitude/phase transform
	std::vector< std::complex< double > > mCplxWin_W_Wtd;   //  real W(n), imag nW'(n)

	//! the complex window used to compute the 
    //! time/frequency correction transform
	std::vector< std::complex< double > > mCplxWin_Wd_Wt;   //  real W'(n), imag nW(n)
		
};	//	end of class ReassignedSpectrum

}	//	end of namespace Loris

#endif /* ndef INCLUDE_REASSIGNEDSPECTRUM_H */