Harmonifier.h

00001 #ifndef INCLUDE_HARMONIFIER_H
00002 #define INCLUDE_HARMONIFIER_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  * Harmonifier.h
00026  *
00027  * Definition of class Harmonifier.
00028  *
00029  * Kelly Fitz, 26 Oct 2005
00030  * loris@cerlsoundgroup.org
00031  *
00032  * http://www.cerlsoundgroup.org/Loris/
00033  *
00034  */
00035 #include "Envelope.h" 
00036 #include "LorisExceptions.h" 
00037 #include "Partial.h"
00038 #include "PartialUtils.h"
00039 
00040 #include <algorithm>    // for find
00041 #include <memory>       // for auto_ptr
00042 
00043 //  begin namespace
00044 namespace Loris {
00045 
00046 
00047 // ---------------------------------------------------------------------------
00048 //  Class Harmonifier
00049 //
00054 //
00055 class Harmonifier
00056 {
00057 //  -- instance variables --
00058 
00059     Partial _refPartial;                
00060 
00061                                         
00062     double _freqFixThresholdDb;         
00063 
00064 
00065 
00066     std::auto_ptr< Envelope > _weight;  
00067 
00068 
00069     
00070 //  -- public interface --
00071 public:
00072 
00073 //  -- lifecycle --
00074 
00080     Harmonifier( const Partial & ref, double threshold_dB = 0 );
00081 
00089     Harmonifier( const Partial & ref, const Envelope & env, 
00090                  double threshold_dB = 0 );
00091 
00098     //
00101     //
00102 #if ! defined(NO_TEMPLATE_MEMBERS)
00103     template<typename Iter>
00104     Harmonifier( Iter b, Iter e, Partial::label_type refLabel, 
00105                 double threshold_dB = 0 );
00106 #else
00107    inline
00108     Harmonifier( PartialList::iterator b, PartialList::iterator e, 
00109                  Partial::label_type refLabel, double threshold_dB = 0 );
00110 #endif
00111 
00122     //
00125     //
00126 #if ! defined(NO_TEMPLATE_MEMBERS)
00127     template<typename Iter>
00128     Harmonifier( Iter b, Iter e, Partial::label_type refLabel, 
00129                  const Envelope & env, double threshold_dB = 0 );
00130 #else
00131    inline
00132     Harmonifier( PartialList::iterator b, PartialList::iterator e, 
00133                  Partial::label_type refLabel, const Envelope & env,
00134                  double threshold_dB = 0 );
00135 #endif
00136 
00138     ~Harmonifier( void );
00139 
00140     // use compiler-generated copy and assign.
00141 
00142 //  -- operation --
00143 
00145     void harmonify( Partial & p ) const;
00146     
00148 #if ! defined(NO_TEMPLATE_MEMBERS)
00149     template<typename Iter>
00150     void harmonify( Iter b, Iter e  );
00151 #else
00152     inline
00153     void harmonify( PartialList::iterator b, PartialList::iterator e  );
00154 #endif
00155 
00156 // -- static members --
00157 
00180 #if ! defined(NO_TEMPLATE_MEMBERS)
00181     template< typename Iter >
00182     static 
00183     void harmonify( Iter b, Iter e, 
00184                     Partial::label_type refLabel,
00185                     double threshold_dB = 0 );
00186 #else
00187     static inline 
00188     void harmonify( PartialList::iterator b, PartialList::iterator e,
00189                     Partial::label_type refLabel,
00190                     double threshold_dB = 0 );
00191 #endif   
00192 
00218 #if ! defined(NO_TEMPLATE_MEMBERS)
00219     template< typename Iter >
00220     static 
00221     void harmonify( Iter b, Iter e, 
00222                     Partial::label_type refLabel,
00223                     const Envelope & env, double threshold_dB = 0 );
00224 #else
00225     static inline 
00226     void harmonify( PartialList::iterator b, PartialList::iterator e,
00227                     Partial::label_type refLabel,
00228                     const Envelope & env, double threshold_dB = 0 );
00229 #endif   
00230 
00231 private:
00232 
00233 //  -- helpers --
00234 
00237     static Envelope * createDefaultEnvelope( void );
00238     
00239 };
00240 
00241 // ---------------------------------------------------------------------------
00242 //  constructor
00243 // ---------------------------------------------------------------------------
00253 //
00254 #if ! defined(NO_TEMPLATE_MEMBERS)
00255 template<typename Iter>
00256 Harmonifier::Harmonifier( Iter b, Iter e, Partial::label_type refLabel, 
00257                           double threshold_dB ) :
00258 #else
00259 inline
00260 Harmonifier::Harmonifier( PartialList::iterator b, PartialList::iterator e, 
00261                           Partial::label_type refLabel, double threshold_dB ) :
00262 #endif
00263     _freqFixThresholdDb( threshold_dB ),
00264     _weight( createDefaultEnvelope() )
00265 {
00266     if ( 1 > refLabel )
00267     {
00268         Throw( InvalidArgument, "The reference label must be positive." );
00269     }
00270 
00271     b = std::find_if( b, e, PartialUtils::isLabelEqual( refLabel ) );
00272     if ( b == e )
00273     {
00274         Throw( InvalidArgument, "no Partial has the specified reference label" );
00275     }
00276 
00277     if ( 0 == b->numBreakpoints() )
00278     {
00279         Throw( InvalidArgument, 
00280                "Cannot use an empty reference Partial in Harmonizer" );
00281     }
00282     _refPartial = *b;
00283 }
00284 
00285 // ---------------------------------------------------------------------------
00286 //  constructor
00287 // ---------------------------------------------------------------------------
00302 //
00303 #if ! defined(NO_TEMPLATE_MEMBERS)
00304 template<typename Iter>
00305 Harmonifier::Harmonifier( Iter b, Iter e, Partial::label_type refLabel, 
00306                           const Envelope & env, double threshold_dB ) :
00307 #else
00308 inline
00309 Harmonifier::Harmonifier( PartialList::iterator b, PartialList::iterator e, 
00310                           Partial::label_type refLabel, const Envelope & env,
00311                           double threshold_dB ) :
00312 #endif
00313     _freqFixThresholdDb( threshold_dB ),
00314     _weight( env.clone() )
00315 {
00316     if ( 1 > refLabel )
00317     {
00318         Throw( InvalidArgument, "The reference label must be positive." );
00319     }
00320 
00321     b = std::find_if( b, e, PartialUtils::isLabelEqual( refLabel ) );
00322     if ( b == e )
00323     {
00324         Throw( InvalidArgument, "no Partial has the specified reference label" );
00325     }
00326 
00327     if ( 0 == b->numBreakpoints() )
00328     {
00329         Throw( InvalidArgument, 
00330                "Cannot use an empty reference Partial in Harmonizer" );
00331     }
00332     _refPartial = *b;
00333 }
00334 
00335 // ---------------------------------------------------------------------------
00336 //  harmonify
00337 // ---------------------------------------------------------------------------
00339 #if ! defined(NO_TEMPLATE_MEMBERS)
00340 template<typename Iter>
00341 void Harmonifier::harmonify( Iter b, Iter e  )
00342 #else
00343 inline
00344 void Harmonifier::harmonify( PartialList::iterator b, PartialList::iterator e  )
00345 #endif
00346 {
00347     while ( b != e )
00348     {
00349         harmonify( *b );
00350         ++b;
00351     }
00352 }    
00353 
00354 // ---------------------------------------------------------------------------
00355 //  harmonify (STATIC)
00356 // ---------------------------------------------------------------------------
00379 #if ! defined(NO_TEMPLATE_MEMBERS)
00380 template< typename Iter >
00381 void Harmonifier::harmonify( Iter b, Iter e, 
00382                              Partial::label_type refLabel,
00383                              double threshold_dB )
00384 #else
00385 inline 
00386 void Harmonifier::harmonify( PartialList::iterator b, PartialList::iterator e,
00387                              Partial::label_type refLabel,
00388                              double threshold_dB )
00389 #endif   
00390 {
00391     Harmonifier instance( b, e, refLabel, threshold_dB );
00392     instance.harmonify( b, e );
00393 }
00394 
00395 // ---------------------------------------------------------------------------
00396 //  harmonify (STATIC)
00397 // ---------------------------------------------------------------------------
00423 #if ! defined(NO_TEMPLATE_MEMBERS)
00424 template< typename Iter >
00425 void Harmonifier::harmonify( Iter b, Iter e, 
00426                              Partial::label_type refLabel,
00427                              const Envelope & env, double threshold_dB )
00428 #else
00429 inline 
00430 void Harmonifier::harmonify( PartialList::iterator b, PartialList::iterator e,
00431                              Partial::label_type refLabel,
00432                              const Envelope & env, double threshold_dB )
00433 #endif   
00434 {
00435     Harmonifier instance( b, e, refLabel, env, threshold_dB );
00436     instance.harmonify( b, e );
00437 }
00438 
00439 }   // namespace Loris
00440 
00441 #endif  /* ndef INCLUDE_HARMONIFIER_H */

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