#ifndef INCLUDE_LORIS_H
#define INCLUDE_LORIS_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
 *
 *
 *    loris.h
 *
 *    Header specifying C-linkable procedural interface for Loris. 
 *
 *    Main components of this interface:
 *    - version identification symbols
 *    - type declarations
 *    - Analyzer configuration
 *    - LinearEnvelope (formerly BreakpointEnvelope) operations
 *    - PartialList operations
 *    - Partial operations
 *    - Breakpoint operations
 *    - sound modeling functions for preparing PartialLists
 *    - utility functions for manipulating PartialLists
 *    - notification and exception handlers (all exceptions must be caught and
 *        handled internally, clients can specify an exception handler and 
 *        a notification function. The default one in Loris uses printf()).
 *
 *    loris.h is generated automatically from loris.h.in. Do not modify loris.h
 *
 * Kelly Fitz, 4 Feb 2002
 * loris@cerlsoundgroup.org
 *
 * http://www.cerlsoundgroup.org/Loris/
 *
 */
 
/* ---------------------------------------------------------------- */
/*      Version
/*
/*  Define symbols that facilitate version/release identification.
 */
 
#define LORIS_MAJOR_VERSION 1
#define LORIS_MINOR_VERSION 8
#define LORIS_SUBMINOR_VERSION 
#define LORIS_VERSION_STR "Loris 1.8"

/* ---------------------------------------------------------------- */
/*      Types
/*
/* The (class) types Breakpoint, LinearEnvelope, Partial, 
   and PartialList are imported from the Loris namespace.
   The first three are classes, the latter is a typedef
   for std::list< Loris::Partial >. 
 */
#if defined(__cplusplus)
    //    include std library list header, declaring templates
    //    is too painful and fragile:
    #include <list>
    
    //    declare Loris classes in Loris namespace:
    namespace Loris
    {
        class Breakpoint;
        class LinearEnvelope;
        class Partial;
      
        //    this typedef has to be copied from PartialList.h
        typedef std::list< Loris::Partial > PartialList;
    }
   
   // import those names into the global namespace
   using Loris::Breakpoint;
   using Loris::LinearEnvelope;
   using Loris::Partial;
   using Loris::PartialList;
#else 
    /* no classes, just declare types and use
      opaque C pointers 
    */
    typedef struct Breakpoint Breakpoint;
    typedef struct LinearEnvelope LinearEnvelope;
    typedef struct PartialList PartialList;
    typedef struct Partial Partial;
#endif

/*
   TODO
    Maybe should also have loris_label_t and loris_size_t
    defined, depending on configure.
*/

