#ifndef INCLUDE_ANALYZER_H
#define INCLUDE_ANALYZER_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
 *
 *
 * Analyzer.h
 *
 * Definition of class Loris::Analyzer.
 *
 * Kelly Fitz, 5 Dec 99
 * loris@cerlsoundgroup.org
 *
 * http://www.cerlsoundgroup.org/Loris/
 *
 */
#include <memory>
#include <vector>
#include <cmath>
#include "LinearEnvelope.h"
#include "Partial.h"
#include "PartialList.h"
#include "SpectralPeaks.h"

//  begin namespace
namespace Loris {

class Envelope;

// ---------------------------------------------------------------------------
//  LinearEnvelopeBuilder
// ---------------------------------------------------------------------------
//  Base class for envelope builders that add a point (possibly) at each
//  analysis frame.
//
//  TODO: make a dictionary of these things and allow clients to add their
//  own envelope builders and builder functions, and retrieve them after
//  analysis.
class LinearEnvelopeBuilder
{
public:
    virtual ~LinearEnvelopeBuilder( void ) {}
    virtual LinearEnvelopeBuilder * clone( void ) const = 0;
    virtual void build( const Peaks & peaks, double frameTime ) = 0;

    const LinearEnvelope & envelope( void ) const { return mEnvelope; }

    //  reset (clear) envelope, override if necesssary:
    virtual void reset( void ) { mEnvelope.clear(); }

protected:

    LinearEnvelope mEnvelope;   //  build this
};


// ---------------------------------------------------------------------------
//  FundamentalBuilder - for constructing an F0 envelope during analysis
// ---------------------------------------------------------------------------
class FundamentalBuilder : public LinearEnvelopeBuilder
{
    std::auto_ptr< Envelope > mFminEnv;
    std::auto_ptr< Envelope > mFmaxEnv;

    double mAmpThresh, mFreqThresh;

    std::vector< double > amplitudes, frequencies;

    const double mMinConfidence;    // 0.9, this could be made a parameter,
                                    // or raised to make estimates smoother

public:
    FundamentalBuilder( double fmin, double fmax, double threshDb = -60, double threshHz = 8000 ) :
        mFminEnv( new LinearEnvelope( fmin ) ),
        mFmaxEnv( new LinearEnvelope( fmax ) ),
        mAmpThresh( std::pow( 10., 0.05*(threshDb) ) ),
        mFreqThresh( threshHz ),
        mMinConfidence( 0.9 )
        {}

    FundamentalBuilder( const Envelope & fmin, const Envelope & fmax,
    					double threshDb = -60, double threshHz = 8000 ) :
        mFminEnv( fmin.clone() ),
        mFmaxEnv( fmax.clone() ),
        mAmpThresh( std::pow( 10., 0.05*(threshDb) ) ),
        mFreqThresh( threshHz ),
        mMinConfidence( 0.9 )
        {}

    FundamentalBuilder( const FundamentalBuilder & rhs ) :
        mFminEnv( rhs.mFminEnv->clone() ),
        mFmaxEnv( rhs.mFmaxEnv->clone() ),
        mAmpThresh( rhs.mAmpThresh ),
        mFreqThresh( rhs.mFreqThresh ),
        mMinConfidence( rhs.mMinConfidence )
        {}


	FundamentalBuilder * clone( void ) const { return new FundamentalBuilder(*this); }

    void build( const Peaks & peaks, double frameTime );
};


// ---------------------------------------------------------------------------
//  AmpEnvBuilder - for constructing an amplitude envelope during analysis
// ---------------------------------------------------------------------------
class AmpEnvBuilder : public LinearEnvelopeBuilder
{
public:
    AmpEnvBuilder( void ) {}

	AmpEnvBuilder * clone( void ) const { return new AmpEnvBuilder(*this); }

