// --------------------------------------------------------------------------- // distillOne // --------------------------------------------------------------------------- // Distill a list of Partials having a common label // into a single Partial with that label, and append it // to the distilled collection. If an empty list of Partials // is passed, then an empty Partial having the specified // label is appended. // void Distiller::distillOne( PartialList & partials, Partial::label_type label, PartialList & distilled ) { debugger << "Distiller found " << partials.size() << " Partials labeled " << label << endl; Partial newp; newp.setLabel( label ); if ( partials.size() == 1 ) { // trivial if there is only one partial to distill newp = partials.front(); } else if ( partials.size() > 0 ) // it will be an empty Partial otherwise { // sort Partials by duration, longer // Partials will be prefered: partials.sort( distillSorter ); // keep the longest Partial: PartialList::iterator it = partials.begin(); newp = *it; fadeInAndOut( newp, _fadeTime ); // Iterate over remaining Partials: for ( ++it; it != partials.end(); ++it ) { fadeInAndOut( *it, _fadeTime ); std::pair< Partial::iterator, Partial::iterator > range = findContribution( *it, newp, _fadeTime, _gapTime ); Partial::iterator cb = range.first, ce = range.second; // There can only be one contributing regions because // (and only because) the partials are sorted by length // first! // merge Breakpoints into the new Partial, if // there are any that contribute, otherwise // just absorb the current Partial as noise: if ( cb != ce ) { // absorb the non-contributing part: if ( ce != it->end() ) { Partial absorbMe( --Partial::iterator(ce), it->end() ); // shouldn't this just be ce? newp.absorb( absorbMe ); // There cannot be a non-contributing part // at the beginning of the Partial too, because // we always retain the beginning of the Partial. // If findContribution were changed, then // we might also want to absorb the beginning. // // Partial absorbMeToo( it->begin(), cb ); // newp.absorb( absorbMeToo ); } // merge the contributing part: merge( cb, ce, newp, _fadeTime, _gapTime ); } else { // no contribution, absorb the whole thing: newp.absorb( *it ); } } } // take the null Breakpoints off the ends // should check whether this is appropriate? if ( 0 == newp.begin().breakpoint().amplitude() ) { newp.erase( newp.begin() ); } Partial::iterator lastBpPos = --(Partial::iterator(newp.end())); if ( 0 == lastBpPos.breakpoint().amplitude() ) { newp.erase( lastBpPos ); } // insert the new Partial in the distilled collection // in label order: distilled.insert( std::lower_bound( distilled.begin(), distilled.end(), newp, PartialUtils::compareLabelLess() ), newp ); }