00001 #ifndef INCLUDE_HARMONIFIER_H
00002 #define INCLUDE_HARMONIFIER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "Envelope.h"
00036 #include "LorisExceptions.h"
00037 #include "Partial.h"
00038 #include "PartialUtils.h"
00039
00040 #include <algorithm>
00041 #include <memory>
00042
00043
00044 namespace Loris {
00045
00046
00047
00048
00049
00054
00055 class Harmonifier
00056 {
00057
00058
00059 Partial _refPartial;
00060
00061
00062 double _freqFixThresholdDb;
00063
00064
00065
00066 std::auto_ptr< Envelope > _weight;
00067
00068
00069
00070
00071 public:
00072
00073
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
00141
00142
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
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
00234
00237 static Envelope * createDefaultEnvelope( void );
00238
00239 };
00240
00241
00242
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
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
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
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
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 }
00440
00441 #endif