    void build( const Peaks & peaks, double frameTime );

};

// ---------------------------------------------------------------------------
//  class Analyzer
//
//! Class Analyzer represents a configuration of parameters for
//! performing Reassigned Bandwidth-Enhanced Additive Analysis
//! of sampled sounds. The analysis process yields a collection
//! of Partials, each having a trio of synchronous, non-uniformly-
//! sampled breakpoint envelopes representing the time-varying
//! frequency, amplitude, and noisiness of a single bandwidth-
//! enhanced sinusoid. These Partials are accumulated in the
//! Analyzer.
//!
//! The core analysis parameter is the frequency resolution, the
//! minimum instantaneous frequency spacing between partials. Most
//! other parameters are initially configured according to this
//! parameter (and the analysis window width, if specified).
//! Subsequent parameter mutations are independent.
//!
//! Bandwidth enhancement:
//! Two different strategies are available for computing bandwidth
//! (or noisiness) envelope:
//!
//! One strategy is to construct bandwidth envelopes during analysis
//! by associating residual energy in the spectrum (after peak
//! extraction) with the selected spectral peaks that are used
//! to construct Partials. This is the original bandwidth enhancement
//! algorithm, and bandwidth envelopes constructed in this way may
//! be suitable for use in bandwidth-enhanced synthesis.
//!
//! Another stategy is to construct bandwidth envelopes during
//! analysis by storing the mixed derivative of short-time phase,
//! scaled and shifted so that a value of 0 corresponds
//! to a pure sinusoid, and a value of 1 corresponds to a
//! bandwidth-enhanced sinusoid with maximal energy spread
//! (minimum convergence in frequency). These bandwidth envelopes
//! are not suitable for bandwidth-enhanced synthesis, be sure
//! to set the bandwidth to 0, or to disable bandwidth enhancement
//! before rendering.
//!
//! The Analyzer may be configured to use either of these two
//! strategies for bandwidth-enhanced analysis, or to construct
//! no bandwidth envelopes at all. If unspecified, the default
//! Analyzer configuration uses spectral residue to construct
//! bandwidth envelopes.
//!
//! \sa storeResidueBandwidth, storeConvergenceBandwidth, storeNoBandwidth
//!
//! For more information about Reassigned Bandwidth-Enhanced
//! Analysis and the Reassigned Bandwidth-Enhanced Additive Sound
//! Model, refer to the Loris website: www.cerlsoundgroup.org/Loris/.
//
class Analyzer
{
//  -- public interface --
public:

//  -- construction --

    //! Construct a new Analyzer configured with the given
    //! frequency resolution (minimum instantaneous frequency
    //! difference between Partials). All other Analyzer parameters
    //! are computed from the specified frequency resolution.
    //!
    //! \param resolutionHz is the frequency resolution in Hz.
    explicit Analyzer( double resolutionHz );

    //! Construct a new Analyzer configured with the given
    //! frequency resolution (minimum instantaneous frequency
    //! difference between Partials) and analysis window width
    //! (main lobe, zero-to-zero). All other Analyzer parameters
    //! are computed from the specified resolution and window width.
    //!
    //! \param resolutionHz is the frequency resolution in Hz.
    //! \param windowWidthHz is the main lobe width of the Kaiser
    //! analysis window in Hz.
    Analyzer( double resolutionHz, double windowWidthHz );

    //! Construct a new Analyzer configured with the given time-varying
    //! frequency resolution (minimum instantaneous frequency
    //! difference between Partials) and analysis window width
    //! (main lobe, zero-to-zero). All other Analyzer parameters
    //! are computed from the specified resolution and window width.
    //!
    //! \param resolutionHz is the frequency resolution in Hz.
    //! \param windowWidthHz is the main lobe width of the Kaiser
    //! analysis window in Hz.
    Analyzer( const Envelope & resolutionEnv, double windowWidthHz );

    //! Construct  a new Analyzer having identical
    //! parameter configuration to another Analyzer.
    //! The list of collected Partials is not copied.
    //!
    //! \param other is the Analyzer to copy.
    Analyzer( const Analyzer & other );

    //! Destroy this Analyzer.
    ~Analyzer( void );

    //! Construct  a new Analyzer having identical
    //! parameter configuration to another Analyzer.
    //! The list of collected Partials is not copied.
    //!
    //! \param rhs is the Analyzer to copy.
    Analyzer & operator=( const Analyzer & rhs );

//  -- configuration --

    //! Configure this Analyzer with the given frequency resolution
    //! (minimum instantaneous frequency difference between Partials,
    //! in Hz). All other Analyzer parameters are (re-)computed from the
    //! frequency resolution, including the window width, which is
    //! twice the resolution.
    //!
    //! \param resolutionHz is the frequency resolution in Hz.
    void configure( double resolutionHz );

