Audacity  3.0.3
Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
RealtimeEffectManager Class Referencefinal

#include <RealtimeEffectManager.h>

Collaboration diagram for RealtimeEffectManager:
[legend]

Public Types

using EffectArray = std::vector< EffectClientInterface * >
 

Public Member Functions

bool RealtimeIsActive ()
 
bool RealtimeIsSuspended ()
 
void RealtimeAddEffect (EffectClientInterface *effect)
 
void RealtimeRemoveEffect (EffectClientInterface *effect)
 
void RealtimeSetEffects (const EffectArray &mActive)
 
void RealtimeInitialize (double rate)
 
void RealtimeAddProcessor (int group, unsigned chans, float rate)
 
void RealtimeFinalize ()
 
void RealtimeSuspend ()
 
void RealtimeSuspendOne (EffectClientInterface &effect)
 
void RealtimeResume ()
 
void RealtimeResumeOne (EffectClientInterface &effect)
 
void RealtimeProcessStart ()
 
size_t RealtimeProcess (int group, unsigned chans, float **buffers, size_t numSamples)
 
void RealtimeProcessEnd ()
 
int GetRealtimeLatency ()
 

Static Public Member Functions

static RealtimeEffectManagerGet ()
 

Private Member Functions

 RealtimeEffectManager ()
 
 ~RealtimeEffectManager ()
 

Private Attributes

wxCriticalSection mRealtimeLock
 
std::vector< std::unique_ptr< RealtimeEffectState > > mStates
 
int mRealtimeLatency
 
bool mRealtimeSuspended
 
bool mRealtimeActive
 
std::vector< unsigned > mRealtimeChans
 
std::vector< double > mRealtimeRates
 

Detailed Description

Definition at line 21 of file RealtimeEffectManager.h.

Member Typedef Documentation

◆ EffectArray

Definition at line 24 of file RealtimeEffectManager.h.

Constructor & Destructor Documentation

◆ RealtimeEffectManager()

RealtimeEffectManager::RealtimeEffectManager ( )
private

Definition at line 49 of file RealtimeEffectManager.cpp.

50 {
51  mRealtimeLock.Enter();
52  mRealtimeActive = false;
53  mRealtimeSuspended = true;
54  mRealtimeLatency = 0;
55  mRealtimeLock.Leave();
56 }

References mRealtimeActive, mRealtimeLatency, mRealtimeLock, and mRealtimeSuspended.

◆ ~RealtimeEffectManager()

RealtimeEffectManager::~RealtimeEffectManager ( )
private

Definition at line 58 of file RealtimeEffectManager.cpp.

59 {
60 }

Member Function Documentation

◆ Get()

RealtimeEffectManager & RealtimeEffectManager::Get ( )
static

Get the singleton instance of the RealtimeEffectManager.

Definition at line 43 of file RealtimeEffectManager.cpp.

44 {
45  static RealtimeEffectManager rem;
46  return rem;
47 }

Referenced by EffectUIHost::CleanupRealtime(), AudioIoCallback::FillOutputBuffers(), EffectUIHost::InitializeRealtime(), anonymous_namespace{PluginMenus.cpp}::IsRealtimeNotActiveFlag(), EffectUIHost::OnEnable(), EffectUIHost::Resume(), AudioIO::SetPaused(), AudioIO::StartStream(), AudioIO::StartStreamCleanup(), and AudioIO::StopStream().

Here is the caller graph for this function:

◆ GetRealtimeLatency()

int RealtimeEffectManager::GetRealtimeLatency ( )

Definition at line 402 of file RealtimeEffectManager.cpp.

403 {
404  return mRealtimeLatency;
405 }

References mRealtimeLatency.

◆ RealtimeAddEffect()

void RealtimeEffectManager::RealtimeAddEffect ( EffectClientInterface effect)

Definition at line 113 of file RealtimeEffectManager.cpp.

114 {
115  // Block RealtimeProcess()
116  RealtimeSuspend();
117 
118  // Add to list of active effects
119  mStates.emplace_back( std::make_unique< RealtimeEffectState >( *effect ) );
120  auto &state = mStates.back();
121 
122  // Initialize effect if realtime is already active
123  if (mRealtimeActive)
124  {
125  // Initialize realtime processing
126  effect->RealtimeInitialize();
127 
128  // Add the required processors
129  for (size_t i = 0, cnt = mRealtimeChans.size(); i < cnt; i++)
130  {
131  state->RealtimeAddProcessor(i, mRealtimeChans[i], mRealtimeRates[i]);
132  }
133  }
134 
135 
136  // Allow RealtimeProcess() to, well, process
137  RealtimeResume();
138 }

