Ejemplo n.º 1
0
// ---------------------------------------------------------------------------
//	Cropper function call operator
// ---------------------------------------------------------------------------
//	Trim a Partial by removing Breakpoints outside a specified time span.
//	Insert a Breakpoint at the boundary when cropping occurs.
//
void 
Cropper::operator()( Partial & p ) const
{
	//	crop beginning of Partial
	Partial::iterator it = p.findAfter( minTime );
	if ( it != p.begin() )    // Partial begins earlier than minTime
	{
	    if ( it != p.end() ) // Partial ends later than minTime
	    {
            Breakpoint bp = p.parametersAt( minTime );
            it = p.insert( minTime, bp );
        }
		it = p.erase( p.begin(), it );
	}
	
	//	crop end of Partial
	it = p.findAfter( maxTime );
	if ( it != p.end() ) // Partial ends later than maxTime
	{
	    if ( it != p.begin() )   // Partial begins earlier than maxTime
	    {
	    	Breakpoint bp = p.parametersAt( maxTime );
    		it = p.insert( maxTime, bp );
    		++it;   //  advance, we don't want to cut this one off
		}
		it = p.erase( it, p.end() );
	}
}
Ejemplo n.º 2
0
// ---------------------------------------------------------------------------
//	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 );
}
Ejemplo n.º 3
0
// ---------------------------------------------------------------------------
//	merge	(STATIC)
// ---------------------------------------------------------------------------
//	Merge the Breakpoints in the specified iterator range into the
//	distilled Partial. The beginning of the range may overlap, and 
//	will replace, some non-zero-amplitude portion of the distilled
//	Partial. Assume that there is no such overlap at the end of the 
//	range (could check), because findContribution only leaves overlap
//  at the beginning of the range.
//
static void merge( Partial::const_iterator beg, 
				   Partial::const_iterator end, 
				   Partial & destPartial, double fadeTime, 
				   double gapTime = 0. )
{	
	//	absorb energy in distilled Partial that overlaps the
	//	range to merge:
	Partial toMerge( beg, end );
	toMerge.absorb( destPartial );  
    fadeInAndOut( toMerge, fadeTime );

		
    //  find the first Breakpoint in destPartial that is after the
    //  range of merged Breakpoints, plus the required gap:
	Partial::iterator removeEnd = destPartial.findAfter( toMerge.endTime() + gapTime );
    
    //  if this Breakpoint has non-zero amplitude, need to leave time
    //  for a fade in:
	while ( removeEnd != destPartial.end() &&
            removeEnd.breakpoint().amplitude() != 0 &&
            removeEnd.time() < toMerge.endTime() + gapTime + fadeTime )
    {
        ++removeEnd;
    }   
    
	//	find the first Breakpoint in the destination Partial that needs
    //  to be removed because it is in the overlap region:
	Partial::iterator removeBegin = destPartial.findAfter( toMerge.startTime() - gapTime );
        
    //  if beforeMerge has non-zero amplitude, need to leave time
    //  for a fade out:
    if ( removeBegin != destPartial.begin() )
	{
        Partial::iterator beforeMerge = --Partial::iterator(removeBegin);
        
        while ( removeBegin != destPartial.begin() &&
                beforeMerge.breakpoint().amplitude() != 0 &&
                beforeMerge.time() > toMerge.startTime() - gapTime - fadeTime )
        {
            --removeBegin;
            if ( beforeMerge != destPartial.begin() )
            {
                --beforeMerge;
            }
        }   
        
	}
	
	//	remove the Breakpoints in the merge range from destPartial:
    double rbt = (removeBegin != destPartial.end())?(removeBegin.time()):(destPartial.endTime());
    double ret = (removeEnd != destPartial.end())?(removeEnd.time()):(destPartial.endTime());
    Assert( rbt <= ret );
	destPartial.erase( removeBegin, removeEnd );

    //  how about doing the fades here instead?
    //  fade in if necessary:
	if ( removeEnd != destPartial.end() &&
         removeEnd.breakpoint().amplitude() != 0 )
	{
        Assert( removeEnd.time() - fadeTime > toMerge.endTime() );

        //	update removeEnd so that we don't remove this 
        //	null we are inserting:
        destPartial.insert( 
            removeEnd.time() - fadeTime, 
            BreakpointUtils::makeNullBefore( removeEnd.breakpoint(), fadeTime ) );
	}

    if ( removeEnd != destPartial.begin() )
    {
        Partial::iterator beforeMerge = --Partial::iterator(removeEnd);
        if ( beforeMerge.breakpoint().amplitude() > 0 )
        {
            Assert( beforeMerge.time() + fadeTime < toMerge.startTime() );
            
            destPartial.insert( 
                beforeMerge.time() + fadeTime, 
                BreakpointUtils::makeNullAfter( beforeMerge.breakpoint(), fadeTime ) );
        }
    }		
    
    //	insert the Breakpoints in the range:
	for ( Partial::const_iterator insert = toMerge.begin(); insert != toMerge.end(); ++insert )
	{
		destPartial.insert( insert.time(), insert.breakpoint() );
	}
}