本文整理汇总了C++中Partial::begin方法的典型用法代码示例。如果您正苦于以下问题:C++ Partial::begin方法的具体用法?C++ Partial::begin怎么用?C++ Partial::begin使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Partial
的用法示例。
在下文中一共展示了Partial::begin方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: giveMeN
// ---------------------------------------------------------------------------
// channelize (one Partial)
// ---------------------------------------------------------------------------
//! Label a Partial with the number of the frequency channel corresponding to
//! the average frequency over all the Partial's Breakpoints.
//!
//! \param partial is the Partial to label.
//
void
Channelizer::channelize( Partial & partial ) const
{
debugger << "channelizing Partial with " << partial.numBreakpoints() << " Breakpoints" << endl;
// compute an amplitude-weighted average channel
// label for each Partial:
double ampsum = 0.;
double weightedlabel = 0.;
Partial::const_iterator bp;
for ( bp = partial.begin(); bp != partial.end(); ++bp )
{
// use sinusoidal amplitude:
double a = bp.breakpoint().amplitude() * std::sqrt( 1. - bp.breakpoint().bandwidth() );
// This used to be an amplitude-weighted avg, but for many sounds,
// particularly those for which the weighted avg would be very
// different from the simple avg, the amplitude-weighted avg
// emphasized the part of the sound in which the frequency estimates
// are least reliable (e.g. a piano tone). The unweighted
// average should give more intuitive results in most cases.
double f = bp.breakpoint().frequency();
double t = bp.time();
double refFreq = _refChannelFreq->valueAt( t ) / _refChannelLabel;
// weightedlabel += a * (f / refFreq);
weightedlabel += a * giveMeN( f, refFreq, _stretchFactor );
ampsum += a;
}
int label;
if ( ampsum > 0. )
// if ( 0 < partial.numBreakpoints() )
{
label = (int)((weightedlabel / ampsum) + 0.5);
}
else // this should never happen, but just in case:
{
label = 0;
}
Assert( label >= 0 );
// assign label, and remember it, but
// only if it is a valid (positive)
// distillation label:
partial.setLabel( label );
}
示例2: pow
// ---------------------------------------------------------------------------
// channelize (one Partial)
// ---------------------------------------------------------------------------
//! Label a Partial with the number of the frequency channel corresponding to
//! the average frequency over all the Partial's Breakpoints.
//!
//! \param partial is the Partial to label.
//
void
Channelizer::channelize( Partial & partial ) const
{
using std::pow;
debugger << "channelizing Partial with " << partial.numBreakpoints() << " Breakpoints" << endl;
// compute an amplitude-weighted average channel
// label for each Partial:
//double ampsum = 0.;
double weightedlabel = 0.;
Partial::const_iterator bp;
for ( bp = partial.begin(); bp != partial.end(); ++bp )
{
double f = bp.breakpoint().frequency();
double t = bp.time();
double weight = 1;
if ( 0 != _ampWeighting )
{
// This used to be an amplitude-weighted avg, but for many sounds,
// particularly those for which the weighted avg would be very
// different from the simple avg, the amplitude-weighted avg
// emphasized the part of the sound in which the frequency estimates
// are least reliable (e.g. a piano tone). The unweighted
// average should give more intuitive results in most cases.
// use sinusoidal amplitude:
double a = bp.breakpoint().amplitude() * std::sqrt( 1. - bp.breakpoint().bandwidth() );
weight = pow( a, _ampWeighting );
}
weightedlabel += weight * computeFractionalChannelNumber( t, f );
}
int label = 0;
if ( 0 < partial.numBreakpoints() ) // should always be the case
{
label = (int)((weightedlabel / partial.numBreakpoints()) + 0.5);
}
Assert( label >= 0 );
// assign label, and remember it, but
// only if it is a valid (positive)
// distillation label:
partial.setLabel( label );
}
示例3:
// ---------------------------------------------------------------------------
// TimeShifter function call operator
// ---------------------------------------------------------------------------
// Shift the time of all the Breakpoints in a Partial by a constant amount.
//
void
TimeShifter::operator()( Partial & p ) const
{
// Since the Breakpoint times are immutable, the only way to
// shift the Partial in time is to construct a new Partial and
// assign it to the argument p.
Partial result;
result.setLabel( p.label() );
for ( Partial::iterator pos = p.begin(); pos != p.end(); ++pos )
{
result.insert( pos.time() + offset, pos.breakpoint() );
}
p = result;
}
示例4: avgFrequency
// ---------------------------------------------------------------------------
// avgFrequency
// ---------------------------------------------------------------------------
//! Return the average frequency over all Breakpoints in this Partial.
//! Return zero if the Partial has no Breakpoints.
//!
//! \param p is the Partial to evaluate
//! \return the average frequency (Hz) of Breakpoints in the Partial p
//
double avgFrequency( const Partial & p )
{
double avg = 0;
for ( Partial::const_iterator it = p.begin();
it != p.end();
++it )
{
avg += it->frequency();
}
if ( avg != 0 )
{
avg /= p.numBreakpoints();
}
return avg;
}
示例5: timeOfPeakEnergy
// ---------------------------------------------------------------------------
// timeOfPeakEnergy (static helper function)
// ---------------------------------------------------------------------------
// Return the time at which the given Partial attains its
// maximum sinusoidal energy.
//
static double timeOfPeakEnergy( const Partial & p )
{
Partial::const_iterator partialIter = p.begin();
double maxAmp =
partialIter->amplitude() * std::sqrt( 1. - partialIter->bandwidth() );
double time = partialIter.time();
for ( ++partialIter; partialIter != p.end(); ++partialIter )
{
double a = partialIter->amplitude() *
std::sqrt( 1. - partialIter->bandwidth() );
if ( a > maxAmp )
{
maxAmp = a;
time = partialIter.time();
}
}
return time;
}
示例6:
Iter
find_overlapping( Partial & p, double minGapTime, Iter start, Iter end)
{
for ( Iter it = start; it != end; ++it )
{
// skip if other partial is already sifted out.
if ( (*it)->label() == 0 )
continue;
// skip the source Partial:
// (identity test: compare addresses)
// (this is a sanity check, should not happen since
// src should be at position end)
Assert( (*it) != &p );
// test for overlap:
if ( p.startTime() < (*it)->endTime() + minGapTime &&
p.endTime() + minGapTime > (*it)->startTime() )
{
// Does the overlapping Partial have longer duration?
// (this should never be true, since the Partials
// are sorted by duration)
Assert( p.duration() <= (*it)->duration() );
#if Debug_Loris
debugger << "Partial starting " << p.startTime() << ", "
<< p.begin().breakpoint().frequency() << " ending "
<< p.endTime() << ", " << (--p.end()).breakpoint().frequency()
<< " zapped by overlapping Partial starting "
<< (*it)->startTime() << ", " << (*it)->begin().breakpoint().frequency()
<< " ending " << (*it)->endTime() << ", "
<< (--(*it)->end()).breakpoint().frequency() << endl;
#endif
return it;
}
}
// no overlapping Partial found:
return end;
}
示例7: weightedAvgFrequency
// ---------------------------------------------------------------------------
// weightedAvgFrequency
// ---------------------------------------------------------------------------
//! Return the average frequency over all Breakpoints in this Partial,
//! weighted by the Breakpoint amplitudes.
//! Return zero if the Partial has no Breakpoints.
//!
//! \param p is the Partial to evaluate
//! \return the average frequency (Hz) of Breakpoints in the Partial p
//
double weightedAvgFrequency( const Partial & p )
{
double avg = 0;
double ampsum = 0;
for ( Partial::const_iterator it = p.begin();
it != p.end();
++it )
{
avg += it->amplitude() * it->frequency();
ampsum += it->amplitude();
}
if ( avg != 0 && ampsum != 0 )
{
avg /= ampsum;
}
else
{
avg = 0;
}
return avg;
}
示例8: 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() );
//.........这里部分代码省略.........
示例9: 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;
}
}
示例10: distillOne
// ---------------------------------------------------------------------------
// 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 );
}
示例11: 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() );
}
}
示例12: quantizer
// ---------------------------------------------------------------------------
// synthesize
// ---------------------------------------------------------------------------
//! Synthesize a bandwidth-enhanced sinusoidal Partial. Zero-amplitude
//! Breakpoints are inserted at either end of the Partial to reduce
//! turn-on and turn-off artifacts, as described above. The synthesizer
//! will resize the buffer as necessary to accommodate all the samples,
//! including the fade out. Previous contents of the buffer are not
//! overwritten. Partials with start times earlier than the Partial fade
//! time will have shorter onset fades. Partials are not rendered at
//! frequencies above the half-sample rate.
//!
//! \param p The Partial to synthesize.
//! \return Nothing.
//! \pre The partial must have non-negative start time.
//! \post This Synthesizer's sample buffer (vector) has been
//! resized to accommodate the entire duration of the
//! Partial, p, including fade out at the end.
//! \throw InvalidPartial if the Partial has negative start time.
//
void
Synthesizer::synthesize( Partial p )
{
if ( p.numBreakpoints() == 0 )
{
debugger << "Synthesizer ignoring a partial that contains no Breakpoints" << endl;
return;
}
if ( p.startTime() < 0 )
{
Throw( InvalidPartial, "Tried to synthesize a Partial having start time less than 0." );
}
debugger << "synthesizing Partial from " << p.startTime() * m_srateHz
<< " to " << p.endTime() * m_srateHz << " starting phase "
<< p.initialPhase() << " starting frequency "
<< p.first().frequency() << endl;
// better to compute this only once:
const double OneOverSrate = 1. / m_srateHz;
// use a Resampler to quantize the Breakpoint times and
// correct the phases:
Resampler quantizer( OneOverSrate );
quantizer.setPhaseCorrect( true );
quantizer.quantize( p );
// resize the sample buffer if necessary:
typedef unsigned long index_type;
index_type endSamp = index_type( ( p.endTime() + m_fadeTimeSec ) * m_srateHz );
if ( endSamp+1 > m_sampleBuffer->size() )
{
// pad by one sample:
m_sampleBuffer->resize( endSamp+1 );
}
// compute the starting time for synthesis of this Partial,
// m_fadeTimeSec before the Partial's startTime, but not before 0:
double itime = ( m_fadeTimeSec < p.startTime() ) ? ( p.startTime() - m_fadeTimeSec ) : 0.;
index_type currentSamp = index_type( (itime * m_srateHz) + 0.5 ); // cheap rounding
// reset the oscillator:
// all that really needs to happen here is setting the frequency
// correctly, the phase will be reset again in the loop over
// Breakpoints below, and the amp and bw can start at 0.
m_osc.resetEnvelopes( BreakpointUtils::makeNullBefore( p.first(), p.startTime() - itime ), m_srateHz );
// cache the previous frequency (in Hz) so that it
// can be used to reset the phase when necessary
// in the sample computation loop below (this saves
// having to recompute from the oscillator's radian
// frequency):
double prevFrequency = p.first().frequency();
// synthesize linear-frequency segments until
// there aren't any more Breakpoints to make segments:
double * bufferBegin = &( m_sampleBuffer->front() );
for ( Partial::const_iterator it = p.begin(); it != p.end(); ++it )
{
index_type tgtSamp = index_type( (it.time() * m_srateHz) + 0.5 ); // cheap rounding
Assert( tgtSamp >= currentSamp );
// if the current oscillator amplitude is
// zero, and the target Breakpoint amplitude
// is not, reset the oscillator phase so that
// it matches exactly the target Breakpoint
// phase at tgtSamp:
if ( m_osc.amplitude() == 0. )
{
// recompute the phase so that it is correct
// at the target Breakpoint (need to do this
// because the null Breakpoint phase was computed
// from an interval in seconds, not samples, so
// it might be inaccurate):
//
// double favg = 0.5 * ( prevFrequency + it.breakpoint().frequency() );
// double dphase = 2 * Pi * favg * ( tgtSamp - currentSamp ) / m_srateHz;
//.........这里部分代码省略.........
示例13: 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:
//.........这里部分代码省略.........