1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-02 17:23:18 +02:00

Remove EXPERIMENTAL_TRUNC_SILENCE #ifdefs since it is no longer experimental.

This commit is contained in:
martynshaw99 2013-05-01 22:07:08 +00:00
parent 1af35d4168
commit 1ddee72498
3 changed files with 0 additions and 343 deletions

View File

@ -150,7 +150,4 @@
//#define AUTOMATED_INPUT_LEVEL_ADJUSTMENT
#endif
// AWD: new Truncate Silence code
#define EXPERIMENTAL_TRUNC_SILENCE
#endif

View File

@ -119,342 +119,6 @@ bool EffectTruncSilence::TransferParameters( Shuttle & shuttle )
return true;
}
#ifndef EXPERIMENTAL_TRUNC_SILENCE
#define QUARTER_SECOND_MS 250
bool EffectTruncSilence::Process()
{
SelectedTrackListOfKindIterator iter(Track::Wave, mTracks);
WaveTrack *t;
double t0 = mT0;
double t1 = mT1;
int tndx;
int tcount = 0;
int fr;
// Init using first track
t = (WaveTrack *) iter.First();
double rate = t->GetRate();
sampleCount blockLen = t->GetMaxBlockSize();
// Get the left and right bounds for all tracks
while (t) {
// Make sure all tracks have the same sample rate
if (rate != t->GetRate()) {
wxMessageBox(_("All tracks must have the same sample rate"), _("Truncate Silence"));
return false;
}
// Count the tracks
tcount++;
// Set the current bounds to whichever left marker is
// greater and whichever right marker is less
t0 = wxMax(mT0, t->GetStartTime());
t1 = wxMin(mT1, t->GetEndTime());
// Use the smallest block size of all the tracks
blockLen = wxMin(blockLen, t->GetMaxBlockSize());
// Iterate to the next track
t = (WaveTrack*) iter.Next();
}
// Just a sanity check, really it should be much higher
if(blockLen < 4*mBlendFrameCount)
blockLen = 4*mBlendFrameCount;
// Transform the marker timepoints to samples
t = (WaveTrack *) iter.First();
sampleCount start = t->TimeToLongSamples(t0);
sampleCount end = t->TimeToLongSamples(t1);
// Bigger buffers reduce 'reset'
//blockLen *= 8;
// Stress-test the logic for cutting samples through block endpoints
//blockLen /= 8;
// Set thresholds
// We have a lower bound on the amount of silence we chop out at a time
// to avoid chopping up low frequency sounds. We're good down to 10Hz
// if we use 100ms.
const float minTruncMs = 1.0f;
double truncDbSilenceThreshold = Enums::Db2Signal[mTruncDbChoiceIndex];
int truncInitialAllowedSilentSamples =
int((wxMax( mTruncInitialAllowedSilentMs, minTruncMs) * rate) / 1000.0);
int truncLongestAllowedSilentSamples =
int((wxMax( mTruncLongestAllowedSilentMs, minTruncMs) * rate) / 1000.0);
// Require at least 4 samples for lengths
if(truncInitialAllowedSilentSamples < 4)
truncInitialAllowedSilentSamples = 4;
if(truncLongestAllowedSilentSamples < 4)
truncLongestAllowedSilentSamples = 4;
// If the cross-fade is longer than the minimum length,
// then limit the cross-fade length to the minimum length
// This allows us to have reasonable cross-fade by default
// and still allow for 1ms minimum lengths
if(truncInitialAllowedSilentSamples < mBlendFrameCount)
mBlendFrameCount = truncInitialAllowedSilentSamples;
if(truncLongestAllowedSilentSamples < mBlendFrameCount)
mBlendFrameCount = truncLongestAllowedSilentSamples;
// For sake of efficiency, don't let blockLen be less than double the longest silent samples
// up until a sane limit of 1Meg samples
while((blockLen > 0) && (blockLen < truncLongestAllowedSilentSamples*2) && (blockLen < 1048576)) {
blockLen *= 2;
}
// Don't allow either value to be more than half of the block length
if(truncLongestAllowedSilentSamples > blockLen/2)
truncLongestAllowedSilentSamples = blockLen/2;
if(truncInitialAllowedSilentSamples > truncLongestAllowedSilentSamples)
truncInitialAllowedSilentSamples = truncLongestAllowedSilentSamples;
// We use the 'longest' variable as additive to the 'initial' variable
truncLongestAllowedSilentSamples -= truncInitialAllowedSilentSamples;
// Perform the crossfade half-way through the minimum removed silence duration
int rampInFrames = (truncInitialAllowedSilentSamples + mBlendFrameCount) / 2;
if(rampInFrames > truncInitialAllowedSilentSamples)
rampInFrames = truncInitialAllowedSilentSamples;
// Allocate buffers
float **buffer = new float*[tcount];
for (tndx = 0; tndx < tcount; tndx++) {
buffer[tndx] = new float[blockLen];
}
// Start processing
//Track::All is needed because this effect has clear functionality
this->CopyInputTracks(Track::All); // Set up mOutputTracks.
SelectedTrackListOfKindIterator iterOut(Track::Wave, mOutputTracks);
sampleCount index = start;
sampleCount outTrackOffset = start;
bool cancelled = false;
// Reset
bool ignoringFrames = false;
bool truncToMinimum = true; // Ignore the initial samples until we get above the noise floor
sampleCount consecutiveSilentFrames = 0;
sampleCount truncIndex = 0;
sampleCount i = 0;
sampleCount keep;
while (index < end) {
// Limit size of current block if we've reached the end
sampleCount count = blockLen-i;
if ((index + count) > end) {
count = end - index;
}
// Fill the buffers
tndx = 0;
t = (WaveTrack *) iter.First();
while (t) {
t->Get((samplePtr)(buffer[tndx++]+i), floatSample, index, count);
t = (WaveTrack *) iter.Next();
}
// Shift over to account for samples remaining from prior block
sampleCount limit = count+i;
// Look for silences in current block
for ( ; i < limit; i++) {
// Is current frame in all tracks below threshold
bool below = true;
for (tndx = 0; tndx < tcount; tndx++) {
if (fabs(buffer[tndx][i]) >= truncDbSilenceThreshold) {
below = false;
break;
}
}
// Make sure we cross-fade and output the last silence
// so we get a smooth transition into whatever follows the selected region
// Also set the 'truncToMinimum' flag so that the last silence is truncated to the minimum amount
if(below && ((index+i+1) == end)) {
below = false;
truncToMinimum = true;
}
// Count frame if it's below threshold
if (below) {
consecutiveSilentFrames++;
// Ignore this frame (equivalent to cutting it)
// otherwise, keep sample to be part of allowed silence
if (consecutiveSilentFrames > truncInitialAllowedSilentSamples) {
ignoringFrames = true;
continue;
}
}
else {
if (ignoringFrames == true) {
// Scale the consectiveSilentFrames so we keep a silence duration
// which is proportional to the original silence up to the limit
keep = consecutiveSilentFrames - truncInitialAllowedSilentSamples;
keep /= mSilenceCompressRatio;
// The first and last samples always get truncated to the minimum amount
if(truncToMinimum == true)
keep = 0;
if(keep > truncLongestAllowedSilentSamples)
keep = truncLongestAllowedSilentSamples;
if(keep < 0)
keep = 0;
// Compute the location of the cross-fade to be halfway through the silence
// with restriction to the samples we still have available to use
rampInFrames = (truncInitialAllowedSilentSamples - keep + mBlendFrameCount) / 2;
if(rampInFrames > truncInitialAllowedSilentSamples)
rampInFrames = truncInitialAllowedSilentSamples;
if(rampInFrames < mBlendFrameCount)
rampInFrames = mBlendFrameCount;
// Include the cross-fade samples in the count to make the loop logic easier
keep += rampInFrames;
truncIndex -= rampInFrames;
if(truncIndex < 0) {
// This happens when we have silence overlapping a block boundary
keep += truncIndex;
if(keep < 0)
keep = 0;
truncIndex = 0;
}
// back up for cross-fade
sampleCount curOffset = i - keep;
if(curOffset < 0) {
// This should never happen, but just in case...
keep += curOffset - rampInFrames;
if(keep < mBlendFrameCount)
keep = mBlendFrameCount;
curOffset = 0;
}
for (tndx = 0; tndx < tcount; tndx++) {
// Cross fade the cut point
for (fr = 0; fr < mBlendFrameCount; fr++) {
buffer[tndx][truncIndex+fr] = ((mBlendFrameCount-fr)*buffer[tndx][truncIndex+fr] + fr*buffer[tndx][curOffset + fr]) / mBlendFrameCount;
}
// Append the 'keep' samples, if any
for ( ; fr < keep; fr++) {
buffer[tndx][truncIndex+fr] = buffer[tndx][curOffset + fr];
}
}
truncIndex += keep;
}
consecutiveSilentFrames = 0;
ignoringFrames = false;
truncToMinimum = false;
}
// Can get here either because > dbThreshold
// or silence duration isn't longer than allowed
for (tndx = 0; tndx < tcount; tndx++) {
buffer[tndx][truncIndex] = buffer[tndx][i];
}
truncIndex++;
}
// Update tracks if any samples were removed, now or before
if (outTrackOffset + truncIndex != index + limit) {
// Put updated sample back into output tracks.
tndx = 0;
t = (WaveTrack *) iterOut.First();
while (t) {
t->Set((samplePtr)buffer[tndx++], floatSample, outTrackOffset, truncIndex);
t = (WaveTrack *) iterOut.Next();
}
}
// If currently in a silent section, retain samples for the next pass
if(consecutiveSilentFrames > mBlendFrameCount) {
if (ignoringFrames == true) {
// Retain only what we need for truncating the silence
keep = consecutiveSilentFrames-truncInitialAllowedSilentSamples;
if(keep > (truncLongestAllowedSilentSamples+mBlendFrameCount))
keep = truncLongestAllowedSilentSamples+mBlendFrameCount;
for (tndx = 0; tndx < tcount; tndx++) {
// Cross fade the cut point
for(fr = 0; fr < mBlendFrameCount; fr++) {
buffer[tndx][fr] = ((mBlendFrameCount-fr)*buffer[tndx][truncIndex-mBlendFrameCount+fr]
+ fr*buffer[tndx][i-keep+fr]) / mBlendFrameCount;
}
for( ; fr < keep; fr++) {
buffer[tndx][fr] = buffer[tndx][i-keep+fr];
}
}
// Update the output index, less what we are retaining for next time
outTrackOffset += truncIndex - mBlendFrameCount;
// Append the following buffer to the existing data
i = keep;
truncIndex = mBlendFrameCount;
} else {
// Retain the silent samples for the next buffer
keep = consecutiveSilentFrames;
for (tndx = 0; tndx < tcount; tndx++) {
for(fr=0 ; fr < keep; fr++) {
buffer[tndx][fr] = buffer[tndx][i-keep+fr];
}
}
// Update the output index, less what we are retaining for next time
outTrackOffset += truncIndex - keep;
// Append the following buffer to the existing data
i = keep;
truncIndex = keep;
}
} else {
// Maintain output index
outTrackOffset += truncIndex;
// Reset the buffer pointers to the beginning
i = 0;
truncIndex = 0;
consecutiveSilentFrames = 0;
}
// Update progress and bail if user cancelled
cancelled = TrackProgress(0, ((double)index / (double)end));
if (cancelled) {
break;
}
// Bump to next block
index += count;
}
AudacityProject *p = GetActiveProject();
if (!p)
return false;
// Remove stale data at end of output tracks.
if (!cancelled && (outTrackOffset < end)) {
t = (WaveTrack *) iterOut.First();
while(t) {
t->Clear(outTrackOffset / rate, t1);
t = (WaveTrack *) iterOut.Next();
}
t1 = outTrackOffset / rate;
}
// Free buffers
for (tndx = 0; tndx < tcount; tndx++) {
delete [] buffer[tndx];
}
delete [] buffer;
mT0 = t0;
mT1 = t1;
this->ReplaceProcessedTracks(!cancelled);
return !cancelled;
}
#else // defined(EXPERIMENTAL_TRUNC_SILENCE)
// AWD: this is the new version!
bool EffectTruncSilence::Process()
{
// Typical fraction of total time taken by detection (better to guess low)
@ -823,8 +487,6 @@ void EffectTruncSilence::Intersect(RegionList &dest, const RegionList &src)
}
}
#endif // EXPERIMENTAL_TRUNC_SILENCE
void EffectTruncSilence::BlendFrames(float* buffer, int blendFrameCount, int leftIndex, int rightIndex)
{
float* bufOutput = &buffer[leftIndex];

View File

@ -61,9 +61,7 @@ public:
private:
//ToDo ... put BlendFrames in Effects, Project, or other class
void BlendFrames(float* buffer, int leftIndex, int rightIndex, int blendFrameCount);
#ifdef EXPERIMENTAL_TRUNC_SILENCE
void Intersect(RegionList &dest, const RegionList &src);
#endif
private:
sampleCount mBlendFrameCount;