    //! Configure this Analyzer with the given frequency resolution
    //! (minimum instantaneous frequency difference between Partials)
    //! and analysis window width (main lobe, zero-to-zero, in Hz).
    //! All other Analyzer parameters are (re-)computed from the
    //! frequency resolution and window width.
    //!
    //! \param resolutionHz is the frequency resolution in Hz.
    //! \param windowWidthHz is the main lobe width of the Kaiser
    //! analysis window in Hz.
    //!
    //! There are three categories of analysis parameters:
    //! - the resolution, and params that are usually related to (or
    //! identical to) the resolution (frequency floor and drift)
    //! - the window width and params that are usually related to (or
    //! identical to) the window width (hop and crop times)
    //! - independent parameters (bw region width and amp floor)
    void configure( double resolutionHz, double windowWidthHz );

	//! Configure this Analyzer with the given time-varying frequency resolution
	//! (minimum instantaneous frequency difference between Partials)
	//! and analysis window width (main lobe, zero-to-zero, in Hz).
	//! All other Analyzer parameters are (re-)computed from the
	//! frequency resolution and window width.
	//!
	//! \param resolutionEnv is the time-varying frequency resolution
	//!	in Hz.
	//! \param windowWidthHz is the main lobe width of the Kaiser
	//! analysis window in Hz.
	//!
	//! There are three categories of analysis parameters:
	//! - the resolution, and params that are usually related to (or
	//! identical to) the resolution (frequency floor and drift)
	//! - the window width and params that are usually related to (or
	//! identical to) the window width (hop and crop times)
	//! - independent parameters (bw region width and amp floor)
	//
	void configure( const Envelope & resolutionEnv, double windowWidthHz );

//  -- analysis --

    //! Analyze a vector of (mono) samples at the given sample rate
    //! (in Hz) and store the extracted Partials in the Analyzer's
    //! PartialList (std::list of Partials).
    //!
    //! \param  vec is a vector of floating point samples
    //! \param  srate is the sample rate of the samples in the vector
    void analyze( const std::vector<double> & vec, double srate );

    //! Analyze a range of (mono) samples at the given sample rate
    //! (in Hz) and store the extracted Partials in the Analyzer's
    //! PartialList (std::list of Partials).
    //!
    //! \param  bufBegin is a pointer to a buffer of floating point samples
    //! \param  bufEnd is (one-past) the end of a buffer of floating point
    //!         samples
    //! \param  srate is the sample rate of the samples in the buffer
    void analyze( const double * bufBegin, const double * bufEnd, double srate );

//  -- tracking analysis --

    //! Analyze a vector of (mono) samples at the given sample rate
    //! (in Hz) and store the extracted Partials in the Analyzer's
    //! PartialList (std::list of Partials). Use the specified envelope
    //! as a frequency reference for Partial tracking.
    //!
    //! \param  vec is a vector of floating point samples
    //! \param  srate is the sample rate of the samples in the vector
    //! \param  reference is an Envelope having the approximate
    //!         frequency contour expected of the resulting Partials.
    void analyze( const std::vector<double> & vec, double srate,
                  const Envelope & reference );

    //! Analyze a range of (mono) samples at the given sample rate
    //! (in Hz) and store the extracted Partials in the Analyzer's
    //! PartialList (std::list of Partials). Use the specified envelope
    //! as a frequency reference for Partial tracking.
    //!
    //! \param  bufBegin is a pointer to a buffer of floating point samples
    //! \param  bufEnd is (one-past) the end of a buffer of floating point
    //!         samples
    //! \param  srate is the sample rate of the samples in the buffer
    //! \param  reference is an Envelope having the approximate
    //!         frequency contour expected of the resulting Partials.
    virtual void analyze( const double * bufBegin, const double * bufEnd, double srate,
                          const Envelope & reference );

//  -- parameter access --

    //! Return the amplitude floor (lowest detected spectral amplitude),
    //! in (negative) dB, for this Analyzer.
    double ampFloor( void ) const;

    //! Return the crop time (maximum temporal displacement of a time-
    //! frequency data point from the time-domain center of the analysis
    //! window, beyond which data points are considered "unreliable")
    //! for this Analyzer.
    double cropTime( void ) const;

    //! Return the maximum allowable frequency difference between
    //! consecutive Breakpoints in a Partial envelope for this Analyzer.
    double freqDrift( void ) const;

    //! Return the frequency floor (minimum instantaneous Partial
    //! frequency), in Hz, for this Analyzer.
    double freqFloor( void ) const;

	//! Return the frequency resolution (minimum instantaneous frequency
	//! difference between Partials) for this Analyzer at the specified
	//! time in seconds. If no time is specified, then the initial resolution
	//!	(at 0 seconds) is returned.
	//!
	//! \param time is the time in seconds at which to evaluate the
	//!		   frequency resolution
	double freqResolution( double time = 0.0 ) const;

