Audacity  2.2.2
EffectManager.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  EffectManager.cpp
6 
7  Audacity(R) is copyright (c) 1999-2008 Audacity Team.
8  License: GPL v2. See License.txt.
9 
10 ******************************************************************//*******************************************************************/
20 
21 #include "../Audacity.h"
22 
23 #include <algorithm>
24 #include <wx/stopwatch.h>
25 #include <wx/tokenzr.h>
26 
27 #include "../Experimental.h"
28 #include "../widgets/ErrorDialog.h"
29 
30 #if defined(EXPERIMENTAL_EFFECTS_RACK)
31 #include "EffectRack.h"
32 #endif
33 
34 #include "EffectManager.h"
35 #include "../commands/Command.h"
36 #include "../commands/CommandContext.h"
37 
38 
39 /*******************************************************************************
40 Creates a singleton and returns reference
41 
42  (Thread-safe...no active threading during construction or after destruction)
43 *******************************************************************************/
45 {
46  static EffectManager em;
47  return em;
48 }
49 
51 {
52  mRealtimeLock.Enter();
53  mRealtimeActive = false;
54  mRealtimeSuspended = true;
55  mRealtimeLatency = 0;
56  mRealtimeLock.Leave();
57  mSkipStateFlag = false;
58 
59 #if defined(EXPERIMENTAL_EFFECTS_RACK)
60  mRack = NULL;
61 #endif
62 }
63 
65 {
66 #if defined(EXPERIMENTAL_EFFECTS_RACK)
67  // wxWidgets has already destroyed the rack since it was derived from wxFrame. So
68  // no need to DELETE it here.
69 #endif
70 }
71 
72 // Here solely for the purpose of Nyquist Workbench until
73 // a better solution is devised.
75 {
77 
78  mEffects[ID] = f;
79 
80  return ID;
81 }
82 
83 // Here solely for the purpose of Nyquist Workbench until
84 // a better solution is devised.
86 {
87  PluginID id = ID;
89  mEffects.erase(id);
90 }
91 
93  wxWindow *parent,
94  double projectRate,
95  TrackList *list,
96  TrackFactory *factory,
97  SelectedRegion *selectedRegion,
98  bool shouldPrompt /* = true */)
99 
100 {
101  this->SetSkipStateFlag(false);
102  Effect *effect = GetEffect(ID);
103 
104  if (!effect)
105  {
106  return false;
107  }
108 
109 #if defined(EXPERIMENTAL_EFFECTS_RACK)
110  if (effect->SupportsRealtime())
111  {
112  GetRack()->Add(effect);
113  }
114 #endif
115 
116  bool res = effect->DoEffect(parent,
117  projectRate,
118  list,
119  factory,
120  selectedRegion,
121  shouldPrompt);
122 
123  return res;
124 }
125 
127  const CommandContext &context,
128  wxWindow *parent,
129  bool shouldPrompt /* = true */)
130 
131 {
132  this->SetSkipStateFlag(false);
133  AudacityCommand *command = GetAudacityCommand(ID);
134 
135  if (!command)
136  {
137  return false;
138  }
139 
140  bool res = command->DoAudacityCommand(parent, context, shouldPrompt);
141 
142  return res;
143 }
144 
146 {
147  return PluginManager::Get().GetSymbol(ID);
148 }
149 
151 {
152  return GetCommandSymbol(ID).Translation();
153 }
154 
156 {
157  auto effect = GetEffect(ID);
158  if (effect)
159  return effect->GetFamilyId().Translation();
160  return {};
161 }
162 
164 {
165  auto effect = GetEffect(ID);
166  if (effect)
167  return effect->GetVendor().Translation();
168  return {};
169 }
170 
172 {
173  wxString name = PluginManager::Get().GetSymbol(ID).Internal();
174 
175  // Get rid of leading and trailing white space
176  name.Trim(true).Trim(false);
177 
178  if (name == wxEmptyString)
179  {
180  return name;
181  }
182 
183  wxStringTokenizer st(name, wxT(" "));
184  wxString id;
185 
186  // CamelCase the name
187  while (st.HasMoreTokens())
188  {
189  wxString tok = st.GetNextToken();
190 
191  id += tok.Left(1).MakeUpper() + tok.Mid(1).MakeLower();
192  }
193 
194  return id;
195 }
196 
198 {
199  if (GetEffect(ID))
200  return wxString::Format(_("Applied effect: %s"), GetCommandName(ID));
201  if (GetAudacityCommand(ID))
202  return wxString::Format(_("Applied command: %s"), GetCommandName(ID));
203 
204  return wxEmptyString;
205 }
206 
208 {
209  Effect* pEff = GetEffect(ID);
210  if( pEff )
211  return pEff->ManualPage();
212  AudacityCommand * pCom = GetAudacityCommand(ID);
213  if( pCom )
214  return pCom->ManualPage();
215 
216  return wxEmptyString;
217 }
218 
220 {
221  Effect* pEff = GetEffect(ID);
222  if( pEff )
223  return pEff->GetDescription();
224  AudacityCommand * pCom = GetAudacityCommand(ID);
225  if( pCom )
226  return pCom->GetDescription();
227 
228  return wxEmptyString;
229 }
230 
231 
232 void EffectManager::GetCommandDefinition(const PluginID & ID, const CommandContext & context, int flags)
233 {
234  ParamsInterface *command;
235  command = GetEffect(ID);
236  if( !command )
237  command = GetAudacityCommand( ID );
238  if( !command )
239  return;
240 
241  ShuttleParams NullShuttle;
242  // Test if it defines any parameters at all.
243  bool bHasParams = command->DefineParams( NullShuttle );
244  if( (flags ==0) && !bHasParams )
245  return;
246 
247  // This is capturing the output context into the shuttle.
248  ShuttleGetDefinition S( *context.pOutput.get()->mStatusTarget.get() );
249  S.StartStruct();
250  S.AddItem( GetCommandIdentifier( ID ), "id" );
251  S.AddItem( GetCommandName( ID ), "name" );
252  if( bHasParams ){
253  S.StartField( "params" );
254  S.StartArray();
255  command->DefineParams( S );
256  S.EndArray();
257  S.EndField();
258  }
259  S.AddItem( GetCommandUrl( ID ), "url" );
260  S.AddItem( GetCommandTip( ID ), "tip" );
261  S.EndStruct();
262 }
263 
264 
265 
267 {
268  Effect *effect = GetEffect(ID);
269 
270  if (effect)
271  {
272  return effect->IsHidden();
273  }
274 
275  return false;
276 }
277 
279 {
280  mSkipStateFlag = flag;
281 }
282 
284 {
285  return mSkipStateFlag;
286 }
287 
289 {
290  const PluginDescriptor *plug = PluginManager::Get().GetPlugin(ID);
291  if (plug)
292  {
293  return plug->IsEffectAutomatable();
294  }
295 
296  return false;
297 }
298 
300 {
301  Effect *effect = GetEffect(ID);
302 
303  if (effect)
304  {
305  wxString parms;
306 
307  effect->GetAutomationParameters(parms);
308 
309  // Some effects don't have automatable parameters and will not return
310  // anything, so try to get the active preset (current or factory).
311  if (parms.IsEmpty())
312  {
313  parms = GetDefaultPreset(ID);
314  }
315 
316  return parms;
317  }
318 
319  AudacityCommand *command = GetAudacityCommand(ID);
320 
321  if (command)
322  {
323  wxString parms;
324 
325  command->GetAutomationParameters(parms);
326 
327  // Some effects don't have automatable parameters and will not return
328  // anything, so try to get the active preset (current or factory).
329  if (parms.IsEmpty())
330  {
331  parms = GetDefaultPreset(ID);
332  }
333 
334  return parms;
335  }
336  return wxEmptyString;
337 }
338 
339 bool EffectManager::SetEffectParameters(const PluginID & ID, const wxString & params)
340 {
341  Effect *effect = GetEffect(ID);
342 
343  if (effect)
344  {
345  CommandParameters eap(params);
346 
347  if (eap.HasEntry(wxT("Use Preset")))
348  {
349  return effect->SetAutomationParameters(eap.Read(wxT("Use Preset")));
350  }
351 
352  return effect->SetAutomationParameters(params);
353  }
354  AudacityCommand *command = GetAudacityCommand(ID);
355 
356  if (command)
357  {
358  // Set defaults (if not initialised) before setting values.
359  command->Init();
360  CommandParameters eap(params);
361 
362  if (eap.HasEntry(wxT("Use Preset")))
363  {
364  return command->SetAutomationParameters(eap.Read(wxT("Use Preset")));
365  }
366 
367  return command->SetAutomationParameters(params);
368  }
369  return false;
370 }
371 
372 bool EffectManager::PromptUser(const PluginID & ID, wxWindow *parent)
373 {
374  bool result = false;
375  Effect *effect = GetEffect(ID);
376 
377  if (effect)
378  {
379  result = effect->PromptUser(parent);
380  return result;
381  }
382 
383  AudacityCommand *command = GetAudacityCommand(ID);
384 
385  if (command)
386  {
387  result = command->PromptUser(parent);
388  return result;
389  }
390 
391  return result;
392 }
393 
395 {
396  Effect *effect = GetEffect(ID);
397 
398  if (!effect)
399  {
400  return false;
401  }
402 
403  return effect->GetUserPresets().GetCount() > 0 ||
404  effect->GetFactoryPresets().GetCount() > 0 ||
405  effect->HasCurrentSettings() ||
406  effect->HasFactoryDefaults();
407 }
408 
409 wxString EffectManager::GetPreset(const PluginID & ID, const wxString & params, wxWindow * parent)
410 {
411  Effect *effect = GetEffect(ID);
412 
413  if (!effect)
414  {
415  return wxEmptyString;
416  }
417 
418  CommandParameters eap(params);
419 
420  wxString preset;
421  if (eap.HasEntry(wxT("Use Preset")))
422  {
423  preset = eap.Read(wxT("Use Preset"));
424  }
425 
426  preset = effect->GetPreset(parent, preset);
427  if (preset.IsEmpty())
428  {
429  return preset;
430  }
431 
432  eap.DeleteAll();
433 
434  eap.Write(wxT("Use Preset"), preset);
435  eap.GetParameters(preset);
436 
437  return preset;
438 }
439 
441 {
442  Effect *effect = GetEffect(ID);
443 
444  if (!effect)
445  {
446  return wxEmptyString;
447  }
448 
449  wxString preset;
450  if (effect->HasCurrentSettings())
451  {
453  }
454  else if (effect->HasFactoryDefaults())
455  {
457  }
458 
459  if (!preset.IsEmpty())
460  {
461  CommandParameters eap;
462 
463  eap.Write(wxT("Use Preset"), preset);
464  eap.GetParameters(preset);
465  }
466 
467  return preset;
468 }
469 
470 void EffectManager::SetBatchProcessing(const PluginID & ID, bool start)
471 {
472  Effect *effect = GetEffect(ID);
473  if (effect)
474  {
475  effect->SetBatchProcessing(start);
476  return;
477  }
478 
479  AudacityCommand *command = GetAudacityCommand(ID);
480  if (command)
481  {
482  command->SetBatchProcessing(start);
483  return;
484  }
485 
486 }
487 
488 #if defined(EXPERIMENTAL_EFFECTS_RACK)
489 EffectRack *EffectManager::GetRack()
490 {
491  if (!mRack)
492  {
493  // EffectRack is constructed with the current project as owner, so safenew is OK
494  mRack = safenew EffectRack();
495  // Make sure what I just commented remains true:
496  wxASSERT(mRack->GetParent());
497  mRack->CenterOnParent();
498  }
499 
500  return mRack;
501 }
502 
503 void EffectManager::ShowRack()
504 {
505  GetRack()->Show(!GetRack()->IsShown());
506 }
507 
509 {
510  // Block RealtimeProcess()
511  RealtimeSuspend();
512 
513  // Tell any effects no longer in the chain to clean up
514  for (auto e: mRealtimeEffects)
515  {
516  // Scan the NEW chain for the effect
517  for (auto e1: effects)
518  {
519  // Found it so we're done
520  if (e == e1)
521  {
522  e = NULL;
523  break;
524  }
525  }
526 
527  // Must not have been in the NEW chain, so tell it to cleanup
528  if (e && mRealtimeActive)
529  {
530  e->RealtimeFinalize();
531  }
532  }
533 
534  // Tell any NEW effects to get ready
535  for (auto e : effects)
536  {
537  // Scan the old chain for the effect
538  for (auto e1 : mRealtimeEffects)
539  {
540  // Found it so tell effect to get ready
541  if (e == e1)
542  {
543  e = NULL;
544  break;
545  }
546  }
547 
548  // Must not have been in the old chain, so tell it to initialize
549  if (e && mRealtimeActive)
550  {
551  e->RealtimeInitialize();
552  }
553  }
554 
555  // Get rid of the old chain
556  // And install the NEW one
557  mRealtimeEffects = effects;
558 
559  // Allow RealtimeProcess() to, well, process
560  RealtimeResume();
561 }
562 #endif
563 
565 {
566  return mRealtimeEffects.size() != 0;
567 }
568 
570 {
571  return mRealtimeSuspended;
572 }
573 
575 {
576  // Block RealtimeProcess()
577  RealtimeSuspend();
578 
579  // Initialize effect if realtime is already active
580  if (mRealtimeActive)
581  {
582  // Initialize realtime processing
583  effect->RealtimeInitialize();
584 
585  // Add the required processors
586  for (size_t i = 0, cnt = mRealtimeChans.size(); i < cnt; i++)
587  {
589  }
590  }
591 
592  // Add to list of active effects
593  mRealtimeEffects.push_back(effect);
594 
595  // Allow RealtimeProcess() to, well, process
596  RealtimeResume();
597 }
598 
600 {
601  // Block RealtimeProcess()
602  RealtimeSuspend();
603 
604  if (mRealtimeActive)
605  {
606  // Cleanup realtime processing
607  effect->RealtimeFinalize();
608  }
609 
610  // Remove from list of active effects
611  auto end = mRealtimeEffects.end();
612  auto found = std::find(mRealtimeEffects.begin(), end, effect);
613  if (found != end)
614  mRealtimeEffects.erase(found);
615 
616  // Allow RealtimeProcess() to, well, process
617  RealtimeResume();
618 }
619 
621 {
622  // The audio thread should not be running yet, but protect anyway
623  RealtimeSuspend();
624 
625  // (Re)Set processor parameters
626  mRealtimeChans.clear();
627  mRealtimeRates.clear();
628 
629  // RealtimeAdd/RemoveEffect() needs to know when we're active so it can
630  // initialize newly added effects
631  mRealtimeActive = true;
632 
633  // Tell each effect to get ready for action
634  for (auto e : mRealtimeEffects) {
635  e->SetSampleRate(rate);
636  e->RealtimeInitialize();
637  }
638 
639  // Get things moving
640  RealtimeResume();
641 }
642 
643 void EffectManager::RealtimeAddProcessor(int group, unsigned chans, float rate)
644 {
645  for (auto e : mRealtimeEffects)
646  e->RealtimeAddProcessor(group, chans, rate);
647 
648  mRealtimeChans.push_back(chans);
649  mRealtimeRates.push_back(rate);
650 }
651 
653 {
654  // Make sure nothing is going on
655  RealtimeSuspend();
656 
657  // It is now safe to clean up
658  mRealtimeLatency = 0;
659 
660  // Tell each effect to clean up as well
661  for (auto e : mRealtimeEffects)
662  e->RealtimeFinalize();
663 
664  // Reset processor parameters
665  mRealtimeChans.clear();
666  mRealtimeRates.clear();
667 
668  // No longer active
669  mRealtimeActive = false;
670 }
671 
673 {
674  mRealtimeLock.Enter();
675 
676  // Already suspended...bail
677  if (mRealtimeSuspended)
678  {
679  mRealtimeLock.Leave();
680  return;
681  }
682 
683  // Show that we aren't going to be doing anything
684  mRealtimeSuspended = true;
685 
686  // And make sure the effects don't either
687  for (auto e : mRealtimeEffects)
688  e->RealtimeSuspend();
689 
690  mRealtimeLock.Leave();
691 }
692 
694 {
695  mRealtimeLock.Enter();
696 
697  // Already running...bail
698  if (!mRealtimeSuspended)
699  {
700  mRealtimeLock.Leave();
701  return;
702  }
703 
704  // Tell the effects to get ready for more action
705  for (auto e : mRealtimeEffects)
706  e->RealtimeResume();
707 
708  // And we should too
709  mRealtimeSuspended = false;
710 
711  mRealtimeLock.Leave();
712 }
713 
714 //
715 // This will be called in a different thread than the main GUI thread.
716 //
718 {
719  // Protect ourselves from the main thread
720  mRealtimeLock.Enter();
721 
722  // Can be suspended because of the audio stream being paused or because effects
723  // have been suspended.
724  if (!mRealtimeSuspended)
725  {
726  for (auto e : mRealtimeEffects)
727  {
728  if (e->IsRealtimeActive())
729  e->RealtimeProcessStart();
730  }
731  }
732 
733  mRealtimeLock.Leave();
734 }
735 
736 //
737 // This will be called in a different thread than the main GUI thread.
738 //
739 size_t EffectManager::RealtimeProcess(int group, unsigned chans, float **buffers, size_t numSamples)
740 {
741  // Protect ourselves from the main thread
742  mRealtimeLock.Enter();
743 
744  // Can be suspended because of the audio stream being paused or because effects
745  // have been suspended, so allow the samples to pass as-is.
746  if (mRealtimeSuspended || mRealtimeEffects.empty())
747  {
748  mRealtimeLock.Leave();
749  return numSamples;
750  }
751 
752  // Remember when we started so we can calculate the amount of latency we
753  // are introducing
754  wxMilliClock_t start = wxGetLocalTimeMillis();
755 
756  // Allocate the in/out buffer arrays
757  float **ibuf = (float **) alloca(chans * sizeof(float *));
758  float **obuf = (float **) alloca(chans * sizeof(float *));
759 
760  // And populate the input with the buffers we've been given while allocating
761  // NEW output buffers
762  for (unsigned int i = 0; i < chans; i++)
763  {
764  ibuf[i] = buffers[i];
765  obuf[i] = (float *) alloca(numSamples * sizeof(float));
766  }
767 
768  // Now call each effect in the chain while swapping buffer pointers to feed the
769  // output of one effect as the input to the next effect
770  size_t called = 0;
771  for (auto e : mRealtimeEffects)
772  {
773  if (e->IsRealtimeActive())
774  {
775  e->RealtimeProcess(group, chans, ibuf, obuf, numSamples);
776  called++;
777  }
778 
779  for (unsigned int j = 0; j < chans; j++)
780  {
781  float *temp;
782  temp = ibuf[j];
783  ibuf[j] = obuf[j];
784  obuf[j] = temp;
785  }
786  }
787 
788  // Once we're done, we might wind up with the last effect storing its results
789  // in the temporary buffers. If that's the case, we need to copy it over to
790  // the caller's buffers. This happens when the number of effects proccessed
791  // is odd.
792  if (called & 1)
793  {
794  for (unsigned int i = 0; i < chans; i++)
795  {
796  memcpy(buffers[i], ibuf[i], numSamples * sizeof(float));
797  }
798  }
799 
800  // Remember the latency
801  mRealtimeLatency = (int) (wxGetLocalTimeMillis() - start).GetValue();
802 
803  mRealtimeLock.Leave();
804 
805  //
806  // This is wrong...needs to handle tails
807  //
808  return numSamples;
809 }
810 
811 //
812 // This will be called in a different thread than the main GUI thread.
813 //
815 {
816  // Protect ourselves from the main thread
817  mRealtimeLock.Enter();
818 
819  // Can be suspended because of the audio stream being paused or because effects
820  // have been suspended.
821  if (!mRealtimeSuspended)
822  {
823  for (auto e : mRealtimeEffects)
824  {
825  if (e->IsRealtimeActive())
826  e->RealtimeProcessEnd();
827  }
828  }
829 
830  mRealtimeLock.Leave();
831 }
832 
834 {
835  return mRealtimeLatency;
836 }
837 
839 {
840  // Must have a "valid" ID
841  if (ID.IsEmpty())
842  {
843  return NULL;
844  }
845 
846  // If it is actually a command then refuse it (as an effect).
847  if( mCommands.find( ID ) != mCommands.end() )
848  return NULL;
849 
850  // TODO: This is temporary and should be redone when all effects are converted
851  if (mEffects.find(ID) == mEffects.end())
852  {
853  // This will instantiate the effect client if it hasn't already been done
855  if (ident && ident->IsLegacy())
856  {
857  auto effect = dynamic_cast<Effect *>(ident);
858  if (effect && effect->Startup(NULL))
859  {
860  mEffects[ID] = effect;
861  return effect;
862  }
863  }
864 
865  auto effect = std::make_shared<Effect>(); // TODO: use make_unique and store in std::unordered_map
866  if (effect)
867  {
868  EffectClientInterface *client = dynamic_cast<EffectClientInterface *>(ident);
869  if (client && effect->Startup(client))
870  {
871  auto pEffect = effect.get();
872  mEffects[ID] = pEffect;
873  mHostEffects[ID] = std::move(effect);
874  return pEffect;
875  }
876  }
877 
878  auto command = dynamic_cast<AudacityCommand *>(PluginManager::Get().GetInstance(ID));
879  if( !command )
880  AudacityMessageBox(wxString::Format(_("Attempting to initialize the following effect failed:\n\n%s\n\nMore information may be available in Help->Show Log"),
881  GetCommandName(ID)),
882  _("Effect failed to initialize"));
883 
884  return NULL;
885  }
886 
887  return mEffects[ID];
888 }
889 
891 {
892  // Must have a "valid" ID
893  if (ID.IsEmpty())
894  {
895  return NULL;
896  }
897 
898  // TODO: This is temporary and should be redone when all effects are converted
899  if (mCommands.find(ID) == mCommands.end())
900  {
901 
902  // This will instantiate the effect client if it hasn't already been done
903  auto command = dynamic_cast<AudacityCommand *>(PluginManager::Get().GetInstance(ID));
904  if (command )//&& command->Startup(NULL))
905  {
906  command->Init();
907  mCommands[ID] = command;
908  return command;
909  }
910 
911  /*
912  if (ident && ident->IsLegacy())
913  {
914  auto command = dynamic_cast<AudacityCommand *>(ident);
915  if (commandt && command->Startup(NULL))
916  {
917  mCommands[ID] = command;
918  return command;
919  }
920  }
921 
922 
923  auto command = std::make_shared<AudacityCommand>(); // TODO: use make_unique and store in std::unordered_map
924  if (command)
925  {
926  AudacityCommand *client = dynamic_cast<AudacityCommand *>(ident);
927  if (client && command->Startup(client))
928  {
929  auto pCommand = command.get();
930  mEffects[ID] = pCommand;
931  mHostEffects[ID] = std::move(effect);
932  return pEffect;
933  }
934  }
935 */
936  AudacityMessageBox(wxString::Format(_("Attempting to initialize the following command failed:\n\n%s\n\nMore information may be available in Help->Show Log"),
937  GetCommandName(ID)),
938  _("Command failed to initialize"));
939 
940  return NULL;
941  }
942 
943  return mCommands[ID];
944 }
945 
946 
947 const PluginID & EffectManager::GetEffectByIdentifier(const wxString & strTarget)
948 {
949  static PluginID empty;
950  if (strTarget == wxEmptyString) // set GetCommandIdentifier to wxT("") to not show an effect in Batch mode
951  {
952  return empty;
953  }
954 
956  // Effects OR Generic commands...
958  while (plug)
959  {
960  if (GetCommandIdentifier(plug->GetID()).IsSameAs(strTarget, false))
961  {
962  return plug->GetID();
963  }
965  }
966  return empty;;
967 }
968 
virtual bool PromptUser(wxWindow *parent)
A list of TrackListNode items.
Definition: Track.h:618
const PluginDescriptor * GetFirstPlugin(int type)
static CommandHandlerObject & ident(AudacityProject &project)
Definition: Menus.cpp:298
virtual void SetBatchProcessing(bool start)
Definition: Effect.cpp:1142
virtual ~EffectManager()
size_t RealtimeProcess(int group, unsigned chans, float **buffers, size_t numSamples)
bool DoEffect(const PluginID &ID, wxWindow *parent, double projectRate, TrackList *list, TrackFactory *factory, SelectedRegion *selectedRegion, bool shouldPrompt=true)
std::unique_ptr< CommandOutputTargets > pOutput
bool HasPresets(const PluginID &ID)
const PluginID & RegisterEffect(Effect *f)
EffectMap mEffects
bool SetAutomationParameters(CommandParameters &parms) override
Definition: Effect.cpp:574
IdentInterfaceSymbol GetCommandSymbol(const PluginID &ID)
void RealtimeAddProcessor(int group, unsigned chans, float rate)
wxString GetEffectFamilyName(const PluginID &ID)
virtual wxString GetDescription() override
wxString GetDefaultPreset(const PluginID &ID)
virtual wxString ManualPage()
Definition: Effect.cpp:1127
const PluginID & GetEffectByIdentifier(const wxString &strTarget)
wxString PluginID
Definition: Types.h:209
bool DoEffect(wxWindow *parent, double projectRate, TrackList *list, TrackFactory *factory, SelectedRegion *selectedRegion, bool shouldPrompt=true)
Definition: Effect.cpp:1156
virtual wxString GetPreset(wxWindow *parent, const wxString &parms)
Definition: Effect.cpp:1110
Base class for many of the effects in Audacity.
Definition: Effect.h:62
const PluginDescriptor * GetNextPlugin(int type)
int AudacityMessageBox(const wxString &message, const wxString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: ErrorDialog.h:92
virtual bool HasCurrentSettings()
Definition: Effect.cpp:1100
CommandContext provides addiitonal information to an 'Apply()' command. It provides the project...
Shuttle that deals with parameters. This is a base class with lots of virtual functions that do nothi...
Definition: Shuttle.h:60
bool IsEffectAutomatable() const
Shuttle that retrieves a JSON format definition of a command's parameters.
Definition: Shuttle.h:129
wxString GetDescription() override
Definition: Effect.cpp:198
EffectArray mRealtimeEffects
virtual bool GetAutomationParameters(wxString &parms)
std::vector< double > mRealtimeRates
#define safenew
Definition: Audacity.h:230
const wxString & Translation() const
Used to create a WaveTrack, or a LabelTrack.. Implementation of the functions of this class are dispe...
Definition: Track.h:862
virtual void SetBatchProcessing(bool start)
const IdentInterfaceSymbol & GetSymbol(const PluginID &ID)
virtual bool HasFactoryDefaults()
Definition: Effect.cpp:1105
wxCriticalSection mRealtimeLock
wxString GetCommandDescription(const PluginID &ID)
bool IsHidden(const PluginID &ID)
bool GetSkipStateFlag()
AudacityCommandMap mCommands
EffectDefinitionInterface is a CommandDefinitionInterface that additionally tracks flag-functions for...
wxArrayString GetFactoryPresets() override
Definition: Effect.cpp:616
Defines a selected portion of a project.
void RealtimeSetEffects(const EffectArray &mActive)
virtual bool Init()
Effect * GetEffect(const PluginID &ID)
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the Shuttle cla...
wxString GetCommandUrl(const PluginID &ID)
bool RealtimeFinalize() override
Definition: Effect.cpp:427
void RealtimeInitialize(double rate)
wxString GetVendorName(const PluginID &ID)
bool SupportsAutomation(const PluginID &ID)
void RealtimeRemoveEffect(Effect *effect)
bool RealtimeAddProcessor(unsigned numChannels, float sampleRate) override
Definition: Effect.cpp:417
bool GetParameters(wxString &parms)
EffectManager is the class that handles effects and effect categories.
Definition: EffectManager.h:45
void UnregisterPlugin(const PluginID &ID)
IdentInterfaceSymbol pairs a persistent string identifier used internally with an optional...
Base class for command in Audacity.
virtual wxString ManualPage()
static EffectManager & Get()
bool PromptUser(const PluginID &ID, wxWindow *parent)
std::vector< Effect * > EffectArray
Definition: EffectManager.h:34
wxString GetPreset(const PluginID &ID, const wxString &params, wxWindow *parent)
virtual bool SetAutomationParameters(const wxString &parms)
bool RealtimeInitialize() override
Definition: Effect.cpp:404
PluginManager maintains a list of all plug ins. That covers modules, effects, generators, analysis-effects, commands. It also has functions for shared and private configs - which need to move out.
ParamsInterface provides a DefineParameters virtual function, that defines the parameters of the comm...
bool GetAutomationParameters(CommandParameters &parms) override
Definition: Effect.cpp:564
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
wxString GetEffectParameters(const PluginID &ID)
bool DoAudacityCommand(const PluginID &ID, const CommandContext &, wxWindow *parent, bool shouldPrompt=true)
virtual bool IsHidden()
Definition: Effect.cpp:2467
const wxChar * name
Definition: Distortion.cpp:94
const wxString & GetID() const
const PluginID & RegisterPlugin(ModuleInterface *module) override
virtual bool DefineParams(ShuttleParams &WXUNUSED(S))
const wxString & Internal() const
void SetSkipStateFlag(bool flag)
wxString GetCommandName(const PluginID &ID)
EffectClientInterface provides the ident interface to Effect, and is what makes Effect into a plug-in...
wxString GetCommandIdentifier(const PluginID &ID)
void UnregisterEffect(const PluginID &ID)
static const wxString kCurrentSettingsIdent
Definition: Effect.h:543
EffectOwnerMap mHostEffects
bool SupportsRealtime() override
Definition: Effect.cpp:250
bool mRealtimeSuspended
void RealtimeAddEffect(Effect *effect)
bool RealtimeIsSuspended()
IdentInterface * GetInstance(const PluginID &ID)
static PluginManager & Get()
wxString GetCommandTip(const PluginID &ID)
int GetRealtimeLatency()
void RealtimeFinalize()
EffectDistortion::Params params
Definition: Distortion.cpp:95
virtual bool PromptUser(wxWindow *parent)
Definition: Effect.cpp:1270
const PluginDescriptor * GetPlugin(const PluginID &ID)
void RealtimeSuspend()
AudacityCommand * GetAudacityCommand(const PluginID &ID)
void RealtimeProcessEnd()
bool RealtimeIsActive()
std::vector< unsigned > mRealtimeChans
virtual wxArrayString GetUserPresets()
Definition: Effect.cpp:1089
virtual bool HasEntry(const wxString &strName) const override
void SetBatchProcessing(const PluginID &ID, bool start)
virtual bool IsLegacy()=0
void GetCommandDefinition(const PluginID &ID, const CommandContext &context, int flags)
static const wxString kFactoryDefaultsIdent
Definition: Effect.h:544
void RealtimeProcessStart()
bool DoAudacityCommand(wxWindow *parent, const CommandContext &context, bool shouldPrompt=true)
bool SetEffectParameters(const PluginID &ID, const wxString &params)