Audacity  2.2.2
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 #include "ODManager.h"
23 #include "../WaveTrack.h"
24 #include "../Project.h"
25 #include "../UndoManager.h"
26 //temporarilly commented out till it is added to all projects
27 //#include "../Profiler.h"
28 
29 
30 DEFINE_EVENT_TYPE(EVT_ODTASK_COMPLETE)
31 
32 ODTask::ODTask()
34 : mDemandSample(0)
35 {
36 
37  static int sTaskNumber=0;
38  mPercentComplete=0;
39  mDoingTask=false;
40  mTerminate = false;
41  mNeedsODUpdate=false;
42  mIsRunning = false;
43 
44  mTaskNumber=sTaskNumber++;
45 }
46 
47 //outside code must ensure this task is not scheduled again.
49 {
50  //one mutex pair for the value of mTerminate
51  mTerminateMutex.Lock();
52  mTerminate=true;
53  //release all data the derived class may have allocated
54  mTerminateMutex.Unlock();
55 
56  //and one mutex pair for the exit of the function
58 //TODO lock mTerminate?
60 
61  //wait till we are out of doSome() to terminate.
62  Terminate();
63 }
64 
69 void ODTask::DoSome(float amountWork)
70 {
71  SetIsRunning(true);
73 
74 // wxPrintf("%s %i subtask starting on NEW thread with priority\n", GetTaskName(),GetTaskNumber());
75 
77 
78  float workUntil = amountWork+PercentComplete();
79 
80 
81 
82  //check periodically to see if we should exit.
83  mTerminateMutex.Lock();
84  if(mTerminate)
85  {
86  mTerminateMutex.Unlock();
87  SetIsRunning(false);
89  return;
90  }
91  mTerminateMutex.Unlock();
92 
93  Update();
94 
95 
98 
99  if(workUntil<PercentComplete())
100  workUntil = PercentComplete();
101 
102  //Do Some of the task.
103 
104  mTerminateMutex.Lock();
105  while(PercentComplete() < workUntil && PercentComplete() < 1.0 && !mTerminate)
106  {
107  wxThread::This()->Yield();
108  //release within the loop so we can cut the number of iterations short
109 
110  DoSomeInternal(); //keep the terminate mutex on so we don't remo
111  mTerminateMutex.Unlock();
112  //check to see if ondemand has been called
113  if(GetNeedsODUpdate() && PercentComplete() < 1.0)
114  ODUpdate();
115 
116 
117  //But add the mutex lock back before we check the value again.
118  mTerminateMutex.Lock();
119  }
120  mTerminateMutex.Unlock();
121  mDoingTask=false;
122 
123  mTerminateMutex.Lock();
124  //if it is not done, put it back onto the ODManager queue.
125  if(PercentComplete() < 1.0&& !mTerminate)
126  {
127  ODManager::Instance()->AddTask(this);
128 
129  //we did a bit of progress - we should allow a resave.
131  for(unsigned i=0; i<gAudacityProjects.size(); i++)
132  {
134  {
135  //mark the changes so that the project can be resaved.
136  gAudacityProjects[i]->GetUndoManager()->SetODChangesFlag();
137  break;
138  }
139  }
140 
141 
142 // wxPrintf("%s %i is %f done\n", GetTaskName(),GetTaskNumber(),PercentComplete());
143  }
144  else
145  {
146  //for profiling, uncomment and look in audacity.app/exe's folder for AudacityProfile.txt
147  //static int tempLog =0;
148  //if(++tempLog % 5==0)
149  //END_TASK_PROFILING("On Demand Drag and Drop 5 80 mb files into audacity, 5 wavs per task");
150  //END_TASK_PROFILING("On Demand open an 80 mb wav stereo file");
151 
152  wxCommandEvent event( EVT_ODTASK_COMPLETE );
153 
155  for(unsigned i=0; i<gAudacityProjects.size(); i++)
156  {
158  {
159  //this assumes tasks are only associated with one project.
160  gAudacityProjects[i]->GetEventHandler()->AddPendingEvent(event);
161  //mark the changes so that the project can be resaved.
162  gAudacityProjects[i]->GetUndoManager()->SetODChangesFlag();
163  break;
164  }
165  }
166 
167 // wxPrintf("%s %i complete\n", GetTaskName(),GetTaskNumber());
168  }
169  mTerminateMutex.Unlock();
170  SetIsRunning(false);
171  mBlockUntilTerminateMutex.Unlock();
172 }
173 
175 {
176  TrackList *tracks = proj->GetTracks();
177  TrackListIterator iter1(tracks);
178  Track *tr = iter1.First();
179 
180  while (tr)
181  {
182  //go over all tracks in the project
183  if (tr->GetKind() == Track::Wave)
184  {
185  //look inside our task's track list for one that matches this projects one.
186  mWaveTrackMutex.Lock();
187  for(int i=0;i<(int)mWaveTracks.size();i++)
188  {
189  if(mWaveTracks[i]==tr)
190  {
191  //if we find one, then the project is associated with us;return true
192  mWaveTrackMutex.Unlock();
193  return true;
194  }
195  }
196  mWaveTrackMutex.Unlock();
197  }
198  tr = iter1.Next();
199  }
200 
201  return false;
202 
203 }
204 
206 {
207  Update();
209 }
210 
211 void ODTask::SetIsRunning(bool value)
212 {
213  mIsRunningMutex.Lock();
214  mIsRunning=value;
215  mIsRunningMutex.Unlock();
216 }
217 
219 {
220  bool ret;
221  mIsRunningMutex.Lock();
222  ret= mIsRunning;
223  mIsRunningMutex.Unlock();
224  return ret;
225 }
226 
228 {
229  sampleCount retval;
230  mDemandSampleMutex.Lock();
231  retval = mDemandSample;
232  mDemandSampleMutex.Unlock();
233  return retval;
234 }
235 
237 {
238 
239  mDemandSampleMutex.Lock();
240  mDemandSample=sample;
241  mDemandSampleMutex.Unlock();
242 }
243 
244 
247 {
248  mPercentCompleteMutex.Lock();
249  float ret = mPercentComplete;
250  mPercentCompleteMutex.Unlock();
251  return ret;
252 }
253 
256 {
257  return PercentComplete() >= 1.0 && !IsRunning();
258 }
259 
260 
262 {
263  WaveTrack* track = NULL;
264  mWaveTrackMutex.Lock();
265  if(i<(int)mWaveTracks.size())
266  track = mWaveTracks[i];
267  mWaveTrackMutex.Unlock();
268  return track;
269 }
270 
274 {
275  mWaveTracks.push_back(track);
276 }
277 
278 
280 {
281  int num;
282  mWaveTrackMutex.Lock();
283  num = (int)mWaveTracks.size();
284  mWaveTrackMutex.Unlock();
285  return num;
286 }
287 
288 
290 {
291  mNeedsODUpdateMutex.Lock();
292  mNeedsODUpdate=true;
293  mNeedsODUpdateMutex.Unlock();
294 }
296 {
297  bool ret;
298  mNeedsODUpdateMutex.Lock();
299  ret=mNeedsODUpdate;
300  mNeedsODUpdateMutex.Unlock();
301  return ret;
302 }
303 
305 {
306  mNeedsODUpdateMutex.Lock();
307  mNeedsODUpdate=false;
308  mNeedsODUpdateMutex.Unlock();
309 }
310 
313 {
314  if(GetNeedsODUpdate())
315  {
316  ODUpdate();
318  }
319 }
320 
324 void ODTask::DemandTrackUpdate(WaveTrack* track, double seconds)
325 {
326  bool demandSampleChanged=false;
327  mWaveTrackMutex.Lock();
328  for(size_t i=0;i<mWaveTracks.size();i++)
329  {
330  if(track == mWaveTracks[i])
331  {
332  auto newDemandSample = (sampleCount)(seconds * track->GetRate());
333  demandSampleChanged = newDemandSample != GetDemandSample();
334  SetDemandSample(newDemandSample);
335  break;
336  }
337  }
338  mWaveTrackMutex.Unlock();
339 
340  if(demandSampleChanged)
342 
343 }
344 
345 
347 {
348  mWaveTrackMutex.Lock();
349  for(size_t i=0;i<mWaveTracks.size();i++)
350  {
351  if(mWaveTracks[i] == track)
352  mWaveTracks[i]=NULL;
353  }
354  mWaveTrackMutex.Unlock();
355 }
356 
359 {
360  mWaveTrackMutex.Lock();
361  for(size_t i=0;i<mWaveTracks.size();i++)
362  {
363  if(oldTrack == mWaveTracks[i])
364  {
365  mWaveTracks[i] = newTrack;
366  }
367  }
368  mWaveTrackMutex.Unlock();
369 }
void DoSome(float amountWork=0.0)
Definition: ODTask.cpp:69
bool IsComplete()
return
Definition: ODTask.cpp:255
A list of TrackListNode items.
Definition: Track.h:618
static ODManager *(* Instance)()
Definition: ODManager.h:49
bool IsRunning()
Definition: ODTask.cpp:218
virtual sampleCount GetDemandSample() const
Definition: ODTask.cpp:227
ODLock mTerminateMutex
Definition: ODTask.h:155
ODLock mDemandSampleMutex
Definition: ODTask.h:163
volatile bool mNeedsODUpdate
Definition: ODTask.h:171
void TerminateAndBlock()
Definition: ODTask.cpp:48
AProjectArray gAudacityProjects
Definition: Project.cpp:303
ODLock mWaveTrackMutex
Definition: ODTask.h:160
DEFINE_EVENT_TYPE(EVT_OPEN_AUDIO_FILE)
Custom events.
virtual void ODUpdate()
Definition: ODTask.cpp:205
virtual void Update()
virtual method called before DoSomeInternal is used from DoSome.
Definition: ODTask.h:138
virtual void CalculatePercentComplete()=0
calculates the percentage complete from existing data.
volatile bool mIsRunning
Definition: ODTask.h:165
virtual void SetDemandSample(sampleCount sample)
Definition: ODTask.cpp:236
std::vector< WaveTrack * > mWaveTracks
Definition: ODTask.h:159
volatile float mPercentComplete
Definition: ODTask.h:150
void SetIsRunning(bool value)
Definition: ODTask.cpp:211
bool GetNeedsODUpdate()
Definition: ODTask.cpp:295
virtual void RecalculatePercentComplete()
does an od update and then recalculates the data.
Definition: ODTask.cpp:312
virtual int GetKind() const
Definition: Track.h:329
virtual float PercentComplete()
return the amount of the task that has been completed. 0.0 to 1.0
Definition: ODTask.cpp:246
virtual bool IsTaskAssociatedWithProject(AudacityProject *proj)
returns true if the task is associated with the project.
Definition: ODTask.cpp:174
AudacityProject provides the main window, with tools and tracks contained within it.
Definition: Project.h:176
void AddTask(ODTask *task)
Adds a task to the running queue. Threas-safe.
Definition: ODManager.cpp:95
A class representing a modular task to be used with the On-Demand structures.
Definition: ODTask.h:39
volatile bool mDoingTask
Definition: ODTask.h:152
static ODLock & AllProjectDeleteMutex()
Prevents DELETE from external thread - for e.g. use of GetActiveProject.
Definition: Project.cpp:183
virtual void StopUsingWaveTrack(WaveTrack *track)
Definition: ODTask.cpp:346
sampleCount mDemandSample
Definition: ODTask.h:162
ODLock mNeedsODUpdateMutex
Definition: ODTask.h:172
A Track that contains audio waveform data.
Definition: WaveTrack.h:60
Fundamental data object of Audacity, placed in the TrackPanel. Classes derived form it include the Wa...
Definition: Track.h:101
virtual WaveTrack * GetWaveTrack(int i)
Definition: ODTask.cpp:261
void ResetNeedsODUpdate()
Definition: ODTask.cpp:304
void AddWaveTrack(WaveTrack *track)
Adds a WaveTrack to do the task for.
Definition: ODTask.cpp:273
virtual Track * First(TrackList *val=nullptr)
Definition: Track.cpp:418
ODLock mBlockUntilTerminateMutex
Definition: ODTask.h:157
virtual void ReplaceWaveTrack(WaveTrack *oldTrack, WaveTrack *newTrack)
Replaces all instances to a wavetrack with a NEW one, effectively transferring the task...
Definition: ODTask.cpp:358
virtual float ComputeNextWorkUntilPercentageComplete()
Definition: ODTask.h:76
virtual int GetNumWaveTracks()
Definition: ODTask.cpp:279
An iterator for a TrackList.
Definition: Track.h:401
ODLock mPercentCompleteMutex
Definition: ODTask.h:151
void SetNeedsODUpdate()
Definition: ODTask.cpp:289
virtual Track * Next(bool skiplinked=false)
Definition: Track.cpp:460
volatile bool mTaskStarted
Definition: ODTask.h:153
double GetRate() const
Definition: WaveTrack.cpp:398
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:324
TrackList * GetTracks()
Definition: Project.h:192
virtual void DoSomeInternal()=0
virtual void Terminate()
releases memory that the ODTask owns. Subclasses should override.
Definition: ODTask.h:101
ODLock mIsRunningMutex
Definition: ODTask.h:166
volatile bool mTerminate
Definition: ODTask.h:154
virtual bool UsesCustomWorkUntilPercentage()
Definition: ODTask.h:75