    //! Return the hop time (which corresponds approximately to the
    //! average density of Partial envelope Breakpoint data) for this
    //! Analyzer.
    double hopTime( void ) const;

    //! Return the sidelobe attenutation level for the Kaiser analysis window in
    //! positive dB. Larger numbers (e.g. 90) give very good sidelobe
    //! rejection but cause the window to be longer in time. Smaller numbers
    //! (like 60) raise the level of the sidelobes, increasing the likelihood
    //! of frequency-domain interference, but allow the window to be shorter
    //! in time.
    double sidelobeLevel( void ) const;

    //! Return the frequency-domain main lobe width (measured between
    //! zero-crossings) of the analysis window used by this Analyzer.
    double windowWidth( void ) const;

    //! Return true if the phases and frequencies of the constructed
    //! partials should be modified to be consistent at the end of the
    //! analysis, and false otherwise. (Default is true.)
    bool phaseCorrect( void ) const;


//  -- parameter mutation --

    //! Set the amplitude floor (lowest detected spectral amplitude), in
    //! (negative) dB, for this Analyzer.
    //!
    //! \param x is the new value of this parameter.
    void setAmpFloor( double x );

    //! Set the crop time (maximum temporal displacement of a time-
    //! frequency data point from the time-domain center of the analysis
    //! window, beyond which data points are considered "unreliable")
    //! for this Analyzer.
    //!
    //! \param x is the new value of this parameter.
    void setCropTime( double x );

    //! Set the maximum allowable frequency difference between
    //! consecutive Breakpoints in a Partial envelope for this Analyzer.
    //!
    //! \param x is the new value of this parameter.
    void setFreqDrift( double x );

    //! Set the frequency floor (minimum instantaneous Partial
    //! frequency), in Hz, for this Analyzer.
    //!
    //! \param x is the new value of this parameter.
    void setFreqFloor( double x );

    //! Set the frequency resolution (minimum instantaneous frequency
    //! difference between Partials) for this Analyzer. (Does not cause
    //! other parameters to be recomputed.)
    //!
    //! \param x is the new value of this parameter.
    void setFreqResolution( double x );

	//! Set the time-varying frequency resolution (minimum instantaneous frequency
	//! difference between Partials) for this Analyzer. (Does not cause
	//! other parameters to be recomputed.)
	//!
	//! \param e is the envelope to copy for this parameter.
	void setFreqResolution( const Envelope & e );

    //! Set the hop time (which corresponds approximately to the average
    //! density of Partial envelope Breakpoint data) for this Analyzer.
    //!
    //! \param x is the new value of this parameter.
    void setHopTime( double x );

    //! Set the sidelobe attenutation level for the Kaiser analysis window in
    //! positive dB. More negative numbers (e.g. -90) give very good sidelobe
    //! rejection but cause the window to be longer in time. Less negative
    //! numbers raise the level of the sidelobes, increasing the likelihood
    //! of frequency-domain interference, but allow the window to be shorter
    //! in time.
    //!
    //! \param x is the new value of this parameter.
    void setSidelobeLevel( double x );

    //! Set the frequency-domain main lobe width (measured between
    //! zero-crossings) of the analysis window used by this Analyzer.
    //!
    //! \param x is the new value of this parameter.
    void setWindowWidth( double x );

    //! Indicate whether the phases and frequencies of the constructed
    //! partials should be modified to be consistent at the end of the
    //! analysis. (Default is true.)
    //!
    //! \param  TF is a flag indicating whether or not to construct
    //!         phase-corrected Partials
    void setPhaseCorrect( bool TF = true );


//  -- bandwidth envelope specification --

    enum { Default_ResidueBandwidth_RegionWidth = 2000,
           Default_ConvergenceBandwidth_TolerancePct = 10 };

    //! Construct Partial bandwidth envelopes during analysis
    //! by associating residual energy in the spectrum (after
    //! peak extraction) with the selected spectral peaks that
    //! are used to construct Partials.
    //!
    //!	This is the default bandwidth-enhancement strategy.
    //!
    //! \param regionWidth is the width (in Hz) of the bandwidth
    //! association regions used by this process, must be positive.
    //! If unspecified, a default value is used.
    void storeResidueBandwidth( double regionWidth = Default_ResidueBandwidth_RegionWidth );