#if defined(__cplusplus)
    extern "C" {
#endif

/* ---------------------------------------------------------------- */
/*      Analyzer configuration
/*
/*  An Analyzer represents a configuration of parameters for
    performing Reassigned Bandwidth-Enhanced Additive Analysis
    of sampled waveforms. This 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. 

    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/.
    
    In the procedural interface, there is only one Analyzer. 
    It must be configured by calling analyzer_configure before
    any of the other analyzer operations can be performed.
 */

void analyze( const double * buffer, unsigned int bufferSize, 
              double srate, PartialList * partials );
/*  Analyze an array of bufferSize (mono) samples at the given sample rate           
    (in Hz) and append the extracted Partials to the given 
    PartialList.                                                 
 */
                       
void analyzer_configure( double resolution, double windowWidth );
/*  Configure the sole Analyzer instance with the specified
    frequency resolution (minimum instantaneous frequency    
    difference between Partials). All other Analyzer parameters     
    are computed from the specified frequency resolution. 
   
    Construct the Analyzer instance if necessary.
   
    In the procedural interface, there is only one Analyzer. 
    It must be configured by calling analyzer_configure before
    any of the other analyzer operations can be performed.   
 */

double analyzer_getAmpFloor( void );
/*  Return the amplitude floor (lowest detected spectral amplitude),              
    in (negative) dB, for the Loris Analyzer.                 
 */

double analyzer_getCropTime( void );
/*  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 the Loris Analyzer.
 */

double analyzer_getFreqDrift( void );
/*  Return the maximum allowable frequency difference between                     
    consecutive Breakpoints in a Partial envelope for the Loris Analyzer.                 
 */

double analyzer_getFreqFloor( void );
/*  Return the frequency floor (minimum instantaneous Partial                  
    frequency), in Hz, for the Loris Analyzer.                 
 */

double analyzer_getFreqResolution( void );
/*  Return the frequency resolution (minimum instantaneous frequency          
    difference between Partials) for the Loris Analyzer.     
 */

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

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

double analyzer_getWindowWidth( void );
/*  Return the frequency-domain main lobe width (measured between 
    zero-crossings) of the analysis window used by the Loris Analyzer.                 
 */

void analyzer_setAmpFloor( double x );
/*  Set the amplitude floor (lowest detected spectral amplitude), in              
    (negative) dB, for the Loris Analyzer.                 
 */

void analyzer_setBwRegionWidth( double x );
/*  Deprecated, use analyzer_storeResidueBandwidth instead.
 */

void analyzer_setCropTime( 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 the Loris Analyzer.
 */

void analyzer_setFreqDrift( double x );
/*  Set the maximum allowable frequency difference between                     
    consecutive Breakpoints in a Partial envelope for the Loris Analyzer.                 
 */

void analyzer_setFreqFloor( double x );
/*  Set the amplitude floor (minimum instantaneous Partial                  
    frequency), in Hz, for the Loris Analyzer.
 */

void analyzer_setFreqResolution( double x );
/*  Set the frequency resolution (minimum instantaneous frequency          
    difference between Partials) for the Loris Analyzer. (Does not cause     
    other parameters to be recomputed.)                                     
 */

void analyzer_setHopTime( double x );
/*  Set the hop time (which corresponds approximately to the average
    density of Partial envelope Breakpoint data) for the Loris Analyzer.
 */

void analyzer_setSidelobeLevel( double x );
/*  Set 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 raise the level of the sidelobes, increasing the likelihood
    of frequency-domain interference, but allow the window to be shorter
    in time.
 */

void analyzer_setWindowWidth( double x );
/*  Set the frequency-domain main lobe width (measured between 
    zero-crossings) of the analysis window used by the Loris Analyzer.                 
 */
 
void analyzer_storeResidueBandwidth( double regionWidth );
/*	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. 
	
	regionWidth is the width (in Hz) of the bandwidth 
	association regions used by this process, must be positive.
 */
 
void analyzer_storeConvergenceBandwidth( double tolerancePct );
/*	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).
	
	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.
 */

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

double analyzer_getBwRegionWidth( void );
/*  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 analyzer_getBwConvergenceTolerance( void );
/*	Return the mixed derivative convergence tolerance
	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.
 */


/* ---------------------------------------------------------------- */
/*      LinearEnvelope object interface                                
/*
/*  A LinearEnvelope represents a linear segment breakpoint 
    function with infinite extension at each end (that is, the 
    values past either end of the breakpoint function have the 
    values at the nearest end).

    In C++, a LinearEnvelope is a Loris::LinearEnvelope.
 */
 
LinearEnvelope * createLinearEnvelope( void );
/*  Construct and return a new LinearEnvelope having no 
    breakpoints and an implicit value of 0. everywhere, 
    until the first breakpoint is inserted.            
 */

LinearEnvelope * copyLinearEnvelope( const LinearEnvelope * ptr_this );
/*  Construct and return a new LinearEnvelope that is an
    exact copy of the specified LinearEnvelopes, having 
    an identical set of breakpoints.    
 */

void destroyLinearEnvelope( LinearEnvelope * ptr_this );
/*  Destroy this LinearEnvelope.                                 
 */
 
void linearEnvelope_insertBreakpoint( LinearEnvelope * ptr_this,
                                      double time, double val );
/*  Insert a breakpoint representing the specified (time, value) 
    pair into this LinearEnvelope. If there is already a 
    breakpoint at the specified time, it will be replaced with 
    the new breakpoint.
 */

double linearEnvelope_valueAt( const LinearEnvelope * ptr_this, 
                               double time );
/*  Return the interpolated value of this LinearEnvelope at the 
    specified time.                            
 */

/* ---------------------------------------------------------------- */
/*      PartialList object interface
/*
/*  A PartialList represents a collection of Bandwidth-Enhanced 
    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.

    For more information about Bandwidth-Enhanced Partials and the  
    Reassigned Bandwidth-Enhanced Additive Sound Model, refer to
    the Loris website: www.cerlsoundgroup.org/Loris/.

    In C++, a PartialList is a Loris::PartialList.
 */ 
PartialList * createPartialList( void );
/*  Return a new empty PartialList.
 */
 
void destroyPartialList( PartialList * ptr_this );
/*  Destroy this PartialList.
 */
 
void partialList_clear( PartialList * ptr_this );
/*  Remove (and destroy) all the Partials from this PartialList,
    leaving it empty.
 */
 
void partialList_copy( PartialList * ptr_this, 
                       const PartialList * src );
/*  Make this PartialList a copy of the source PartialList by making
    copies of all of the Partials in the source and adding them to 
    this PartialList.
 */
 
unsigned long partialList_size( const PartialList * ptr_this );
/*  Return the number of Partials in this PartialList.
 */
 
void partialList_splice( PartialList * ptr_this, 
                               PartialList * src );
/*  Splice all the Partials in the source PartialList onto the end of
    this PartialList, leaving the source empty.
 */
 
/* ---------------------------------------------------------------- */
/*      Partial object interface
/*
/*  A Partial represents a single component in the
    reassigned bandwidth-enhanced additive model. A Partial consists of a
    chain of Breakpoints describing the time-varying frequency, amplitude,
    and bandwidth (or noisiness) envelopes of the component, and a 4-byte
    label. The Breakpoints are non-uniformly distributed in time. 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/.
 */ 

double partial_startTime( const Partial * p );
/*  Return the start time (seconds) for the specified Partial.
 */

double partial_endTime( const Partial * p );
/*  Return the end time (seconds) for the specified Partial.
 */

double partial_duration( const Partial * p );
/*  Return the duration (seconds) for the specified Partial.
 */

double partial_initialPhase( const Partial * p );
/*  Return the initial phase (radians) for the specified Partial.
 */

int partial_label( const Partial * p );
/*  Return the integer label for the specified Partial.
 */

unsigned long partial_numBreakpoints( const Partial * p );
/*  Return the number of Breakpoints in the specified Partial.
 */

double partial_frequencyAt( const Partial * p, double t );
/*  Return the frequency (Hz) of the specified Partial interpolated
    at a particular time. It is an error to apply this function to
    a Partial having no Breakpoints.
 */

double partial_bandwidthAt( const Partial * p, double t );
/*  Return the bandwidth of the specified Partial interpolated
    at a particular time. It is an error to apply this function to
    a Partial having no Breakpoints.
 */

double partial_phaseAt( const Partial * p, double t );
/*  Return the phase (radians) of the specified Partial interpolated
    at a particular time. It is an error to apply this function to
    a Partial having no Breakpoints.
 */

double partial_amplitudeAt( const Partial * p, double t );
/*  Return the (absolute) amplitude of the specified Partial interpolated
    at a particular time. Partials are assumed to fade out
    over 1 millisecond at the ends (rather than instantaneously).
    It is an error to apply this function to a Partial having no Breakpoints.
 */

void partial_setLabel( Partial * p, int label );
/*   Assign a new integer label to the specified Partial.
 */

/* ---------------------------------------------------------------- */
/*      Breakpoint object interface
/*
/*  A Breakpoint represents a single breakpoint in the
    Partial parameter (frequency, amplitude, bandwidth) envelope.
    Instantaneous phase is also stored, but is only used at the onset of 
    a partial, or when it makes a transition from zero to nonzero amplitude.
    
    Loris Partials represent reassigned bandwidth-enhanced model components.
    A Partial consists of a chain of Breakpoints describing the time-varying
    frequency, amplitude, and bandwidth (noisiness) of the component.
    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/.
 */ 

double breakpoint_getAmplitude( const Breakpoint * bp );
/*   Return the (absolute) amplitude of the specified Breakpoint.
 */

double breakpoint_getBandwidth( const Breakpoint * bp );
/*  Return the bandwidth coefficient of the specified Breakpoint.
 */

double breakpoint_getFrequency( const Breakpoint * bp );
/*  Return the frequency (Hz) of the specified Breakpoint.
 */

double breakpoint_getPhase( const Breakpoint * bp );
/*  Return the phase (radians) of the specified Breakpoint.
 */

void breakpoint_setAmplitude( Breakpoint * bp, double a );
/*   Assign a new (absolute) amplitude to the specified Breakpoint.
 */

void breakpoint_setBandwidth( Breakpoint * bp, double bw );
/*  Assign a new bandwidth coefficient to the specified Breakpoint.
 */

void breakpoint_setFrequency( Breakpoint * bp, double f );
/*  Assign a new frequency (Hz) to the specified Breakpoint.
 */

void breakpoint_setPhase( Breakpoint * bp, double phi );
/*  Assign a new phase (radians) to the specified Breakpoint.
 */

/* ---------------------------------------------------------------- */
/*      non-object-based procedures
/*
/*  Operations in Loris that need not be accessed though object
    interfaces are represented as simple functions.
 */

void channelize( PartialList * partials, 
                 LinearEnvelope * refFreqEnvelope, int refLabel );
/*  Label Partials in a PartialList with the integer nearest to
    the amplitude-weighted average ratio of their frequency envelope
    to a reference frequency envelope. The frequency spectrum is 
    partitioned into non-overlapping channels whose time-varying 
    center frequencies track the reference frequency envelope. 
    The reference label indicates which channel's center frequency
    is exactly equal to the reference envelope frequency, and other
    channels' center frequencies are multiples of the reference 
    envelope frequency divided by the reference label. Each Partial 
    in the PartialList is labeled with the number of the channel
    that best fits its frequency envelope. The quality of the fit
    is evaluated at the breakpoints in the Partial envelope and
    weighted by the amplitude at each breakpoint, so that high-
    amplitude breakpoints contribute more to the channel decision.
    Partials are labeled, but otherwise unmodified. In particular, 
    their frequencies are not modified in any way.
 */

void collate( PartialList * partials );
/*  Collate unlabeled (zero-labeled) Partials into the smallest-possible 
    number of Partials that does not combine any overlapping Partials.
    Collated Partials appear at the end of the sequence, after all 
    labeled Partials.
 */

LinearEnvelope * 
createFreqReference( PartialList * partials, 
                     double minFreq, double maxFreq, long numSamps );
/*  Return a newly-constructed LinearEnvelope using the legacy 
    FrequencyReference class. The envelope will have approximately
    the specified number of samples. The specified number of samples 
    must be greater than 1. Uses the FundamentalEstimator 
    (FundamentalFromPartials) class to construct an estimator of 
    fundamental frequency, configured to emulate the behavior of
    the FrequencyReference class in Loris 1.4-1.5.2. If numSamps 
    is zero, construct the reference envelope from fundamental 
    estimates taken every five milliseconds.
	
	For simple sounds, this frequency reference may be a 
	good first approximation to a reference envelope for
	channelization (see channelize()).
	
	Clients are responsible for disposing of the newly-constructed 
	LinearEnvelope.
 */
 
LinearEnvelope * 
createF0Estimate( PartialList * partials, double minFreq, double maxFreq, 
                  double interval );
/* Return a newly-constructed LinearEnvelope that estimates
   the time-varying fundamental frequency of the sound
   represented by the Partials in a PartialList. This uses
   the FundamentalEstimator (FundamentalFromPartials) 
   class to construct an estimator of fundamental frequency, 
   and returns a LinearEnvelope that samples the estimator at the 
   specified time interval (in seconds). Default values are used 
   to configure the estimator. Only estimates in the specified 
   frequency range will be considered valid, estimates outside this 
   range will be ignored.
   
   Clients are responsible for disposing of the newly-constructed 
   LinearEnvelope.
 */

void dilate( PartialList * partials, 
             const double * initial, const double * target, int npts );
/*  Dilate Partials in a PartialList according to the given 
    initial and target time points. Partial envelopes are 
    stretched and compressed so that temporal features at
    the initial time points are aligned with the final time
    points. Time points are sorted, so Partial envelopes are 
    are only stretched and compressed, but breakpoints are not
    reordered. Duplicate time points are allowed. There must be
    the same number of initial and target time points.
 */

void distill( PartialList * partials );
/*  Distill labeled (channelized) Partials in a PartialList into a 
    PartialList containing at most one Partial per label. Unlabeled 
    (zero-labeled) Partials are left unmodified at the end of the 
    distilled Partials.
 */

void exportAiff( const char * path, const double * buffer, 
                 unsigned int bufferSize, double samplerate, int bitsPerSamp );
/*  Export mono audio samples stored in an array of size bufferSize to 
    an AIFF file having the specified sample rate at the given file path 
    (or name). The floating point samples in the buffer are clamped to the 
    range (-1.,1.) and converted to integers having bitsPerSamp bits.
 */
                 
void exportSdif( const char * path, PartialList * partials );
/*  Export Partials in a PartialList to a SDIF file at the specified
    file path (or name). SDIF data is described by RBEM and RBEL 
    matrices. 
    For more information about SDIF, see the SDIF web site at:
        www.ircam.fr/equipes/analyse-synthese/sdif/  
 */
                
void exportSpc( const char * path, PartialList * partials, double midiPitch, 
                int enhanced, double endApproachTime );
/*  Export Partials in a PartialList to a Spc file at the specified file
    path (or name). The fractional MIDI pitch must be specified. The 
    enhanced parameter defaults to true (for bandwidth-enhanced spc files), 
    but an be specified false for pure-sines spc files. The endApproachTime 
    parameter is in seconds. A nonzero endApproachTime indicates that the plist does 
    not include a release, but rather ends in a static spectrum corresponding 
    to the final breakpoint values of the partials. The endApproachTime
    specifies how long before the end of the sound the amplitude, frequency, 
    and bandwidth values are to be modified to make a gradual transition to 
    the static spectrum.
 */

/*  Apply a reference Partial to fix the frequencies of Breakpoints
    whose amplitude is below threshold_dB. 0 harmonifies full-amplitude
    Partials, to apply only to quiet Partials, specify a lower 
    threshold like -90). The reference Partial is the first Partial
    in the PartialList labeled refLabel (usually 1). The LinearEnvelope 
    is a time-varying weighting on the harmonifing process. When 1, 
    harmonic frequencies are used, when 0, breakpoint frequencies are 
    unmodified. 
 */
void harmonify( PartialList * partials, long refLabel,
                const LinearEnvelope * env, double threshold_dB );
 
unsigned int importAiff( const char * path, double * buffer, unsigned int bufferSize, 
                         double * samplerate );
/*  Import audio samples stored in an AIFF file at the given file
    path (or name). The samples are converted to floating point 
    values on the range (-1.,1.) and stored in an array of doubles. 
    The value returned is the number of samples in buffer, and it is at
    most bufferSize. If samplerate is not a NULL pointer, 
    then, on return, it points to the value of the sample rate (in
    Hz) of the AIFF samples. The AIFF file must contain only a single
    channel of audio data. The prior contents of buffer, if any, are 
    overwritten.
 */

void importSdif( const char * path, PartialList * partials );
/*  Import Partials from an SDIF file at the given file path (or 
    name), and append them to a PartialList.
 */    

void importSpc( const char * path, PartialList * partials );
/*  Import Partials from an Spc file at the given file path (or 
    name), and return them in a PartialList.
 */    

void morph( const PartialList * src0, const PartialList * src1, 
            const LinearEnvelope * ffreq, 
            const LinearEnvelope * famp, 
            const LinearEnvelope * fbw, 
            PartialList * dst );
/*  Morph labeled Partials in two PartialLists according to the
    given frequency, amplitude, and bandwidth (noisiness) morphing
    envelopes, and append the morphed Partials to the destination 
    PartialList. Loris morphs Partials by interpolating frequency,
    amplitude, and bandwidth envelopes of corresponding Partials in 
    the source PartialLists. For more information about the Loris
    morphing algorithm, see the Loris website: 
    www.cerlsoundgroup.org/Loris/
 */

void morphWithReference( const PartialList * src0, 
                         const PartialList * src1,
                         long src0RefLabel, 
                         long src1RefLabel,
                         const LinearEnvelope * ffreq, 
                         const LinearEnvelope * famp, 
                         const LinearEnvelope * fbw, 
                         PartialList * dst );
/*	Morph labeled Partials in two PartialLists according to the
	given frequency, amplitude, and bandwidth (noisiness) morphing
	envelopes, and append the morphed Partials to the destination 
	PartialList. Specify the labels of the Partials to be used as 
	reference Partial for the two morph sources. The reference 
	partial is used to compute frequencies for very low-amplitude 
	Partials whose frequency estimates are not considered reliable. 
	The reference Partial is considered to have good frequency 
	estimates throughout. A reference label of 0 indicates that 
	no reference Partial should be used for the corresponding
	morph source.
   
	Loris morphs Partials by interpolating frequency,
	amplitude, and bandwidth envelopes of corresponding Partials in 
	the source PartialLists. For more information about the Loris
	morphing algorithm, see the Loris website: 
	www.cerlsoundgroup.org/Loris/
 */
 
void morpher_setAmplitudeShape( double shape );
/* Set the shaping parameter for the amplitude morphing
	function. This shaping parameter controls the slope of
	the amplitude morphing function, for values greater than
	1, this function gets nearly linear (like the old
	amplitude morphing function), for values much less than
	1 (e.g. 1E-5) the slope is gently curved and sounds
	pretty "linear", for very small values (e.g. 1E-12) the
	curve is very steep and sounds un-natural because of the
	huge jump from zero amplitude to very small amplitude.
	
	Use LORIS_DEFAULT_AMPMORPHSHAPE to obtain the default
	amplitude morphing shape for Loris, (equal to 1E-5,
	which works well for many musical instrument morphs,
	unless Loris was compiled with the symbol
	LINEAR_AMP_MORPHS defined, in which case
	LORIS_DEFAULT_AMPMORPHSHAPE is equal to
	LORIS_LINEAR_AMPMORPHSHAPE).
	
	Use LORIS_LINEAR_AMPMORPHSHAPE to approximate the linear
	amplitude morphs performed by older versions of Loris.
	
	The amplitude shape must be positive.
 */
 
extern const double LORIS_DEFAULT_AMPMORPHSHAPE;    
extern const double LORIS_LINEAR_AMPMORPHSHAPE;

void resample( PartialList * partials, double interval );
/*  Resample all Partials in a PartialList using the specified
    sampling interval, so that the Breakpoints in the Partial 
    envelopes will all lie on a common temporal grid.
    The Breakpoint times in resampled Partials will comprise a  
    contiguous sequence of integer multiples of the sampling interval,
    beginning with the multiple nearest to the Partial's start time and
    ending with the multiple nearest to the Partial's end time. Resampling
    is performed in-place. 

 */

void shapeSpectrum( PartialList * partials, PartialList * surface,
                    double stretchFreq, double stretchTime );
/*  Scale the amplitudes of a set of Partials by applying 
    a spectral suface constructed from another set.
    Stretch the spectral surface in time and frequency
    using the specified stretch factors. Set the stretch
    factors to one for no stretching.
 */

void sift( PartialList * partials );
/*  Identify overlapping Partials having the same (nonzero)
    label. If any two partials with same label
    overlap in time, set the label of the weaker
    (having less total energy) partial to zero.

 */ 

unsigned int 
synthesize( const PartialList * partials,
            double * buffer, unsigned int bufferSize,
            double srate );
/*  Synthesize Partials in a PartialList at the given sample
    rate, and store the (floating point) samples in a buffer of
    size bufferSize. The buffer is neither resized nor 
    cleared before synthesis, so newly synthesized samples are
    added to any previously computed samples in the buffer, and
    samples beyond the end of the buffer are lost. Return the
    number of samples synthesized, that is, the index of the
    latest sample in the buffer that was modified.
 */

/* ---------------------------------------------------------------- */
/*      utility functions
/*
/*  Operations for transforming and manipulating collections
    of Partials.
 */

double avgAmplitude( const Partial * p );
/*  Return the average amplitude over all Breakpoints in this Partial.
    Return zero if the Partial has no Breakpoints.
 */

double avgFrequency( const Partial * p );
/*  Return the average frequency over all Breakpoints in this Partial.
    Return zero if the Partial has no Breakpoints.
 */

void copyIf( const PartialList * src, PartialList * dst, 
             int ( * predicate )( const Partial * p, void * data ),
             void * data );
/*  Append copies of Partials in the source PartialList satisfying the
    specified predicate to the destination PartialList. The source list
    is unmodified. The data parameter can be used to 
    supply extra user-defined data to the function. Pass 0 if no 
    additional data is needed.
 */
             
void copyLabeled( const PartialList * src, long label, PartialList * dst );
/*  Append copies of Partials in the source PartialList having the
    specified label to the destination PartialList. The source list
    is unmodified.
 */

void crop( PartialList * partials, double t1, double t2 );
/*  Trim Partials by removing Breakpoints outside a specified time span.
    Insert a Breakpoint at the boundary when cropping occurs. Remove
	any Partials that are left empty after cropping (Partials having no
	Breakpoints between t1 and t2).
 */

void extractIf( PartialList * src, PartialList * dst, 
                int ( * predicate )( const Partial * p, void * data ),
                void * data );
/*  Remove Partials in the source PartialList satisfying the
    specified predicate from the source list and append them to
    the destination PartialList. The data parameter can be used to 
    supply extra user-defined data to the function. Pass 0 if no 
    additional data is needed.
 */

void extractLabeled( PartialList * src, long label, PartialList * dst );
/*  Remove Partials in the source PartialList having the specified
    label from the source list and append them to the destination 
    PartialList. 
 */

void fixPhaseAfter( PartialList * partials, double time );
/*  Recompute phases of all Breakpoints later than the specified 
    time so that the synthesized phases of those later Breakpoints 
    matches the stored phase, as long as the synthesized phase at 
    the specified time matches the stored (not recomputed) phase.
    
    Phase fixing is only applied to non-null (nonzero-amplitude) 
    Breakpoints, because null Breakpoints are interpreted as phase 
    reset points in Loris. If a null is encountered, its phase is 
    corrected from its non-Null successor, if it has one, otherwise 
    it is unmodified.
 */

void fixPhaseAt( PartialList * partials, double time );
/*  Recompute phases of all Breakpoints in a Partial
    so that the synthesized phases match the stored phases, 
    and the synthesized phase at (nearest) the specified
    time matches the stored (not recomputed) phase.
    
    Backward phase-fixing stops if a null (zero-amplitude) 
    Breakpoint is encountered, because nulls are interpreted as 
    phase reset points in Loris. If a null is encountered, the 
    remainder of the Partial (the front part) is fixed in the 
    forward direction, beginning at the start of the Partial. 
    Forward phase fixing is only applied to non-null 
    (nonzero-amplitude) Breakpoints. If a null is encountered, 
    its phase is corrected from its non-Null successor, if 
    it has one, otherwise it is unmodified.
 */

void fixPhaseBefore( PartialList * partials, double time );
/*  Recompute phases of all Breakpoints earlier than the specified 
    time so that the synthesized phases of those earlier Breakpoints 
    matches the stored phase, and the synthesized phase at the 
    specified time matches the stored (not recomputed) phase.

    Backward phase-fixing stops if a null (zero-amplitude) Breakpoint
    is encountered, because nulls are interpreted as phase reset 
    points in Loris. If a null is encountered, the remainder of the 
    Partial (the front part) is fixed in the forward direction, 
    beginning at the start of the Partial.
 */

void fixPhaseBetween( PartialList * partials, double tbeg, double tend );
/*
    Fix the phase travel between two times by adjusting the
    frequency and phase of Breakpoints between those two times.
    
    This algorithm assumes that there is nothing interesting 
    about the phases of the intervening Breakpoints, and modifies 
    their frequencies as little as possible to achieve the correct 
    amount of phase travel such that the frequencies and phases at 
    the specified times match the stored values. The phases of all 
    the Breakpoints between the specified times are recomputed.
 */

void fixPhaseForward( PartialList * partials, double tbeg, double tend );
/*  Recompute phases of all Breakpoints later than the specified 
    time so that the synthesized phases of those later Breakpoints 
    matches the stored phase, as long as the synthesized phase at 
    the specified time matches the stored (not recomputed) phase. 
    Breakpoints later than tend are unmodified.
    
    Phase fixing is only applied to non-null (nonzero-amplitude) 
    Breakpoints, because null Breakpoints are interpreted as phase 
    reset points in Loris. If a null is encountered, its phase is 
    corrected from its non-Null successor, if it has one, otherwise 
    it is unmodified.
 */

int forEachBreakpoint( Partial * p,
                       int ( * func )( Breakpoint * p, double time, void * data ),
                       void * data );
/*  Apply a function to each Breakpoint in a Partial. The function
    is called once for each Breakpoint in the source Partial. The
    function may modify the Breakpoint (but should not otherwise attempt 
    to modify the Partial). The data parameter can be used to supply extra
    user-defined data to the function. Pass 0 if no additional data is needed.
    The function should return 0 if successful. If the function returns
    a non-zero value, then forEachBreakpoint immediately returns that value
    without applying the function to any other Breakpoints in the Partial.
    forEachBreakpoint returns zero if all calls to func return zero.
 */
                         
int forEachPartial( PartialList * src,
                    int ( * func )( Partial * p, void * data ),
                    void * data );
/*  Apply a function to each Partial in a PartialList. The function
    is called once for each Partial in the source PartialList. The
    function may modify the Partial (but should not attempt to modify
    the PartialList). The data parameter can be used to supply extra
    user-defined data to the function. Pass 0 if no additional data 
    is needed. The function should return 0 if successful. If the 
    function returns a non-zero value, then forEachPartial immediately 
    returns that value without applying the function to any other 
    Partials in the PartialList. forEachPartial returns zero if all 
    calls to func return zero.
 */

double peakAmplitude( const Partial * p );
/*  Return the maximum amplitude achieved by a Partial.
 */

void removeIf( PartialList * src, 
               int ( * predicate )( const Partial * p, void * data ),
               void * data );
/*  Remove from a PartialList all Partials satisfying the
    specified predicate. The data parameter can be used to 
    supply extra user-defined data to the function. Pass 0 if no 
    additional data is needed.
 */

void removeLabeled( PartialList * src, long label );
/*  Remove from a PartialList all Partials having the specified label.
 */

void scaleAmplitude( PartialList * partials, LinearEnvelope * ampEnv );
/*  Scale the amplitude of the Partials in a PartialList according 
    to an envelope representing a time-varying amplitude scale value.
 */

void scaleAmp( PartialList * partials, LinearEnvelope * ampEnv );
/*  Bad old name for scaleAmplitude.
 */
                 
void scaleBandwidth( PartialList * partials, LinearEnvelope * bwEnv );
/*  Scale the bandwidth of the Partials in a PartialList according 
    to an envelope representing a time-varying bandwidth scale value.
 */
                 
void scaleFrequency( PartialList * partials, LinearEnvelope * freqEnv );
/*  Scale the frequency of the Partials in a PartialList according 
    to an envelope representing a time-varying frequency scale value.
 */
                 
void scaleNoiseRatio( PartialList * partials, LinearEnvelope * noiseEnv );
/*  Scale the relative noise content of the Partials in a PartialList 
    according to an envelope representing a (time-varying) noise energy 
    scale value.
 */

void setBandwidth( PartialList * partials, LinearEnvelope * bwEnv );
/*  Set the bandwidth of the Partials in a PartialList according 
    to an envelope representing a time-varying bandwidth value.
 */
                 
void shiftPitch( PartialList * partials, LinearEnvelope * pitchEnv );
/*  Shift the pitch of all Partials in a PartialList according to 
    the given pitch envelope. The pitch envelope is assumed to have 
    units of cents (1/100 of a halfstep).
 */

void shiftTime( PartialList * partials, double offset );
/*  Shift the time of all the Breakpoints in a Partial by a 
    constant amount.
 */

void sortByLabel( PartialList * partials );
/*  Sort the Partials in a PartialList in order of increasing label.
    The sort is stable; Partials having the same label are not 
    reordered.
 */

void timeSpan( PartialList * partials, double * tmin, double * tmax );
/* Return the minimum start time and maximum end time
   in seconds of all Partials in this PartialList. The v
   times are returned in the (non-null) pointers tmin
   and tmax.
 */

double weightedAvgFrequency( const Partial * p );
/*  Return the average frequency over all Breakpoints in this Partial, 
    weighted by the Breakpoint amplitudes. Return zero if the Partial 
    has no Breakpoints.
 */
 
/* ---------------------------------------------------------------- */
/*      Notification and exception handlers                            
/*
/*  An exception handler and a notifier may be specified. Both 
    are functions taking a const char * argument and returning
    void.
 */

void setExceptionHandler( void(*f)(const char *) );
/*  Specify a function to call when reporting exceptions. The 
    function takes a const char * argument, and returns void.
 */

void setNotifier( void(*f)(const char *) );
/*  Specify a notification function. The function takes a 
    const char * argument, and returns void.
 */

#if defined(__cplusplus)
}    /* extern "C"     */
#endif

#endif    /* ndef INCLUDE_LORIS_H */