References mRealtimeActive, mRealtimeChans, mRealtimeRates, mStates, EffectClientInterface::RealtimeInitialize(), RealtimeResume(), and RealtimeSuspend().

Referenced by EffectUIHost::InitializeRealtime().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RealtimeAddProcessor()

void RealtimeEffectManager::RealtimeAddProcessor ( int  group,
unsigned  chans,
float  rate 
)

Definition at line 188 of file RealtimeEffectManager.cpp.

189 {
190  for (auto &state : mStates)
191  state->RealtimeAddProcessor(group, chans, rate);
192 
193  mRealtimeChans.push_back(chans);
194  mRealtimeRates.push_back(rate);
195 }

References mRealtimeChans, mRealtimeRates, and mStates.

◆ RealtimeFinalize()

void RealtimeEffectManager::RealtimeFinalize ( )

Definition at line 197 of file RealtimeEffectManager.cpp.

198 {
199  // Make sure nothing is going on
200  RealtimeSuspend();
201 
202  // It is now safe to clean up
203  mRealtimeLatency = 0;
204 
205  // Tell each effect to clean up as well
206  for (auto &state : mStates)
207  state->GetEffect().RealtimeFinalize();
208 
209  // Reset processor parameters
210  mRealtimeChans.clear();
211  mRealtimeRates.clear();
212 
213  // No longer active
214  mRealtimeActive = false;
215 }

References mRealtimeActive, mRealtimeChans, mRealtimeLatency, mRealtimeRates, mStates, and RealtimeSuspend().

Referenced by AudioIO::StartStreamCleanup(), and AudioIO::StopStream().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RealtimeInitialize()

void RealtimeEffectManager::RealtimeInitialize ( double  rate)

Definition at line 165 of file RealtimeEffectManager.cpp.

166 {
167  // The audio thread should not be running yet, but protect anyway
168  RealtimeSuspend();
169 
170  // (Re)Set processor parameters
171  mRealtimeChans.clear();
172  mRealtimeRates.clear();
173 
174  // RealtimeAdd/RemoveEffect() needs to know when we're active so it can
175  // initialize newly added effects
176  mRealtimeActive = true;
177 
178  // Tell each effect to get ready for action
179  for (auto &state : mStates) {
180  state->GetEffect().SetSampleRate(rate);
181  state->GetEffect().RealtimeInitialize();
182  }
183 
184  // Get things moving
185  RealtimeResume();
186 }

References mRealtimeActive, mRealtimeChans, mRealtimeRates, mStates, RealtimeResume(), and RealtimeSuspend().

Here is the call graph for this function:

◆ RealtimeIsActive()

bool RealtimeEffectManager::RealtimeIsActive ( )

Definition at line 103 of file RealtimeEffectManager.cpp.

104 {
105  return mStates.size() != 0;
106 }

References mStates.

Referenced by anonymous_namespace{PluginMenus.cpp}::IsRealtimeNotActiveFlag().

Here is the caller graph for this function:

◆ RealtimeIsSuspended()

bool RealtimeEffectManager::RealtimeIsSuspended ( )

Definition at line 108 of file RealtimeEffectManager.cpp.

109 {
110  return mRealtimeSuspended;
111 }

References mRealtimeSuspended.

◆ RealtimeProcess()

size_t RealtimeEffectManager::RealtimeProcess ( int  group,
unsigned  chans,
float **  buffers,
size_t  numSamples 
)

Definition at line 308 of file RealtimeEffectManager.cpp.

