mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
WaveTrack.cpp does not depend on ODManager.cpp ...
... Breaking up an s.c.c. of 6 into 3 components: ODManager, ODTask, ODWaveTrackTaskQueue UndoManager WaveClip, WaveTrack Rewrite the OD tasks and queues to hold weak pointers to tracks, so the track destructor need not notify them.
This commit is contained in:
parent
71250b1dc3
commit
86320838de
@ -210,7 +210,7 @@ void ProjectFileManager::EnqueueODTasks()
|
||||
//add the track to the already created tasks that correspond to the od flags in the wavetrack.
|
||||
for(unsigned int i=0;i<newTasks.size();i++) {
|
||||
if(newTasks[i]->GetODType() & odFlags)
|
||||
newTasks[i]->AddWaveTrack(wt);
|
||||
newTasks[i]->AddWaveTrack(wt->SharedPointer< WaveTrack >());
|
||||
}
|
||||
|
||||
//create whatever NEW tasks we need to.
|
||||
@ -236,7 +236,7 @@ void ProjectFileManager::EnqueueODTasks()
|
||||
}
|
||||
if(newTask)
|
||||
{
|
||||
newTask->AddWaveTrack(wt);
|
||||
newTask->AddWaveTrack(wt->SharedPointer< WaveTrack >());
|
||||
newTasks.push_back(std::move(newTask));
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ Paul Licameli split from ProjectManager.cpp
|
||||
#include "Track.h"
|
||||
#include "UndoManager.h"
|
||||
#include "ViewInfo.h"
|
||||
#include "WaveTrack.h"
|
||||
#include "ondemand/ODComputeSummaryTask.h"
|
||||
#include "ondemand/ODManager.h"
|
||||
|
||||
@ -167,7 +168,7 @@ void ProjectHistory::PopState(const UndoState &state)
|
||||
// PRL: Is it correct to add all tracks to one task, even if they
|
||||
// are not partnered channels? Rather than
|
||||
// make one task for each?
|
||||
computeTask->AddWaveTrack(wt);
|
||||
computeTask->AddWaveTrack(wt->SharedPointer< WaveTrack >());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -53,8 +53,6 @@ Track classes.
|
||||
|
||||
#include "Prefs.h"
|
||||
|
||||
#include "ondemand/ODManager.h"
|
||||
|
||||
#include "effects/TimeWarper.h"
|
||||
#include "prefs/SpectrogramSettings.h"
|
||||
#include "prefs/TracksPrefs.h"
|
||||
@ -213,10 +211,6 @@ void WaveTrack::Merge(const Track &orig)
|
||||
|
||||
WaveTrack::~WaveTrack()
|
||||
{
|
||||
//Let the ODManager know this WaveTrack is disappearing.
|
||||
//Deschedules tasks associated with this track.
|
||||
if(ODManager::IsInstanceCreated())
|
||||
ODManager::Instance()->RemoveWaveTrack(this);
|
||||
}
|
||||
|
||||
double WaveTrack::GetOffset() const
|
||||
|
@ -2256,7 +2256,7 @@ void Effect::ReplaceProcessedTracks(const bool bGoodResult)
|
||||
// Swap the wavecache track the ondemand task uses, since now the NEW
|
||||
// one will be kept in the project
|
||||
if (ODManager::IsInstanceCreated()) {
|
||||
ODManager::Instance()->ReplaceWaveTrack( t, o.get() );
|
||||
ODManager::Instance()->ReplaceWaveTrack( t, o );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -588,7 +588,7 @@ ProgressResult FFmpegImportFileHandle::Import(TrackFactory *trackFactory,
|
||||
|
||||
//for each wavetrack within the stream add coded blockfiles
|
||||
for (int c = 0; c < sc->m_stream->codec->channels; c++) {
|
||||
WaveTrack *t = stream[c].get();
|
||||
auto t = stream[c];
|
||||
odTask->AddWaveTrack(t);
|
||||
|
||||
auto maxBlockSize = t->GetMaxBlockSize();
|
||||
|
@ -505,7 +505,7 @@ ProgressResult FLACImportFileHandle::Import(TrackFactory *trackFactory,
|
||||
bool moreThanStereo = mNumChannels>2;
|
||||
for (const auto &channel : mChannels)
|
||||
{
|
||||
mDecoderTask->AddWaveTrack(channel.get());
|
||||
mDecoderTask->AddWaveTrack(channel);
|
||||
if(moreThanStereo)
|
||||
{
|
||||
//if we have 3 more channels, they get imported on seperate tracks, so we add individual tasks for each.
|
||||
|
@ -445,7 +445,7 @@ ProgressResult PCMImportFileHandle::Import(TrackFactory *trackFactory,
|
||||
bool moreThanStereo = mInfo.channels>2;
|
||||
for (const auto &channel : channels)
|
||||
{
|
||||
computeTask->AddWaveTrack(channel.get());
|
||||
computeTask->AddWaveTrack(channel);
|
||||
if(moreThanStereo)
|
||||
{
|
||||
//if we have 3 more channels, they get imported on seperate tracks, so we add individual tasks for each.
|
||||
|
@ -116,8 +116,9 @@ void ODComputeSummaryTask::DoSomeInternal()
|
||||
mWaveTrackMutex.Lock();
|
||||
for(size_t i=0;i<mWaveTracks.size();i++)
|
||||
{
|
||||
if(success && mWaveTracks[i])
|
||||
mWaveTracks[i]->AddInvalidRegion(blockStartSample,blockEndSample);
|
||||
auto waveTrack = mWaveTracks[i].lock();
|
||||
if(success && waveTrack)
|
||||
waveTrack->AddInvalidRegion(blockStartSample,blockEndSample);
|
||||
}
|
||||
mWaveTrackMutex.Unlock();
|
||||
}
|
||||
@ -182,13 +183,14 @@ void ODComputeSummaryTask::Update()
|
||||
|
||||
for(size_t j=0;j<mWaveTracks.size();j++)
|
||||
{
|
||||
if(mWaveTracks[j])
|
||||
auto waveTrack = mWaveTracks[j].lock();
|
||||
if(waveTrack)
|
||||
{
|
||||
BlockArray *blocks;
|
||||
Sequence *seq;
|
||||
|
||||
//gather all the blockfiles that we should process in the wavetrack.
|
||||
for (const auto &clip : mWaveTracks[j]->GetAllClips()) {
|
||||
for (const auto &clip : waveTrack->GetAllClips()) {
|
||||
seq = clip->GetSequence();
|
||||
//This lock may be way too big since the whole file is one sequence.
|
||||
//TODO: test for large files and find a way to break it down.
|
||||
|
@ -102,8 +102,9 @@ void ODDecodeTask::DoSomeInternal()
|
||||
mWaveTrackMutex.Lock();
|
||||
for(size_t i=0;i<mWaveTracks.size();i++)
|
||||
{
|
||||
if(mWaveTracks[i])
|
||||
mWaveTracks[i]->AddInvalidRegion(blockStartSample,blockEndSample);
|
||||
auto waveTrack = mWaveTracks[i].lock();
|
||||
if(waveTrack)
|
||||
waveTrack->AddInvalidRegion(blockStartSample,blockEndSample);
|
||||
}
|
||||
mWaveTrackMutex.Unlock();
|
||||
}
|
||||
@ -138,13 +139,14 @@ void ODDecodeTask::Update()
|
||||
|
||||
for(size_t j=0;j<mWaveTracks.size();j++)
|
||||
{
|
||||
if(mWaveTracks[j])
|
||||
auto waveTrack = mWaveTracks[j].lock();
|
||||
if(waveTrack)
|
||||
{
|
||||
BlockArray *blocks;
|
||||
Sequence *seq;
|
||||
|
||||
//gather all the blockfiles that we should process in the wavetrack.
|
||||
for (const auto &clip : mWaveTracks[j]->GetAllClips()) {
|
||||
for (const auto &clip : waveTrack->GetAllClips()) {
|
||||
seq = clip->GetSequence();
|
||||
//TODO:this lock is way to big since the whole file is one sequence. find a way to break it down.
|
||||
seq->LockDeleteUpdateMutex();
|
||||
|
@ -257,7 +257,7 @@ void ODManager::AddNewTask(std::unique_ptr<ODTask> &&mtask, bool lockMutex)
|
||||
{
|
||||
//search for a task containing the lead track. wavetrack removal is threadsafe and bound to the mQueuesMutex
|
||||
//note that GetWaveTrack is not threadsafe, but we are assuming task is not running on a different thread yet.
|
||||
if(mQueues[i]->ContainsWaveTrack(task->GetWaveTrack(0)))
|
||||
if(mQueues[i]->ContainsWaveTrack(task->GetWaveTrack(0).get()))
|
||||
queue = mQueues[i].get();
|
||||
}
|
||||
|
||||
@ -472,20 +472,9 @@ void ODManager::Quit()
|
||||
}
|
||||
}
|
||||
|
||||
///removes a wavetrack and notifies its associated tasks to stop using its reference.
|
||||
void ODManager::RemoveWaveTrack(WaveTrack* track)
|
||||
{
|
||||
mQueuesMutex.Lock();
|
||||
for(unsigned int i=0;i<mQueues.size();i++)
|
||||
{
|
||||
if(mQueues[i]->ContainsWaveTrack(track))
|
||||
mQueues[i]->RemoveWaveTrack(track);
|
||||
}
|
||||
mQueuesMutex.Unlock();
|
||||
}
|
||||
|
||||
///replace the wavetrack whose wavecache the gui watches for updates
|
||||
void ODManager::ReplaceWaveTrack(Track *oldTrack, Track *newTrack)
|
||||
void ODManager::ReplaceWaveTrack(Track *oldTrack,
|
||||
const std::shared_ptr<Track> &newTrack)
|
||||
{
|
||||
mQueuesMutex.Lock();
|
||||
for(unsigned int i=0;i<mQueues.size();i++)
|
||||
@ -496,13 +485,14 @@ void ODManager::ReplaceWaveTrack(Track *oldTrack, Track *newTrack)
|
||||
}
|
||||
|
||||
///if it shares a queue/task, creates a NEW queue/task for the track, and removes it from any previously existing tasks.
|
||||
void ODManager::MakeWaveTrackIndependent(WaveTrack* track)
|
||||
void ODManager::MakeWaveTrackIndependent(
|
||||
const std::shared_ptr< WaveTrack > &track)
|
||||
{
|
||||
ODWaveTrackTaskQueue* owner=NULL;
|
||||
mQueuesMutex.Lock();
|
||||
for(unsigned int i=0;i<mQueues.size();i++)
|
||||
{
|
||||
if(mQueues[i]->ContainsWaveTrack(track))
|
||||
if(mQueues[i]->ContainsWaveTrack(track.get()))
|
||||
{
|
||||
owner = mQueues[i].get();
|
||||
break;
|
||||
@ -519,7 +509,10 @@ void ODManager::MakeWaveTrackIndependent(WaveTrack* track)
|
||||
///better design in the future.
|
||||
///@return returns success. Some ODTask conditions require that the tasks finish before merging.
|
||||
///e.g. they have different effects being processed at the same time.
|
||||
bool ODManager::MakeWaveTrackDependent(WaveTrack* dependentTrack,WaveTrack* masterTrack)
|
||||
bool ODManager::MakeWaveTrackDependent(
|
||||
const std::shared_ptr< WaveTrack > &dependentTrack,
|
||||
WaveTrack* masterTrack
|
||||
)
|
||||
{
|
||||
//First, check to see if the task lists are mergeable. If so, we can simply add this track to the other task and queue,
|
||||
//then DELETE this one.
|
||||
@ -535,7 +528,7 @@ bool ODManager::MakeWaveTrackDependent(WaveTrack* dependentTrack,WaveTrack* mast
|
||||
{
|
||||
masterQueue = mQueues[i].get();
|
||||
}
|
||||
else if(mQueues[i]->ContainsWaveTrack(dependentTrack))
|
||||
else if(mQueues[i]->ContainsWaveTrack(dependentTrack.get()))
|
||||
{
|
||||
dependentQueue = mQueues[i].get();
|
||||
dependentIndex = i;
|
||||
|
@ -67,19 +67,20 @@ class ODManager final
|
||||
///Wakes the queue loop up by signalling its condition variable.
|
||||
void SignalTaskQueueLoop();
|
||||
|
||||
///removes a wavetrack and notifies its associated tasks to stop using its reference.
|
||||
void RemoveWaveTrack(WaveTrack* track);
|
||||
|
||||
///if it shares a queue/task, creates a NEW queue/task for the track, and removes it from any previously existing tasks.
|
||||
void MakeWaveTrackIndependent(WaveTrack* track);
|
||||
void MakeWaveTrackIndependent( const std::shared_ptr< WaveTrack > &track);
|
||||
|
||||
///attach the track in question to another, already existing track's queues and tasks. Remove the task/tracks.
|
||||
///Returns success if it was possible.. Some ODTask conditions make it impossible until the Tasks finish.
|
||||
bool MakeWaveTrackDependent(WaveTrack* dependentTrack,WaveTrack* masterTrack);
|
||||
bool MakeWaveTrackDependent(
|
||||
const std::shared_ptr< WaveTrack > &dependentTrack,
|
||||
WaveTrack* masterTrack
|
||||
);
|
||||
|
||||
///if oldTrack is being watched,
|
||||
///replace the wavetrack whose wavecache the gui watches for updates
|
||||
void ReplaceWaveTrack(Track *oldTrack, Track *newTrack);
|
||||
void ReplaceWaveTrack(Track *oldTrack,
|
||||
const std::shared_ptr< Track > &newTrack);
|
||||
|
||||
///Adds a task to the running queue. Threas-safe.
|
||||
void AddTask(ODTask* task);
|
||||
|
@ -182,7 +182,7 @@ bool ODTask::IsTaskAssociatedWithProject(AudacityProject* proj)
|
||||
mWaveTrackMutex.Lock();
|
||||
for(int i=0;i<(int)mWaveTracks.size();i++)
|
||||
{
|
||||
if(mWaveTracks[i]==tr)
|
||||
if ( mWaveTracks[i].lock().get() == tr )
|
||||
{
|
||||
//if we find one, then the project is associated with us;return true
|
||||
mWaveTrackMutex.Unlock();
|
||||
@ -252,19 +252,19 @@ bool ODTask::IsComplete()
|
||||
}
|
||||
|
||||
|
||||
WaveTrack* ODTask::GetWaveTrack(int i)
|
||||
std::shared_ptr< WaveTrack > ODTask::GetWaveTrack(int i)
|
||||
{
|
||||
WaveTrack* track = NULL;
|
||||
std::shared_ptr< WaveTrack > track;
|
||||
mWaveTrackMutex.Lock();
|
||||
if(i<(int)mWaveTracks.size())
|
||||
track = mWaveTracks[i];
|
||||
track = mWaveTracks[i].lock();
|
||||
mWaveTrackMutex.Unlock();
|
||||
return track;
|
||||
}
|
||||
|
||||
///Sets the wavetrack that will be analyzed for ODPCMAliasBlockFiles that will
|
||||
///have their summaries computed and written to disk.
|
||||
void ODTask::AddWaveTrack(WaveTrack* track)
|
||||
void ODTask::AddWaveTrack( const std::shared_ptr< WaveTrack > &track)
|
||||
{
|
||||
mWaveTracks.push_back(track);
|
||||
}
|
||||
@ -321,7 +321,7 @@ void ODTask::DemandTrackUpdate(WaveTrack* track, double seconds)
|
||||
mWaveTrackMutex.Lock();
|
||||
for(size_t i=0;i<mWaveTracks.size();i++)
|
||||
{
|
||||
if(track == mWaveTracks[i])
|
||||
if ( track == mWaveTracks[i].lock().get() )
|
||||
{
|
||||
auto newDemandSample = (sampleCount)(seconds * track->GetRate());
|
||||
demandSampleChanged = newDemandSample != GetDemandSample();
|
||||
@ -342,21 +342,22 @@ void ODTask::StopUsingWaveTrack(WaveTrack* track)
|
||||
mWaveTrackMutex.Lock();
|
||||
for(size_t i=0;i<mWaveTracks.size();i++)
|
||||
{
|
||||
if(mWaveTracks[i] == track)
|
||||
mWaveTracks[i]=NULL;
|
||||
if(mWaveTracks[i].lock().get() == track)
|
||||
mWaveTracks[i].reset();
|
||||
}
|
||||
mWaveTrackMutex.Unlock();
|
||||
}
|
||||
|
||||
///Replaces all instances to a wavetrack with a NEW one, effectively transferring the task.
|
||||
void ODTask::ReplaceWaveTrack(Track *oldTrack, Track *newTrack)
|
||||
void ODTask::ReplaceWaveTrack(Track *oldTrack,
|
||||
const std::shared_ptr< Track > &newTrack)
|
||||
{
|
||||
mWaveTrackMutex.Lock();
|
||||
for(size_t i=0;i<mWaveTracks.size();i++)
|
||||
{
|
||||
if(oldTrack == mWaveTracks[i])
|
||||
if(oldTrack == mWaveTracks[i].lock().get())
|
||||
{
|
||||
mWaveTracks[i] = static_cast<WaveTrack*>( newTrack );
|
||||
mWaveTracks[i] = std::static_pointer_cast<WaveTrack>( newTrack );
|
||||
}
|
||||
}
|
||||
mWaveTrackMutex.Unlock();
|
||||
|
@ -84,12 +84,13 @@ class ODTask /* not final */
|
||||
|
||||
///Replaces all instances to a wavetrack with a NEW one, effectively transferring the task.
|
||||
///ODTask has no wavetrack, so it does nothing. But subclasses that do should override this.
|
||||
virtual void ReplaceWaveTrack(Track *oldTrack, Track *newTrack);
|
||||
virtual void ReplaceWaveTrack(Track *oldTrack,
|
||||
const std::shared_ptr< Track > &newTrack);
|
||||
|
||||
///Adds a WaveTrack to do the task for
|
||||
void AddWaveTrack(WaveTrack* track);
|
||||
void AddWaveTrack( const std::shared_ptr< WaveTrack > &track);
|
||||
virtual int GetNumWaveTracks();
|
||||
virtual WaveTrack* GetWaveTrack(int i);
|
||||
virtual std::shared_ptr< WaveTrack > GetWaveTrack(int i);
|
||||
|
||||
///changes the tasks associated with this Waveform to process the task from a different point in the track
|
||||
virtual void DemandTrackUpdate(WaveTrack* track, double seconds);
|
||||
@ -156,7 +157,7 @@ class ODTask /* not final */
|
||||
//for a function not a member var.
|
||||
ODLock mBlockUntilTerminateMutex;
|
||||
|
||||
std::vector<WaveTrack*> mWaveTracks;
|
||||
std::vector< std::weak_ptr< WaveTrack > > mWaveTracks;
|
||||
ODLock mWaveTrackMutex;
|
||||
|
||||
sampleCount mDemandSample;
|
||||
|
@ -64,7 +64,8 @@ bool ODWaveTrackTaskQueue::CanMergeWith(ODWaveTrackTaskQueue* otherQueue)
|
||||
/// sets the NeedODUpdateFlag since we don't want the head task to finish without haven't dealt with the depednent
|
||||
///
|
||||
///@param track the track to bring into the tasks AND tracklist for this queue
|
||||
void ODWaveTrackTaskQueue::MergeWaveTrack(WaveTrack* track)
|
||||
void ODWaveTrackTaskQueue::MergeWaveTrack(
|
||||
const std::shared_ptr< WaveTrack > &track)
|
||||
{
|
||||
AddWaveTrack(track);
|
||||
mTasksMutex.Lock();
|
||||
@ -83,7 +84,7 @@ bool ODWaveTrackTaskQueue::ContainsWaveTrack(const WaveTrack* track)
|
||||
mTracksMutex.Lock();
|
||||
for(unsigned int i=0;i<mTracks.size();i++)
|
||||
{
|
||||
if(mTracks[i]==track)
|
||||
if ( mTracks[i].lock().get() == track )
|
||||
{
|
||||
mTracksMutex.Unlock();
|
||||
return true;
|
||||
@ -93,7 +94,8 @@ bool ODWaveTrackTaskQueue::ContainsWaveTrack(const WaveTrack* track)
|
||||
return false;
|
||||
}
|
||||
///Adds a track to the associated list.
|
||||
void ODWaveTrackTaskQueue::AddWaveTrack(WaveTrack* track)
|
||||
void ODWaveTrackTaskQueue::AddWaveTrack(
|
||||
const std::shared_ptr< WaveTrack > &track)
|
||||
{
|
||||
|
||||
mTracksMutex.Lock();
|
||||
@ -117,8 +119,7 @@ void ODWaveTrackTaskQueue::AddTask(std::unique_ptr<ODTask> &&mtask)
|
||||
{
|
||||
//task->GetWaveTrack(i) may return NULL, but we handle it by checking before using.
|
||||
//The other worry that the WaveTrack returned and was deleted in the meantime is also
|
||||
//handled since mQueuesMutex is locked one up in the stack from here,
|
||||
//and WaveTrack deletion is bound to that.
|
||||
//handled by keeping standard weak pointers to tracks, which give thread safety.
|
||||
mTracks.push_back(task->GetWaveTrack(i));
|
||||
}
|
||||
|
||||
@ -126,32 +127,15 @@ void ODWaveTrackTaskQueue::AddTask(std::unique_ptr<ODTask> &&mtask)
|
||||
|
||||
}
|
||||
|
||||
///Removes a track from the list. Also notifies mTasks to stop using references
|
||||
///to the instance in a thread-safe manner (may block)
|
||||
void ODWaveTrackTaskQueue::RemoveWaveTrack(WaveTrack* track)
|
||||
{
|
||||
if(track)
|
||||
{
|
||||
|
||||
mTasksMutex.Lock();
|
||||
for(unsigned int i=0;i<mTasks.size();i++)
|
||||
mTasks[i]->StopUsingWaveTrack(track);
|
||||
mTasksMutex.Unlock();
|
||||
|
||||
mTracksMutex.Lock();
|
||||
for(unsigned int i=0;i<mTracks.size();i++)
|
||||
if(mTracks[i]==track)
|
||||
mTracks.erase(mTracks.begin()+i--);//decrement i after the removal.
|
||||
|
||||
mTracksMutex.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//if the wavetrack is in this queue, and is not the only wavetrack, clones the tasks and schedules it.
|
||||
void ODWaveTrackTaskQueue::MakeWaveTrackIndependent(WaveTrack* track)
|
||||
void ODWaveTrackTaskQueue::MakeWaveTrackIndependent(
|
||||
const std::shared_ptr< WaveTrack > &track)
|
||||
{
|
||||
|
||||
// First remove expired weak pointers
|
||||
Compress();
|
||||
|
||||
mTracksMutex.Lock();
|
||||
|
||||
if(mTracks.size()<2)
|
||||
{
|
||||
//if there is only one track, it is already independent.
|
||||
@ -161,17 +145,16 @@ void ODWaveTrackTaskQueue::MakeWaveTrackIndependent(WaveTrack* track)
|
||||
|
||||
for(unsigned int i=0;i<mTracks.size();i++)
|
||||
{
|
||||
if(mTracks[i]==track)
|
||||
if ( mTracks[i].lock() == track )
|
||||
{
|
||||
mTracksMutex.Unlock();//release the lock, since RemoveWaveTrack is a public threadsafe method.
|
||||
RemoveWaveTrack(mTracks[i]);
|
||||
mTracks[i].reset();
|
||||
|
||||
//clone the items in order and add them to the ODManager.
|
||||
mTasksMutex.Lock();
|
||||
for(unsigned int j=0;j<mTasks.size();j++)
|
||||
{
|
||||
auto task = mTasks[j]->Clone();
|
||||
task->AddWaveTrack(track);
|
||||
mTasks[j]->StopUsingWaveTrack( track.get() );
|
||||
//AddNewTask requires us to relinquish this lock. However, it is safe because ODManager::MakeWaveTrackIndependent
|
||||
//has already locked the m_queuesMutex.
|
||||
mTasksMutex.Unlock();
|
||||
@ -181,7 +164,6 @@ void ODWaveTrackTaskQueue::MakeWaveTrackIndependent(WaveTrack* track)
|
||||
mTasksMutex.Lock();
|
||||
}
|
||||
mTasksMutex.Unlock();
|
||||
mTracksMutex.Lock();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -207,7 +189,8 @@ void ODWaveTrackTaskQueue::DemandTrackUpdate(WaveTrack* track, double seconds)
|
||||
|
||||
|
||||
//Replaces all instances of a wavetracck with a NEW one (effectively transferes the task.)
|
||||
void ODWaveTrackTaskQueue::ReplaceWaveTrack(Track *oldTrack, Track *newTrack)
|
||||
void ODWaveTrackTaskQueue::ReplaceWaveTrack(Track *oldTrack,
|
||||
const std::shared_ptr<Track> &newTrack)
|
||||
{
|
||||
if(oldTrack)
|
||||
{
|
||||
@ -218,26 +201,17 @@ void ODWaveTrackTaskQueue::ReplaceWaveTrack(Track *oldTrack, Track *newTrack)
|
||||
|
||||
mTracksMutex.Lock();
|
||||
for(unsigned int i=0;i<mTracks.size();i++)
|
||||
if(mTracks[i]==oldTrack)
|
||||
mTracks[i] = static_cast<WaveTrack*>( newTrack );
|
||||
if ( mTracks[i].lock().get() == oldTrack )
|
||||
mTracks[i] = std::static_pointer_cast<WaveTrack>( newTrack );
|
||||
mTracksMutex.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
//returns the wavetrack at position x.
|
||||
WaveTrack* ODWaveTrackTaskQueue::GetWaveTrack(size_t x)
|
||||
{
|
||||
WaveTrack* ret = NULL;
|
||||
mTracksMutex.Lock();
|
||||
if (x < mTracks.size())
|
||||
ret = mTracks[x];
|
||||
mTracksMutex.Unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
///returns the number of wavetracks in this queue.
|
||||
int ODWaveTrackTaskQueue::GetNumWaveTracks()
|
||||
{
|
||||
Compress();
|
||||
|
||||
int ret = 0;
|
||||
mTracksMutex.Lock();
|
||||
ret=mTracks.size();
|
||||
@ -271,6 +245,8 @@ ODTask* ODWaveTrackTaskQueue::GetTask(size_t x)
|
||||
//returns true if either tracks or tasks are empty
|
||||
bool ODWaveTrackTaskQueue::IsEmpty()
|
||||
{
|
||||
Compress();
|
||||
|
||||
bool isEmpty;
|
||||
mTracksMutex.Lock();
|
||||
isEmpty = mTracks.size()<=0;
|
||||
@ -342,3 +318,13 @@ void ODWaveTrackTaskQueue::FillTipForWaveTrack( const WaveTrack * t, wxString &t
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ODWaveTrackTaskQueue::Compress()
|
||||
{
|
||||
mTracksMutex.Lock();
|
||||
auto begin = mTracks.begin(), end = mTracks.end(),
|
||||
new_end = std::remove_if( begin, end,
|
||||
[]( const std::weak_ptr<WaveTrack> &ptr ){ return ptr.expired(); } );
|
||||
mTracks.erase( new_end, end );
|
||||
mTracksMutex.Unlock();
|
||||
}
|
||||
|
@ -42,31 +42,26 @@ class ODWaveTrackTaskQueue final
|
||||
|
||||
|
||||
///Adds a track to the associated list.
|
||||
void AddWaveTrack(WaveTrack* track);
|
||||
///Removes a track from the list. Also notifies mTasks to stop using references
|
||||
///to the instance in a thread-safe manner (may block)
|
||||
void RemoveWaveTrack(WaveTrack* track);
|
||||
void AddWaveTrack( const std::shared_ptr< WaveTrack > &track);
|
||||
|
||||
///changes the tasks associated with this Waveform to process the task from a different point in the track
|
||||
void DemandTrackUpdate(WaveTrack* track, double seconds);
|
||||
|
||||
///replaces all instances of a WaveTrack within this task with another.
|
||||
void ReplaceWaveTrack(Track *oldTrack, Track *newTrack);
|
||||
void ReplaceWaveTrack(Track *oldTrack,
|
||||
const std::shared_ptr<Track> &newTrack);
|
||||
|
||||
//if the wavetrack is in this queue, and is not the only wavetrack, clones the tasks and schedules it.
|
||||
void MakeWaveTrackIndependent(WaveTrack* track);
|
||||
void MakeWaveTrackIndependent( const std::shared_ptr< WaveTrack > &track);
|
||||
|
||||
///returns whether or not this queue's task list and another's can merge together, as when we make two mono tracks stereo.
|
||||
bool CanMergeWith(ODWaveTrackTaskQueue* otherQueue);
|
||||
void MergeWaveTrack(WaveTrack* track);
|
||||
void MergeWaveTrack( const std::shared_ptr< WaveTrack > &track);
|
||||
|
||||
|
||||
//returns true if the agrument is in the WaveTrack list.
|
||||
bool ContainsWaveTrack(const WaveTrack* track);
|
||||
|
||||
//returns the wavetrack at position x.
|
||||
WaveTrack* GetWaveTrack(size_t x);
|
||||
|
||||
///returns the number of wavetracks in this queue.
|
||||
int GetNumWaveTracks();
|
||||
|
||||
@ -96,12 +91,15 @@ class ODWaveTrackTaskQueue final
|
||||
|
||||
protected:
|
||||
|
||||
// Remove expired weak pointers to tracks
|
||||
void Compress();
|
||||
|
||||
//because we need to save this around for the tool tip.
|
||||
wxString mTipMsg;
|
||||
|
||||
|
||||
///the list of tracks associated with this queue.
|
||||
std::vector<WaveTrack*> mTracks;
|
||||
std::vector< std::weak_ptr< WaveTrack > > mTracks;
|
||||
ODLock mTracksMutex;
|
||||
|
||||
///the list of tasks associated with the tracks. This class owns these tasks.
|
||||
|
@ -889,7 +889,8 @@ void WaveTrackMenuTable::OnMergeStereo(wxCommandEvent &)
|
||||
|
||||
//On Demand - join the queues together.
|
||||
if (ODManager::IsInstanceCreated())
|
||||
if (!ODManager::Instance()->MakeWaveTrackDependent(partner, pTrack))
|
||||
if (!ODManager::Instance()
|
||||
->MakeWaveTrackDependent(partner->SharedPointer<WaveTrack>(), pTrack))
|
||||
{
|
||||
;
|
||||
//TODO: in the future, we will have to check the return value of MakeWaveTrackDependent -
|
||||
@ -927,7 +928,8 @@ void WaveTrackMenuTable::SplitStereo(bool stereo)
|
||||
|
||||
//On Demand - have each channel add its own.
|
||||
if (ODManager::IsInstanceCreated())
|
||||
ODManager::Instance()->MakeWaveTrackIndependent(channel);
|
||||
ODManager::Instance()->MakeWaveTrackIndependent(
|
||||
channel->SharedPointer<WaveTrack>() );
|
||||
//make sure no channel is smaller than its minimum height
|
||||
if (view.GetHeight() < view.GetMinimizedHeight())
|
||||
view.SetHeight(view.GetMinimizedHeight());
|
||||
|
Loading…
x
Reference in New Issue
Block a user