Collator.h

00001 #ifndef INCLUDE_COLLATOR_H
00002 #define INCLUDE_COLLATOR_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  * Collator.h
00026  *
00027  * Definition of class Collator.
00028  *
00029  * Kelly Fitz, 29 April 2005
00030  * loris@cerlsoundgroup.org
00031  *
00032  * http://www.cerlsoundgroup.org/Loris/
00033  *
00034  */
00035 
00036 #include "Partial.h"
00037 #include "PartialList.h"
00038 #include "PartialUtils.h"
00039 
00040 #include <algorithm>
00041 
00042 //  begin namespace
00043 namespace Loris {
00044 
00045 // ---------------------------------------------------------------------------
00046 //  class Collator
00047 //
00064 //
00065 class Collator
00066 {
00067 //  -- instance variables --
00068 
00069     double _fadeTime, _gapTime;       
00070         
00071 //  -- public interface --
00072 public:
00073 
00074 //  -- global defaults and constants --
00075 
00078     static const double DefaultFadeTime;
00079     
00082     static const double DefaultSilentTime;
00083     
00084 //  -- construction --
00085 
00105     explicit
00106     Collator( double partialFadeTime = Collator::DefaultFadeTime,
00107               double partialSilentTime = Collator::DefaultSilentTime );
00108      
00109     //  Use compiler-generated copy, assign, and destroy.
00110     
00111 //  -- collating --
00112 
00137 #if ! defined(NO_TEMPLATE_MEMBERS)
00138     template< typename Container >
00139     typename Container::iterator collate( Container & partials );
00140 #else
00141     inline
00142     PartialList::iterator collate( PartialList & partials );
00143 #endif
00144 
00146 #if ! defined(NO_TEMPLATE_MEMBERS)
00147     template< typename Container >
00148     typename Container::iterator operator() ( Container & partials );
00149 #else
00150     PartialList::iterator operator() ( PartialList & partials );
00151 #endif
00152     
00170 #if ! defined(NO_TEMPLATE_MEMBERS)
00171     template< typename Container >
00172     static typename Container::iterator 
00173     collate( Container & partials, double partialFadeTime,
00174                                    double partialSilentTime );
00175 #else
00176     static inline PartialList::iterator
00177     collate( PartialList & partials, double partialFadeTime,
00178                                      double partialSilentTime );
00179 #endif
00180 
00181 
00182 private:
00183 
00184 //  -- helpers --
00185 
00192     void collateAux( PartialList & unlabled );
00193     
00194 };  //  end of class Collator
00195 
00196 // ---------------------------------------------------------------------------
00197 //  collate
00198 // ---------------------------------------------------------------------------
00221 //
00222 #if ! defined(NO_TEMPLATE_MEMBERS)
00223 template< typename Container >
00224 typename Container::iterator 
00225 Collator::collate( Container & partials )
00226 #else
00227 inline
00228 PartialList::iterator 
00229 Collator::collate( PartialList & partials )
00230 #endif
00231 {
00232 #if ! defined(NO_TEMPLATE_MEMBERS)
00233     typedef typename Container::iterator Iterator;
00234 #else
00235     typedef PartialList::iterator Iterator;
00236 #endif
00237 
00238     // Partition the Partials into labeled and unlabeled, 
00239     // and collate the unlabeled ones and replace the 
00240     // unlabeled range.
00241     // (This requires bidirectional iterator support.)
00242     Iterator beginUnlabeled = 
00243        std::partition( partials.begin(), partials.end(), 
00244                               std::not1( PartialUtils::isLabelEqual(0) ) );
00245         //  this used to be a stable partition, which 
00246         //  is very much slower and seems unnecessary
00247         
00248     // cannot splice if this operation is to be generic
00249     // with respect to container, have to copy:
00250     PartialList collated( beginUnlabeled, partials.end() );
00251     // collated.splice( collated.end(), beginUnlabeled, partials.end() );
00252     
00253     //  determine the label for the first collated Partial:
00254     Partial::label_type labelCollated = 1;
00255     if ( partials.begin() != beginUnlabeled )
00256     {
00257        labelCollated = 
00258         1 + std::max_element( partials.begin(), beginUnlabeled, 
00259                               PartialUtils::compareLabelLess() )->label();
00260     }
00261     if ( labelCollated < 1 )
00262     {
00263         labelCollated = 1;
00264     }
00265 
00266     //  collate unlabeled (zero-labeled) Partials:
00267     collateAux( collated );
00268     
00269     //  label the collated Partials:
00270     for ( Iterator it = collated.begin(); it != collated.end(); ++it )
00271     {
00272         it->setLabel( labelCollated++ );
00273     }
00274     
00275     //  copy the collated Partials back into the source container
00276     //  after the range of labeled Partials     
00277     Iterator endCollated = 
00278         std::copy( collated.begin(), collated.end(), beginUnlabeled );
00279 
00280     //  remove extra Partials from the end of the source container
00281     if ( endCollated != partials.end() )
00282     {
00283         typename Iterator::difference_type numLabeled = 
00284             std::distance( partials.begin(), beginUnlabeled );
00285 
00286         partials.erase( endCollated, partials.end() );
00287 
00288         // restore beginUnlabeled:    
00289         beginUnlabeled = partials.begin();
00290         std::advance( beginUnlabeled, numLabeled );
00291     }
00292     return beginUnlabeled;
00293 }
00294 
00295 // ---------------------------------------------------------------------------
00296 //  Function call operator 
00297 // ---------------------------------------------------------------------------
00301 //
00302 #if ! defined(NO_TEMPLATE_MEMBERS)
00303 template< typename Container >
00304 typename Container::iterator Collator::operator()( Container & partials )
00305 #else
00306 inline
00307 PartialList::iterator Collator::operator()( PartialList & partials )
00308 #endif
00309 { 
00310     return collate( partials );
00311 }
00312 
00313 // ---------------------------------------------------------------------------
00314 //  collate
00315 // ---------------------------------------------------------------------------
00337 //
00338 #if ! defined(NO_TEMPLATE_MEMBERS)
00339 template< typename Container >
00340 typename Container::iterator 
00341 Collator::collate( Container & partials, double partialFadeTime,
00342                                          double partialSilentTime )
00343 #else
00344 inline
00345 PartialList::iterator 
00346 Collator::collate( PartialList & partials, double partialFadeTime,
00347                                            double partialSilentTime )
00348 #endif
00349 {
00350     Collator instance( partialFadeTime, partialSilentTime );
00351     return instance.collate( partials );
00352 }
00353 
00354 }   //  end of namespace Loris
00355 
00356 #endif /* ndef INCLUDE_COLLATOR_H */

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