309 {
310  // Protect ourselves from the main thread
311  mRealtimeLock.Enter();
312 
313  // Can be suspended because of the audio stream being paused or because effects
314  // have been suspended, so allow the samples to pass as-is.
315  if (mRealtimeSuspended || mStates.empty())
316  {
317  mRealtimeLock.Leave();
318  return numSamples;
319  }
320 
321  // Remember when we started so we can calculate the amount of latency we
322  // are introducing
323  wxMilliClock_t start = wxGetUTCTimeMillis();
324 
325  // Allocate the in/out buffer arrays
326  float **ibuf = (float **) alloca(chans * sizeof(float *));
327  float **obuf = (float **) alloca(chans * sizeof(float *));
328 
329  // And populate the input with the buffers we've been given while allocating
330  // NEW output buffers
331  for (unsigned int i = 0; i < chans; i++)
332  {
333  ibuf[i] = buffers[i];
334  obuf[i] = (float *) alloca(numSamples * sizeof(float));
335  }
336 
337  // Now call each effect in the chain while swapping buffer pointers to feed the
338  // output of one effect as the input to the next effect
339  size_t called = 0;
340  for (auto &state : mStates)
341  {
342  if (state->IsRealtimeActive())
343  {
344  state->RealtimeProcess(group, chans, ibuf, obuf, numSamples);
345  called++;
346  }
347 
348  for (unsigned int j = 0; j < chans; j++)
349  {
350  float *temp;
351  temp = ibuf[j];
352  ibuf[j] = obuf[j];
353  obuf[j] = temp;
354  }
355  }
356 
357  // Once we're done, we might wind up with the last effect storing its results
358  // in the temporary buffers. If that's the case, we need to copy it over to
359  // the caller's buffers. This happens when the number of effects processed
360  // is odd.
361  if (called & 1)
362  {
363  for (unsigned int i = 0; i < chans; i++)
364  {
365  memcpy(buffers[i], ibuf[i], numSamples * sizeof(float));
366  }
367  }
368 
369  // Remember the latency
370  mRealtimeLatency = (int) (wxGetUTCTimeMillis() - start).GetValue();
371 
372  mRealtimeLock.Leave();
373 
374  //
375  // This is wrong...needs to handle tails
376  //
377  return numSamples;
378 }

References mRealtimeLatency, mRealtimeLock, mRealtimeSuspended, and mStates.

◆ RealtimeProcessEnd()

void RealtimeEffectManager::RealtimeProcessEnd ( )

Definition at line 383 of file RealtimeEffectManager.cpp.

384 {
385  // Protect ourselves from the main thread
386  mRealtimeLock.Enter();
387 
388  // Can be suspended because of the audio stream being paused or because effects
389  // have been suspended.
390  if (!mRealtimeSuspended)
391  {
392  for (auto &state : mStates)
393  {
394  if (state->IsRealtimeActive())
395  state->GetEffect().RealtimeProcessEnd();
396  }
397  }
398 
399  mRealtimeLock.Leave();
400 }

References mRealtimeLock, mRealtimeSuspended, and mStates.

◆ RealtimeProcessStart()

void RealtimeEffectManager::RealtimeProcessStart ( )

Definition at line 286 of file RealtimeEffectManager.cpp.

287 {
288  // Protect ourselves from the main thread
289  mRealtimeLock.Enter();
290 
291  // Can be suspended because of the audio stream being paused or because effects
292  // have been suspended.
293  if (!mRealtimeSuspended)
294  {
295  for (auto &state : mStates)
296  {
297  if (state->IsRealtimeActive())
298  state->GetEffect().RealtimeProcessStart();
299  }
300  }
301 
302  mRealtimeLock.Leave();
303 }

References mRealtimeLock, mRealtimeSuspended, and mStates.

◆ RealtimeRemoveEffect()

void RealtimeEffectManager::RealtimeRemoveEffect ( EffectClientInterface effect)

Definition at line 140 of file RealtimeEffectManager.cpp.

141 {
142  // Block RealtimeProcess()
143  RealtimeSuspend();
144 
145  if (mRealtimeActive)
146  {
147  // Cleanup realtime processing
148  effect->RealtimeFinalize();
149  }
150 
151  // Remove from list of active effects
152  auto end = mStates.end();
153  auto found = std::find_if( mStates.begin(), end,
154  [&](const decltype(mStates)::value_type &state){
155  return &state->GetEffect() == effect;
156  }
157  );
158  if (found != end)
159  mStates.erase(found);
160 
161  // Allow RealtimeProcess() to, well, process
162  RealtimeResume();
163 }

References mRealtimeActive, mStates, EffectClientInterface::RealtimeFinalize(), RealtimeResume(), and RealtimeSuspend().

Referenced by EffectUIHost::CleanupRealtime().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RealtimeResume()

void RealtimeEffectManager::RealtimeResume ( )

Definition at line 250 of file RealtimeEffectManager.cpp.

251 {
252  mRealtimeLock.Enter();
253 
254  // Already running...bail
255  if (!mRealtimeSuspended)
256  {
257  mRealtimeLock.Leave();
258  return;
259  }
260 
261  // Tell the effects to get ready for more action
262  for (auto &state : mStates)
263  state->RealtimeResume();
264 
265  // And we should too
266  mRealtimeSuspended = false;
267 
268  mRealtimeLock.Leave();
269 }

References mRealtimeLock, mRealtimeSuspended, and mStates.

Referenced by RealtimeAddEffect(), RealtimeInitialize(), RealtimeRemoveEffect(), and AudioIO::SetPaused().

