Fixed resampling glitches when deleting notes

Moving the code to detect the sample rates of the currently used samples
after the code deleting notes seemed to fix these glitches. Also, fixed a
few ADSR issues that could have resulted in clipping in the attack or
glitching after the release.
This commit is contained in:
Garrett
2014-11-11 09:39:24 -08:00
parent a251391249
commit 8693623758

View File

@@ -391,10 +391,10 @@ void GigInstrument::play( sampleFrame * _working_buffer )
addSamples( *it, false );
}
// Delete ended samples
for( QList<GigSample>::iterator sample = it->samples.begin();
sample != it->samples.end(); ++sample )
{
// Delete ended samples
if( sample->sample == NULL || sample->adsr.done() ||
sample->pos >= sample->sample->SamplesTotal - 1 )
{
@@ -405,21 +405,6 @@ void GigInstrument::play( sampleFrame * _working_buffer )
break;
}
}
// Verify all the samples have the same rate
else
{
int currentRate = sample->sample->SamplesPerSecond;
if( oldRate == -1 )
{
oldRate = currentRate;
}
else if( oldRate != currentRate )
{
qCritical() << "GigInstrument: not all samples are the same rate, not converting";
sampleError = true;
}
}
}
// Delete ended notes (either in the completed state or all the samples ended)
@@ -432,6 +417,23 @@ void GigInstrument::play( sampleFrame * _working_buffer )
break;
}
}
// Verify all the samples have the same rate
for( QList<GigSample>::iterator sample = it->samples.begin();
sample != it->samples.end(); ++sample )
{
int currentRate = sample->sample->SamplesPerSecond;
if( oldRate == -1 )
{
oldRate = currentRate;
}
else if( oldRate != currentRate )
{
qCritical() << "GigInstrument: not all samples are the same rate, not converting";
sampleError = true;
}
}
}
// If all samples have the same sample rate and it's not the output sample
@@ -863,7 +865,7 @@ bool GigInstrument::convertSampleRate( sampleFrame & oldBuf, sampleFrame & newBu
return false;
}
if( src_data.output_frames_gen == 0 )
if( oldSize != 0 && src_data.output_frames_gen == 0 )
{
qCritical( "GigInstrument: could not resample, no frames generated" );
return false;
@@ -1183,7 +1185,7 @@ double ADSR::value()
{
if( attackPosition < attackLength )
{
amplitude = preattack + ( attack - preattack ) / attackLength * attackPosition;
amplitude = preattack + ( 1.0 - preattack ) / attackLength * attackPosition;
}
else if( attackPosition < attackLength + decayLength )
{
@@ -1199,20 +1201,14 @@ double ADSR::value()
// If we're in the sustain phase, decrease from sustain to zero
else if( isRelease == true )
{
if( releasePosition < releaseLength )
{
// Maybe not the best way of doing this, but it appears to be about right
amplitude = sustain * exp( -5.0 / releaseLength * releasePosition ) - 1e-5;
// Maybe not the best way of doing this, but it appears to be about right
// Satisfies f(0) = sustain and f(releaseLength) = very small
amplitude = ( sustain + 1e-3 ) * exp( -5.0 / releaseLength * releasePosition ) - 1e-3;
// Don't have an infinite exponential decay
if( amplitude < 0 )
{
amplitude = 0;
isDone = true;
}
}
else
// Don't have an infinite exponential decay
if( amplitude < 0 )
{
amplitude = 0;
isDone = true;
}