	//!	Construct Partial bandwidth envelopes during analysis
	//!	by storing the mixed derivative of short-time phase,
	//!	scaled and shifted so that a value of 0 corresponds
	//!	to a pure sinusoid, and a value of 1 corresponds to a
	//! bandwidth-enhanced sinusoid with maximal energy spread
	//! (minimum sinusoidal convergence).
	//!
	//!	\param tolerance is the amount of range over which the
	//!	mixed derivative indicator should be allowed to drift away
	//!	from a pure sinusoid before saturating. This range is mapped
	//!	to bandwidth values on the range [0,1]. Must be positive and
	//!	not greater than 1. If unspecified, a default value is used.
    void storeConvergenceBandwidth( double tolerancePct =
    		0.01 * (double)Default_ConvergenceBandwidth_TolerancePct );

    //! Disable bandwidth envelope construction. Bandwidth
    //! will be zero for all Breakpoints in all Partials.
    void storeNoBandwidth( void );

    //! Return true if this Analyzer is configured to compute
    //! bandwidth envelopes using the spectral residue after
    //! peaks have been identified, and false otherwise.
    bool bandwidthIsResidue( void ) const;

    //! Return true if this Analyzer is configured to compute
    //! bandwidth envelopes using the mixed derivative convergence
    //! indicator, and false otherwise.
    bool bandwidthIsConvergence( void ) const;

    //! Return the width (in Hz) of the Bandwidth Association regions
    //! used by this Analyzer, only if the spectral residue method is
    //! used to compute bandwidth envelopes. Return zero if the mixed
    //! derivative method is used, or if no bandwidth is computed.
    double bwRegionWidth( void ) const;

    //! Return the mixed derivative convergence tolerance (percent)
    //! only if the convergence indicator is used to compute
    //! bandwidth envelopes. Return zero if the spectral residue
    //! method is used or if no bandwidth is computed.
    double bwConvergenceTolerance( void ) const;

    //! Return true if bandwidth envelopes are to be constructed
    //!	by any means, that is, if either bandwidthIsResidue() or
    //!	bandwidthIsConvergence() are true. Otherwise, return
    //! false.
    bool associateBandwidth( void ) const
        { return bandwidthIsResidue() || bandwidthIsConvergence(); }

    //! Deprecated, use storeResidueBandwidth or storeNoBandwidth instead.
    void setBwRegionWidth( double x )
        {
            if ( x != 0 )
            {
                storeResidueBandwidth( x );
            }
            else
            {
                storeNoBandwidth();
            }
        }


//  -- PartialList access --

    //! Return a mutable reference to this Analyzer's list of
    //! analyzed Partials.
    PartialList & partials( void );

    //! Return an immutable (const) reference to this Analyzer's
    //! list of analyzed Partials.
    const PartialList & partials( void ) const;

//  -- envelope access --

    enum { Default_FundamentalEnv_ThreshDb = -60,
           Default_FundamentalEnv_ThreshHz = 8000 };

    //! Specify parameters for constructing a fundamental frequency
    //! envelope for the analyzed sound during analysis. The fundamental
    //! frequency estimate can be accessed by fundamentalEnv() after the
    //! analysis is complete.
    //!
    //! By default, a fundamental envelope is estimated during analysis
    //! between the frequency resolution and 1.5 times the resolution.
    //!
    //! \param  fmin is the lower bound on the fundamental frequency estimate
    //! \param  fmax is the upper bound on the fundamental frequency estimate
    //! \param  threshDb is the lower bound on the amplitude of a spectral peak
    //!         that will constribute to the fundamental frequency estimate (very
    //!         low amplitude peaks tend to have less reliable frequency estimates).
    //!         Default is -60 dB.
    //! \param  threshHz is the upper bound on the frequency of a spectral
    //!         peak that will constribute to the fundamental frequency estimate.
    //!         Default is 8 kHz.
    void buildFundamentalEnv( double fmin, double fmax,
                              double threshDb = Default_FundamentalEnv_ThreshDb,
                              double threshHz = Default_FundamentalEnv_ThreshHz );


    //! Return the fundamental frequency estimate envelope constructed
    //! during the most recent analysis performed by this Analyzer.
    //!
    //! By default, a fundamental envelope is estimated during analysis
    //! between the frequency resolution and 1.5 times the resolution.
    const LinearEnvelope & fundamentalEnv( void ) const;

    //! Return the overall amplitude estimate envelope constructed
    //! during the most recent analysis performed by this Analyzer.
    const LinearEnvelope & ampEnv( void ) const;


//  -- legacy support --

