#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 // 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 */