Fundamental.h

00001 #ifndef INCLUDE_FUNDAMENTAL_H
00002 #define INCLUDE_FUNDAMENTAL_H
00003 /*
00004  * This is the Loris C++ Class Library, implementing analysis, 
00005  * manipulation, and synthesis of digitized sounds using the Reassigned 
00006  * Bandwidth-Enhanced Additive Sound Model.
00007  *
00008  * Loris is Copyright (c) 1999-2007 by Kelly Fitz and Lippold Haken
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY, without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  *
00025  * Fundamental.h
00026  *
00027  * Definition of class Fundamental for computing an estimate of 
00028  * fundamental frequency from a sequence of Partials using a 
00029  * maximum likelihood algorithm.
00030  *
00031  * Kelly Fitz, 10 June 2004
00032  * loris@cerlsoundgroup.org
00033  *
00034  * http://www.cerlsoundgroup.org/Loris/
00035  *
00036  */
00037 
00038 #include "LorisExceptions.h"
00039 #include "Envelope.h"
00040 #include "LinearEnvelope.h"
00041 #include "PartialList.h"
00042 
00043 //  begin namespace
00044 namespace Loris {
00045 
00046 
00047 // ---------------------------------------------------------------------------
00048 //  class Fundamental
00049 //
00062 //
00063 class Fundamental : public Envelope
00064 {
00065 //  -- instance variables --
00066     PartialList partials_;      //  store a collated copy of the 
00067                                 //  sequence of Partials
00068     double freqMin_, freqMax_;  //  frequency bounds on the search for 
00069                                 //  a likely estimate
00070     double ampThreshold_;       //  minimum Partial amplitude (dB), quieter Partials
00071                                 //  are ignored when estimating the fundamental
00072     double freqResolution_;     //  estimates of fundamental frequency are 
00073                                 //  computed iteratively until within this
00074                                 //  many Hz of the local most likely value
00075     
00076 //  -- public interface --
00077 public:
00078 //  -- construction --
00079 
00094 #if !defined(NO_TEMPLATE_MEMBERS)
00095     template<typename Iter>
00096     Fundamental( Iter begin_partials, Iter end_partials,
00097                  double fmin, double fmax  ); 
00098 #else 
00099     Fundamental( PartialList::const_iterator begin_partials, 
00100                  PartialList::const_iterator end_partials,
00101                  double fmin, double fmax );
00102 #endif
00103     
00104     //  copy, assign, and destroy are free, the 
00105     //  compiler-generated versions are OK   
00106      
00107 //  -- estimation of fundamental frequency --
00108 
00123     double estimateAt( double time ) const;
00124 
00135     double operator() ( double time ) const;
00136      
00155     LinearEnvelope constructEnvelope( double interval ) const;
00156      
00180     LinearEnvelope 
00181     constructEnvelope( double t1, double t2, double interval ) const;
00182  
00183 //  -- parameter access/mutation --
00184 
00190     double ampThreshold( void ) const { return ampThreshold_; }
00191     
00197     void setAmpThreshold( double x );
00198     
00204     double freqResolution( void ) const { return freqResolution_; }
00205     
00211     void setFreqResolution( double x ); 
00212     
00213 //  -- Envelope interface --
00214 
00219     virtual Fundamental * clone( void ) const 
00220         { return new Fundamental( *this ); }
00221     
00222     virtual double valueAt( double time ) const
00223         { return estimateAt( time ); }
00233      
00234 //  -- default parameters --
00235 
00236     static const double DefaultThreshold;   
00237     static const double DefaultResolution;  
00238 
00239 private:
00240 //  -- internal implementation members --
00241     void preparePartials( void );   //  preprocess the Partials for speed
00242     
00243 };  // end of class FrequencyReference
00244 
00245 
00246 // ---------------------------------------------------------------------------
00247 //  constructor from Partial range
00248 // ---------------------------------------------------------------------------
00249 //  Construct a fundamental estimator for a sequence
00250 //  of Partials. [begin_partials, end_partials) must 
00251 //  specify a valid range of Partials. f1 and f2 are 
00252 //  frequency bounds on the search for a likely estimate
00253 //  of the fundamental (a narrower range will speed 
00254 //  up the search). Throws InvalidArgument if f1==f2 or
00255 //  if either frequency is negative.
00256 //
00257 #if !defined(NO_TEMPLATE_MEMBERS)
00258 template <typename Iter>
00259 Fundamental::Fundamental( Iter begin_partials, Iter end_partials,
00260                           double f1, double f2  ) :
00261 #else
00262 inline
00263 Fundamental::Fundamental( PartialList::const_iterator begin_partials, 
00264                           PartialList::const_iterator end_partials,
00265                           double f1, double f2 ) :
00266 #endif
00267     //  initializers
00268     partials_( begin_partials, end_partials ),
00269     freqMin_( (f1<f2)?(f1):(f2) ),  //  the lesser of f1 and f2
00270     freqMax_( (f1<f2)?(f2):(f1) ),  //  the greater of f1 and f2
00271     ampThreshold_( DefaultThreshold ),
00272     freqResolution_( DefaultResolution )
00273 {
00274     //  sanity check:
00275     if ( f1 == f2 )
00276     {
00277         Throw( InvalidArgument, "Cannot estimate the fundamental over "
00278                                 "an empty frequency range." );
00279     }
00280     if ( f1 < 0 )
00281     {
00282         Throw( InvalidArgument, "Cannot estimate the fundamental over "
00283                                 "a negative frequency range." );
00284     }
00285     
00286     preparePartials();
00287 }
00288 
00289 }   //  end of namespace Loris
00290 
00291 #endif  // ndef INCLUDE_FUNDAMENTAL_H

Generated on Sat Jan 19 19:02:50 2008 for Loris by  doxygen 1.5.2