    //  Fundamental and amplitude envelopes are always constructed during
    //  analysis, these members do nothing, and are retained for backwards
    //  compatibility.
    void buildAmpEnv( bool TF = true ) { TF = TF; }
    void buildFundamentalEnv( bool TF = true ) { TF = TF; }

//  -- private member variables --

protected:

    std::auto_ptr< Envelope > m_freqResolutionEnv;
    							//!  in Hz, minimum instantaneous frequency distance;
                                //!  this is the core parameter, others are, by default,
                                //!  computed from this one

    double m_ampFloor;          //!  dB, relative to full amplitude sine wave, absolute
                                //!  amplitude threshold (negative)

    double m_windowWidth;       //!  in Hz, width of main lobe; this might be more
                                //!  conveniently presented as window length, but
                                //!  the main lobe width more explicitly highlights
                                //!  the critical interaction with resolution

    // std::auto_ptr< Envelope > m_freqFloorEnv;
    double m_freqFloor;         //!  lowest frequency (Hz) component extracted
                                //!  in spectral analysis

    double m_freqDrift;         //!  the maximum frequency (Hz) difference between two
                                //!  consecutive Breakpoints that will be linked to
                                //!  form a Partial

    double m_hopTime;           //!  in seconds, time between analysis windows in
                                //!  successive spectral analyses

    double m_cropTime;          //!  in seconds, maximum time correction for a spectral
                                //!  component to be considered reliable, and to be eligible
                                //!  for extraction and for Breakpoint formation

    double m_bwAssocParam;      //!  formerly, width in Hz of overlapping bandwidth
                                //!  association regions, or zero if bandwidth association
                                //!  is disabled, now a catch-all bandwidth association
                                //!  parameter that, if negative, indicates the tolerance (%)
                                //!  level used to construct bandwidth envelopes from the
                                //!  mixed phase derivative indicator

    double m_sidelobeLevel;     //!  sidelobe attenutation level for the Kaiser analysis
                                //!  window, in positive dB

    bool m_phaseCorrect;        //!  flag indicating that phases/frequencies should be
                                //!  made consistent at the end of the analysis

    PartialList m_partials;     //!  collect Partials here

    //! builder object for constructing a fundamental frequency
    //! estimate during analysis
    std::auto_ptr< LinearEnvelopeBuilder > m_f0Builder;

    //! builder object for constructing an amplitude
    //! estimate during analysis
    std::auto_ptr< LinearEnvelopeBuilder > m_ampEnvBuilder;

//  -- private auxiliary functions --
//	future development
/*

	//	These members make up the sequence of operations in an
	//	analysis. If analysis were ever to be made into a
	//	template method, these would be the operations that
	//	derived classes could override. Or each of these could
	//	be represented by a strategy class.

	//!	Compute the spectrum of the next sequence of samples.
	void computeSpectrum( void );

	//!	Identify and select the spectral components that will be
	//!	used to form Partials.
	void selectPeaks( void );

	//!	Compute the bandwidth coefficients for the Breakpoints
	//!	that are going to be used to form Partials.
	void associateBandwidth( void );

	//!	Construct Partials from extracted spectral components.
	//!	Partials are built up frame by frame by appending
	//!	Breakpoints to Partials under construction, and giving
	//!	birth to new Partials using unmatched Peaks.
	void formPartials( Peaks & peaks );
*/
    //  Reject peaks that are too close in frequency to a louder peak that is
    //  being retained, and peaks that are too quiet. Peaks that are retained,
    //  but are quiet enough to be in the specified fadeRange should be faded.
    //
    //  Rejected peaks are placed at the end of the peak collection.
    //  Return the first position in the collection containing a rejected peak,
    //  or the end of the collection if no peaks are rejected.
    Peaks::iterator thinPeaks( Peaks & peaks, double frameTime  );

    //  Fix the bandwidth value stored in the specified Peaks.
    //  This function is invoked if the spectral residue method is
    //  not used to compute bandwidth (that method overwrites the
    //  bandwidth already). If the convergence method is used to
    //  compute bandwidth, the appropriate scaling is applied
    //  to the stored mixed phase derivative. Otherwise, the
    //  Peak bandwidth is set to zero.
    void fixBandwidth( Peaks & peaks );

};  //  end of class Analyzer

}   //  end of namespace Loris

#endif /* ndef INCLUDE_ANALYZER_H */