Exception safety in: some effects and generators...
... Those that directly call WaveTrack functions in their Process() routines, which might throw exceptions for disk space exhaustion.
This commit is contained in:
parent
1fad6292a2
commit
22a12c6852
|
@ -179,13 +179,10 @@ bool EffectAmplify::Init()
|
|||
|
||||
void EffectAmplify::Preview(bool dryOnly)
|
||||
{
|
||||
double ratio = mRatio;
|
||||
double peak = mPeak;
|
||||
auto cleanup1 = valueRestorer( mRatio );
|
||||
auto cleanup2 = valueRestorer( mPeak );
|
||||
|
||||
Effect::Preview(dryOnly);
|
||||
|
||||
mRatio = ratio;
|
||||
mPeak = peak;
|
||||
}
|
||||
|
||||
void EffectAmplify::PopulateOrExchange(ShuttleGui & S)
|
||||
|
|
|
@ -1092,9 +1092,7 @@ bool EffectEqualization::ProcessOne(int count, WaveTrack * t,
|
|||
for(size_t j = mM - 1; j < wcopy; j++)
|
||||
buffer[i+j] = thisWindow[j];
|
||||
|
||||
float *tempP = thisWindow;
|
||||
thisWindow = lastWindow;
|
||||
lastWindow = tempP;
|
||||
std::swap( thisWindow, lastWindow );
|
||||
} //next i, lump of this block
|
||||
|
||||
output->Append((samplePtr)buffer.get(), floatSample, block);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "../Audacity.h"
|
||||
#include "../Experimental.h"
|
||||
#ifdef EXPERIMENTAL_EQ_SSE_THREADED
|
||||
#include "../MemoryX.h"
|
||||
#include "../Project.h"
|
||||
#include "Equalization.h"
|
||||
#include "../WaveTrack.h"
|
||||
|
@ -296,6 +297,7 @@ bool EffectEqualization48x::Process(EffectEqualization* effectEqualization)
|
|||
if(sMathPath) // !!! Filter MUST BE QUAD WORD ALIGNED !!!!
|
||||
mEffectEqualization->mM=(mEffectEqualization->mM&(~15))+1;
|
||||
AllocateBuffersWorkers(sMathPath&MATH_FUNCTION_THREADED);
|
||||
auto cleanup = finally( [&] { FreeBuffersWorkers(); } );
|
||||
SelectedTrackListOfKindIterator iter(Track::Wave, mEffectEqualization->mOutputTracks.get());
|
||||
WaveTrack *track = (WaveTrack *) iter.First();
|
||||
int count = 0;
|
||||
|
@ -316,7 +318,6 @@ bool EffectEqualization48x::Process(EffectEqualization* effectEqualization)
|
|||
track = (WaveTrack *) iter.Next();
|
||||
count++;
|
||||
}
|
||||
FreeBuffersWorkers();
|
||||
|
||||
mEffectEqualization->ReplaceProcessedTracks(!bBreakLoop);
|
||||
return !bBreakLoop;
|
||||
|
@ -331,6 +332,7 @@ bool EffectEqualization48x::TrackCompare()
|
|||
if(sMathPath) // !!! Filter MUST BE QUAD WORD ALIGNED !!!!
|
||||
mEffectEqualization->mM=(mEffectEqualization->mM&(~15))+1;
|
||||
AllocateBuffersWorkers(sMathPath&MATH_FUNCTION_THREADED);
|
||||
auto cleanup = finally( [&] { FreeBuffersWorkers(); } );
|
||||
// Reset map
|
||||
// PRL: These two maps aren't really used
|
||||
std::vector<Track*> SecondIMap;
|
||||
|
@ -402,9 +404,8 @@ bool EffectEqualization48x::TrackCompare()
|
|||
track = (WaveTrack *) iter.Next();
|
||||
track2 = (WaveTrack *) iter2.Next();
|
||||
}
|
||||
FreeBuffersWorkers();
|
||||
mEffectEqualization->ReplaceProcessedTracks(!bBreakLoop);
|
||||
return bBreakLoop;
|
||||
mEffectEqualization->ReplaceProcessedTracks(!bBreakLoop);
|
||||
return bBreakLoop; // return !bBreakLoop ?
|
||||
}
|
||||
|
||||
bool EffectEqualization48x::DeltaTrack(WaveTrack * t, WaveTrack * t2, sampleCount start, sampleCount len)
|
||||
|
@ -446,6 +447,7 @@ bool EffectEqualization48x::Benchmark(EffectEqualization* effectEqualization)
|
|||
if(sMathPath) // !!! Filter MUST BE QUAD WORD ALIGNED !!!!
|
||||
mEffectEqualization->mM=(mEffectEqualization->mM&(~15))+1;
|
||||
AllocateBuffersWorkers(MATH_FUNCTION_THREADED);
|
||||
auto cleanup = finally( [&] { FreeBuffersWorkers(); } );
|
||||
SelectedTrackListOfKindIterator
|
||||
iter(Track::Wave, mEffectEqualization->mOutputTracks.get());
|
||||
long times[] = { 0,0,0,0,0 };
|
||||
|
@ -494,7 +496,6 @@ bool EffectEqualization48x::Benchmark(EffectEqualization* effectEqualization)
|
|||
times[i]=timer.Time();
|
||||
}
|
||||
}
|
||||
FreeBuffersWorkers();
|
||||
mBenching=false;
|
||||
bBreakLoop=false;
|
||||
mEffectEqualization->ReplaceProcessedTracks(bBreakLoop);
|
||||
|
@ -507,7 +508,7 @@ bool EffectEqualization48x::Benchmark(EffectEqualization* effectEqualization)
|
|||
|
||||
wxMessageBox(wxString::Format(_("Benchmark times:\nOriginal: %s\nDefault Segmented: %s\nDefault Threaded: %s\nSSE: %s\nSSE Threaded: %s\n"),tsDefault.Format(wxT("%M:%S.%l")).c_str(),
|
||||
tsDefaultEnhanced.Format(wxT("%M:%S.%l")).c_str(), tsDefaultThreaded.Format(wxT("%M:%S.%l")).c_str(),tsSSE.Format(wxT("%M:%S.%l")).c_str(),tsSSEThreaded.Format(wxT("%M:%S.%l")).c_str()));
|
||||
return bBreakLoop;
|
||||
return bBreakLoop; // return !bBreakLoop ?
|
||||
}
|
||||
|
||||
bool EffectEqualization48x::ProcessTail(WaveTrack * t, WaveTrack * output, sampleCount start, sampleCount len)
|
||||
|
@ -862,30 +863,32 @@ bool EffectEqualization48x::ProcessOne4x(int count, WaveTrack * t,
|
|||
ProcessTail(t, output.get(), start, len);
|
||||
return bBreakLoop;
|
||||
}
|
||||
|
||||
void *EQWorker::Entry()
|
||||
{
|
||||
while(!mExitLoop) {
|
||||
mMutex->Lock();
|
||||
bool bufferAquired=false;
|
||||
for(int i=0;i<mBufferInfoCount;i++)
|
||||
if(mBufferInfoList[i].mBufferStatus==BufferReady) { // we found an unlocked ready buffer
|
||||
bufferAquired=true;
|
||||
mBufferInfoList[i].mBufferStatus=BufferBusy; // we own it now
|
||||
mMutex->Unlock();
|
||||
switch (mProcessingType)
|
||||
{
|
||||
int i = 0;
|
||||
{
|
||||
wxMutexLocker locker( mMutex );
|
||||
for(; i < mBufferInfoCount; i++) {
|
||||
if(mBufferInfoList[i].mBufferStatus==BufferReady) { // we found an unlocked ready buffer
|
||||
mBufferInfoList[i].mBufferStatus=BufferBusy; // we own it now
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( i < mBufferInfoCount ) {
|
||||
switch (mProcessingType)
|
||||
{
|
||||
case 1:
|
||||
mEffectEqualization48x->ProcessBuffer1x(&mBufferInfoList[i]);
|
||||
break;
|
||||
case 4:
|
||||
case 4:
|
||||
mEffectEqualization48x->ProcessBuffer4x(&mBufferInfoList[i]);
|
||||
break;
|
||||
}
|
||||
mBufferInfoList[i].mBufferStatus=BufferDone; // we're done
|
||||
break;
|
||||
}
|
||||
if(!bufferAquired)
|
||||
mMutex->Unlock();
|
||||
}
|
||||
mBufferInfoList[i].mBufferStatus=BufferDone; // we're done
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -940,7 +943,7 @@ bool EffectEqualization48x::ProcessOne1x4xThreaded(int count, WaveTrack * t,
|
|||
bBreakLoop=mEffectEqualization->TrackProgress(count, (double)(bigBlocksWritten)/bigRuns.as_double());
|
||||
if( bBreakLoop )
|
||||
break;
|
||||
mDataMutex.Lock(); // Get in line for data
|
||||
wxMutexLocker locker( mDataMutex ); // Get in line for data
|
||||
// process as many blocks as we can
|
||||
while((mBufferInfo[currentIndex].mBufferStatus==BufferDone) && (bigBlocksWritten<bigRuns)) { // data is ours
|
||||
output->Append((samplePtr)&mBufferInfo[currentIndex].mBufferDest[0][(bigBlocksWritten?mBlockSize:0)+(mFilterSize>>1)], floatSample, subBufferSize-((bigBlocksWritten?mBlockSize:0)+(mFilterSize>>1)));
|
||||
|
@ -961,7 +964,6 @@ bool EffectEqualization48x::ProcessOne1x4xThreaded(int count, WaveTrack * t,
|
|||
} else mBufferInfo[currentIndex].mBufferStatus=BufferEmpty; // this is completely unecessary
|
||||
currentIndex=(currentIndex+1)%mWorkerDataCount;
|
||||
}
|
||||
mDataMutex.Unlock(); // Get back in line for data
|
||||
}
|
||||
if(singleProcessLength && !bBreakLoop) {
|
||||
t->Get((samplePtr)mBigBuffer.get(), floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
|
||||
|
@ -1237,7 +1239,7 @@ bool EffectEqualization48x::ProcessOne8xThreaded(int count, WaveTrack * t,
|
|||
{
|
||||
break;
|
||||
}
|
||||
mDataMutex.Lock(); // Get in line for data
|
||||
wxMutexLocker locker( mDataMutex ); // Get in line for data
|
||||
// process as many blocks as we can
|
||||
while((mBufferInfo[currentIndex].mBufferStatus==BufferDone) && (bigBlocksWritten<bigRuns)) { // data is ours
|
||||
output->Append((samplePtr)&mBufferInfo[currentIndex].mBufferDest[0][(bigBlocksWritten?mBlockSize:0)+(mFilterSize>>1)], floatSample, mSubBufferSize-((bigBlocksWritten?mBlockSize:0)+(mFilterSize>>1)));
|
||||
|
@ -1258,7 +1260,6 @@ bool EffectEqualization48x::ProcessOne8xThreaded(int count, WaveTrack * t,
|
|||
} else mBufferInfo[currentIndex].mBufferStatus=BufferEmpty; // this is completely unecessary
|
||||
currentIndex=(currentIndex+1)%mWorkerDataCount;
|
||||
}
|
||||
mDataMutex.Unlock(); // Get back in line for data
|
||||
}
|
||||
if(singleProcessLength && !bBreakLoop) {
|
||||
t->Get((samplePtr)mBigBuffer.get(), floatSample, currentSample, singleProcessLength+mBlockSize+(mFilterSize>>1));
|
||||
|
|
|
@ -1656,14 +1656,11 @@ void EffectNoiseReduction::Dialog::OnPreview(wxCommandEvent & WXUNUSED(event))
|
|||
return;
|
||||
|
||||
// Save & restore parameters around Preview, because we didn't do OK.
|
||||
EffectNoiseReduction::Settings oldSettings(*m_pSettings);
|
||||
|
||||
auto cleanup = valueRestorer( *m_pSettings );
|
||||
*m_pSettings = mTempSettings;
|
||||
m_pSettings->mDoProfile = false;
|
||||
|
||||
m_pEffect->Preview();
|
||||
|
||||
*m_pSettings = oldSettings;
|
||||
}
|
||||
|
||||
void EffectNoiseReduction::Dialog::OnReduceNoise( wxCommandEvent & WXUNUSED(event))
|
||||
|
|
|
@ -224,7 +224,6 @@ bool EffectNoiseRemoval::Process()
|
|||
auto len = end - start;
|
||||
|
||||
if (!ProcessOne(count, track, start, len)) {
|
||||
Cleanup();
|
||||
bGoodResult = false;
|
||||
break;
|
||||
}
|
||||
|
@ -238,8 +237,6 @@ bool EffectNoiseRemoval::Process()
|
|||
mDoProfile = false;
|
||||
}
|
||||
|
||||
if (bGoodResult)
|
||||
Cleanup();
|
||||
this->ReplaceProcessedTracks(bGoodResult);
|
||||
return bGoodResult;
|
||||
}
|
||||
|
@ -305,7 +302,7 @@ void EffectNoiseRemoval::Initialize()
|
|||
}
|
||||
}
|
||||
|
||||
void EffectNoiseRemoval::Cleanup()
|
||||
void EffectNoiseRemoval::End()
|
||||
{
|
||||
hFFT.reset();
|
||||
|
||||
|
@ -322,6 +319,8 @@ void EffectNoiseRemoval::Cleanup()
|
|||
mInWaveBuffer.reset();
|
||||
mWindow.reset();
|
||||
mOutOverlapBuffer.reset();
|
||||
|
||||
mOutputTrack.reset();
|
||||
}
|
||||
|
||||
void EffectNoiseRemoval::StartNewTrack()
|
||||
|
@ -579,9 +578,6 @@ bool EffectNoiseRemoval::ProcessOne(int count, WaveTrack * track,
|
|||
bool bResult = track->ClearAndPaste(t0, t0 + tLen, mOutputTrack.get(), true, false);
|
||||
wxASSERT(bResult); // TO DO: Actually handle this.
|
||||
}
|
||||
|
||||
// Delete the outputTrack now that its data is inserted in place
|
||||
mOutputTrack.reset();
|
||||
}
|
||||
|
||||
return bLoopSuccess;
|
||||
|
@ -688,14 +684,16 @@ void NoiseRemovalDialog::OnPreview(wxCommandEvent & WXUNUSED(event))
|
|||
m_pEffect->mFreqSmoothingHz = mFreq;
|
||||
m_pEffect->mAttackDecayTime = mTime;
|
||||
|
||||
m_pEffect->Preview();
|
||||
auto cleanup = finally( [&] {
|
||||
m_pEffect->mSensitivity = oldSensitivity;
|
||||
m_pEffect->mNoiseGain = oldGain;
|
||||
m_pEffect->mFreqSmoothingHz = oldFreq;
|
||||
m_pEffect->mAttackDecayTime = oldTime;
|
||||
m_pEffect->mbLeaveNoise = oldLeaveNoise;
|
||||
m_pEffect->mDoProfile = oldDoProfile;
|
||||
} );
|
||||
|
||||
m_pEffect->mSensitivity = oldSensitivity;
|
||||
m_pEffect->mNoiseGain = oldGain;
|
||||
m_pEffect->mFreqSmoothingHz = oldFreq;
|
||||
m_pEffect->mAttackDecayTime = oldTime;
|
||||
m_pEffect->mbLeaveNoise = oldLeaveNoise;
|
||||
m_pEffect->mDoProfile = oldDoProfile;
|
||||
m_pEffect->Preview();
|
||||
}
|
||||
|
||||
void NoiseRemovalDialog::OnRemoveNoise( wxCommandEvent & WXUNUSED(event))
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
bool Init() override;
|
||||
bool CheckWhetherSkipEffect() override;
|
||||
bool Process() override;
|
||||
void End() override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -98,7 +99,6 @@ private:
|
|||
void RemoveNoise();
|
||||
void RotateHistoryWindows();
|
||||
void FinishTrack();
|
||||
void Cleanup();
|
||||
|
||||
// Variables that only exist during processing
|
||||
std::unique_ptr<WaveTrack> mOutputTrack;
|
||||
|
|
|
@ -34,8 +34,6 @@ public:
|
|||
ResampleBuf()
|
||||
{
|
||||
processed = 0;
|
||||
outputLeftTrack = NULL;
|
||||
outputRightTrack = NULL;
|
||||
}
|
||||
|
||||
~ResampleBuf()
|
||||
|
|
|
@ -103,10 +103,9 @@ bool EffectSimpleMono::ProcessOne(WaveTrack * track,
|
|||
track->Get((samplePtr) buffer.get(), floatSample, s, block);
|
||||
|
||||
//Process the buffer. If it fails, clean up and exit.
|
||||
if (!ProcessSimpleMono(buffer.get(), block)) {
|
||||
if (!ProcessSimpleMono(buffer.get(), block))
|
||||
//Return false because the effect failed.
|
||||
return false;
|
||||
}
|
||||
|
||||
//Processing succeeded. copy the newly-changed samples back
|
||||
//onto the track.
|
||||
|
@ -118,9 +117,8 @@ bool EffectSimpleMono::ProcessOne(WaveTrack * track,
|
|||
//Update the Progress meter
|
||||
if (TrackProgress(mCurTrackNum,
|
||||
(s - start).as_double() /
|
||||
len)) {
|
||||
len))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Return true because the effect processing succeeded.
|
||||
|
|
|
@ -159,14 +159,17 @@ bool EffectSoundTouch::ProcessWithTimeWarper(const TimeWarper &warper)
|
|||
if (bGoodResult)
|
||||
ReplaceProcessedTracks(bGoodResult);
|
||||
|
||||
mSoundTouch.reset();
|
||||
|
||||
// mT0 = mCurT0;
|
||||
// mT1 = mCurT0 + m_maxNewLength; // Update selection.
|
||||
|
||||
return bGoodResult;
|
||||
}
|
||||
|
||||
void EffectSoundTouch::End()
|
||||
{
|
||||
mSoundTouch.reset();
|
||||
}
|
||||
|
||||
//ProcessOne() takes a track, transforms it to bunch of buffer-blocks,
|
||||
//and executes ProcessSoundTouch on these blocks
|
||||
bool EffectSoundTouch::ProcessOne(WaveTrack *track,
|
||||
|
@ -345,7 +348,7 @@ bool EffectSoundTouch::ProcessStereo(
|
|||
return true;
|
||||
}
|
||||
|
||||
bool EffectSoundTouch::ProcessStereoResults(const unsigned int outputCount,
|
||||
bool EffectSoundTouch::ProcessStereoResults(const size_t outputCount,
|
||||
WaveTrack* outputLeftTrack,
|
||||
WaveTrack* outputRightTrack)
|
||||
{
|
||||
|
|
|
@ -39,6 +39,10 @@ class EffectSoundTouch /* not final */ : public Effect
|
|||
{
|
||||
public:
|
||||
|
||||
// Effect implementation
|
||||
|
||||
void End() override;
|
||||
|
||||
// EffectSoundTouch implementation
|
||||
|
||||
#ifdef USE_MIDI
|
||||
|
@ -66,7 +70,7 @@ private:
|
|||
bool ProcessStereo(WaveTrack* leftTrack, WaveTrack* rightTrack,
|
||||
sampleCount start, sampleCount end,
|
||||
const TimeWarper &warper);
|
||||
bool ProcessStereoResults(const unsigned int outputCount,
|
||||
bool ProcessStereoResults(const size_t outputCount,
|
||||
WaveTrack* outputLeftTrack,
|
||||
WaveTrack* outputRightTrack);
|
||||
|
||||
|
|
|
@ -125,11 +125,15 @@ bool EffectStereoToMono::Process()
|
|||
count++;
|
||||
}
|
||||
|
||||
mOutTrack.reset();
|
||||
this->ReplaceProcessedTracks(bGoodResult);
|
||||
return bGoodResult;
|
||||
}
|
||||
|
||||
void EffectStereoToMono::End()
|
||||
{
|
||||
mOutTrack.reset();
|
||||
}
|
||||
|
||||
bool EffectStereoToMono::ProcessOne(int count)
|
||||
{
|
||||
float curLeftFrame;
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
// Effect implementation
|
||||
|
||||
bool Process() override;
|
||||
void End() override;
|
||||
bool IsHidden() override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -165,9 +165,8 @@ double EffectTimeScale::CalcPreviewInputLength(double previewLength)
|
|||
void EffectTimeScale::Preview(bool dryOnly)
|
||||
{
|
||||
previewSelectedDuration = Effect::GetDuration();
|
||||
bPreview = true;
|
||||
auto cleanup = valueRestorer( bPreview, true );
|
||||
Effect::Preview(dryOnly);
|
||||
bPreview = false;
|
||||
}
|
||||
|
||||
bool EffectTimeScale::Process()
|
||||
|
|
|
@ -117,6 +117,8 @@ END_EVENT_TABLE()
|
|||
|
||||
NyquistEffect::NyquistEffect(const wxString &fName)
|
||||
{
|
||||
mOutputTrack[0] = mOutputTrack[1] = nullptr;
|
||||
|
||||
mAction = _("Applying Nyquist Effect...");
|
||||
mInputCmd = wxEmptyString;
|
||||
mCmd = wxEmptyString;
|
||||
|
@ -670,6 +672,13 @@ _("Selection too long for Nyquist code.\nMaximum allowed selection is %ld sample
|
|||
nyx_set_os_callback(StaticOSCallback, (void *)this);
|
||||
nyx_capture_output(StaticOutputCallback, (void *)this);
|
||||
|
||||
auto cleanup = finally( [&] {
|
||||
nyx_capture_output(NULL, (void *)NULL);
|
||||
nyx_set_os_callback(NULL, (void *)NULL);
|
||||
nyx_cleanup();
|
||||
} );
|
||||
|
||||
|
||||
if (mVersion >= 4)
|
||||
{
|
||||
mPerTrackProps = wxEmptyString;
|
||||
|
@ -709,10 +718,6 @@ _("Selection too long for Nyquist code.\nMaximum allowed selection is %ld sample
|
|||
|
||||
success = ProcessOne();
|
||||
|
||||
nyx_capture_output(NULL, (void *)NULL);
|
||||
nyx_set_os_callback(NULL, (void *)NULL);
|
||||
nyx_cleanup();
|
||||
|
||||
// Reset previous locale
|
||||
wxSetlocale(LC_NUMERIC, prevlocale);
|
||||
|
||||
|
@ -1110,16 +1115,23 @@ bool NyquistEffect::ProcessOne()
|
|||
cmd += mCmd;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < mCurNumChannels; i++) {
|
||||
// Put the fetch buffers in a clean initial state
|
||||
for (size_t i = 0; i < mCurNumChannels; i++)
|
||||
mCurBuffer[i].Free();
|
||||
}
|
||||
|
||||
// Guarantee release of memory when done
|
||||
auto cleanup = finally( [&] {
|
||||
for (size_t i = 0; i < mCurNumChannels; i++)
|
||||
mCurBuffer[i].Free();
|
||||
} );
|
||||
|
||||
// Evaluate the expression, which may invoke the get callback, but often does
|
||||
// not, leaving that to delayed evaluation of the output sound
|
||||
rval = nyx_eval_expression(cmd.mb_str(wxConvUTF8));
|
||||
|
||||
// Audacity has no idea how long Nyquist processing will take, but
|
||||
// can monitor audio being returned.
|
||||
// Anything other than audio should be returmed almost instantly
|
||||
// Anything other than audio should be returned almost instantly
|
||||
// so notify the user that process has completed (bug 558)
|
||||
if ((rval != nyx_audio) && ((mCount + mCurNumChannels) == mNumSelectedChannels)) {
|
||||
if (mCurNumChannels == 1) {
|
||||
|
@ -1225,19 +1237,30 @@ bool NyquistEffect::ProcessOne()
|
|||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<WaveTrack> outputTrack[2];
|
||||
|
||||
double rate = mCurTrack[0]->GetRate();
|
||||
for (i = 0; i < outChannels; i++) {
|
||||
for (size_t i = 0; i < outChannels; i++) {
|
||||
sampleFormat format = mCurTrack[i]->GetSampleFormat();
|
||||
|
||||
if (outChannels == (int)mCurNumChannels) {
|
||||
rate = mCurTrack[i]->GetRate();
|
||||
}
|
||||
|
||||
mOutputTrack[i] = mFactory->NewWaveTrack(format, rate);
|
||||
outputTrack[i] = mFactory->NewWaveTrack(format, rate);
|
||||
|
||||
// Clean the initial buffer states again for the get callbacks
|
||||
// -- is this really needed?
|
||||
mCurBuffer[i].Free();
|
||||
}
|
||||
|
||||
int success = nyx_get_audio(StaticPutCallback, (void *)this);
|
||||
// Now fully evaluate the sound
|
||||
int success;
|
||||
{
|
||||
auto vr0 = valueRestorer( mOutputTrack[0], outputTrack[0].get() );
|
||||
auto vr1 = valueRestorer( mOutputTrack[1], outputTrack[1].get() );
|
||||
success = nyx_get_audio(StaticPutCallback, (void *)this);
|
||||
}
|
||||
|
||||
// See if GetCallback found read errors
|
||||
if (mFailedFileName.IsOk())
|
||||
|
@ -1250,38 +1273,29 @@ bool NyquistEffect::ProcessOne()
|
|||
// what, then?
|
||||
success = false;
|
||||
|
||||
if (!success) {
|
||||
for(i = 0; i < outChannels; i++) {
|
||||
mOutputTrack[i].reset();
|
||||
}
|
||||
|
||||
if (!success)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < outChannels; i++) {
|
||||
mOutputTrack[i]->Flush();
|
||||
mCurBuffer[i].Free();
|
||||
mOutputTime = mOutputTrack[i]->GetEndTime();
|
||||
for (size_t i = 0; i < outChannels; i++) {
|
||||
outputTrack[i]->Flush();
|
||||
mOutputTime = outputTrack[i]->GetEndTime();
|
||||
|
||||
if (mOutputTime <= 0) {
|
||||
wxMessageBox(_("Nyquist did not return audio.\n"),
|
||||
wxT("Nyquist"),
|
||||
wxOK | wxCENTRE, mUIParent);
|
||||
for (int j = 0; j < outChannels; j++) {
|
||||
mOutputTrack[j].reset();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < mCurNumChannels; i++) {
|
||||
for (size_t i = 0; i < mCurNumChannels; i++) {
|
||||
WaveTrack *out;
|
||||
|
||||
if (outChannels == (int)mCurNumChannels) {
|
||||
out = mOutputTrack[i].get();
|
||||
out = outputTrack[i].get();
|
||||
}
|
||||
else {
|
||||
out = mOutputTrack[0].get();
|
||||
out = outputTrack[0].get();
|
||||
}
|
||||
|
||||
if (mMergeClips < 0) {
|
||||
|
@ -1310,9 +1324,6 @@ bool NyquistEffect::ProcessOne()
|
|||
mFirstInGroup = false;
|
||||
}
|
||||
|
||||
for (i = 0; i < outChannels; i++) {
|
||||
mOutputTrack[i].reset();
|
||||
}
|
||||
mProjectChanged = true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -224,7 +224,7 @@ private:
|
|||
sampleCount mCurBufferStart[2];
|
||||
size_t mCurBufferLen[2];
|
||||
|
||||
std::unique_ptr<WaveTrack> mOutputTrack[2];
|
||||
WaveTrack *mOutputTrack[2];
|
||||
|
||||
wxArrayString mCategories;
|
||||
|
||||
|
|
Loading…
Reference in New Issue