mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-05 14:18:53 +02:00
Various precautions, efficiencies, fixes of unreported bugs
This commit is contained in:
commit
3d29ba12a6
@ -914,13 +914,12 @@ void AudacityApp::OnTimer(wxTimerEvent& WXUNUSED(event))
|
||||
// find which project owns the blockfile
|
||||
// note: there may be more than 1, but just go with the first one.
|
||||
//size_t numProjects = gAudacityProjects.size();
|
||||
AudacityProject *offendingProject {};
|
||||
AProjectHolder offendingProject;
|
||||
wxString missingFileName;
|
||||
|
||||
{
|
||||
ODLocker locker { &m_LastMissingBlockFileLock };
|
||||
offendingProject =
|
||||
AProjectHolder{ m_LastMissingBlockFileProject }.get();
|
||||
offendingProject = m_LastMissingBlockFileProject.lock();
|
||||
missingFileName = m_LastMissingBlockFilePath;
|
||||
}
|
||||
|
||||
@ -944,7 +943,7 @@ locations of the missing files."), missingFileName.c_str());
|
||||
if (offendingProject->GetMissingAliasFileDialog()) {
|
||||
offendingProject->GetMissingAliasFileDialog()->Raise();
|
||||
} else {
|
||||
ShowAliasMissingDialog(offendingProject, _("Files Missing"),
|
||||
ShowAliasMissingDialog(offendingProject.get(), _("Files Missing"),
|
||||
errorMessage, wxT(""), true);
|
||||
}
|
||||
}
|
||||
|
@ -354,12 +354,12 @@ void BenchmarkDialog::OnRun( wxCommandEvent & WXUNUSED(event))
|
||||
|
||||
srand(randSeed);
|
||||
|
||||
int nChunks, chunkSize;
|
||||
size_t nChunks, chunkSize;
|
||||
//chunkSize = 7500 + (rand() % 1000);
|
||||
chunkSize = 200 + (rand() % 100);
|
||||
nChunks = (dataSize * 1048576) / (chunkSize*sizeof(short));
|
||||
while(nChunks < 20 || chunkSize > (blockSize*1024)/4) {
|
||||
chunkSize = (chunkSize / 2) + (rand() % 100);
|
||||
while(nChunks < 20 || chunkSize > ((unsigned long)(blockSize)*1024)/4) {
|
||||
chunkSize = std::max( size_t(1), (chunkSize / 2) + (rand() % 100) );
|
||||
nChunks = (dataSize * 1048576) / (chunkSize*sizeof(short));
|
||||
}
|
||||
|
||||
@ -374,7 +374,6 @@ void BenchmarkDialog::OnRun( wxCommandEvent & WXUNUSED(event))
|
||||
int trials = numEdits;
|
||||
|
||||
short *small1 = new short[nChunks];
|
||||
short *small2 = new short[nChunks];
|
||||
short *block = new short[chunkSize];
|
||||
|
||||
Printf(wxT("Preparing...\n"));
|
||||
@ -416,8 +415,13 @@ void BenchmarkDialog::OnRun( wxCommandEvent & WXUNUSED(event))
|
||||
|
||||
timer.Start();
|
||||
for (z = 0; z < trials; z++) {
|
||||
int x0 = rand() % nChunks;
|
||||
int xlen = 1 + (rand() % (nChunks - x0));
|
||||
// First chunk to cut
|
||||
// 0 <= x0 < nChunks
|
||||
const size_t x0 = rand() % nChunks;
|
||||
|
||||
// Number of chunks to cut
|
||||
// 1 <= xlen <= nChunks - x0
|
||||
const size_t xlen = 1 + (rand() % (nChunks - x0));
|
||||
if (mEditDetail)
|
||||
Printf(wxT("Cut: %d - %d \n"), x0 * chunkSize, (x0 + xlen) * chunkSize);
|
||||
|
||||
@ -431,7 +435,10 @@ void BenchmarkDialog::OnRun( wxCommandEvent & WXUNUSED(event))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int y0 = rand() % (nChunks - xlen);
|
||||
// Position to paste
|
||||
// 0 <= y0 <= nChunks - xlen
|
||||
const size_t y0 = rand() % (nChunks - xlen + 1);
|
||||
|
||||
if (mEditDetail)
|
||||
Printf(wxT("Paste: %d\n"), y0 * chunkSize);
|
||||
|
||||
@ -447,18 +454,12 @@ void BenchmarkDialog::OnRun( wxCommandEvent & WXUNUSED(event))
|
||||
t->GetClipByIndex(0)->GetSequence()->GetNumSamples().as_long_long());
|
||||
goto fail;
|
||||
}
|
||||
// Copy
|
||||
for (i = 0; i < xlen; i++)
|
||||
small2[i] = small1[x0 + i];
|
||||
// Delete
|
||||
for (i = 0; i < (nChunks - x0 - xlen); i++)
|
||||
small1[x0 + i] = small1[x0 + xlen + i];
|
||||
// Insert
|
||||
for (i = 0; i < (nChunks - xlen - y0); i++)
|
||||
small1[nChunks - i - 1] = small1[nChunks - i - 1 - xlen];
|
||||
// Paste
|
||||
for (i = 0; i < xlen; i++)
|
||||
small1[y0 + i] = small2[i];
|
||||
|
||||
// Permute small1 correspondingly to the cut and paste
|
||||
auto first = &small1[0];
|
||||
if (x0 + xlen < nChunks)
|
||||
std::rotate( first + x0, first + x0 + xlen, first + nChunks );
|
||||
std::rotate( first + y0, first + nChunks - xlen, first + nChunks );
|
||||
}
|
||||
|
||||
elapsed = timer.Time();
|
||||
@ -534,7 +535,6 @@ void BenchmarkDialog::OnRun( wxCommandEvent & WXUNUSED(event))
|
||||
|
||||
success:
|
||||
delete[]small1;
|
||||
delete[]small2;
|
||||
delete[]block;
|
||||
|
||||
dd.reset();
|
||||
|
@ -266,6 +266,10 @@ void LabelTrack::WarpLabels(const TimeWarper &warper) {
|
||||
warper.Warp(labelStruct.getT0()),
|
||||
warper.Warp(labelStruct.getT1()));
|
||||
}
|
||||
|
||||
// This should not be needed, assuming the warper is nondecreasing, but
|
||||
// let's not assume too much.
|
||||
SortLabels();
|
||||
}
|
||||
|
||||
void LabelTrack::ResetFlags()
|
||||
|
24
src/Mix.cpp
24
src/Mix.cpp
@ -136,9 +136,9 @@ void MixAndRender(TrackList *tracks, TrackFactory *trackFactory,
|
||||
mixRight = trackFactory->NewWaveTrack(format, rate);
|
||||
if (oneinput) {
|
||||
if (usefulIter.First()->GetLink() != NULL) // we have linked track
|
||||
mixLeft->SetName(usefulIter.First()->GetLink()->GetName()); /* set name to match input track's right channel!*/
|
||||
mixRight->SetName(usefulIter.First()->GetLink()->GetName()); /* set name to match input track's right channel!*/
|
||||
else
|
||||
mixLeft->SetName(usefulIter.First()->GetName()); /* set name to that of sole input channel */
|
||||
mixRight->SetName(usefulIter.First()->GetName()); /* set name to that of sole input channel */
|
||||
}
|
||||
else
|
||||
mixRight->SetName(_("Mix"));
|
||||
@ -456,7 +456,10 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
|
||||
if (getLen > 0) {
|
||||
if (backwards) {
|
||||
auto results = cache.Get(floatSample, *pos - (getLen - 1), getLen);
|
||||
memcpy(&queue[*queueLen], results, sizeof(float) * getLen);
|
||||
if (results)
|
||||
memcpy(&queue[*queueLen], results, sizeof(float) * getLen);
|
||||
else
|
||||
memset(&queue[*queueLen], 0, sizeof(float) * getLen);
|
||||
|
||||
track->GetEnvelopeValues(mEnvValues,
|
||||
getLen,
|
||||
@ -465,7 +468,10 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
|
||||
}
|
||||
else {
|
||||
auto results = cache.Get(floatSample, *pos, getLen);
|
||||
memcpy(&queue[*queueLen], results, sizeof(float) * getLen);
|
||||
if (results)
|
||||
memcpy(&queue[*queueLen], results, sizeof(float) * getLen);
|
||||
else
|
||||
memset(&queue[*queueLen], 0, sizeof(float) * getLen);
|
||||
|
||||
track->GetEnvelopeValues(mEnvValues,
|
||||
getLen,
|
||||
@ -571,7 +577,10 @@ size_t Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache,
|
||||
|
||||
if (backwards) {
|
||||
auto results = cache.Get(floatSample, *pos - (slen - 1), slen);
|
||||
memcpy(mFloatBuffer, results, sizeof(float) * slen);
|
||||
if (results)
|
||||
memcpy(mFloatBuffer, results, sizeof(float) * slen);
|
||||
else
|
||||
memset(mFloatBuffer, 0, sizeof(float) * slen);
|
||||
track->GetEnvelopeValues(mEnvValues, slen, t - (slen - 1) / mRate);
|
||||
for(decltype(slen) i = 0; i < slen; i++)
|
||||
mFloatBuffer[i] *= mEnvValues[i]; // Track gain control will go here?
|
||||
@ -581,7 +590,10 @@ size_t Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache,
|
||||
}
|
||||
else {
|
||||
auto results = cache.Get(floatSample, *pos, slen);
|
||||
memcpy(mFloatBuffer, results, sizeof(float) * slen);
|
||||
if (results)
|
||||
memcpy(mFloatBuffer, results, sizeof(float) * slen);
|
||||
else
|
||||
memset(mFloatBuffer, 0, sizeof(float) * slen);
|
||||
track->GetEnvelopeValues(mEnvValues, slen, t);
|
||||
for(decltype(slen) i = 0; i < slen; i++)
|
||||
mFloatBuffer[i] *= mEnvValues[i]; // Track gain control will go here?
|
||||
|
@ -110,7 +110,6 @@ Track(projDirManager)
|
||||
SetName(GetDefaultName());
|
||||
|
||||
mSeq = NULL;
|
||||
mSerializationBuffer = NULL;
|
||||
mSerializationLength = 0;
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
@ -125,9 +124,6 @@ Track(projDirManager)
|
||||
|
||||
NoteTrack::~NoteTrack()
|
||||
{
|
||||
if (mSerializationBuffer) {
|
||||
delete [] mSerializationBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
Track::Holder NoteTrack::Duplicate() const
|
||||
@ -143,13 +139,15 @@ Track::Holder NoteTrack::Duplicate() const
|
||||
SonifyBeginSerialize();
|
||||
assert(!mSerializationBuffer);
|
||||
// serialize from this to duplicate's mSerializationBuffer
|
||||
mSeq->serialize((void**)&duplicate->mSerializationBuffer,
|
||||
void *buffer;
|
||||
mSeq->serialize(&buffer,
|
||||
&duplicate->mSerializationLength);
|
||||
duplicate->mSerializationBuffer.reset( (char*)buffer );
|
||||
SonifyEndSerialize();
|
||||
} else if (mSerializationBuffer) {
|
||||
SonifyBeginUnserialize();
|
||||
assert(!mSeq);
|
||||
std::unique_ptr<Alg_track> alg_track{ Alg_seq::unserialize(mSerializationBuffer,
|
||||
std::unique_ptr<Alg_track> alg_track{ Alg_seq::unserialize(mSerializationBuffer.get(),
|
||||
mSerializationLength) };
|
||||
assert(alg_track->get_type() == 's');
|
||||
duplicate->mSeq.reset(static_cast<Alg_seq*>(alg_track.release()));
|
||||
@ -198,9 +196,8 @@ void NoteTrack::WarpAndTransposeNotes(double t0, double t1,
|
||||
const auto nt = static_cast<NoteTrack*>(unt.get());
|
||||
wxASSERT(!mSeq && nt->mSeq && !nt->mSerializationBuffer);
|
||||
// swap mSeq and Buffer between this and nt
|
||||
nt->mSerializationBuffer = mSerializationBuffer;
|
||||
nt->mSerializationBuffer = std::move(mSerializationBuffer);
|
||||
nt->mSerializationLength = mSerializationLength;
|
||||
mSerializationBuffer = NULL;
|
||||
mSerializationLength = 0;
|
||||
mSeq = std::move(nt->mSeq);
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ class AUDACITY_DLL_API NoteTrack final : public Track {
|
||||
// mSeq variable. (TrackArtist should check to make sure this
|
||||
// flip-flop from mSeq to mSerializationBuffer happened an
|
||||
// even number of times, otherwise mSeq will be NULL).
|
||||
mutable char *mSerializationBuffer; // NULL means no buffer
|
||||
mutable std::unique_ptr<char[]> mSerializationBuffer; // NULL means no buffer
|
||||
long mSerializationLength;
|
||||
|
||||
#ifdef EXPERIMENTAL_MIDI_OUT
|
||||
|
@ -2829,12 +2829,11 @@ void TrackArtist::DrawNoteTrack(const NoteTrack *track,
|
||||
// JKC: Previously this indirected via seq->, a NULL pointer.
|
||||
// This was actually OK, since unserialize is a static function.
|
||||
// Alg_seq:: is clearer.
|
||||
std::unique_ptr<Alg_track> alg_track{ Alg_seq::unserialize(track->mSerializationBuffer,
|
||||
std::unique_ptr<Alg_track> alg_track{ Alg_seq::unserialize(track->mSerializationBuffer.get(),
|
||||
track->mSerializationLength) };
|
||||
assert(alg_track->get_type() == 's');
|
||||
const_cast<NoteTrack*>(track)->mSeq.reset(seq = static_cast<Alg_seq*>(alg_track.release()));
|
||||
free(track->mSerializationBuffer);
|
||||
track->mSerializationBuffer = NULL;
|
||||
track->mSerializationBuffer.reset();
|
||||
}
|
||||
assert(seq);
|
||||
int visibleChannels = track->mVisibleChannels;
|
||||
|
@ -854,12 +854,16 @@ bool SpecCache::CalculateOneSpectrum
|
||||
myLen)
|
||||
);
|
||||
|
||||
if (copy)
|
||||
memcpy(adj, useBuffer, myLen * sizeof(float));
|
||||
if (copy) {
|
||||
if (useBuffer)
|
||||
memcpy(adj, useBuffer, myLen * sizeof(float));
|
||||
else
|
||||
memset(adj, 0, myLen * sizeof(float));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (copy)
|
||||
if (copy || !useBuffer)
|
||||
useBuffer = scratch;
|
||||
|
||||
if (autocorrelation) {
|
||||
|
@ -2661,9 +2661,7 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format,
|
||||
// Request starts in the second buffer and extends past it.
|
||||
// Discard the first buffer.
|
||||
// (But don't deallocate the buffer space.)
|
||||
float *save = mBuffers[0].data;
|
||||
mBuffers[0] = mBuffers[1];
|
||||
mBuffers[1].data = save;
|
||||
mBuffers[0] .swap ( mBuffers[1] );
|
||||
fillSecond = true;
|
||||
mNValidBuffers = 1;
|
||||
}
|
||||
@ -2678,9 +2676,7 @@ constSamplePtr WaveTrackCache::Get(sampleFormat format,
|
||||
// refill the first.
|
||||
// (This case might be useful when marching backwards through
|
||||
// the track, as with scrubbing.)
|
||||
float *save = mBuffers[1].data;
|
||||
mBuffers[1] = mBuffers[0];
|
||||
mBuffers[0].data = save;
|
||||
mBuffers[0] .swap ( mBuffers[1] );
|
||||
fillFirst = true;
|
||||
fillSecond = false;
|
||||
// Cache is not in a consistent state yet
|
||||
|
@ -646,6 +646,13 @@ private:
|
||||
Buffer() : data(0), start(0), len(0) {}
|
||||
void Free() { delete[] data; data = 0; start = 0; len = 0; }
|
||||
sampleCount end() const { return start + len; }
|
||||
|
||||
void swap ( Buffer &other )
|
||||
{
|
||||
std::swap( data, other.data );
|
||||
std::swap( start, other.start );
|
||||
std::swap( len, other.len );
|
||||
}
|
||||
};
|
||||
|
||||
const WaveTrack *mPTrack;
|
||||
|
@ -680,7 +680,8 @@ bool Effect::HideUI()
|
||||
|
||||
bool Effect::CloseUI()
|
||||
{
|
||||
mUIParent->RemoveEventHandler(this);
|
||||
if (mUIParent)
|
||||
mUIParent->RemoveEventHandler(this);
|
||||
|
||||
mUIParent = NULL;
|
||||
mUIDialog = NULL;
|
||||
|
@ -194,7 +194,9 @@ bool EffectNormalize::Process()
|
||||
else
|
||||
msg = topMsg + _("Analyzing first track of stereo pair: ") + trackName;
|
||||
float offset, min, max;
|
||||
AnalyseTrack(track, msg, curTrackNum, offset, min, max);
|
||||
if (! ( bGoodResult =
|
||||
AnalyseTrack(track, msg, curTrackNum, offset, min, max) ) )
|
||||
break;
|
||||
if(!track->GetLinked() || mStereoInd) {
|
||||
// mono or 'stereo tracks independently'
|
||||
float extent = wxMax(fabs(max), fabs(min));
|
||||
@ -220,7 +222,9 @@ bool EffectNormalize::Process()
|
||||
track = (WaveTrack *) iter.Next(); // get the next one
|
||||
msg = topMsg + _("Analyzing second track of stereo pair: ") + trackName;
|
||||
float offset2, min2, max2;
|
||||
AnalyseTrack(track, msg, curTrackNum + 1, offset2, min2, max2);
|
||||
if ( ! ( bGoodResult =
|
||||
AnalyseTrack(track, msg, curTrackNum + 1, offset2, min2, max2) ) )
|
||||
break;
|
||||
float extent = wxMax(fabs(min), fabs(max));
|
||||
extent = wxMax(extent, fabs(min2));
|
||||
extent = wxMax(extent, fabs(max2));
|
||||
@ -325,7 +329,7 @@ bool EffectNormalize::TransferDataFromWindow()
|
||||
|
||||
// EffectNormalize implementation
|
||||
|
||||
void EffectNormalize::AnalyseTrack(const WaveTrack * track, const wxString &msg,
|
||||
bool EffectNormalize::AnalyseTrack(const WaveTrack * track, const wxString &msg,
|
||||
int curTrackNum,
|
||||
float &offset, float &min, float &max)
|
||||
{
|
||||
@ -334,7 +338,9 @@ void EffectNormalize::AnalyseTrack(const WaveTrack * track, const wxString &msg,
|
||||
// TODO: should we restrict the flags to just the relevant block files (for selections)
|
||||
while (track->GetODFlags()) {
|
||||
// update the gui
|
||||
mProgress->Update(0, wxT("Waiting for waveform to finish computing..."));
|
||||
if (ProgressResult::Cancelled == mProgress->Update(
|
||||
0, wxT("Waiting for waveform to finish computing...")) )
|
||||
return false;
|
||||
wxMilliSleep(100);
|
||||
}
|
||||
|
||||
@ -344,11 +350,13 @@ void EffectNormalize::AnalyseTrack(const WaveTrack * track, const wxString &msg,
|
||||
}
|
||||
|
||||
if(mDC) {
|
||||
AnalyseDC(track, msg, curTrackNum, offset);
|
||||
auto rc = AnalyseDC(track, msg, curTrackNum, offset);
|
||||
min += offset;
|
||||
max += offset;
|
||||
return rc;
|
||||
} else {
|
||||
offset = 0.0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ private:
|
||||
|
||||
bool ProcessOne(
|
||||
WaveTrack * t, const wxString &msg, int curTrackNum, float offset);
|
||||
void AnalyseTrack(const WaveTrack * track, const wxString &msg,
|
||||
bool AnalyseTrack(const WaveTrack * track, const wxString &msg,
|
||||
int curTrackNum,
|
||||
float &offset, float &min, float &max);
|
||||
void AnalyzeData(float *buffer, size_t len);
|
||||
|
@ -731,7 +731,7 @@ void LV2Effect::SetSampleRate(double rate)
|
||||
{
|
||||
LV2_Options_Option options[2]; // 2 for empty terminating option
|
||||
memset(&options, 0, sizeof(options));
|
||||
memcpy(&options, mSampleRateOption, sizeof(*mSampleRateOption));
|
||||
memcpy(&options, &mOptions[mSampleRateOption], sizeof(mOptions[0]));
|
||||
|
||||
if (mMaster)
|
||||
{
|
||||
@ -753,7 +753,7 @@ size_t LV2Effect::SetBlockSize(size_t maxBlockSize)
|
||||
{
|
||||
LV2_Options_Option options[2]; // 2 for empty terminating option
|
||||
memset(&options, 0, sizeof(options));
|
||||
memcpy(&options, mBlockSizeOption, sizeof(*mBlockSizeOption));
|
||||
memcpy(&options, &mOptions[mBlockSizeOption], sizeof(mOptions[0]));
|
||||
|
||||
if (mMaster)
|
||||
{
|
||||
@ -1342,7 +1342,7 @@ bool LV2Effect::SaveParameters(const wxString & group)
|
||||
return mHost->SetPrivateConfig(group, wxT("Parameters"), parms);
|
||||
}
|
||||
|
||||
LV2_Options_Option *LV2Effect::AddOption(const char *key, uint32_t size, const char *type, void *value)
|
||||
size_t LV2Effect::AddOption(const char *key, uint32_t size, const char *type, void *value)
|
||||
{
|
||||
int ndx = mNumOptions;
|
||||
|
||||
@ -1360,7 +1360,7 @@ LV2_Options_Option *LV2Effect::AddOption(const char *key, uint32_t size, const c
|
||||
mOptions[ndx].value = value;
|
||||
}
|
||||
|
||||
return &mOptions[ndx];
|
||||
return ndx;
|
||||
}
|
||||
|
||||
LV2_Feature *LV2Effect::AddFeature(const char *uri, void *data)
|
||||
|
@ -204,7 +204,7 @@ private:
|
||||
static int ui_resize(LV2UI_Feature_Handle handle, int width, int height);
|
||||
int UIResize(int width, int height);
|
||||
|
||||
LV2_Options_Option *AddOption(const char *key, uint32_t size, const char *type, void *value);
|
||||
size_t AddOption(const char *key, uint32_t size, const char *type, void *value);
|
||||
LV2_Feature *AddFeature(const char *uri, void *data);
|
||||
|
||||
bool BuildFancy();
|
||||
@ -295,8 +295,8 @@ private:
|
||||
LV2UI_Resize mUIResizeFeature;
|
||||
LV2_Extension_Data_Feature mExtDataFeature;
|
||||
|
||||
LV2_Options_Option *mBlockSizeOption;
|
||||
LV2_Options_Option *mSampleRateOption;
|
||||
size_t mBlockSizeOption;
|
||||
size_t mSampleRateOption;
|
||||
|
||||
LV2_Options_Interface *mOptionsInterface;
|
||||
LV2_Options_Option *mOptions;
|
||||
|
@ -942,7 +942,7 @@ bool NyquistEffect::ProcessOne()
|
||||
|
||||
float maxPeakLevel = 0.0; // Deprecated as of 2.1.3
|
||||
wxString clips, peakString, rmsString;
|
||||
for (int i = 0; i < mCurNumChannels; i++) {
|
||||
for (size_t i = 0; i < mCurNumChannels; i++) {
|
||||
auto ca = mCurTrack[i]->SortedClipArray();
|
||||
float maxPeak = 0.0;
|
||||
|
||||
@ -1019,7 +1019,7 @@ bool NyquistEffect::ProcessOne()
|
||||
nyx_set_audio_params(mCurTrack[0]->GetRate(), curLen);
|
||||
|
||||
nyx_set_input_audio(StaticGetCallback, (void *)this,
|
||||
mCurNumChannels,
|
||||
(int)mCurNumChannels,
|
||||
curLen, mCurTrack[0]->GetRate());
|
||||
}
|
||||
|
||||
@ -1200,7 +1200,7 @@ bool NyquistEffect::ProcessOne()
|
||||
}
|
||||
|
||||
int outChannels = nyx_get_audio_num_channels();
|
||||
if (outChannels > mCurNumChannels) {
|
||||
if (outChannels > (int)mCurNumChannels) {
|
||||
wxMessageBox(_("Nyquist returned too many audio channels.\n"),
|
||||
wxT("Nyquist"),
|
||||
wxOK | wxCENTRE, mUIParent);
|
||||
@ -1225,7 +1225,7 @@ bool NyquistEffect::ProcessOne()
|
||||
for (i = 0; i < outChannels; i++) {
|
||||
sampleFormat format = mCurTrack[i]->GetSampleFormat();
|
||||
|
||||
if (outChannels == mCurNumChannels) {
|
||||
if (outChannels == (int)mCurNumChannels) {
|
||||
rate = mCurTrack[i]->GetRate();
|
||||
}
|
||||
|
||||
@ -1261,7 +1261,7 @@ bool NyquistEffect::ProcessOne()
|
||||
for (i = 0; i < mCurNumChannels; i++) {
|
||||
WaveTrack *out;
|
||||
|
||||
if (outChannels == mCurNumChannels) {
|
||||
if (outChannels == (int)mCurNumChannels) {
|
||||
out = mOutputTrack[i].get();
|
||||
}
|
||||
else {
|
||||
|
@ -205,7 +205,7 @@ private:
|
||||
int mVersion;
|
||||
NyqControlArray mControls;
|
||||
|
||||
int mCurNumChannels; // See bug 1566
|
||||
unsigned mCurNumChannels;
|
||||
WaveTrack *mCurTrack[2];
|
||||
sampleCount mCurStart[2];
|
||||
sampleCount mCurLen;
|
||||
|
@ -933,7 +933,7 @@ ProgressResult ExportMultiple::ExportMultipleByTrack(bool byName,
|
||||
}
|
||||
|
||||
// Restore the selection states
|
||||
for (auto pTrack : mSelected)
|
||||
for (auto pTrack : selected)
|
||||
pTrack->SetSelected(true);
|
||||
|
||||
return ok ;
|
||||
|
@ -113,9 +113,6 @@ private:
|
||||
int mNumLabels;
|
||||
int mNumWaveTracks;
|
||||
|
||||
// PRL: This is never populated anywhere?
|
||||
std::vector<Track*> mSelected;
|
||||
|
||||
int mFilterIndex; /**< The index in the drop-down list of export
|
||||
formats (mFormat) of the selected export format.
|
||||
This list includes all possible
|
||||
|
@ -451,17 +451,16 @@ ProgressResult PCMImportFileHandle::Import(TrackFactory *trackFactory,
|
||||
if (maxBlock < 1)
|
||||
return ProgressResult::Failed;
|
||||
|
||||
SampleBuffer srcbuffer;
|
||||
SampleBuffer srcbuffer, buffer;
|
||||
wxASSERT(mInfo.channels >= 0);
|
||||
while (NULL == srcbuffer.Allocate(maxBlock * mInfo.channels, mFormat).ptr())
|
||||
while (NULL == srcbuffer.Allocate(maxBlock * mInfo.channels, mFormat).ptr() ||
|
||||
NULL == buffer.Allocate(maxBlock, mFormat).ptr())
|
||||
{
|
||||
maxBlock /= 2;
|
||||
if (maxBlock < 1)
|
||||
return ProgressResult::Failed;
|
||||
}
|
||||
|
||||
SampleBuffer buffer(maxBlock, mFormat);
|
||||
|
||||
decltype(fileTotalFrames) framescompleted = 0;
|
||||
|
||||
long block;
|
||||
|
@ -71,12 +71,9 @@ void ODComputeSummaryTask::DoSomeInternal()
|
||||
mBlockFilesMutex.Lock();
|
||||
for(size_t i=0; i < mWaveTracks.size() && mBlockFiles.size();i++)
|
||||
{
|
||||
const auto &bf = mBlockFiles[0];
|
||||
const auto bf = mBlockFiles[0].lock();
|
||||
|
||||
//first check to see if the ref count is at least 2. It should have one
|
||||
//from when we added it to this instance's mBlockFiles array, and one from
|
||||
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
|
||||
if(bf.use_count() >= 2)
|
||||
if(bf)
|
||||
{
|
||||
bf->DoWriteSummary();
|
||||
success = true;
|
||||
@ -85,6 +82,7 @@ void ODComputeSummaryTask::DoSomeInternal()
|
||||
}
|
||||
else
|
||||
{
|
||||
// The block file disappeared.
|
||||
//the waveform in the wavetrack now is shorter, so we need to update mMaxBlockFiles
|
||||
//because now there is less work to do.
|
||||
mMaxBlockFiles--;
|
||||
@ -164,7 +162,7 @@ void ODComputeSummaryTask::CalculatePercentComplete()
|
||||
///by default left to right, or frome the point the user has clicked.
|
||||
void ODComputeSummaryTask::Update()
|
||||
{
|
||||
std::vector< std::shared_ptr< ODPCMAliasBlockFile > > tempBlocks;
|
||||
std::vector< std::weak_ptr< ODPCMAliasBlockFile > > tempBlocks;
|
||||
|
||||
mWaveTrackMutex.Lock();
|
||||
|
||||
@ -207,10 +205,14 @@ void ODComputeSummaryTask::Update()
|
||||
));
|
||||
|
||||
//these will always be linear within a sequence-lets take advantage of this by keeping a cursor.
|
||||
while(insertCursor<(int)tempBlocks.size()&&
|
||||
tempBlocks[insertCursor]->GetStart() + tempBlocks[insertCursor]->GetClipOffset() <
|
||||
odpcmaFile->GetStart() + odpcmaFile->GetClipOffset())
|
||||
insertCursor++;
|
||||
{
|
||||
std::shared_ptr< ODPCMAliasBlockFile > ptr;
|
||||
while(insertCursor < (int)tempBlocks.size() &&
|
||||
(!(ptr = tempBlocks[insertCursor].lock()) ||
|
||||
ptr->GetStart() + ptr->GetClipOffset() <
|
||||
odpcmaFile->GetStart() + odpcmaFile->GetClipOffset()))
|
||||
insertCursor++;
|
||||
}
|
||||
|
||||
tempBlocks.insert(tempBlocks.begin() + insertCursor++, odpcmaFile);
|
||||
}
|
||||
@ -232,7 +234,7 @@ void ODComputeSummaryTask::Update()
|
||||
|
||||
///Computes the summary calculation queue order of the blockfiles
|
||||
void ODComputeSummaryTask::OrderBlockFiles
|
||||
(std::vector< std::shared_ptr< ODPCMAliasBlockFile > > &unorderedBlocks)
|
||||
(std::vector< std::weak_ptr< ODPCMAliasBlockFile > > &unorderedBlocks)
|
||||
{
|
||||
mBlockFiles.clear();
|
||||
//Order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
|
||||
@ -242,27 +244,29 @@ void ODComputeSummaryTask::OrderBlockFiles
|
||||
|
||||
//find the startpoint
|
||||
auto processStartSample = GetDemandSample();
|
||||
for(int i= ((int)unorderedBlocks.size())-1;i>= 0;i--)
|
||||
std::shared_ptr< ODPCMAliasBlockFile > firstBlock;
|
||||
for(auto i = unorderedBlocks.size(); i--;)
|
||||
{
|
||||
//check to see if the refcount is at least two before we add it to the list.
|
||||
//There should be one Ref() from the one added by this ODTask, and one from the track.
|
||||
//If there isn't, then the block was deleted for some reason and we should ignore it.
|
||||
if(unorderedBlocks[i].use_count() >= 2)
|
||||
auto ptr = unorderedBlocks[i].lock();
|
||||
if(ptr)
|
||||
{
|
||||
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
|
||||
//and add ones that are closer.
|
||||
if(mBlockFiles.size() &&
|
||||
unorderedBlocks[i]->GetGlobalEnd() >= processStartSample &&
|
||||
( mBlockFiles[0]->GetGlobalEnd() < processStartSample ||
|
||||
unorderedBlocks[i]->GetGlobalStart() <= mBlockFiles[0]->GetGlobalStart())
|
||||
if(firstBlock &&
|
||||
ptr->GetGlobalEnd() >= processStartSample &&
|
||||
( firstBlock->GetGlobalEnd() < processStartSample ||
|
||||
ptr->GetGlobalStart() <= firstBlock->GetGlobalStart())
|
||||
)
|
||||
{
|
||||
//insert at the front of the list if we get blockfiles that are after the demand sample
|
||||
mBlockFiles.insert(mBlockFiles.begin()+0,unorderedBlocks[i]);
|
||||
firstBlock = ptr;
|
||||
mBlockFiles.insert(mBlockFiles.begin(), unorderedBlocks[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//otherwise no priority
|
||||
if ( !firstBlock )
|
||||
firstBlock = ptr;
|
||||
mBlockFiles.push_back(unorderedBlocks[i]);
|
||||
}
|
||||
if(mMaxBlockFiles< (int) mBlockFiles.size())
|
||||
@ -270,7 +274,8 @@ void ODComputeSummaryTask::OrderBlockFiles
|
||||
}
|
||||
else
|
||||
{
|
||||
//Otherwise, let it be deleted and forget about it.
|
||||
// The block file disappeared.
|
||||
// Let it be deleted and forget about it.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ protected:
|
||||
|
||||
///Orders the input as either On-Demand or default layered order.
|
||||
void OrderBlockFiles
|
||||
(std::vector< std::shared_ptr< ODPCMAliasBlockFile > > &unorderedBlocks);
|
||||
(std::vector< std::weak_ptr< ODPCMAliasBlockFile > > &unorderedBlocks);
|
||||
|
||||
///tells us whether or not Update has been run at least once.
|
||||
void MarkUpdateRan();
|
||||
@ -73,7 +73,7 @@ protected:
|
||||
|
||||
//mBlockFiles is touched on several threads- the OD terminate thread, and the task thread, so we need to mutex it.
|
||||
ODLock mBlockFilesMutex;
|
||||
std::vector< std::shared_ptr< ODPCMAliasBlockFile > > mBlockFiles;
|
||||
std::vector< std::weak_ptr< ODPCMAliasBlockFile > > mBlockFiles;
|
||||
int mMaxBlockFiles;
|
||||
ODLock mHasUpdateRanMutex;
|
||||
bool mHasUpdateRan;
|
||||
|
@ -48,16 +48,13 @@ void ODDecodeTask::DoSomeInternal()
|
||||
|
||||
for(size_t i=0; i < mWaveTracks.size() && mBlockFiles.size();i++)
|
||||
{
|
||||
const auto &bf = mBlockFiles[0];
|
||||
const auto bf = mBlockFiles[0].lock();
|
||||
|
||||
int ret = 1;
|
||||
|
||||
//first check to see if the ref count is at least 2. It should have one
|
||||
//from when we added it to this instance's mBlockFiles array, and one from
|
||||
//the Wavetrack/sequence. If it doesn't it has been deleted and we should forget it.
|
||||
if(bf.use_count()>=2)
|
||||
if(bf)
|
||||
{
|
||||
//OD TODO: somehow pass the bf a reference to the decoder that manages it's file.
|
||||
//OD TODO: somehow pass the bf a reference to the decoder that manages its file.
|
||||
//we need to ensure that the filename won't change or be moved. We do this by calling LockRead(),
|
||||
//which the dirmanager::EnsureSafeFilename also does.
|
||||
bf->LockRead();
|
||||
@ -77,6 +74,7 @@ void ODDecodeTask::DoSomeInternal()
|
||||
}
|
||||
else
|
||||
{
|
||||
// The block file disappeared.
|
||||
//the waveform in the wavetrack now is shorter, so we need to update mMaxBlockFiles
|
||||
//because now there is less work to do.
|
||||
mMaxBlockFiles--;
|
||||
@ -123,7 +121,7 @@ bool ODDecodeTask::SeekingAllowed()
|
||||
///by default creates the order of the wavetrack to load.
|
||||
void ODDecodeTask::Update()
|
||||
{
|
||||
std::vector< std::shared_ptr< ODDecodeBlockFile > > tempBlocks;
|
||||
std::vector< std::weak_ptr< ODDecodeBlockFile > > tempBlocks;
|
||||
|
||||
mWaveTrackMutex.Lock();
|
||||
|
||||
@ -162,12 +160,16 @@ void ODDecodeTask::Update()
|
||||
));
|
||||
|
||||
//these will always be linear within a sequence-lets take advantage of this by keeping a cursor.
|
||||
while(insertCursor<(int)tempBlocks.size()&&
|
||||
tempBlocks[insertCursor]->GetStart() + tempBlocks[insertCursor]->GetClipOffset() <
|
||||
oddbFile->GetStart() + oddbFile->GetClipOffset())
|
||||
insertCursor++;
|
||||
{
|
||||
std::shared_ptr< ODDecodeBlockFile > ptr;
|
||||
while(insertCursor < (int)tempBlocks.size() &&
|
||||
(!(ptr = tempBlocks[insertCursor].lock()) ||
|
||||
ptr->GetStart() + ptr->GetClipOffset() <
|
||||
oddbFile->GetStart() + oddbFile->GetClipOffset()))
|
||||
insertCursor++;
|
||||
}
|
||||
|
||||
tempBlocks.insert(tempBlocks.begin()+insertCursor++, oddbFile);
|
||||
tempBlocks.insert(tempBlocks.begin() + insertCursor++, oddbFile);
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +187,7 @@ void ODDecodeTask::Update()
|
||||
|
||||
///Orders the input as either On-Demand or default layered order.
|
||||
void ODDecodeTask::OrderBlockFiles
|
||||
(std::vector< std::shared_ptr< ODDecodeBlockFile > > &unorderedBlocks)
|
||||
(std::vector< std::weak_ptr< ODDecodeBlockFile > > &unorderedBlocks)
|
||||
{
|
||||
mBlockFiles.clear();
|
||||
//TODO:order the blockfiles into our queue in a fancy convenient way. (this could be user-prefs)
|
||||
@ -194,28 +196,30 @@ void ODDecodeTask::OrderBlockFiles
|
||||
|
||||
//find the startpoint
|
||||
auto processStartSample = GetDemandSample();
|
||||
for(int i= ((int)unorderedBlocks.size())-1;i>= 0;i--)
|
||||
std::shared_ptr< ODDecodeBlockFile > firstBlock;
|
||||
for(auto i = unorderedBlocks.size(); i--; )
|
||||
{
|
||||
//check to see if the refcount is at least two before we add it to the list.
|
||||
//There should be one Ref() from the one added by this ODTask, and one from the track.
|
||||
//If there isn't, then the block was deleted for some reason and we should ignore it.
|
||||
if(unorderedBlocks[i].use_count() >= 2)
|
||||
auto ptr = unorderedBlocks[i].lock();
|
||||
if(ptr)
|
||||
{
|
||||
//test if the blockfiles are near the task cursor. we use the last mBlockFiles[0] as our point of reference
|
||||
//and add ones that are closer.
|
||||
//since the order is linear right to left, this will add blocks so that the ones on the right side of the target
|
||||
//are processed first, with the ones closer being processed earlier. Then the ones on the left side get processed.
|
||||
if(mBlockFiles.size() &&
|
||||
unorderedBlocks[i]->GetGlobalEnd() >= processStartSample &&
|
||||
( mBlockFiles[0]->GetGlobalEnd() < processStartSample ||
|
||||
unorderedBlocks[i]->GetGlobalStart() <= mBlockFiles[0]->GetGlobalStart()) )
|
||||
ptr->GetGlobalEnd() >= processStartSample &&
|
||||
( firstBlock->GetGlobalEnd() < processStartSample ||
|
||||
ptr->GetGlobalStart() <= firstBlock->GetGlobalStart()) )
|
||||
{
|
||||
//insert at the front of the list if we get blockfiles that are after the demand sample
|
||||
mBlockFiles.insert(mBlockFiles.begin()+0,unorderedBlocks[i]);
|
||||
firstBlock = ptr;
|
||||
mBlockFiles.insert(mBlockFiles.begin(), unorderedBlocks[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
//otherwise no priority
|
||||
if ( !firstBlock )
|
||||
firstBlock = ptr;
|
||||
mBlockFiles.push_back(unorderedBlocks[i]);
|
||||
}
|
||||
if(mMaxBlockFiles< (int) mBlockFiles.size())
|
||||
@ -223,6 +227,7 @@ void ODDecodeTask::OrderBlockFiles
|
||||
}
|
||||
else
|
||||
{
|
||||
// The block file disappeared.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,10 +86,10 @@ protected:
|
||||
|
||||
///Orders the input as either On-Demand or default layered order.
|
||||
void OrderBlockFiles
|
||||
(std::vector< std::shared_ptr< ODDecodeBlockFile > > &unorderedBlocks);
|
||||
(std::vector< std::weak_ptr< ODDecodeBlockFile > > &unorderedBlocks);
|
||||
|
||||
|
||||
std::vector<std::shared_ptr<ODDecodeBlockFile>> mBlockFiles;
|
||||
std::vector<std::weak_ptr<ODDecodeBlockFile>> mBlockFiles;
|
||||
std::vector<movable_ptr<ODFileDecoder>> mDecoders;
|
||||
|
||||
int mMaxBlockFiles;
|
||||
|
@ -886,7 +886,16 @@ void ControlToolBar::OnRecord(wxCommandEvent &evt)
|
||||
#ifdef EXPERIMENTAL_DA
|
||||
shifted = !shifted;
|
||||
#endif
|
||||
if(it.First() == NULL)
|
||||
bool hasWave = false;
|
||||
for (auto t = it.First(); t; t = it.Next()) {
|
||||
if (t->GetKind() == Track::Wave) {
|
||||
hasWave = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!hasWave)
|
||||
// Treat append-record like record, when there was no given wave track
|
||||
// to append onto.
|
||||
shifted = false;
|
||||
|
||||
double t0 = p->GetSel0();
|
||||
|
Loading…
x
Reference in New Issue
Block a user