本文整理汇总了C++中Partial::insert方法的典型用法代码示例。如果您正苦于以下问题:C++ Partial::insert方法的具体用法?C++ Partial::insert怎么用?C++ Partial::insert使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Partial
的用法示例。
在下文中一共展示了Partial::insert方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1:
// ---------------------------------------------------------------------------
// 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() );
}
}
示例2: fadeInAndOut
// ---------------------------------------------------------------------------
// fadeInAndOut (STATIC)
// ---------------------------------------------------------------------------
// Add zero-amplitude Breakpoints to the ends of a Partial if necessary.
// Do this to all Partials before distilling to make distillation easier.
//
static void fadeInAndOut( Partial & p, double fadeTime )
{
if ( p.first().amplitude() != 0 )
{
p.insert(
p.startTime() - fadeTime,
BreakpointUtils::makeNullBefore( p.first(), fadeTime ) );
}
if ( p.last().amplitude() != 0 )
{
p.insert(
p.endTime() + fadeTime,
BreakpointUtils::makeNullAfter( p.last(), fadeTime ) );
}
}
示例3: bp
// ---------------------------------------------------------------------------
// getPartial
// ---------------------------------------------------------------------------
// Convert any FileIOExceptions into ImportExceptions, so that clients can
// reasonably expect to catch only ImportExceptions.
//
static void
getPartial( std::istream & s, PartialList & partials, double bweCutoff )
{
try
{
// read the Track header:
TrackOnDisk tkHeader;
readTrackHeader( s, tkHeader );
// create a Partial:
Partial p;
p.setLabel( tkHeader.label );
// keep running phase and time for Breakpoint construction:
double phase = tkHeader.initialPhase;
// convert time to seconds and offset by a millisecond to
// allow for implied onset (Lemur analysis data was shifted
// such that the earliest Partial starts at 0).
double time = tkHeader.startTime * 0.001;
// use this to compute phases:
double prevTtnSec = 0.;
// loop: read Peak, create Breakpoint, add to Partial:
for ( int i = 0; i < tkHeader.numPeaks; ++i ) {
// read Peak:
PeakOnDisk pkData;
readPeakData( s, pkData );
double frequency = pkData.frequency;
double amplitude = pkData.magnitude;
double bandwidth = std::min( pkData.bandwidth, 1.f );
// fix bandwidth:
// Lemur used a cutoff frequency, below which
// bandwidth was ignored; Loris does not, so
// toss out that bogus bandwidth.
if ( frequency < bweCutoff ) {
amplitude *= std::sqrt(1. - bandwidth);
bandwidth = 0.;
}
// otherwise, adjust the bandwidth value
// to account for the difference in noise
// scaling between Lemur and Loris; this
// mess doubles the noise modulation index
// without changing the sine modulation index,
// see Oscillator::modulate().
else {
amplitude *= std::sqrt( 1. + (3. * bandwidth) );
bandwidth = (4. * bandwidth) / ( 1. + (3. * bandwidth) );
}
// update phase based on _this_ pkData's interpolated freq:
phase +=2. * Pi * prevTtnSec * pkData.interpolatedFrequency;
phase = std::fmod( phase, 2. * Pi );
// create Breakpoint:
Breakpoint bp( frequency, amplitude, bandwidth, phase );
// insert in Partial:
p.insert( time, bp );
// update time:
prevTtnSec = pkData.ttn * 0.001;
time += prevTtnSec;
}
if ( p.duration() > 0. ) {
partials.push_back( p );
}
/*
else {
debugger << "import rejecting a Partial of zero duration ("
<< tkHeader.numPeaks << " peaks read)" << endl;
}
*/
}
catch( FileIOException & ex ) {
ex.append( "Failed to import a partial from a Lemur file." );
throw;
}
}
示例4: main
int main( void )
{
cout << "Loris C++ API test, using " << LORIS_VERSION_STR << endl;
cout << "Kelly Fitz 2006" << endl << endl;
cout << "Generates a simple linear morph between a " << endl;
cout << "clarinet and a flute using the C++ library." << endl << endl;
std::string path("");
if ( std::getenv("srcdir") )
{
path = std::getenv("srcdir");
path = path + "/";
}
try
{
// analyze clarinet tone
cout << "importing clarinet samples" << endl;
Analyzer a( 415*.8, 415*1.6 );
AiffFile f( path + "clarinet.aiff" );
// analyze the clarinet
cout << "analyzing clarinet 4G#" << endl;
a.analyze( f.samples(), f.sampleRate() );
PartialList clar = a.partials();
// channelize and distill
cout << "distilling" << endl;
FrequencyReference clarRef( clar.begin(), clar.end(), 415*.8, 415*1.2, 50 );
Channelizer::channelize( clar.begin(), clar.end(), clarRef , 1 );
Distiller::distill( clar, 0.001 );
// test SDIF import and export
cout << "exporting " << clar.size() << " partials to SDIF file" << endl;
SdifFile::Export( "clarinet.ctest.sdif", clar );
cout << "importing from SDIF file" << endl;
SdifFile ip("clarinet.ctest.sdif");
if ( clar.size() != ip.partials().size() )
{
throw std::runtime_error( "SDIF import yields a different number of partials than were exported!" );
}
clar = ip.partials();
// shift pitch of clarinet partials
cout << "shifting pitch of " << clar.size() << " Partials by 600 cents" << endl;
PartialUtils::shiftPitch( clar.begin(), clar.end(), -600 );
// check clarinet synthesis
cout << "checking clarinet synthesis" << endl;
AiffFile clarout( clar.begin(), clar.end(), f.sampleRate() );
clarout.write( "clarOK.ctest.aiff" );
// analyze flute tone
cout << "importing flute samples" << endl;
f = AiffFile( path + "flute.aiff" );
// analyze the flute
cout << "analyzing flute 4D" << endl;
a = Analyzer( 270 );
#if defined(ESTIMATE_F0) && ESTIMATE_F0
cout << "Analyzer will build a fundamental frequency estimate for the flute" << endl;
a.buildFundamentalEnv( 270, 310 );
#endif
#if defined(ESTIMATE_AMP) && ESTIMATE_AMP
a.buildAmpEnv( true );
#endif
a.analyze( f.samples(), f.sampleRate() );
PartialList flut = a.partials();
// channelize and distill
cout << "distilling" << endl;
#if defined(ESTIMATE_F0) && ESTIMATE_F0
const LinearEnvelope & flutRef = a.fundamentalEnv();
double est_time = flutRef.begin()->first;
cout << "flute fundamental envelope starts at time " << est_time << endl;
while ( est_time < 2 )
{
cout << "flute fundamental estimate at time "
<< est_time << " is " << flutRef.valueAt( est_time ) << endl;
est_time += 0.35;
}
#else
FrequencyReference flutRef( flut.begin(), flut.end(), 291*.8, 291*1.2, 50 );
#endif
Channelizer::channelize( flut.begin(), flut.end(), flutRef, 1 );
Distiller::distill( flut, 0.001 );
cout << "obtained " << flut.size() << " distilled flute Partials" << endl;
#if defined(ESTIMATE_F0) && ESTIMATE_F0
#if defined(ESTIMATE_AMP) && ESTIMATE_AMP
// generate a sinusoid that tracks the fundamental
// and amplitude envelopes obtained during analysis
cout << "synthesizing sinusoid from flute amp and fundamental estimates" << endl;
Partial boo;
LinearEnvelope fund = a.fundamentalEnv();
LinearEnvelope::iterator it;
for ( it = fund.begin(); it != fund.end(); ++it )
{
Breakpoint bp( it->second, a.ampEnv().valueAt( it->first ), 0, 0 );
boo.insert( it->first, bp );
//.........这里部分代码省略.........
示例5: defined
//.........这里部分代码省略.........
//const Breakpoint & bp = bpIter->breakpoint;
const double peakTime = frameTime + bpIter->time();
// find the Partial that is nearest in frequency to the Peak:
PartialPtrs::iterator nextEligible = eligible;
if ( eligible != mEligiblePartials.end() &&
end_frequency( **eligible ) < bpIter->frequency() )
{
++nextEligible;
while ( nextEligible != mEligiblePartials.end() &&
end_frequency( **nextEligible ) < bpIter->frequency() )
{
++nextEligible;
++eligible;
}
if ( nextEligible != mEligiblePartials.end() &&
better_match( **nextEligible, **eligible, *bpIter ) )
{
eligible = nextEligible;
}
}
// INVARIANT:
//
// eligible is the position of the nearest (in frequency)
// eligible Partial (pointer) or it is mEligiblePartials.end().
//
// nextEligible is the eligible Partial with frequency
// greater than bp, or it is mEligiblePartials.end().
#if defined(Debug_Loris) && Debug_Loris
/*
if ( nextEligible != mEligiblePartials.end() )
{
debugger << matchFrequency << "( " << end_frequency( **eligible )
<< ", " << end_frequency( **nextEligible ) << ")" << endl;
}
*/
#endif
// create a new Partial if there is no eligible Partial,
// or the frequency difference to the eligible Partial is
// too great, or the next peak is a better match for the
// eligible Partial, otherwise add this peak to the eligible
// Partial:
Peaks::iterator nextPeak = //Peaks::iterator( bpIter ); ++nextPeak;
++Peaks::iterator( bpIter ); // some compilers choke on this?
// decide whether this match should be made:
// - can only make the match if eligible is not the end of the list
// - the match is only good if it is close enough in frequency
// - even if the match is good, only match if the next one is not better
bool makeMatch = false;
if ( eligible != mEligiblePartials.end() )
{
bool matchIsGood = mFreqDrift >
std::fabs( end_frequency( **eligible ) - bpIter->frequency() );
if ( matchIsGood )
{
bool nextIsBetter = ( nextPeak != peaks.end() &&
better_match( **eligible, *nextPeak, *bpIter ) );
if ( ! nextIsBetter )
{
makeMatch = true;
}
}
}
Breakpoint bp = bpIter->createBreakpoint();
if ( makeMatch )
{
// invariant:
// if makeMatch is true, then eligible is the position of a valid Partial
(*eligible)->insert( peakTime, bp );
mNewlyEligible.push_back( *eligible );
++matchCount;
}
else
{
Partial p;
p.insert( peakTime, bp );
mCollectedPartials.push_back( p );
mNewlyEligible.push_back( & mCollectedPartials.back() );
}
// update eligible, nextEligible is the eligible Partial
// with frequency greater than bp, or it is mEligiblePartials.end():
eligible = nextEligible;
}
mEligiblePartials = mNewlyEligible;
/*
debugger << "PartialBuilder::buildPartials: matched " << matchCount << endl;
debugger << "PartialBuilder::buildPartials: " << mNewlyEligible.size() << " newly eligible partials" << endl;
*/
}
示例6: d
// ----------- test_distill_overlapping3 -----------
//
static void test_distill_overlapping3( void )
{
std::cout << "\t--- testing distill on three "
"temporally-overlapping Partials... ---\n\n";
// Fabricate three Partials, overlapping temporally, give
// them the same label, and distill them.
Partial p1;
p1.insert( 0, Breakpoint( 100, 0.4, 0, 0 ) );
p1.insert( 0.28, Breakpoint( 100, 0.4, 0, .1 ) );
p1.setLabel( 123 );
Partial p2;
p2.insert( 0.2, Breakpoint( 200, 0.3, 0.2, 0 ) );
p2.insert( 0.29, Breakpoint( 200, 0.3, 0.2, .1 ) );
p2.insert( 0.35, Breakpoint( 200, 0.3, 0.2, .1 ) );
p2.setLabel( 123 );
Partial p3;
p3.insert( 0.32, Breakpoint( 300, 0.3, 0, 0 ) );
p3.insert( 0.4, Breakpoint( 310, 0.3, 0.2, .1 ) );
p3.insert( 0.7, Breakpoint( 310, 0.3, 0.2, .1 ) );
p3.setLabel( 123 );
PartialList l;
l.push_back( p3 );
l.push_back( p1 );
l.push_back( p2 );
const double fade = .008; // 8 ms
Distiller d( fade );
d.distill( l );
// Fabricate the Partial that the distillation should
// produce.
Partial compare;
// first Breakpoint from p1
compare.insert( 0, Breakpoint( 100, 0.4, 0, 0 ) );
// null Breakpoint at 0+fade
double t = 0 + fade;
compare.insert( t, Breakpoint( p1.frequencyAt(t), 0,
p1.bandwidthAt(t), p1.phaseAt(t) ) );
// interpolated Breakpoint at .18 (.2 - 2*fade)
//double t = 0.2 - (2*fade);
//compare.insert( t, p1.parametersAt( t ) );
// null Breakpoint at .19 (.2-fade)
// bandwidth introduced in the overlap region:
// (0.4^2 + 0.2*0.3^2) / (0.3^2 + 0.4^2)) = 0.712
// amp = sqrt(0.3^2 + 0.4^2) = .5
// no, actually zero-amplitude Breakpoints are
// introduced with zero bandwidth.
t = 0.2 - fade;
compare.insert( t, Breakpoint( p2.frequencyAt(t), 0,
0, // 0.712,
p2.phaseAt(t) ) );
// first Breakpoint from p2:
compare.insert( 0.2, Breakpoint( 200, 0.5, 0.712, 0 ) );
// second Breakpoint from p2:
compare.insert( 0.29, Breakpoint( 200, 0.3, 0.2, 0.1 ) );
// null Breakpoint at .29 + fade
t = 0.29 + fade;
compare.insert( t, Breakpoint( p2.frequencyAt(t), 0,
0, // p2.bandwidthAt(t),
p2.phaseAt(t) ) );
// null Breakpoint at .31 (.32-fade)
t = 0.32 - fade;
compare.insert( t, Breakpoint( p3.frequencyAt(t), 0,
0, p3.phaseAt(t) ) );
// first Breakpoint from p3 (with bandwidth):
compare.insert( 0.32, Breakpoint( 300, std::sqrt(0.18), 0.5, 0 ) );
// second Breakpoint from p3:
compare.insert( 0.4, Breakpoint( 310, 0.3, 0.2, .1 ) );
// third Breakpoint from p3:
compare.insert( 0.7, Breakpoint( 310, 0.3, 0.2, .1 ) );
compare.setLabel( 123 );
// compare Partials (distilled Partials
// should be in label order):
TEST_VALUE( l.size(), 1 );
TEST_VALUE( l.begin()->numBreakpoints(), compare.numBreakpoints() );
Partial::iterator distit = l.begin()->begin();
Partial::iterator compareit = compare.begin();
while ( compareit != compare.end() )
{
SAME_PARAM_VALUES( distit.time(), compareit.time() );
SAME_PARAM_VALUES( distit->frequency(), compareit->frequency() );
SAME_PARAM_VALUES( distit->amplitude(), compareit->amplitude() );
//.........这里部分代码省略.........
示例7: test_distill_nonoverlapping
// ----------- test_distill_nonoverlapping -----------
//
static void test_distill_nonoverlapping( void )
{
std::cout << "\t--- testing distill on "
"non-overlapping Partials... ---\n\n";
// Fabricate three non-overlapping Partials, give
// them all the same label, and distill them. Also
// add a fourth Partial with a different label, verify
// that it remains unaffacted.
Partial p1;
p1.insert( 0, Breakpoint( 100, 0.1, 0, 0 ) );
p1.insert( .1, Breakpoint( 110, 0.2, 0.2, .1 ) );
p1.setLabel( 123 );
Partial p2;
p2.insert( 0.2, Breakpoint( 200, 0.1, 0, 0 ) );
p2.insert( 0.3, Breakpoint( 210, 0.2, 0.2, .1 ) );
p2.setLabel( 123 );
Partial p3;
p3.insert( 0.4, Breakpoint( 300, 0.1, 0, 0 ) );
p3.insert( 0.5, Breakpoint( 310, 0.2, 0.2, .1 ) );
p3.setLabel( 123 );
Partial p4;
p4.insert( 0, Breakpoint( 400, 0.1, 0, 0 ) );
p4.insert( 0.5, Breakpoint( 410, 0.2, 0.2, .1 ) );
p4.setLabel( 4 );
PartialList l;
l.push_back( p1 );
l.push_back( p3 );
l.push_back( p4 );
l.push_back( p2 );
const double fade = .01; // 10 ms
Distiller d( fade );
d.distill( l );
// Fabricate the Partial that the distillation should
// produce.
Partial compare;
compare.insert( 0, Breakpoint( 100, 0.1, 0, 0 ) );
compare.insert( 0.1, Breakpoint( 110, 0.2, 0.2, .1 ) );
double t = 0.1 + fade;
compare.insert( t, Breakpoint( p1.frequencyAt(t), 0,
0, // p1.bandwidthAt(t),
p1.phaseAt(t) ) );
t = 0.2 - fade;
compare.insert( t, Breakpoint( p2.frequencyAt(t), 0,
0, // p2.bandwidthAt(t),
p2.phaseAt(t) ) );
compare.insert( 0.2, Breakpoint( 200, 0.1, 0, 0 ) );
compare.insert( 0.3, Breakpoint( 210, 0.2, 0.2, .1 ) );
t = 0.3 + fade;
compare.insert( t, Breakpoint( p2.frequencyAt(t), 0,
0, // p2.bandwidthAt(t),
p2.phaseAt(t) ) );
t = 0.4 - fade;
compare.insert( t, Breakpoint( p3.frequencyAt(t), 0,
0, // p3.bandwidthAt(t),
p3.phaseAt(t) ) );
compare.insert( 0.4, Breakpoint( 300, 0.1, 0, 0 ) );
compare.insert( 0.5, Breakpoint( 310, 0.2, 0.2, .1 ) );
compare.setLabel( 123 );
// compare Partials (distilled Partials
// should be in label order):
TEST( l.size() == 2 );
PartialList::iterator it = l.begin();
TEST( it->label() == p4.label() );
TEST( it->numBreakpoints() == p4.numBreakpoints() );
++it;
for ( Partial::iterator distit = it->begin(); distit != it->end(); ++distit )
{
cout << distit.time() << " " << distit.breakpoint().frequency() << endl;
}
TEST( it->numBreakpoints() == compare.numBreakpoints() );
Partial::iterator distit = it->begin();
Partial::iterator compareit = compare.begin();
while ( compareit != compare.end() )
{
SAME_PARAM_VALUES( distit.time(), compareit.time() );
SAME_PARAM_VALUES( distit->frequency(), compareit->frequency() );
SAME_PARAM_VALUES( distit->amplitude(), compareit->amplitude() );
SAME_PARAM_VALUES( distit->bandwidth(), compareit->bandwidth() );
SAME_PARAM_VALUES( distit->phase(), compareit->phase() );
++compareit;
++distit;
}
}
示例8: merge
// ---------------------------------------------------------------------------
// 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() );
}
}
示例9: if
// ---------------------------------------------------------------------------
// dilate
// ---------------------------------------------------------------------------
//! Replace the Partial envelope with a new envelope having the
//! same Breakpoints at times computed to align temporal features
//! in the sorted sequence of initial time points with their
//! counterparts the sorted sequence of target time points.
//!
//! Depending on the specification of initial and target time
//! points, the dilated Partial may have Breakpoints at times
//! less than 0, even if the original Partial did not.
//!
//! It is possible to have duplicate time points in either sequence.
//! Duplicate initial time points result in very localized stretching.
//! Duplicate target time points result in very localized compression.
//!
//! If all initial time points are greater than 0, then an implicit
//! time point at 0 is assumed in both initial and target sequences,
//! so the onset of a sound can be stretched without explcitly specifying a
//! zero point in each vector. (This seems most intuitive, and only looks
//! like an inconsistency if clients are using negative time points in
//! their Dilator, or Partials having Breakpoints before time 0, both
//! of which are probably unusual circumstances.)
//!
//! \param p is the Partial to dilate.
//
void
Dilator::dilate( Partial & p ) const
{
debugger << "dilating Partial having " << p.numBreakpoints()
<< " Breakpoints" << endl;
// sanity check:
Assert( _initial.size() == _target.size() );
// don't dilate if there's no time points, or no Breakpoints:
if ( 0 == _initial.size() ||
0 == p.numBreakpoints() )
{
return;
}
// create the new Partial:
Partial newp;
newp.setLabel( p.label() );
// timepoint index:
int idx = 0;
for ( Partial::const_iterator iter = p.begin(); iter != p.end(); ++iter )
{
// find the first initial time point later
// than the currentTime:
double currentTime = iter.time();
idx = std::distance( _initial.begin(),
std::lower_bound( _initial.begin(), _initial.end(), currentTime ) );
Assert( idx == _initial.size() || currentTime <= _initial[idx] );
// compute a new time for the Breakpoint at pIter:
double newtime = 0;
if ( idx == 0 )
{
// all time points in _initial are later than
// the currentTime; stretch if no zero time
// point has been specified, otherwise, shift:
if ( _initial[idx] != 0. )
newtime = currentTime * _target[idx] / _initial[idx];
else
newtime = _target[idx] + (currentTime - _initial[idx]);
}
else if ( idx == _initial.size() )
{
// all time points in _initial are earlier than
// the currentTime; shift:
//
// note: size is already known to be > 0, so
// idx-1 is safe
newtime = _target[idx-1] + (currentTime - _initial[idx-1]);
}
else
{
// currentTime is between the time points at idx and
// idx-1 in _initial; shift and stretch:
//
// note: size is already known to be > 0, so
// idx-1 is safe
Assert( _initial[idx-1] < _initial[idx] ); // currentTime can't wind up
// between two equal times
double stretch = (_target[idx] - _target[idx-1]) / (_initial[idx] - _initial[idx-1]);
newtime = _target[idx-1] + ((currentTime - _initial[idx-1]) * stretch);
}
// add a Breakpoint at the computed time:
newp.insert( newtime, iter.breakpoint() );
}
// new Breakpoints need to be added to the Partial at times corresponding
// to all target time points that are after the first Breakpoint and
// before the last, otherwise, Partials may be briefly out of tune with
// each other, since our Breakpoints are non-uniformly distributed in time:
//.........这里部分代码省略.........