00001 #ifndef INCLUDE_COLLATOR_H
00002 #define INCLUDE_COLLATOR_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
00036 #include "Distiller.h"
00037 #include "Partial.h"
00038 #include "PartialList.h"
00039 #include "PartialUtils.h"
00040
00041 #include <algorithm>
00042
00043
00044 namespace Loris {
00045
00046
00047
00048
00065
00066 class Collator
00067 {
00068
00069
00070 double _fadeTime, _gapTime;
00071
00072
00073 public:
00074
00075
00076
00077 enum
00078 {
00079
00084 DefaultFadeTimeMs = Distiller::DefaultFadeTimeMs,
00085
00091 DefaultSilentTimeMs = Distiller::DefaultSilentTimeMs
00092 };
00093
00094
00095
00115 explicit
00116 Collator( double partialFadeTime = Collator::DefaultFadeTimeMs/1000.0,
00117 double partialSilentTime = Collator::DefaultSilentTimeMs/1000.0 );
00118
00119
00120
00121
00122
00147 #if ! defined(NO_TEMPLATE_MEMBERS)
00148 template< typename Container >
00149 typename Container::iterator collate( Container & partials );
00150 #else
00151 inline
00152 PartialList::iterator collate( PartialList & partials );
00153 #endif
00154
00156 #if ! defined(NO_TEMPLATE_MEMBERS)
00157 template< typename Container >
00158 typename Container::iterator operator() ( Container & partials );
00159 #else
00160 PartialList::iterator operator() ( PartialList & partials );
00161 #endif
00162
00180 #if ! defined(NO_TEMPLATE_MEMBERS)
00181 template< typename Container >
00182 static typename Container::iterator
00183 collate( Container & partials, double partialFadeTime,
00184 double partialSilentTime );
00185 #else
00186 static inline PartialList::iterator
00187 collate( PartialList & partials, double partialFadeTime,
00188 double partialSilentTime );
00189 #endif
00190
00191
00192 private:
00193
00194
00195
00202 void collateAux( PartialList & unlabled );
00203
00204 };
00205
00206
00207
00208
00231
00232 #if ! defined(NO_TEMPLATE_MEMBERS)
00233 template< typename Container >
00234 typename Container::iterator
00235 Collator::collate( Container & partials )
00236 #else
00237 inline
00238 PartialList::iterator
00239 Collator::collate( PartialList & partials )
00240 #endif
00241 {
00242 #if ! defined(NO_TEMPLATE_MEMBERS)
00243 typedef typename Container::iterator Iterator;
00244 #else
00245 typedef PartialList::iterator Iterator;
00246 #endif
00247
00248
00249
00250
00251
00252 Iterator beginUnlabeled =
00253 std::partition( partials.begin(), partials.end(),
00254 std::not1( PartialUtils::isLabelEqual(0) ) );
00255
00256
00257
00258
00259
00260 PartialList collated( beginUnlabeled, partials.end() );
00261
00262
00263
00264 Partial::label_type labelCollated = 1;
00265 if ( partials.begin() != beginUnlabeled )
00266 {
00267 labelCollated =
00268 1 + std::max_element( partials.begin(), beginUnlabeled,
00269 PartialUtils::compareLabelLess() )->label();
00270 }
00271 if ( labelCollated < 1 )
00272 {
00273 labelCollated = 1;
00274 }
00275
00276
00277 collateAux( collated );
00278
00279
00280 for ( Iterator it = collated.begin(); it != collated.end(); ++it )
00281 {
00282 it->setLabel( labelCollated++ );
00283 }
00284
00285
00286
00287 Iterator endCollated =
00288 std::copy( collated.begin(), collated.end(), beginUnlabeled );
00289
00290
00291 if ( endCollated != partials.end() )
00292 {
00293 typename Iterator::difference_type numLabeled =
00294 std::distance( partials.begin(), beginUnlabeled );
00295
00296 partials.erase( endCollated, partials.end() );
00297
00298
00299 beginUnlabeled = partials.begin();
00300 std::advance( beginUnlabeled, numLabeled );
00301 }
00302 return beginUnlabeled;
00303 }
00304
00305
00306
00307
00311
00312 #if ! defined(NO_TEMPLATE_MEMBERS)
00313 template< typename Container >
00314 typename Container::iterator Collator::operator()( Container & partials )
00315 #else
00316 inline
00317 PartialList::iterator Collator::operator()( PartialList & partials )
00318 #endif
00319 {
00320 return collate( partials );
00321 }
00322
00323
00324
00325
00347
00348 #if ! defined(NO_TEMPLATE_MEMBERS)
00349 template< typename Container >
00350 typename Container::iterator
00351 Collator::collate( Container & partials, double partialFadeTime,
00352 double partialSilentTime )
00353 #else
00354 inline
00355 PartialList::iterator
00356 Collator::collate( PartialList & partials, double partialFadeTime,
00357 double partialSilentTime )
00358 #endif
00359 {
00360 Collator instance( partialFadeTime, partialSilentTime );
00361 return instance.collate( partials );
00362 }
00363
00364 }
00365
00366 #endif