Here is the caller graph for this function:

◆ RealtimeResumeOne()

void RealtimeEffectManager::RealtimeResumeOne ( EffectClientInterface effect)

Definition at line 271 of file RealtimeEffectManager.cpp.

272 {
273  auto begin = mStates.begin(), end = mStates.end();
274  auto found = std::find_if( begin, end,
275  [&effect]( const decltype( mStates )::value_type &state ){
276  return state && &state->GetEffect() == &effect;
277  }
278  );
279  if ( found != end )
280  (*found)->RealtimeResume();
281 }

References mStates.

Referenced by EffectUIHost::Resume().

Here is the caller graph for this function:

◆ RealtimeSetEffects()

void RealtimeEffectManager::RealtimeSetEffects ( const EffectArray mActive)

◆ RealtimeSuspend()

void RealtimeEffectManager::RealtimeSuspend ( )

Definition at line 217 of file RealtimeEffectManager.cpp.

218 {
219  mRealtimeLock.Enter();
220 
221  // Already suspended...bail
222  if (mRealtimeSuspended)
223  {
224  mRealtimeLock.Leave();
225  return;
226  }
227 
228  // Show that we aren't going to be doing anything
229  mRealtimeSuspended = true;
230 
231  // And make sure the effects don't either
232  for (auto &state : mStates)
233  state->RealtimeSuspend();
234 
235  mRealtimeLock.Leave();
236 }

References mRealtimeLock, mRealtimeSuspended, and mStates.

Referenced by RealtimeAddEffect(), RealtimeFinalize(), RealtimeInitialize(), RealtimeRemoveEffect(), and AudioIO::SetPaused().

Here is the caller graph for this function:

◆ RealtimeSuspendOne()

void RealtimeEffectManager::RealtimeSuspendOne ( EffectClientInterface effect)

Definition at line 238 of file RealtimeEffectManager.cpp.

239 {
240  auto begin = mStates.begin(), end = mStates.end();
241  auto found = std::find_if( begin, end,
242  [&effect]( const decltype( mStates )::value_type &state ){
243  return state && &state->GetEffect() == &effect;
244  }
245  );
246  if ( found != end )
247  (*found)->RealtimeSuspend();
248 }

References mStates.

Referenced by EffectUIHost::OnEnable().

Here is the caller graph for this function:

Member Data Documentation

◆ mRealtimeActive

bool RealtimeEffectManager::mRealtimeActive
private

◆ mRealtimeChans

std::vector<unsigned> RealtimeEffectManager::mRealtimeChans
private

◆ mRealtimeLatency

int RealtimeEffectManager::mRealtimeLatency
private

◆ mRealtimeLock

wxCriticalSection RealtimeEffectManager::mRealtimeLock
private

◆ mRealtimeRates

std::vector<double> RealtimeEffectManager::mRealtimeRates
private

◆ mRealtimeSuspended

bool RealtimeEffectManager::mRealtimeSuspended
private

◆ mStates

std::vector< std::unique_ptr<RealtimeEffectState> > RealtimeEffectManager::mStates
private

The documentation for this class was generated from the following files:
RealtimeEffectManager::mRealtimeChans
std::vector< unsigned > mRealtimeChans
Definition: RealtimeEffectManager.h:56
EffectClientInterface::RealtimeInitialize
virtual bool RealtimeInitialize()=0
EffectClientInterface::RealtimeFinalize
virtual bool RealtimeFinalize()=0
RealtimeEffectManager::mRealtimeRates
std::vector< double > mRealtimeRates
Definition: RealtimeEffectManager.h:57
RealtimeEffectManager::mRealtimeLock
wxCriticalSection mRealtimeLock
Definition: RealtimeEffectManager.h:51
RealtimeEffectManager::RealtimeSuspend
void RealtimeSuspend()
Definition: RealtimeEffectManager.cpp:217
RealtimeEffectManager
Definition: RealtimeEffectManager.h:22
RealtimeEffectManager::mStates
std::vector< std::unique_ptr< RealtimeEffectState > > mStates
Definition: RealtimeEffectManager.h:52
RealtimeEffectManager::RealtimeResume
void RealtimeResume()
Definition: RealtimeEffectManager.cpp:250
RealtimeEffectManager::mRealtimeLatency
int mRealtimeLatency
Definition: RealtimeEffectManager.h:53
RealtimeEffectManager::mRealtimeActive
bool mRealtimeActive
Definition: RealtimeEffectManager.h:55
RealtimeEffectManager::mRealtimeSuspended
bool mRealtimeSuspended
Definition: RealtimeEffectManager.h:54