Audacity  3.0.3
ODTask.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  ODTask.cpp
6 
7  Created by Michael Chinen (mchinen)
8  Audacity(R) is copyright (c) 1999-2008 Audacity Team.
9  License: GPL v2. See License.txt.
10 
11 ******************************************************************//*******************************************************************/
19 
20 
21 #include "ODTask.h"
22 
23 #include "ODManager.h"
24 #include "../WaveClip.h"
25 #include "../WaveTrack.h"
26 #include "../Project.h"
27 #include "../UndoManager.h"
28 //temporarily commented out till it is added to all projects
29 //#include "../Profiler.h"
30 
31 
32 wxDEFINE_EVENT(EVT_ODTASK_COMPLETE, wxCommandEvent);
33 
36 : mDemandSample(0)
37 {
38 
39  static int sTaskNumber=0;
41  mDoingTask=false;
42  mTerminate = false;
43  mNeedsODUpdate=false;
44  mIsRunning = false;
45 
46  mTaskNumber=sTaskNumber++;
47 }
48 
49 //outside code must ensure this task is not scheduled again.
51 {
52  //one mutex pair for the value of mTerminate
53  mTerminateMutex.Lock();
54  mTerminate=true;
55  //release all data the derived class may have allocated
56  mTerminateMutex.Unlock();
57 
58  //and one mutex pair for the exit of the function
60 //TODO lock mTerminate?
62 
63  //wait till we are out of doSome() to terminate.
64  Terminate();
65 }
66 
71 void ODTask::DoSome(float amountWork)
72 {
73  SetIsRunning(true);
75 
76 // wxPrintf("%s %i subtask starting on NEW thread with priority\n", GetTaskName(),GetTaskNumber());
77 
79 
80  float workUntil = amountWork+PercentComplete();
81 
82 
83 
84  //check periodically to see if we should exit.
85  mTerminateMutex.Lock();
86  if(mTerminate)
87  {
88  mTerminateMutex.Unlock();
89  SetIsRunning(false);
91  return;
92  }
93  mTerminateMutex.Unlock();
94 
95  Update();
96 
97 
100 
101  if(workUntil<PercentComplete())
102  workUntil = PercentComplete();
103 
104  //Do Some of the task.
105 
106  mTerminateMutex.Lock();
107  while(PercentComplete() < workUntil && PercentComplete() < 1.0 && !mTerminate)
108  {
109  wxThread::This()->Yield();
110  //release within the loop so we can cut the number of iterations short
111 
112  DoSomeInternal(); //keep the terminate mutex on so we don't remo
113  mTerminateMutex.Unlock();
114  //check to see if ondemand has been called
115  if(GetNeedsODUpdate() && PercentComplete() < 1.0)
116  ODUpdate();
117 
118 
119  //But add the mutex lock back before we check the value again.
120  mTerminateMutex.Lock();
121  }
122  mTerminateMutex.Unlock();
123  mDoingTask=false;
124 
125  mTerminateMutex.Lock();
126  //if it is not done, put it back onto the ODManager queue.
127  if(PercentComplete() < 1.0&& !mTerminate)
128  {
129  ODManager::Instance()->AddTask(this);
130 
131  //we did a bit of progress - we should allow a resave.
132  ODLocker locker{ &AllProjects::Mutex() };
133  for ( auto pProject : AllProjects{} )
134  {
135  if(IsTaskAssociatedWithProject(pProject.get()))
136  {
137  //mark the changes so that the project can be resaved.
138  UndoManager::Get( *pProject ).SetODChangesFlag();
139  break;
140  }
141  }
142 
143 
144 // wxPrintf("%s %i is %f done\n", GetTaskName(),GetTaskNumber(),PercentComplete());
145  }
146  else
147  {
148  //for profiling, uncomment and look in audacity.app/exe's folder for AudacityProfile.txt
149  //static int tempLog =0;
150  //if(++tempLog % 5==0)
151  //END_TASK_PROFILING("On Demand Drag and Drop 5 80 mb files into audacity, 5 wavs per task");
152  //END_TASK_PROFILING("On Demand open an 80 mb wav stereo file");
153 
154  wxCommandEvent event( EVT_ODTASK_COMPLETE );
155 
156  ODLocker locker{ &AllProjects::Mutex() };
157  for ( auto pProject : AllProjects{} )
158  {
159  if(IsTaskAssociatedWithProject(pProject.get()))
160  {
161  //this assumes tasks are only associated with one project.
162  pProject->wxEvtHandler::AddPendingEvent(event);
163  //mark the changes so that the project can be resaved.
164  UndoManager::Get( *pProject ).SetODChangesFlag();
165  break;
166  }
167  }
168 
169 // wxPrintf("%s %i complete\n", GetTaskName(),GetTaskNumber());
170  }
171  mTerminateMutex.Unlock();
172  SetIsRunning(false);
173  mBlockUntilTerminateMutex.Unlock();
174 }
175 
177 {
178  for (auto tr : TrackList::Get( *proj ).Any<const WaveTrack>())
179  {
180  //go over all tracks in the project
181  //look inside our task's track list for one that matches this projects one.
182  mWaveTrackMutex.Lock();
183  for(int i=0;i<(int)mWaveTracks.size();i++)
184  {
185  if ( mWaveTracks[i].lock().get() == tr )
186  {
187  //if we find one, then the project is associated with us;return true
188  mWaveTrackMutex.Unlock();
189  return true;
190  }
191  }
192  mWaveTrackMutex.Unlock();
193  }
194 
195  return false;
196 
197 }
198 
200 {
201  Update();
203 }
204 
205 void ODTask::SetIsRunning(bool value)
206 {
207  mIsRunningMutex.Lock();
208  mIsRunning=value;
209  mIsRunningMutex.Unlock();
210 }
211 
213 {
214  bool ret;
215  mIsRunningMutex.Lock();
216  ret= mIsRunning;
217  mIsRunningMutex.Unlock();
218  return ret;
219 }
220 
222 {
223  sampleCount retval;
224  mDemandSampleMutex.Lock();
225  retval = mDemandSample;
226  mDemandSampleMutex.Unlock();
227  return retval;
228 }
229 
231 {
232 
233  mDemandSampleMutex.Lock();
234  mDemandSample=sample;
235  mDemandSampleMutex.Unlock();
236 }
237 
238 
241 {
242  mPercentCompleteMutex.Lock();
243  float ret = mPercentComplete;
244  mPercentCompleteMutex.Unlock();
245  return ret;
246 }
247 
250 {
251  return PercentComplete() >= 1.0 && !IsRunning();
252 }
253 
254 
255 std::shared_ptr< WaveTrack > ODTask::GetWaveTrack(int i)
256 {
257  std::shared_ptr< WaveTrack > track;
258  mWaveTrackMutex.Lock();
259  if(i<(int)mWaveTracks.size())
260  track = mWaveTracks[i].lock();
261  mWaveTrackMutex.Unlock();
262  return track;
263 }
264 
267 void ODTask::AddWaveTrack( const std::shared_ptr< WaveTrack > &track)
268 {
269  mWaveTracks.push_back(track);
270 }
271 
272 
274 {
275  int num;
276  mWaveTrackMutex.Lock();
277  num = (int)mWaveTracks.size();
278  mWaveTrackMutex.Unlock();
279  return num;
280 }
281 
282 
284 {
285  mNeedsODUpdateMutex.Lock();
286  mNeedsODUpdate=true;
287  mNeedsODUpdateMutex.Unlock();
288 }
290 {
291  bool ret;
292  mNeedsODUpdateMutex.Lock();
293  ret=mNeedsODUpdate;
294  mNeedsODUpdateMutex.Unlock();
295  return ret;
296 }
297 
299 {
300  mNeedsODUpdateMutex.Lock();
301  mNeedsODUpdate=false;
302  mNeedsODUpdateMutex.Unlock();
303 }
304 
307 {
308  if(GetNeedsODUpdate())
309  {
310  ODUpdate();
312  }
313 }
314 
318 void ODTask::DemandTrackUpdate(WaveTrack* track, double seconds)
319 {
320  bool demandSampleChanged=false;
321  mWaveTrackMutex.Lock();
322  for(size_t i=0;i<mWaveTracks.size();i++)
323  {
324  if ( track == mWaveTracks[i].lock().get() )
325  {
326  auto newDemandSample = (sampleCount)(seconds * track->GetRate());
327  demandSampleChanged = newDemandSample != GetDemandSample();
328  SetDemandSample(newDemandSample);
329  break;
330  }
331  }
332  mWaveTrackMutex.Unlock();
333 
334  if(demandSampleChanged)
336 
337 }
338 
339 
341 {
342  mWaveTrackMutex.Lock();
343  for(size_t i=0;i<mWaveTracks.size();i++)
344  {
345  if(mWaveTracks[i].lock().get() == track)
346  mWaveTracks[i].reset();
347  }
348  mWaveTrackMutex.Unlock();
349 }
350 
353  const std::shared_ptr< Track > &newTrack)
354 {
355  mWaveTrackMutex.Lock();
356  for(size_t i=0;i<mWaveTracks.size();i++)
357  {
358  if(oldTrack == mWaveTracks[i].lock().get())
359  {
360  mWaveTracks[i] = std::static_pointer_cast<WaveTrack>( newTrack );
361  }
362  }
363  mWaveTrackMutex.Unlock();
364 }
ODTask::ReplaceWaveTrack
virtual void ReplaceWaveTrack(Track *oldTrack, const std::shared_ptr< Track > &newTrack)
Replaces all instances to a wavetrack with a NEW one, effectively transferring the task.
Definition: ODTask.cpp:352
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
ODTask::SetNeedsODUpdate
void SetNeedsODUpdate()
Definition: ODTask.cpp:283
ODTask::DemandTrackUpdate
virtual void DemandTrackUpdate(WaveTrack *track, double seconds)
changes the tasks associated with this Waveform to process the task from a different point in the tra...
Definition: ODTask.cpp:318
ODTask::mIsRunning
volatile bool mIsRunning
Definition: ODTask.h:166
ODTask::AddWaveTrack
void AddWaveTrack(const std::shared_ptr< WaveTrack > &track)
Adds a WaveTrack to do the task for.
Definition: ODTask.cpp:267
ODTask::IsTaskAssociatedWithProject
virtual bool IsTaskAssociatedWithProject(AudacityProject *proj)
returns true if the task is associated with the project.
Definition: ODTask.cpp:176
ODTask::UsesCustomWorkUntilPercentage
virtual bool UsesCustomWorkUntilPercentage()
Definition: ODTask.h:75
ODTask::RecalculatePercentComplete
virtual void RecalculatePercentComplete()
does an od update and then recalculates the data.
Definition: ODTask.cpp:306
ODTask::mDemandSampleMutex
ODLock mDemandSampleMutex
Definition: ODTask.h:164
ODTask::GetNeedsODUpdate
bool GetNeedsODUpdate()
Definition: ODTask.cpp:289
ODManager::AddTask
void AddTask(ODTask *task)
Adds a task to the running queue. Thread-safe.
Definition: ODManager.cpp:195
ODTask::IsRunning
bool IsRunning()
Definition: ODTask.cpp:212
ODTask::PercentComplete
virtual float PercentComplete()
return the amount of the task that has been completed. 0.0 to 1.0
Definition: ODTask.cpp:240
ODTask::mPercentCompleteMutex
ODLock mPercentCompleteMutex
Definition: ODTask.h:152
ODTask::mWaveTracks
std::vector< std::weak_ptr< WaveTrack > > mWaveTracks
Definition: ODTask.h:160
ODTask::ComputeNextWorkUntilPercentageComplete
virtual float ComputeNextWorkUntilPercentageComplete()
Definition: ODTask.h:76
ODTask::CalculatePercentComplete
virtual void CalculatePercentComplete()=0
calculates the percentage complete from existing data.
ODTask::mTaskStarted
volatile bool mTaskStarted
Definition: ODTask.h:154
ODManager.h
ODTask::IsComplete
bool IsComplete()
return
Definition: ODTask.cpp:249
ODTask::mWaveTrackMutex
ODLock mWaveTrackMutex
Definition: ODTask.h:161
ODTask::mTerminate
volatile bool mTerminate
Definition: ODTask.h:155
ODTask::TerminateAndBlock
void TerminateAndBlock()
Definition: ODTask.cpp:50
wxDEFINE_EVENT
wxDEFINE_EVENT(EVT_ODTASK_COMPLETE, wxCommandEvent)
ODTask::Terminate
virtual void Terminate()
releases memory that the ODTask owns. Subclasses should override.
Definition: ODTask.h:102
ODLocker
Definition: ODTaskThread.h:120
ODTask::mNeedsODUpdate
volatile bool mNeedsODUpdate
Definition: ODTask.h:172
ODTask::mTerminateMutex
ODLock mTerminateMutex
Definition: ODTask.h:156
ODTask.h
ODTask::ODTask
ODTask()
Constructs an ODTask.
Definition: ODTask.cpp:35
ODTask::ResetNeedsODUpdate
void ResetNeedsODUpdate()
Definition: ODTask.cpp:298
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:506
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
ODTask::mDoingTask
volatile bool mDoingTask
Definition: ODTask.h:153
UndoManager::Get
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:57
ODTask::Update
virtual void Update()
virtual method called before DoSomeInternal is used from DoSome.
Definition: ODTask.h:139
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:92
AllProjects
Definition: Project.h:35
ODTask::mPercentComplete
volatile float mPercentComplete
Definition: ODTask.h:151
ODTask::GetNumWaveTracks
virtual int GetNumWaveTracks()
Definition: ODTask.cpp:273
ODTask::GetDemandSample
virtual sampleCount GetDemandSample() const
Definition: ODTask.cpp:221
ODTask::mTaskNumber
int mTaskNumber
Definition: ODTask.h:150
ODTask::SetIsRunning
void SetIsRunning(bool value)
Definition: ODTask.cpp:205
AllProjects::Mutex
static std::mutex & Mutex()
Definition: Project.cpp:68
ODTask::SetDemandSample
virtual void SetDemandSample(sampleCount sample)
Definition: ODTask.cpp:230
TrackList::Any
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1371
ODTask::GetWaveTrack
virtual std::shared_ptr< WaveTrack > GetWaveTrack(int i)
Definition: ODTask.cpp:255
ODTask::mIsRunningMutex
ODLock mIsRunningMutex
Definition: ODTask.h:167
ODManager::Instance
static ODManager *(* Instance)()
Definition: ODManager.h:51
ODTask::DoSomeInternal
virtual void DoSomeInternal()=0
ODTask::StopUsingWaveTrack
virtual void StopUsingWaveTrack(WaveTrack *track)
Definition: ODTask.cpp:340
ODTask::mDemandSample
sampleCount mDemandSample
Definition: ODTask.h:163
ODTask::mBlockUntilTerminateMutex
ODLock mBlockUntilTerminateMutex
Definition: ODTask.h:158
ODTask::mNeedsODUpdateMutex
ODLock mNeedsODUpdateMutex
Definition: ODTask.h:173
ODTask::DoSome
void DoSome(float amountWork=0.0)
Definition: ODTask.cpp:71
WaveTrack::GetRate
double GetRate() const
Definition: WaveTrack.cpp:452
ODTask::ODUpdate
virtual void ODUpdate()
Definition: ODTask.cpp:199