Audacity  3.0.3
AudioUnitEffect.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  AudioUnitEffect.cpp
6 
7  Dominic Mazzoni
8  Leland Lucius
9 
10 *******************************************************************//*******************************************************************/
16 
17 
18 
19 #if USE_AUDIO_UNITS
20 #include "AudioUnitEffect.h"
21 #include "../../ModuleManager.h"
22 #include "SampleCount.h"
23 
24 #include <wx/defs.h>
25 #include <wx/base64.h>
26 #include <wx/button.h>
27 #include <wx/control.h>
28 #include <wx/crt.h>
29 #include <wx/dir.h>
30 #include <wx/ffile.h>
31 
32 #ifdef __WXMAC__
33 #include <wx/evtloop.h>
34 #endif
35 
36 #include <wx/filename.h>
37 #include <wx/frame.h>
38 #include <wx/listctrl.h>
39 #include <wx/log.h>
40 #include <wx/sizer.h>
41 #include <wx/settings.h>
42 #include <wx/stattext.h>
43 #include <wx/textctrl.h>
44 #include <wx/tokenzr.h>
45 
46 #include "../../ShuttleGui.h"
47 #include "../../widgets/AudacityMessageBox.h"
48 #include "../../widgets/valnum.h"
49 #include "../../widgets/wxPanelWrapper.h"
50 
51 //
52 // When a plug-ins state is saved to the settings file (as a preset),
53 // it can be one of two formats, binary or XML. In either case, it
54 // gets base64 encoded before storing.
55 //
56 // The advantages of XML format is less chance of failures occurring
57 // when exporting. But, it can take a bit more space per preset int
58 // the Audacity settings file.
59 //
60 // Using binary for now. Use kCFPropertyListXMLFormat_v1_0 if XML
61 // format is desired.
62 //
63 #define PRESET_FORMAT kCFPropertyListBinaryFormat_v1_0
64 
65 // Name of the settings key to use for the above value
66 #define PRESET_KEY wxT("Data")
67 
68 // Where the presets are located
69 #define PRESET_LOCAL_PATH wxT("/Library/Audio/Presets")
70 #define PRESET_USER_PATH wxT("~/Library/Audio/Presets")
71 
72 static const struct
73 {
75  OSType componentType;
77 }
78 BlackList[] =
79 {
80  { 'appl', 'augn', 'afpl' }, // Apple: AUAudioFilePlayer
81  { 'appl', 'augn', 'sspl' }, // Apple: AUScheduledSoundPlayer
82  { 'appl', 'augn', 'ttsp' }, // Apple: AUSpeechSynthesis
83  { 'appl', 'augn', 'nrcv' }, // Apple: AUNetReceive
84  { 'appl', 'aumx', '3dmx' }, // Apple: AUMixer3D
85  { 'appl', 'aumx', 'mspl' }, // Apple: AUMultiSplitter
86  { 'appl', 'aumx', 'mxcm' }, // Apple: AUMultiChannelMixer
87  { 'appl', 'aumx', 'mxmx' }, // Apple: AUMatrixMixer
88  { 'appl', 'aumx', 'smxr' }, // Apple: AUMixer
89 };
90 
91 struct CFReleaser
92 {
93  void operator () (const void *p) const
94  {
95  if (p) CFRelease(p);
96  }
97 };
98 template <typename T> using CFunique_ptr = std::unique_ptr<T, CFReleaser>;
99 
100 // Uncomment to include parameter IDs in the final name. Only needed if it's
101 // discovered that many effects have duplicate names. It could even be done
102 // at runtime by scanning an effects parameters to determine if dups are present
103 // and, if so, enable the clump and parameter IDs.
104 #define USE_EXTENDED_NAMES
106 {
107 public:
109  {
110  info = {};
111  }
112 
113  virtual ~ParameterInfo()
114  {
115  if (info.flags & kAudioUnitParameterFlag_HasCFNameString)
116  {
117  if (info.flags & kAudioUnitParameterFlag_CFNameRelease)
118  {
119  CFRelease(info.cfNameString);
120  }
121  }
122  }
123 
124  bool Get(AudioUnit mUnit, AudioUnitParameterID parmID)
125  {
126  OSStatus result;
127  UInt32 dataSize;
128 
129  info = {};
130  dataSize = sizeof(info);
131  result = AudioUnitGetProperty(mUnit,
132  kAudioUnitProperty_ParameterInfo,
133  kAudioUnitScope_Global,
134  parmID,
135  &info,
136  &dataSize);
137  if (result != noErr)
138  {
139  return false;
140  }
141 
142  if (info.flags & kAudioUnitParameterFlag_HasCFNameString)
143  {
144  name = wxCFStringRef::AsString(info.cfNameString);
145  }
146  else
147  {
148  name = wxString(info.name);
149  }
150 
151 #if defined(USE_EXTENDED_NAMES)
152  // If the parameter has a non-empty name, then the final parameter name will
153  // be either:
154  //
155  // <parmID,ParameterName>
156  //
157  // or (if the name isn't available):
158  //
159  // <parmID>
160  if (!name.empty())
161  {
162  name.Replace(idBeg, wxT('_'));
163  name.Replace(idSep, wxT('_'));
164  name.Replace(idEnd, wxT('_'));
165  name.Append(idSep);
166  }
167  name = wxString::Format(wxT("%c%s%x%c"),
168  idBeg,
169  name,
170  parmID,
171  idEnd);
172 
173  // If the parameter has a clumpID, then the final parameter name will be
174  // either:
175  //
176  // <clumpID,clumpName><parmID,ParameterName>
177  //
178  // or (if the clumpName isn't available):
179  //
180  // <clumpID><parmID,ParameterName>
181  if (info.flags & kAudioUnitParameterFlag_HasClump)
182  {
183  wxString clumpName;
184 
185  AudioUnitParameterNameInfo clumpInfo = {};
186  clumpInfo.inID = info.clumpID;
187  clumpInfo.inDesiredLength = kAudioUnitParameterName_Full;
188  dataSize = sizeof(clumpInfo);
189 
190  result = AudioUnitGetProperty(mUnit,
191  kAudioUnitProperty_ParameterClumpName,
192  kAudioUnitScope_Global,
193  0,
194  &clumpInfo,
195  &dataSize);
196  if (result == noErr)
197  {
198  clumpName = wxCFStringRef::AsString(clumpInfo.outName);
199  clumpName.Replace(idBeg, wxT('_'));
200  clumpName.Replace(idSep, wxT('_'));
201  clumpName.Replace(idEnd, wxT('_'));
202  clumpName.Append(idSep);
203  }
204  name = wxString::Format(wxT("%c%s%x%c%s"),
205  idBeg,
206  clumpName,
207  info.clumpID,
208  idEnd,
209  name);
210  }
211 #endif
212 
213  return true;
214  }
215 
216  static const char idBeg = wxT('<');
217  static const char idSep = wxT(',');
218  static const char idEnd = wxT('>');
219 
220  wxString name;
221  AudioUnitParameterInfo info;
222 };
223 
224 // ============================================================================
225 // Module registration entry point
226 //
227 // This is the symbol that Audacity looks for when the module is built as a
228 // dynamic library.
229 //
230 // When the module is builtin to Audacity, we use the same function, but it is
231 // declared static so as not to clash with other builtin modules.
232 // ============================================================================
233 DECLARE_MODULE_ENTRY(AudacityModule)
234 {
235  // Create and register the importer
236  // Trust the module manager not to leak this
238 }
239 
240 // ============================================================================
241 // Register this as a builtin module
242 // ============================================================================
243 DECLARE_BUILTIN_MODULE(AudioUnitEffectsBuiltin);
244 
246 //
247 // AudioUnitEffectsModule
248 //
250 
252 {
253 }
254 
256 {
257 }
258 
259 // ============================================================================
260 // ComponentInterface implementation
261 // ============================================================================
262 
264 {
265  return {};
266 }
267 
269 {
270  /* i18n-hint: Audio Unit is the name of an Apple audio software protocol */
271  return XO("Audio Unit Effects");
272 }
273 
275 {
276  return XO("The Audacity Team");
277 }
278 
280 {
281  // This "may" be different if this were to be maintained as a separate DLL
283 }
284 
286 {
287  return XO("Provides Audio Unit Effects support to Audacity");
288 }
289 
290 // ============================================================================
291 // ModuleInterface implementation
292 // ============================================================================
293 
295 {
296  static FileExtensions result{{ _T("au") }};
297  return result;
298 }
299 
301 {
302  // Nothing to do here
303  return true;
304 }
305 
307 {
308  // Nothing to do here
309  return;
310 }
311 
313 {
314 #if USE_AUDIO_UNITS
316 #else
317  return {};
318 #endif
319 }
320 
322 {
323  // Nothing to be done here
324  return true;
325 }
326 
328 {
329  PluginPaths effects;
330 
331  LoadAudioUnitsOfType(kAudioUnitType_Effect, effects);
332  LoadAudioUnitsOfType(kAudioUnitType_Generator, effects);
333  LoadAudioUnitsOfType(kAudioUnitType_Mixer, effects);
334  LoadAudioUnitsOfType(kAudioUnitType_MusicEffect, effects);
335  LoadAudioUnitsOfType(kAudioUnitType_Panner, effects);
336 
337  return effects;
338 }
339 
341  const PluginPath & path, TranslatableString &errMsg,
342  const RegistrationCallback &callback)
343 {
344  errMsg = {};
345  wxString name;
346  AudioComponent component = FindAudioUnit(path, name);
347  if (component == NULL)
348  {
349  errMsg = XO("Could not find component");
350  return 0;
351  }
352 
353  AudioUnitEffect effect(path, name, component);
354  if (!effect.SetHost(NULL))
355  {
356  // TODO: Is it worth it to discriminate all the ways SetHost might
357  // return false?
358  errMsg = XO("Could not initialize component");
359  return 0;
360  }
361 
362  if (callback)
363  {
364  callback(this, &effect);
365  }
366 
367  return 1;
368 }
369 
370 bool AudioUnitEffectsModule::IsPluginValid(const PluginPath & path, bool bFast)
371 {
372  if (bFast)
373  {
374  return true;
375  }
376 
377  wxString name;
378  return FindAudioUnit(path, name) != NULL;
379 }
380 
381 std::unique_ptr<ComponentInterface>
383 {
384  // Acquires a resource for the application.
385  if (wxString name; auto component = FindAudioUnit(path, name))
386  return std::make_unique<AudioUnitEffect>(path, name, component);
387  return nullptr;
388 }
389 
390 // ============================================================================
391 // AudioUnitEffectsModule implementation
392 // ============================================================================
393 
395  PluginPaths & effects)
396 {
397  AudioComponentDescription desc;
398  AudioComponent component;
399 
400  desc.componentType = inAUType;
401  desc.componentSubType = 0;
402  desc.componentManufacturer = 0;
403  desc.componentFlags = 0;
404  desc.componentFlagsMask = 0;
405 
406  component = AudioComponentFindNext(NULL, &desc);
407  while (component != NULL)
408  {
409  OSStatus result;
410  AudioComponentDescription found;
411 
412  result = AudioComponentGetDescription(component, &found);
413  if (result == noErr)
414  {
415  CFStringRef cfName{};
416  result = AudioComponentCopyName(component, &cfName);
417  CFunique_ptr<const __CFString> uName{ cfName };
418 
419  if (result == noErr)
420  {
421  wxString path;
422 
423  path.Printf(wxT("%-4.4s/%-4.4s/%-4.4s/%s"),
424  FromOSType(found.componentManufacturer),
425  FromOSType(found.componentType),
426  FromOSType(found.componentSubType),
427  wxCFStringRef::AsString(cfName));
428 
429  for (int i = 0; i < WXSIZEOF(BlackList); ++i)
430  {
431  if (BlackList[i].componentType == found.componentType &&
432  BlackList[i].componentSubType == found.componentSubType &&
433  BlackList[i].componentManufacturer == found.componentManufacturer)
434  {
435  wxLogDebug(wxT("Blacklisted AU skipped: %s"), path);
436  result = !noErr;
437  break;
438  }
439  }
440 
441  if (result == noErr)
442  {
443  effects.push_back(path);
444  }
445  }
446  }
447 
448  component = AudioComponentFindNext(component, &desc);
449  }
450 }
451 
453  wxString & name)
454 {
455  wxStringTokenizer tokens(path, wxT("/"));
456 
457  AudioComponentDescription desc;
458 
459  desc.componentManufacturer = ToOSType(tokens.GetNextToken());
460  desc.componentType = ToOSType(tokens.GetNextToken());
461  desc.componentSubType = ToOSType(tokens.GetNextToken());
462  desc.componentFlags = 0;
463  desc.componentFlagsMask = 0;
464 
465  name = tokens.GetNextToken();
466  return AudioComponentFindNext(NULL, &desc);
467 }
468 
470 {
471  OSType rev = (type & 0xff000000) >> 24 |
472  (type & 0x00ff0000) >> 8 |
473  (type & 0x0000ff00) << 8 |
474  (type & 0x000000ff) << 24;
475 
476  return wxString::FromUTF8((char *)&rev, 4);
477 }
478 
479 OSType AudioUnitEffectsModule::ToOSType(const wxString & type)
480 {
481  wxCharBuffer buf = type.ToUTF8();
482 
483  OSType rev = ((unsigned char)buf.data()[0]) << 24 |
484  ((unsigned char)buf.data()[1]) << 16 |
485  ((unsigned char)buf.data()[2]) << 8 |
486  ((unsigned char)buf.data()[3]);
487 
488  return rev;
489 }
490 
492 //
493 // AudioUnitEffectOptionsDialog
494 //
496 
498 {
499 public:
500  AudioUnitEffectOptionsDialog(wxWindow * parent, EffectHostInterface *host);
502 
503  void PopulateOrExchange(ShuttleGui & S);
504 
505  void OnOk(wxCommandEvent & evt);
506 
507 private:
509 
512 
513  DECLARE_EVENT_TABLE()
514 };
515 
519 
521 : wxDialogWrapper(parent, wxID_ANY, XO("Audio Unit Effect Options"))
522 {
523  mHost = host;
524 
525  mHost->GetSharedConfig(wxT("Options"), wxT("UseLatency"), mUseLatency, true);
526 
527  // Expect one of three string values from the config file
528  wxString uiType;
529  mHost->GetSharedConfig(wxT("Options"), wxT("UIType"), uiType, wxT("Full"));
530 
531  // Get the localization of the string for display to the user
532  mUIType = TranslatableString{ uiType, {} };
533 
534  ShuttleGui S(this, eIsCreating);
535  PopulateOrExchange(S);
536 }
537 
539 {
540 }
541 
543 {
544 
545  S.SetBorder(5);
546  S.StartHorizontalLay(wxEXPAND, 1);
547  {
548  S.StartVerticalLay(false);
549  {
550  S.StartStatic(XO("Latency Compensation"));
551  {
553 "As part of their processing, some Audio Unit effects must delay returning "
554 "audio to Audacity. When not compensating for this delay, you will "
555 "notice that small silences have been inserted into the audio. "
556 "Enabling this option will provide that compensation, but it may "
557 "not work for all Audio Unit effects."),
558  false, 0, 650);
559 
560  S.StartHorizontalLay(wxALIGN_LEFT);
561  {
562  S.TieCheckBox(XXO("Enable &compensation"),
563  mUseLatency);
564  }
565  S.EndHorizontalLay();
566  }
567  S.EndStatic();
568 
569  S.StartStatic(XO("User Interface"));
570  {
572 "Select \"Full\" to use the graphical interface if supplied by the Audio Unit."
573 " Select \"Generic\" to use the system supplied generic interface."
574 #if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
575 " Select \"Basic\" for a basic text-only interface."
576 #endif
577 " Reopen the effect for this to take effect."),
578  false, 0, 650);
579 
580  S.StartHorizontalLay(wxALIGN_LEFT);
581  {
582  S.TieChoice(XXO("Select &interface"),
583  mUIType,
584  {
585  XO("Full"),
586  XO("Generic"),
587 #if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
588  XO("Basic")
589 #endif
590  });
591  }
592  S.EndHorizontalLay();
593  }
594  S.EndStatic();
595  }
596  S.EndVerticalLay();
597  }
598  S.EndHorizontalLay();
599 
600  S.AddStandardButtons();
601 
602  Layout();
603  Fit();
604  Center();
605 }
606 
607 void AudioUnitEffectOptionsDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
608 {
609  if (!Validate())
610  {
611  return;
612  }
613 
616 
617  // un-translate the type
618  auto uiType = mUIType.MSGID().GET();
619 
620  mHost->SetSharedConfig(wxT("Options"), wxT("UseLatency"), mUseLatency);
621  mHost->SetSharedConfig(wxT("Options"), wxT("UIType"), uiType);
622 
623  EndModal(wxID_OK);
624 }
625 
627 //
628 // AudioUnitEffectImportDialog
629 //
631 
633 {
634 public:
635  AudioUnitEffectImportDialog(wxWindow * parent, AudioUnitEffect *effect);
637 
638  void PopulateOrExchange(ShuttleGui & S);
639  bool HasPresets();
640  TranslatableString Import(const wxString & path, const wxString & name);
641 
642  void OnOk(wxCommandEvent & evt);
643 
644 private:
645  wxWindow *mParent;
647 
648  wxListCtrl *mList;
649 
650  DECLARE_EVENT_TABLE()
651 };
652 
656 
658 : wxDialogWrapper(parent, wxID_ANY, XO("Import Audio Unit Presets"))
659 {
660  mEffect = effect;
661 
662  ShuttleGui S(this, eIsCreating);
663  PopulateOrExchange(S);
664 }
665 
667 {
668 }
669 
671 {
672  S.SetBorder(5);
673  S.StartHorizontalLay(wxEXPAND, 1);
674  {
675  S.StartVerticalLay(true);
676  {
677  S.StartStatic(XO("Presets (may select multiple)"));
678  {
679  mList = S.Style(wxLC_REPORT | wxLC_HRULES | wxLC_VRULES |
680  wxLC_NO_SORT_HEADER)
681  .AddListControlReportMode({ XO("Preset"), XO("Location") });
682  }
683  S.EndStatic();
684  }
685  S.EndVerticalLay();
686  }
687  S.EndHorizontalLay();
688 
689  S.AddStandardButtons();
690 
691  FilePaths presets;
692  wxFileName fn;
693 
694  // Generate the local domain path
695  wxString path;
696  path.Printf(wxT("%s/%s/%s"),
698  mEffect->mVendor,
699  mEffect->mName);
700  fn = path;
701  fn.Normalize();
702 
703  // Get all presets in the local domain for this effect
704  wxDir::GetAllFiles(fn.GetFullPath(), &presets, wxT("*.aupreset"));
705 
706  // Generate the user domain path
707  path.Printf(wxT("%s/%s/%s"),
709  mEffect->mVendor,
710  mEffect->mName);
711  fn = path;
712  fn.Normalize();
713 
714  // Get all presets in the user domain for this effect
715  wxDir::GetAllFiles(fn.GetFullPath(), &presets, wxT("*.aupreset"));
716 
717  presets.Sort();
718 
719  for (size_t i = 0, cnt = presets.size(); i < cnt; i++)
720  {
721  fn = presets[i];
722  mList->InsertItem(i, fn.GetName());
723  mList->SetItem(i, 1, fn.GetPath());
724  }
725 
726  mList->SetColumnWidth(0, wxLIST_AUTOSIZE);
727  mList->SetColumnWidth(1, wxLIST_AUTOSIZE);
728 
729  // Set the list size...with a little extra for good measure
730  wxSize sz = mList->GetBestSize();
731  sz.x += 5;
732  sz.y += 5;
733  mList->SetMinSize(sz);
734 
735  Layout();
736  Fit();
737  Center();
738 }
739 
741 {
742  return mList->GetItemCount() > 0;
743 }
744 
746  const wxString & path, const wxString & name)
747 {
748  // Generate the path
749  wxString fullPath;
750  fullPath.Printf(wxT("%s/%s.aupreset"),
751  path,
752  name);
753 
754  // Open the preset
755  wxFFile f(fullPath, wxT("r"));
756  if (!f.IsOpened())
757  {
758  return XO("Couldn't open \"%s\"").Format(fullPath);
759  }
760 
761  // Load it into the buffer
762  size_t len = f.Length();
763  wxMemoryBuffer buf(len);
764  if (f.Read(buf.GetData(), len) != len || f.Error())
765  {
766  return XO("Unable to read the preset from \"%s\"").Format(fullPath);
767  }
768 
769  wxString parms = wxBase64Encode(buf.GetData(), len);
770  if (parms.IsEmpty())
771  {
772  return XO("Failed to encode preset from \"%s\"").Format(fullPath);
773  }
774 
775  // And write it to the config
776  wxString group = mEffect->mHost->GetUserPresetsGroup(name);
777  if (!mEffect->mHost->SetPrivateConfig(group, PRESET_KEY, parms))
778  {
779  return XO("Unable to store preset in config file");
780  }
781 
782  return {};
783 }
784 
785 void AudioUnitEffectImportDialog::OnOk(wxCommandEvent & evt)
786 {
787  evt.Skip();
788 
789  // Import all selected presets
790  long sel = -1;
791  while ((sel = mList->GetNextItem(sel, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) >= 0)
792  {
793  wxListItem item;
794  item.SetId(sel);
795  item.SetColumn(1);
796  item.SetMask(wxLIST_MASK_TEXT);
797  mList->GetItem(item);
798 
799  wxString path = item.GetText();
800  wxString name = mList->GetItemText(sel);
801  auto msg = Import(path, name);
802 
803  if (!msg.empty())
804  {
806  XO("Could not import \"%s\" preset\n\n%s").Format(name, msg),
807  XO("Import Audio Unit Presets"),
808  wxOK | wxCENTRE,
809  this);
810  return;
811  }
812  }
813 
814  EndModal(wxID_OK);
815 }
816 
818 //
819 // AudioUnitEffect
820 //
822 
824  const wxString & name,
825  AudioComponent component,
826  AudioUnitEffect *master)
827 {
828  mPath = path;
829  mName = name.AfterFirst(wxT(':')).Trim(true).Trim(false);
830  mVendor = name.BeforeFirst(wxT(':')).Trim(true).Trim(false);
831  mComponent = component;
832  mMaster = master;
833 
834  mpControl = NULL;
835  mUnit = NULL;
836 
837  mBlockSize = 0.0;
838  mInteractive = false;
839  mIsGraphical = false;
840 
841  mUIHost = NULL;
842  mDialog = NULL;
843  mParent = NULL;
844 
845  mUnitInitialized = false;
846 
847  mEventListenerRef = NULL;
848 
849  mReady = false;
850 }
851 
853 {
854  if (mUnitInitialized)
855  {
856  AudioUnitUninitialize(mUnit);
857  }
858 
859  if (mEventListenerRef)
860  {
861  AUListenerDispose(mEventListenerRef);
862  }
863 
864  if (mUnit)
865  {
866  AudioComponentInstanceDispose(mUnit);
867  }
868 }
869 
870 // ============================================================================
871 // ComponentInterface implementation
872 // ============================================================================
873 
875 {
876  return mPath;
877 }
878 
880 {
881  return mName;
882 }
883 
885 {
886  return { mVendor };
887 }
888 
890 {
891  UInt32 version;
892 
893  OSStatus result = AudioComponentGetVersion(mComponent, &version);
894 
895  return wxString::Format(wxT("%d.%d.%d"),
896  (version >> 16) & 0xffff,
897  (version >> 8) & 0xff,
898  version & 0xff);
899 }
900 
902 {
903  /* i18n-hint: Can mean "not available," "not applicable," "no answer" */
904  return XO("n/a");
905 }
906 
907 // ============================================================================
908 // EffectComponentInterface implementation
909 // ============================================================================
910 
912 {
913  if (mAudioIns == 0 && mAudioOuts == 0)
914  {
915  return EffectTypeNone;
916  }
917 
918  if (mAudioIns == 0)
919  {
920  return EffectTypeGenerate;
921  }
922 
923  if (mAudioOuts == 0)
924  {
925  return EffectTypeAnalyze;
926  }
927 
928  return EffectTypeProcess;
929 }
930 
932 {
934 }
935 
937 {
938  return mInteractive;
939 }
940 
942 {
943  return false;
944 }
945 
947 {
948  return false;
949 }
950 
952 {
953  return GetType() == EffectTypeProcess;
954 }
955 
957 {
958  OSStatus result;
959  UInt32 dataSize;
960  Boolean isWritable;
961 
962  result = AudioUnitGetPropertyInfo(mUnit,
963  kAudioUnitProperty_ParameterList,
964  kAudioUnitScope_Global,
965  0,
966  &dataSize,
967  &isWritable);
968  if (result != noErr)
969  {
970  return false;
971  }
972 
973  UInt32 cnt = dataSize / sizeof(AudioUnitParameterID);
975 
976  result = AudioUnitGetProperty(mUnit,
977  kAudioUnitProperty_ParameterList,
978  kAudioUnitScope_Global,
979  0,
980  array.get(),
981  &dataSize);
982  if (result != noErr)
983  {
984  return false;
985  }
986 
987  for (int i = 0; i < cnt; i++)
988  {
989  ParameterInfo pi;
990 
991  if (pi.Get(mUnit, array[i]))
992  {
993  if (pi.info.flags & kAudioUnitParameterFlag_IsWritable)
994  {
995  // All we need is one
996  return true;
997  }
998  }
999  }
1000 
1001  return false;
1002 }
1003 
1004 // ============================================================================
1005 // EffectClientInterface Implementation
1006 // ============================================================================
1007 
1009 {
1010  OSStatus result;
1011 
1012  mHost = host;
1013 
1014  mSampleRate = 44100;
1015  result = AudioComponentInstanceNew(mComponent, &mUnit);
1016  if (!mUnit)
1017  {
1018  return false;
1019  }
1020 
1021  GetChannelCounts();
1022 
1024 
1025  // Retrieve the desired number of frames per slice
1026  UInt32 dataSize = sizeof(mBlockSize);
1027  mBlockSize = 512;
1028  AudioUnitGetProperty(mUnit,
1029  kAudioUnitProperty_MaximumFramesPerSlice,
1030  kAudioUnitScope_Global,
1031  0,
1032  &mBlockSize,
1033  &dataSize);
1034 
1035  // mHost will be null during registration
1036  if (mHost)
1037  {
1038  mHost->GetSharedConfig(wxT("Options"), wxT("UseLatency"), mUseLatency, true);
1039  mHost->GetSharedConfig(wxT("Options"), wxT("UIType"), mUIType, wxT("Full"));
1040 
1041  bool haveDefaults;
1042  mHost->GetPrivateConfig(mHost->GetFactoryDefaultsGroup(), wxT("Initialized"), haveDefaults, false);
1043  if (!haveDefaults)
1044  {
1046  mHost->SetPrivateConfig(mHost->GetFactoryDefaultsGroup(), wxT("Initialized"), true);
1047  }
1048 
1050  }
1051 
1052  if (!mMaster)
1053  {
1054  result = AUEventListenerCreate(AudioUnitEffect::EventListenerCallback,
1055  this,
1056  (CFRunLoopRef)GetCFRunLoopFromEventLoop(GetCurrentEventLoop()),
1057  kCFRunLoopDefaultMode,
1058  0.0,
1059  0.0,
1061  if (result != noErr)
1062  {
1063  return false;
1064  }
1065 
1066  AudioUnitEvent event;
1067 
1068  event.mEventType = kAudioUnitEvent_ParameterValueChange;
1069  event.mArgument.mParameter.mAudioUnit = mUnit;
1070  event.mArgument.mParameter.mScope = kAudioUnitScope_Global;
1071  event.mArgument.mParameter.mElement = 0;
1072 
1073  UInt32 dataSize;
1074  Boolean isWritable;
1075 
1076  // Retrieve the list of parameters
1077  result = AudioUnitGetPropertyInfo(mUnit,
1078  kAudioUnitProperty_ParameterList,
1079  kAudioUnitScope_Global,
1080  0,
1081  &dataSize,
1082  &isWritable);
1083  if (result != noErr)
1084  {
1085  return false;
1086  }
1087 
1088  // And get them
1089  UInt32 cnt = dataSize / sizeof(AudioUnitParameterID);
1090  if (cnt != 0)
1091  {
1092  ArrayOf<AudioUnitParameterID> array {cnt};
1093 
1094  result = AudioUnitGetProperty(mUnit,
1095  kAudioUnitProperty_ParameterList,
1096  kAudioUnitScope_Global,
1097  0,
1098  array.get(),
1099  &dataSize);
1100  if (result != noErr)
1101  {
1102  return false;
1103  }
1104 
1105  // Register them as something we're interested in
1106  for (int i = 0; i < cnt; i++)
1107  {
1108  event.mArgument.mParameter.mParameterID = array[i];
1109  result = AUEventListenerAddEventType(mEventListenerRef,
1110  this,
1111  &event);
1112  if (result != noErr)
1113  {
1114  return false;
1115  }
1116  }
1117  }
1118 
1119  event.mEventType = kAudioUnitEvent_PropertyChange;
1120  event.mArgument.mProperty.mAudioUnit = mUnit;
1121  event.mArgument.mProperty.mPropertyID = kAudioUnitProperty_Latency;
1122  event.mArgument.mProperty.mScope = kAudioUnitScope_Global;
1123  event.mArgument.mProperty.mElement = 0;
1124 
1125  result = AUEventListenerAddEventType(mEventListenerRef,
1126  this,
1127  &event);
1128  if (result != noErr)
1129  {
1130  return false;
1131  }
1132 
1133  AudioUnitCocoaViewInfo cocoaViewInfo;
1134  dataSize = sizeof(AudioUnitCocoaViewInfo);
1135 
1136  // Check for a Cocoa UI
1137  result = AudioUnitGetProperty(mUnit,
1138  kAudioUnitProperty_CocoaUI,
1139  kAudioUnitScope_Global,
1140  0,
1141  &cocoaViewInfo,
1142  &dataSize);
1143 
1144  bool hasCocoa = result == noErr;
1145 
1146  // Check for a Carbon UI
1147  AudioComponentDescription compDesc;
1148  dataSize = sizeof(compDesc);
1149  result = AudioUnitGetProperty(mUnit,
1150  kAudioUnitProperty_GetUIComponentList,
1151  kAudioUnitScope_Global,
1152  0,
1153  &compDesc,
1154  &dataSize);
1155  bool hasCarbon = result == noErr;
1156 
1157  mInteractive = (cnt > 0) || hasCocoa || hasCarbon;
1158  }
1159 
1160  return true;
1161 }
1162 
1164 {
1165  return mAudioIns;
1166 }
1167 
1169 {
1170  return mAudioOuts;
1171 }
1172 
1174 {
1175  return 0;
1176 }
1177 
1179 {
1180  return 0;
1181 }
1182 
1184 {
1185  mSampleRate = rate;
1186 }
1187 
1188 size_t AudioUnitEffect::SetBlockSize(size_t maxBlockSize)
1189 {
1190  return mBlockSize;
1191 }
1192 
1194 {
1195  return mBlockSize;
1196 }
1197 
1199 {
1200  // Retrieve the latency (can be updated via an event)
1201  if (mUseLatency && !mLatencyDone)
1202  {
1203  mLatencyDone = true;
1204 
1205  Float64 latency = 0.0;
1206  UInt32 dataSize = sizeof(latency);
1207  AudioUnitGetProperty(mUnit,
1208  kAudioUnitProperty_Latency,
1209  kAudioUnitScope_Global,
1210  0,
1211  &latency,
1212  &dataSize);
1213 
1214  return sampleCount(latency * mSampleRate);
1215  }
1216 
1217  return 0;
1218 }
1219 
1221 {
1222  // Retrieve the tail time
1223  Float64 tailTime = 0.0;
1224  UInt32 dataSize = sizeof(tailTime);
1225  AudioUnitGetProperty(mUnit,
1226  kAudioUnitProperty_TailTime,
1227  kAudioUnitScope_Global,
1228  0,
1229  &tailTime,
1230  &dataSize);
1231 
1232  return tailTime * mSampleRate;
1233 }
1234 
1236 {
1237  return mReady;
1238 }
1239 
1240 bool AudioUnitEffect::ProcessInitialize(sampleCount WXUNUSED(totalLen), ChannelNames WXUNUSED(chanMap))
1241 {
1242  OSStatus result;
1243 
1245  mInputList[0].mNumberBuffers = mAudioIns;
1246 
1248  mOutputList[0].mNumberBuffers = mAudioOuts;
1249 
1250  memset(&mTimeStamp, 0, sizeof(AudioTimeStamp));
1251  mTimeStamp.mSampleTime = 0; // This is a double-precision number that should
1252  // accumulate the number of frames processed so far
1253  mTimeStamp.mFlags = kAudioTimeStampSampleTimeValid;
1254 
1255  if (!SetRateAndChannels())
1256  {
1257  return false;
1258  }
1259 
1260  AURenderCallbackStruct callbackStruct;
1261  callbackStruct.inputProc = RenderCallback;
1262  callbackStruct.inputProcRefCon = this;
1263  result = AudioUnitSetProperty(mUnit,
1264  kAudioUnitProperty_SetRenderCallback,
1265  kAudioUnitScope_Input,
1266  0,
1267  &callbackStruct,
1268  sizeof(AURenderCallbackStruct));
1269  if (result != noErr)
1270  {
1271  wxPrintf("Setting input render callback failed.\n");
1272  return false;
1273  }
1274 
1275  result = AudioUnitReset(mUnit, kAudioUnitScope_Global, 0);
1276  if (result != noErr)
1277  {
1278  return false;
1279  }
1280 
1281  if (!BypassEffect(false))
1282  {
1283  return false;
1284  }
1285 
1286  mLatencyDone = false;
1287 
1288  mReady = true;
1289 
1290  return true;
1291 }
1292 
1294 {
1295  mReady = false;
1296 
1297  mOutputList.reset();
1298  mInputList.reset();
1299 
1300  return true;
1301 }
1302 
1303 size_t AudioUnitEffect::ProcessBlock(float **inBlock, float **outBlock, size_t blockLen)
1304 {
1305  for (size_t i = 0; i < mAudioIns; i++)
1306  {
1307  mInputList[0].mBuffers[i].mNumberChannels = 1;
1308  mInputList[0].mBuffers[i].mData = inBlock[i];
1309  mInputList[0].mBuffers[i].mDataByteSize = sizeof(float) * blockLen;
1310  }
1311 
1312  for (size_t i = 0; i < mAudioOuts; i++)
1313  {
1314  mOutputList[0].mBuffers[i].mNumberChannels = 1;
1315  mOutputList[0].mBuffers[i].mData = outBlock[i];
1316  mOutputList[0].mBuffers[i].mDataByteSize = sizeof(float) * blockLen;
1317  }
1318 
1319  AudioUnitRenderActionFlags flags = 0;
1320  OSStatus result;
1321 
1322  result = AudioUnitRender(mUnit,
1323  &flags,
1324  &mTimeStamp,
1325  0,
1326  blockLen,
1327  mOutputList.get());
1328  if (result != noErr)
1329  {
1330  wxPrintf("Render failed: %d %4.4s\n", (int)result, (char *)&result);
1331  return 0;
1332  }
1333 
1334  mTimeStamp.mSampleTime += blockLen;
1335 
1336  return blockLen;
1337 }
1338 
1340 {
1343  return ProcessInitialize(0);
1344 }
1345 
1346 bool AudioUnitEffect::RealtimeAddProcessor(unsigned numChannels, float sampleRate)
1347 {
1348  auto slave = std::make_unique<AudioUnitEffect>(mPath, mName, mComponent, this);
1349  if (!slave->SetHost(NULL))
1350  {
1351  return false;
1352  }
1353 
1354  slave->SetBlockSize(mBlockSize);
1355  slave->SetChannelCount(numChannels);
1356  slave->SetSampleRate(sampleRate);
1357 
1358  if (!CopyParameters(mUnit, slave->mUnit))
1359  {
1360  return false;
1361  }
1362 
1363  auto pSlave = slave.get();
1364  mSlaves.push_back(std::move(slave));
1365 
1366  return pSlave->ProcessInitialize(0);
1367 }
1368 
1370 {
1371  for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++)
1372  {
1373  mSlaves[i]->ProcessFinalize();
1374  }
1375  mSlaves.clear();
1376 
1377  mMasterIn.reset();
1378  mMasterOut.reset();
1379 
1380  return ProcessFinalize();
1381 }
1382 
1384 {
1385  if (!BypassEffect(true))
1386  {
1387  return false;
1388  }
1389 
1390  for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++)
1391  {
1392  if (!mSlaves[i]->BypassEffect(true))
1393  {
1394  return false;
1395  }
1396  }
1397 
1398  return true;
1399 }
1400 
1402 {
1403  if (!BypassEffect(false))
1404  {
1405  return false;
1406  }
1407 
1408  for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++)
1409  {
1410  if (!mSlaves[i]->BypassEffect(false))
1411  {
1412  return false;
1413  }
1414  }
1415 
1416  return true;
1417 }
1418 
1420 {
1421  for (size_t i = 0; i < mAudioIns; i++)
1422  {
1423  memset(mMasterIn[i].get(), 0, mBlockSize * sizeof(float));
1424  }
1425 
1426  mNumSamples = 0;
1427 
1428  return true;
1429 }
1430 
1432  float **inbuf,
1433  float **outbuf,
1434  size_t numSamples)
1435 {
1436  wxASSERT(numSamples <= mBlockSize);
1437 
1438  for (size_t c = 0; c < mAudioIns; c++)
1439  {
1440  for (decltype(numSamples) s = 0; s < numSamples; s++)
1441  {
1442  mMasterIn[c][s] += inbuf[c][s];
1443  }
1444  }
1445  mNumSamples = wxMax(numSamples, mNumSamples);
1446 
1447  return mSlaves[group]->ProcessBlock(inbuf, outbuf, numSamples);
1448 }
1449 
1451 {
1452  ProcessBlock(reinterpret_cast<float**>(mMasterIn.get()),
1453  reinterpret_cast<float**>(mMasterOut.get()),
1454  mNumSamples);
1455 
1456  return true;
1457 }
1458 
1459 bool AudioUnitEffect::ShowInterface(wxWindow &parent,
1461  bool forceModal)
1462 {
1463  if (mDialog)
1464  {
1465  if (mDialog->Close(true))
1466  {
1467  mDialog = nullptr;
1468  }
1469  return false;
1470  }
1471 
1472  // mDialog is null
1473  auto cleanup = valueRestorer(mDialog);
1474 
1475  if (factory)
1476  {
1477  mDialog = factory(parent, mHost, this);
1478  }
1479 
1480  if (!mDialog)
1481  {
1482  return false;
1483  }
1484 
1485  if ((SupportsRealtime() || GetType() == EffectTypeAnalyze) && !forceModal)
1486  {
1487  mDialog->Show();
1488  cleanup.release();
1489 
1490  return false;
1491  }
1492 
1493  bool res = mDialog->ShowModal() != 0;
1494 
1495  return res;
1496 }
1497 
1499 {
1500  OSStatus result;
1501  UInt32 dataSize;
1502  Boolean isWritable;
1503 
1504  result = AudioUnitGetPropertyInfo(mUnit,
1505  kAudioUnitProperty_ParameterList,
1506  kAudioUnitScope_Global,
1507  0,
1508  &dataSize,
1509  &isWritable);
1510  if (result != noErr)
1511  {
1512  return false;
1513  }
1514 
1515  UInt32 cnt = dataSize / sizeof(AudioUnitParameterID);
1516  ArrayOf<AudioUnitParameterID> array {cnt};
1517 
1518  result = AudioUnitGetProperty(mUnit,
1519  kAudioUnitProperty_ParameterList,
1520  kAudioUnitScope_Global,
1521  0,
1522  array.get(),
1523  &dataSize);
1524  if (result != noErr)
1525  {
1526  return false;
1527  }
1528 
1529  for (int i = 0; i < cnt; i++)
1530  {
1531  ParameterInfo pi;
1532 
1533  if (!pi.Get(mUnit, array[i]))
1534  {
1535  // Probably failed because of invalid parameter which can happen
1536  // if a plug-in is in a certain mode that doesn't contain the
1537  // parameter. In any case, just ignore it.
1538  continue;
1539  }
1540 
1541  AudioUnitParameterValue value;
1542  result = AudioUnitGetParameter(mUnit,
1543  array[i],
1544  kAudioUnitScope_Global,
1545  0,
1546  &value);
1547  if (result != noErr)
1548  {
1549  // Probably failed because of invalid parameter which can happen
1550  // if a plug-in is in a certain mode that doesn't contain the
1551  // parameter. In any case, just ignore it.
1552  continue;
1553  }
1554 
1555  parms.Write(pi.name, value);
1556  }
1557 
1558  return true;
1559 }
1560 
1562 {
1563  OSStatus result;
1564  UInt32 dataSize;
1565  Boolean isWritable;
1566 
1567  result = AudioUnitGetPropertyInfo(mUnit,
1568  kAudioUnitProperty_ParameterList,
1569  kAudioUnitScope_Global,
1570  0,
1571  &dataSize,
1572  &isWritable);
1573  if (result != noErr)
1574  {
1575  return false;
1576  }
1577 
1578  UInt32 cnt = dataSize / sizeof(AudioUnitParameterID);
1579  ArrayOf<AudioUnitParameterID> array {cnt};
1580 
1581  result = AudioUnitGetProperty(mUnit,
1582  kAudioUnitProperty_ParameterList,
1583  kAudioUnitScope_Global,
1584  0,
1585  array.get(),
1586  &dataSize);
1587  if (result != noErr)
1588  {
1589  return false;
1590  }
1591 
1592  for (int i = 0; i < cnt; i++)
1593  {
1594  ParameterInfo pi;
1595 
1596  if (!pi.Get(mUnit, array[i]))
1597  {
1598  // Probably failed because of invalid parameter which can happen
1599  // if a plug-in is in a certain mode that doesn't contain the
1600  // parameter. In any case, just ignore it.
1601  continue;
1602  }
1603 
1604  double d = 0.0;
1605  if (parms.Read(pi.name, &d))
1606  {
1607  AudioUnitParameterValue value = d;
1608  AudioUnitSetParameter(mUnit,
1609  array[i],
1610  kAudioUnitScope_Global,
1611  0,
1612  value,
1613  0);
1614 
1615  Notify(mUnit, array[i]);
1616  }
1617  }
1618 
1619  return true;
1620 }
1621 
1623 {
1624  return LoadPreset(name);
1625 }
1626 
1628 {
1629  return SavePreset(name);
1630 }
1631 
1633 {
1634  OSStatus result;
1635 
1636  // Retrieve the list of factory presets
1637  CFArrayRef array{};
1638  UInt32 dataSize = sizeof(CFArrayRef);
1639  result = AudioUnitGetProperty(mUnit,
1640  kAudioUnitProperty_FactoryPresets,
1641  kAudioUnitScope_Global,
1642  0,
1643  &array,
1644  &dataSize);
1645  CFunique_ptr<const __CFArray> uarray { array };
1646  if (result != noErr)
1647  {
1648  return false;
1649  }
1650 
1651  if (id < 0 || id >= CFArrayGetCount(array))
1652  {
1653  return false;
1654  }
1655 
1656  const AUPreset *preset = (const AUPreset *) CFArrayGetValueAtIndex(array, id);
1657 
1658  result = AudioUnitSetProperty(mUnit,
1659  kAudioUnitProperty_PresentPreset,
1660  kAudioUnitScope_Global,
1661  0,
1662  preset,
1663  sizeof(AUPreset));
1664  if (result == noErr)
1665  {
1666  // Notify interested parties of change and propagate to slaves
1667  Notify(mUnit, kAUParameterListener_AnyParameter);
1668  }
1669 
1670  return result == noErr;
1671 }
1672 
1674 {
1676 }
1677 
1679 {
1680  OSStatus result;
1681  RegistryPaths presets;
1682 
1683  // Retrieve the list of factory presets
1684  CFArrayRef array{};
1685  UInt32 dataSize = sizeof(CFArrayRef);
1686  result = AudioUnitGetProperty(mUnit,
1687  kAudioUnitProperty_FactoryPresets,
1688  kAudioUnitScope_Global,
1689  0,
1690  &array,
1691  &dataSize);
1692  CFunique_ptr<const __CFArray> uarray { array };
1693  if (result == noErr)
1694  {
1695  for (CFIndex i = 0, cnt = CFArrayGetCount(array); i < cnt; i++)
1696  {
1697  AUPreset *preset = (AUPreset *) CFArrayGetValueAtIndex(array, i);
1698  presets.push_back(wxCFStringRef::AsString(preset->presetName));
1699  }
1700  }
1701 
1702  return presets;
1703 }
1704 
1705 // ============================================================================
1706 // EffectUIClientInterface Implementation
1707 // ============================================================================
1708 
1710 {
1711  mUIHost = host;
1712 }
1713 
1715 {
1716  // OSStatus result;
1717 
1718  auto parent = S.GetParent();
1719  mDialog = static_cast<wxDialog *>(wxGetTopLevelParent(parent));
1720  mParent = parent;
1721  mpControl = NULL;
1722 
1723  wxPanel *container;
1724  {
1725  auto mainSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
1726 
1727  wxASSERT(mParent); // To justify safenew
1728  container = safenew wxPanelWrapper(mParent, wxID_ANY);
1729  mainSizer->Add(container, 1, wxEXPAND);
1730 
1731  mParent->SetSizer(mainSizer.release());
1732  }
1733 
1734 #if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
1735  if (mUIType == wxT("Basic"))
1736  {
1737  if (!CreatePlain(mParent))
1738  {
1739  return false;
1740  }
1741  }
1742  else
1743 #endif
1744  {
1745  auto pControl = Destroy_ptr<AUControl>(safenew AUControl);
1746  if (!pControl)
1747  {
1748  return false;
1749  }
1750 
1751  if (!pControl->Create(container, mComponent, mUnit, mUIType == wxT("Full")))
1752  {
1753  return false;
1754  }
1755 
1756  {
1757  auto innerSizer = std::make_unique<wxBoxSizer>(wxVERTICAL);
1758 
1759  innerSizer->Add((mpControl = pControl.release()), 1, wxEXPAND);
1760  container->SetSizer(innerSizer.release());
1761  }
1762 
1763  mParent->SetMinSize(wxDefaultSize);
1764 
1765 #ifdef __WXMAC__
1766 #ifdef __WX_EVTLOOP_BUSY_WAITING__
1767  wxEventLoop::SetBusyWaiting(true);
1768 #endif
1769 #endif
1770  }
1771 
1772  if (mpControl)
1773  {
1774  mParent->PushEventHandler(this);
1775  }
1776 
1777  return true;
1778 }
1779 
1781 {
1782  return mUIType != wxT("Plain");
1783 }
1784 
1786 {
1787 #if 0
1788  if (!mParent->Validate())
1789  {
1790  return false;
1791  }
1792 
1793  if (GetType() == EffectTypeGenerate)
1794  {
1795  mHost->SetDuration(mDuration->GetValue());
1796  }
1797 #endif
1798  return true;
1799 }
1800 
1801 #if defined(HAVE_AUDIOUNIT_BASIC_SUPPORT)
1802 bool AudioUnitEffect::CreatePlain(wxWindow *parent)
1803 {
1804  // TODO??? Never implemented...
1805  return false;
1806 }
1807 #endif
1808 
1810 {
1811 #if 0
1812  if (GetType() == EffectTypeAnalyze || mNumOutputControls > 0)
1813  {
1814  return false;
1815  }
1816 #endif
1817  return true;
1818 }
1819 
1821 {
1822 #ifdef __WXMAC__
1823 #ifdef __WX_EVTLOOP_BUSY_WAITING__
1824  wxEventLoop::SetBusyWaiting(false);
1825 #endif
1826  if (mpControl)
1827  {
1828  mParent->RemoveEventHandler(this);
1829 
1830  mpControl->Close();
1831  mpControl = nullptr;
1832  }
1833 #endif
1834 
1835  mUIHost = NULL;
1836  mParent = NULL;
1837  mDialog = NULL;
1838 
1839  return true;
1840 }
1841 
1843 {
1844  return true;
1845 }
1846 
1848 {
1849  // Generate the user domain path
1850  wxFileName fn;
1851  fn.SetPath(PRESET_USER_PATH);
1852  fn.AppendDir(mVendor);
1853  fn.AppendDir(mName);
1854  fn.Normalize();
1855  FilePath path = fn.GetFullPath();
1856 
1857  if (!fn.Mkdir(fn.GetFullPath(), 0755, wxPATH_MKDIR_FULL))
1858  {
1859  wxLogError(wxT("Couldn't create the \"%s\" directory"), fn.GetPath());
1860  return;
1861  }
1862 
1863  // Ask the user for the name to use
1864  //
1865  // Passing a valid parent will cause some effects dialogs to malfunction
1866  // upon returning from the FileNames::SelectFile().
1867  path = FileNames::SelectFile(FileNames::Operation::_None,
1868  XO("Export Audio Unit Preset As %s:").Format(fn.GetFullPath()),
1869  fn.GetFullPath(),
1870  wxEmptyString,
1871  wxT("aupreset"),
1872  {
1873  { XO("Standard Audio Unit preset file"), { wxT("aupreset") }, true },
1874  },
1875  wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER,
1876  NULL);
1877 
1878  // User canceled...
1879  if (path.empty())
1880  {
1881  return;
1882  }
1883 
1884  auto msg = Export(path);
1885  if (!msg.empty())
1886  {
1888  XO("Could not export \"%s\" preset\n\n%s").Format(path, msg),
1889  XO("Export Audio Unit Presets"),
1890  wxOK | wxCENTRE,
1891  mParent);
1892  }
1893 }
1894 
1896 {
1897  // Generate the user domain path
1898  wxFileName fn;
1899  fn.SetPath(PRESET_USER_PATH);
1900  fn.AppendDir(mVendor);
1901  fn.AppendDir(mName);
1902  fn.Normalize();
1903  FilePath path = fn.GetFullPath();
1904 
1905  // Ask the user for the name to use
1906  //
1907  // Passing a valid parent will cause some effects dialogs to malfunction
1908  // upon returning from the FileNames::SelectFile().
1909  path = FileNames::SelectFile(FileNames::Operation::_None,
1910  XO("Import Audio Unit Preset As %s:").Format(fn.GetFullPath()),
1911  fn.GetFullPath(),
1912  wxEmptyString,
1913  wxT("aupreset"),
1914  {
1915  { XO("Standard Audio Unit preset file"), { wxT("aupreset") }, true },
1916  },
1917  wxFD_OPEN | wxRESIZE_BORDER,
1918  NULL);
1919 
1920  // User canceled...
1921  if (path.empty())
1922  {
1923  return;
1924  }
1925 
1926  auto msg = Import(path);
1927  if (!msg.empty())
1928  {
1930  XO("Could not import \"%s\" preset\n\n%s").Format(path, msg),
1931  XO("Import Audio Unit Presets"),
1932  wxOK | wxCENTRE,
1933  mParent);
1934  }
1935 }
1936 
1938 {
1939  return true;
1940 }
1941 
1943 {
1945  if (dlg.ShowModal())
1946  {
1947  // Reinitialize configuration settings
1948  mHost->GetSharedConfig(wxT("Options"), wxT("UseLatency"), mUseLatency, true);
1949  mHost->GetSharedConfig(wxT("Options"), wxT("UIType"), mUIType, wxT("Full"));
1950  }
1951 }
1952 
1953 // ============================================================================
1954 // AudioUnitEffect Implementation
1955 // ============================================================================
1956 
1958 {
1959  wxString parms;
1960 
1961  // Attempt to load old preset parameters and resave using new method
1962  if (mHost->GetPrivateConfig(group, wxT("Parameters"), parms, wxEmptyString))
1963  {
1964  CommandParameters eap;
1965  if (eap.SetParameters(parms))
1966  {
1967  if (SetAutomationParameters(eap))
1968  {
1969  if (SavePreset(group))
1970  {
1971  mHost->RemovePrivateConfig(group, wxT("Parameters"));
1972  }
1973  }
1974  }
1975  return true;
1976  }
1977 
1978  // Retrieve the preset
1979  if (!mHost->GetPrivateConfig(group, PRESET_KEY, parms, wxEmptyString))
1980  {
1981  // Commented "CurrentSettings" gets tried a lot and useless messages appear
1982  // in the log
1983  //wxLogError(wxT("Preset key \"%s\" not found in group \"%s\""), PRESET_KEY, group);
1984  return false;
1985  }
1986 
1987  // Decode it
1988  wxMemoryBuffer buf = wxBase64Decode(parms);
1989  size_t bufLen = buf.GetDataLen();
1990  if (!bufLen)
1991  {
1992  wxLogError(wxT("Failed to decode \"%s\" preset"), group);
1993  return false;
1994  }
1995  const uint8_t *bufPtr = (uint8_t *) buf.GetData();
1996 
1997  // Create a CFData object that references the decoded preset
1999  {
2000  CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
2001  bufPtr,
2002  bufLen,
2003  kCFAllocatorNull)
2004  };
2005  if (!data)
2006  {
2007  wxLogError(wxT("Failed to convert \"%s\" preset to internal format"), group);
2008  return false;
2009  }
2010 
2011  // Convert it back to a property list.
2012  CFPropertyListRef content
2013  {
2014  CFPropertyListCreateWithData(kCFAllocatorDefault,
2015  data.get(),
2016  kCFPropertyListImmutable,
2017  NULL,
2018  NULL)
2019  };
2020  if (!content)
2021  {
2022  wxLogError(wxT("Failed to create property list for \"%s\" preset"), group);
2023  return false;
2024  }
2025  CFunique_ptr<char /* CFPropertyList */> ucontent { (char *) content };
2026 
2027  // See AUView::viewWillDraw
2028  if (mpControl)
2029  {
2031  }
2032 
2033  // Finally, update the properties and parameters
2034  OSStatus result;
2035  result = AudioUnitSetProperty(mUnit,
2036  kAudioUnitProperty_ClassInfo,
2037  kAudioUnitScope_Global,
2038  0,
2039  &content,
2040  sizeof(content));
2041  if (result != noErr)
2042  {
2043  wxLogError(wxT("Failed to set class info for \"%s\" preset"), group);
2044  return false;
2045  }
2046 
2047  // Notify interested parties of change and propagate to slaves
2048  Notify(mUnit, kAUParameterListener_AnyParameter);
2049 
2050  return true;
2051 }
2052 
2054 {
2055  // First set the name of the preset
2056  wxCFStringRef cfname(wxFileNameFromPath(group));
2057 
2058  // Define the preset property
2059  AUPreset preset;
2060  preset.presetNumber = -1; // indicates user preset
2061  preset.presetName = cfname;
2062 
2063  // And set it in the audio unit
2064  AudioUnitSetProperty(mUnit,
2065  kAudioUnitProperty_PresentPreset,
2066  kAudioUnitScope_Global,
2067  0,
2068  &preset,
2069  sizeof(preset));
2070 
2071  // Now retrieve the preset content
2072  CFPropertyListRef content;
2073  UInt32 size = sizeof(content);
2074  AudioUnitGetProperty(mUnit,
2075  kAudioUnitProperty_ClassInfo,
2076  kAudioUnitScope_Global,
2077  0,
2078  &content,
2079  &size);
2080  CFunique_ptr<char /* CFPropertyList */> ucontent { (char *) content };
2081 
2082  // And convert it to serialized binary data
2084  {
2085  CFPropertyListCreateData(kCFAllocatorDefault,
2086  content,
2087  PRESET_FORMAT,
2088  0,
2089  NULL)
2090  };
2091  if (!data)
2092  {
2093  return false;
2094  }
2095 
2096  // Nothing to do if we don't have any data
2097  SInt32 length = CFDataGetLength(data.get());
2098  if (length)
2099  {
2100  // Base64 encode the returned binary property list
2101  wxString parms = wxBase64Encode(CFDataGetBytePtr(data.get()), length);
2102 
2103  // And write it to the config
2104  if (!mHost->SetPrivateConfig(group, PRESET_KEY, parms))
2105  {
2106  return false;
2107  }
2108  }
2109 
2110  return true;
2111 }
2112 
2114 {
2115  OSStatus result;
2116 
2117  if (mUnitInitialized)
2118  {
2119  AudioUnitUninitialize(mUnit);
2120 
2121  mUnitInitialized = false;
2122  }
2123 
2124  AudioStreamBasicDescription streamFormat {
2125  // Float64 mSampleRate;
2126  mSampleRate,
2127 
2128  // UInt32 mFormatID;
2129  kAudioFormatLinearPCM,
2130 
2131  // UInt32 mFormatFlags;
2132  (kAudioFormatFlagsNativeFloatPacked |
2133  kAudioFormatFlagIsNonInterleaved),
2134 
2135  // UInt32 mBytesPerPacket;
2136  sizeof(float),
2137 
2138  // UInt32 mFramesPerPacket;
2139  1,
2140 
2141  // UInt32 mBytesPerFrame;
2142  sizeof(float),
2143 
2144  // UInt32 mChannelsPerFrame;
2145  mAudioIns,
2146 
2147  // UInt32 mBitsPerChannel;
2148  sizeof(float) * 8,
2149 
2150  // UInt32 mReserved;
2151  0
2152  };
2153 
2154  result = AudioUnitSetProperty(mUnit,
2155  kAudioUnitProperty_SampleRate,
2156  kAudioUnitScope_Global,
2157  0,
2158  &mSampleRate,
2159  sizeof(Float64));
2160  if (result != noErr)
2161  {
2162  wxPrintf("%ls Didn't accept sample rate on global\n",
2163  // Exposing internal name only in debug printf
2164  GetSymbol().Internal().wx_str());
2165  return false;
2166  }
2167 
2168  if (mAudioIns > 0)
2169  {
2170  result = AudioUnitSetProperty(mUnit,
2171  kAudioUnitProperty_SampleRate,
2172  kAudioUnitScope_Input,
2173  0,
2174  &mSampleRate,
2175  sizeof(Float64));
2176  if (result != noErr)
2177  {
2178  wxPrintf("%ls Didn't accept sample rate on input\n",
2179  // Exposing internal name only in debug printf
2180  GetSymbol().Internal().wx_str());
2181  return false;
2182  }
2183 
2184  result = AudioUnitSetProperty(mUnit,
2185  kAudioUnitProperty_StreamFormat,
2186  kAudioUnitScope_Input,
2187  0,
2188  &streamFormat,
2189  sizeof(AudioStreamBasicDescription));
2190  if (result != noErr)
2191  {
2192  wxPrintf("%ls didn't accept stream format on input\n",
2193  // Exposing internal name only in debug printf
2194  GetSymbol().Internal().wx_str());
2195  return false;
2196  }
2197  }
2198 
2199  if (mAudioOuts > 0)
2200  {
2201  result = AudioUnitSetProperty(mUnit,
2202  kAudioUnitProperty_SampleRate,
2203  kAudioUnitScope_Output,
2204  0,
2205  &mSampleRate,
2206  sizeof(Float64));
2207  if (result != noErr)
2208  {
2209  wxPrintf("%ls Didn't accept sample rate on output\n",
2210  // Exposing internal name only in debug printf
2211  GetSymbol().Internal().wx_str());
2212  return false;
2213  }
2214 
2215  streamFormat.mChannelsPerFrame = mAudioOuts;
2216  result = AudioUnitSetProperty(mUnit,
2217  kAudioUnitProperty_StreamFormat,
2218  kAudioUnitScope_Output,
2219  0,
2220  &streamFormat,
2221  sizeof(AudioStreamBasicDescription));
2222 
2223  if (result != noErr)
2224  {
2225  wxPrintf("%ls didn't accept stream format on output\n",
2226  // Exposing internal name only in debug printf
2227  GetSymbol().Internal().wx_str());
2228  return false;
2229  }
2230  }
2231 
2232  result = AudioUnitInitialize(mUnit);
2233  if (result != noErr)
2234  {
2235  wxPrintf("Couldn't initialize audio unit\n");
2236  return false;
2237  }
2238 
2239  mUnitInitialized = true;
2240 
2241  return true;
2242 }
2243 
2244 bool AudioUnitEffect::CopyParameters(AudioUnit srcUnit, AudioUnit dstUnit)
2245 {
2246  OSStatus result;
2247 
2248  // Retrieve the class state from the source AU
2249  CFPropertyListRef content;
2250  UInt32 size = sizeof(content);
2251  result = AudioUnitGetProperty(srcUnit,
2252  kAudioUnitProperty_ClassInfo,
2253  kAudioUnitScope_Global,
2254  0,
2255  &content,
2256  &size);
2257  if (result != noErr)
2258  {
2259  return false;
2260  }
2261 
2262  // Make sure it get's freed
2263  CFunique_ptr<char /* CFPropertyList */> ucontent { (char *) content };
2264 
2265  // Set the destination AUs state from the source AU's content
2266  result = AudioUnitSetProperty(dstUnit,
2267  kAudioUnitProperty_ClassInfo,
2268  kAudioUnitScope_Global,
2269  0,
2270  &content,
2271  sizeof(content));
2272  if (result != noErr)
2273  {
2274  return false;
2275  }
2276 
2277  // Notify interested parties
2278  Notify(dstUnit, kAUParameterListener_AnyParameter);
2279 
2280  return true;
2281 }
2282 
2284 {
2285  return mNumChannels;
2286 }
2287 
2288 void AudioUnitEffect::SetChannelCount(unsigned numChannels)
2289 {
2290  mNumChannels = numChannels;
2291 }
2292 
2294 {
2295  // Create the file
2296  wxFFile f(path, wxT("wb"));
2297  if (!f.IsOpened())
2298  {
2299  return XO("Couldn't open \"%s\"").Format(path);
2300  }
2301 
2302  // First set the name of the preset
2303  wxCFStringRef cfname(wxFileName(path).GetName());
2304 
2305  // Define the preset property
2306  AUPreset preset;
2307  preset.presetNumber = -1; // indicates user preset
2308  preset.presetName = cfname;
2309 
2310  // And set it in the audio unit
2311  OSStatus result;
2312  result = AudioUnitSetProperty(mUnit,
2313  kAudioUnitProperty_PresentPreset,
2314  kAudioUnitScope_Global,
2315  0,
2316  &preset,
2317  sizeof(preset));
2318  if (result != noErr)
2319  {
2320  return XO("Failed to set preset name");
2321  }
2322 
2323  // Now retrieve the preset content
2324  CFPropertyListRef content;
2325  UInt32 size = sizeof(content);
2326  result = AudioUnitGetProperty(mUnit,
2327  kAudioUnitProperty_ClassInfo,
2328  kAudioUnitScope_Global,
2329  0,
2330  &content,
2331  &size);
2332  CFunique_ptr<char /* CFPropertyList */> ucontent { (char *) content };
2333  if (result != noErr)
2334  {
2335  return XO("Failed to retrieve preset content");
2336  }
2337 
2338  // And convert it to serialized XML data
2340  {
2341  CFPropertyListCreateData(kCFAllocatorDefault,
2342  content,
2343  kCFPropertyListXMLFormat_v1_0,
2344  0,
2345  NULL)
2346  };
2347  if (!data)
2348  {
2349  return XO("Failed to convert property list to XML data");
2350  }
2351 
2352  // Nothing to do if we don't have any data
2353  SInt32 length = CFDataGetLength(data.get());
2354  if (!length)
2355  {
2356  return XO("XML data is empty after conversion");
2357  }
2358 
2359  // Write XML data
2360  if (f.Write(CFDataGetBytePtr(data.get()), length) != length || f.Error())
2361  {
2362  return XO("Failed to write XML preset to \"%s\"").Format(path);
2363  }
2364 
2365  f.Close();
2366 
2367  return {};
2368 }
2369 
2371 {
2372  // Open the preset
2373  wxFFile f(path, wxT("r"));
2374  if (!f.IsOpened())
2375  {
2376  return XO("Couldn't open \"%s\"").Format(path);
2377  }
2378 
2379  // Load it into the buffer
2380  size_t len = f.Length();
2381  wxMemoryBuffer buf(len);
2382  if (f.Read(buf.GetData(), len) != len || f.Error())
2383  {
2384  return XO("Unable to read the preset from \"%s\"").Format(path);
2385  }
2386 
2387  // Create a CFData object that references the decoded preset
2389  {
2390  CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
2391  (const UInt8 *) buf.GetData(),
2392  len,
2393  kCFAllocatorNull)
2394  };
2395  if (!data)
2396  {
2397  return XO("Failed to convert preset to internal format");
2398  }
2399 
2400  // Convert it back to a property list.
2401  CFPropertyListRef content
2402  {
2403  CFPropertyListCreateWithData(kCFAllocatorDefault,
2404  data.get(),
2405  kCFPropertyListImmutable,
2406  NULL,
2407  NULL)
2408  };
2409  if (!content)
2410  {
2411  return XO("Failed to create property list for preset");
2412  }
2413  CFunique_ptr<char /* CFPropertyList */> ucontent { (char *) content };
2414 
2415  // Finally, update the properties and parameters
2416  OSStatus result;
2417  result = AudioUnitSetProperty(mUnit,
2418  kAudioUnitProperty_ClassInfo,
2419  kAudioUnitScope_Global,
2420  0,
2421  &content,
2422  sizeof(content));
2423  if (result != noErr)
2424  {
2425  return XO("Failed to set class info for \"%s\" preset");
2426  }
2427 
2428  // Notify interested parties of change and propagate to slaves
2429  Notify(mUnit, kAUParameterListener_AnyParameter);
2430 
2431  return {};
2432 }
2433 
2434 void AudioUnitEffect::Notify(AudioUnit unit, AudioUnitParameterID parm)
2435 {
2436  // Notify any interested parties
2437  AudioUnitParameter aup = {};
2438  aup.mAudioUnit = unit;
2439  aup.mParameterID = parm;
2440  aup.mScope = kAudioUnitScope_Global;
2441  aup.mElement = 0;
2442  AUParameterListenerNotify(NULL, NULL, &aup);
2443 }
2444 
2445 OSStatus AudioUnitEffect::Render(AudioUnitRenderActionFlags *inActionFlags,
2446  const AudioTimeStamp *inTimeStamp,
2447  UInt32 inBusNumber,
2448  UInt32 inNumFrames,
2449  AudioBufferList *ioData)
2450 {
2451  for (int i = 0; i < ioData->mNumberBuffers; i++)
2452  ioData->mBuffers[i].mData = mInputList[0].mBuffers[i].mData;
2453 
2454  return 0;
2455 }
2456 
2457 // static
2458 OSStatus AudioUnitEffect::RenderCallback(void *inRefCon,
2459  AudioUnitRenderActionFlags *inActionFlags,
2460  const AudioTimeStamp *inTimeStamp,
2461  UInt32 inBusNumber,
2462  UInt32 inNumFrames,
2463  AudioBufferList *ioData)
2464 {
2465  return ((AudioUnitEffect *) inRefCon)->Render(inActionFlags,
2466  inTimeStamp,
2467  inBusNumber,
2468  inNumFrames,
2469  ioData);
2470 }
2471 
2472 void AudioUnitEffect::EventListener(const AudioUnitEvent *inEvent,
2473  AudioUnitParameterValue inParameterValue)
2474 {
2475  // Handle property changes
2476  if (inEvent->mEventType == kAudioUnitEvent_PropertyChange)
2477  {
2478  // Handle latency changes
2479  if (inEvent->mArgument.mProperty.mPropertyID == kAudioUnitProperty_Latency)
2480  {
2481  // Allow change to be used
2482  //mLatencyDone = false;
2483  }
2484 
2485  return;
2486  }
2487 
2488  // Only parameter changes at this point
2489 
2490  if (mMaster)
2491  {
2492  // We're a slave, so just set the parameter
2493  AudioUnitSetParameter(mUnit,
2494  inEvent->mArgument.mParameter.mParameterID,
2495  kAudioUnitScope_Global,
2496  0,
2497  inParameterValue,
2498  0);
2499  }
2500  else
2501  {
2502  // We're the master, so propagate
2503  for (size_t i = 0, cnt = mSlaves.size(); i < cnt; i++)
2504  {
2505  mSlaves[i]->EventListener(inEvent, inParameterValue);
2506  }
2507  }
2508 }
2509 
2510 // static
2511 void AudioUnitEffect::EventListenerCallback(void *inCallbackRefCon,
2512  void *inObject,
2513  const AudioUnitEvent *inEvent,
2514  UInt64 inEventHostTime,
2515  AudioUnitParameterValue inParameterValue)
2516 {
2517  ((AudioUnitEffect *) inCallbackRefCon)->EventListener(inEvent,
2518  inParameterValue);
2519 }
2520 
2522 {
2523  Boolean isWritable = 0;
2524  UInt32 dataSize = 0;
2525  OSStatus result;
2526 
2527  // Does AU have channel info
2528  result = AudioUnitGetPropertyInfo(mUnit,
2529  kAudioUnitProperty_SupportedNumChannels,
2530  kAudioUnitScope_Global,
2531  0,
2532  &dataSize,
2533  &isWritable);
2534  if (result)
2535  {
2536  // None supplied. Apparently all FX type units can do any number of INs
2537  // and OUTs as long as they are the same number. In this case, we'll
2538  // just say stereo.
2539  //
2540  // We should probably check to make sure we're dealing with an FX type.
2541  mAudioIns = 2;
2542  mAudioOuts = 2;
2543  return;
2544  }
2545 
2546  ArrayOf<char> buffer{ dataSize };
2547  auto info = (AUChannelInfo *) buffer.get();
2548 
2549  // Retrieve the channel info
2550  result = AudioUnitGetProperty(mUnit,
2551  kAudioUnitProperty_SupportedNumChannels,
2552  kAudioUnitScope_Global,
2553  0,
2554  info,
2555  &dataSize);
2556  if (result)
2557  {
2558  // Oh well, not much we can do out this case
2559  mAudioIns = 2;
2560  mAudioOuts = 2;
2561 
2562  return;
2563  }
2564 
2565  // This is where it gets weird...not sure what is the best
2566  // way to do this really. If we knew how many ins/outs we
2567  // really needed, we could make a better choice.
2568 
2569  bool haven2m = false; // nothing -> mono
2570  bool haven2s = false; // nothing -> stereo
2571  bool havem2n = false; // mono -> nothing
2572  bool haves2n = false; // stereo -> nothing
2573  bool havem2m = false; // mono -> mono
2574  bool haves2s = false; // stereo -> stereo
2575  bool havem2s = false; // mono -> stereo
2576  bool haves2m = false; // stereo -> mono
2577 
2578  mAudioIns = 2;
2579  mAudioOuts = 2;
2580 
2581  // Look only for exact channel constraints
2582  for (int i = 0; i < dataSize / sizeof(AUChannelInfo); i++)
2583  {
2584  AUChannelInfo *ci = &info[i];
2585 
2586  int ic = ci->inChannels;
2587  int oc = ci->outChannels;
2588 
2589  if (ic < 0 && oc >= 0)
2590  {
2591  ic = 2;
2592  }
2593  else if (ic >= 0 && oc < 0)
2594  {
2595  oc = 2;
2596  }
2597  else if (ic < 0 && oc < 0)
2598  {
2599  ic = 2;
2600  oc = 2;
2601  }
2602 
2603  if (ic == 2 && oc == 2)
2604  {
2605  haves2s = true;
2606  }
2607  else if (ic == 1 && oc == 1)
2608  {
2609  havem2m = true;
2610  }
2611  else if (ic == 1 && oc == 2)
2612  {
2613  havem2s = true;
2614  }
2615  else if (ic == 2 && oc == 1)
2616  {
2617  haves2m = true;
2618  }
2619  else if (ic == 0 && oc == 2)
2620  {
2621  haven2s = true;
2622  }
2623  else if (ic == 0 && oc == 1)
2624  {
2625  haven2m = true;
2626  }
2627  else if (ic == 1 && oc == 0)
2628  {
2629  havem2n = true;
2630  }
2631  else if (ic == 2 && oc == 0)
2632  {
2633  haves2n = true;
2634  }
2635  }
2636 
2637  if (haves2s)
2638  {
2639  mAudioIns = 2;
2640  mAudioOuts = 2;
2641  }
2642  else if (havem2m)
2643  {
2644  mAudioIns = 1;
2645  mAudioOuts = 1;
2646  }
2647  else if (havem2s)
2648  {
2649  mAudioIns = 1;
2650  mAudioOuts = 2;
2651  }
2652  else if (haves2m)
2653  {
2654  mAudioIns = 2;
2655  mAudioOuts = 1;
2656  }
2657  else if (haven2m)
2658  {
2659  mAudioIns = 0;
2660  mAudioOuts = 1;
2661  }
2662  else if (haven2s)
2663  {
2664  mAudioIns = 0;
2665  mAudioOuts = 2;
2666  }
2667  else if (haves2n)
2668  {
2669  mAudioIns = 2;
2670  mAudioOuts = 0;
2671  }
2672  else if (havem2n)
2673  {
2674  mAudioIns = 1;
2675  mAudioOuts = 0;
2676  }
2677 
2678  return;
2679 }
2680 
2682 {
2683  OSStatus result;
2684 
2685  UInt32 value = (bypass ? 1 : 0);
2686 
2687  result = AudioUnitSetProperty(mUnit,
2688  kAudioUnitProperty_BypassEffect,
2689  kAudioUnitScope_Global,
2690  0,
2691  &value,
2692  sizeof(value));
2693  if (result != noErr)
2694  {
2695  return false;
2696  }
2697 
2698  return true;
2699 }
2700 
2701 #endif
AudioUnitEffect::GetFamily
EffectFamilySymbol GetFamily() override
Definition: AudioUnitEffect.cpp:931
ParameterInfo::idEnd
static const char idEnd
Definition: AudioUnitEffect.cpp:218
EVT_BUTTON
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
AudioUnitEffect::LoadUserPreset
bool LoadUserPreset(const RegistryPath &name) override
Definition: AudioUnitEffect.cpp:1622
FilePath
wxString FilePath
Definition: Identifier.h:227
AudioUnitEffect::GetChannelCounts
void GetChannelCounts()
Definition: AudioUnitEffect.cpp:2521
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
AudioUnitEffectsModule::GetOptionalFamilySymbol
EffectFamilySymbol GetOptionalFamilySymbol() override
Definition: AudioUnitEffect.cpp:312
ParameterInfo::idBeg
static const char idBeg
Definition: AudioUnitEffect.cpp:216
CommandParameters
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the Shuttle cla...
Definition: EffectAutomationParameters.h:67
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:38
AudioUnitEffect::mPath
PluginPath mPath
Definition: AudioUnitEffect.h:179
CommandParameters::SetParameters
bool SetParameters(const wxString &parms)
Definition: EffectAutomationParameters.h:286
AudioUnitEffectsModule::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: AudioUnitEffect.cpp:268
valueRestorer
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
Definition: MemoryX.h:354
AudioUnitEffectsModule::LoadAudioUnitsOfType
void LoadAudioUnitsOfType(OSType inAUType, PluginPaths &effects)
Definition: AudioUnitEffect.cpp:394
AudioUnitEffect::SetSampleRate
void SetSampleRate(double rate) override
Definition: AudioUnitEffect.cpp:1183
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1184
EffectTypeProcess
@ EffectTypeProcess
Definition: EffectInterface.h:59
AudioUnitEffectImportDialog::HasPresets
bool HasPresets()
Definition: AudioUnitEffect.cpp:740
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption=XO("Message"), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: AudacityMessageBox.h:20
BlackList
static const struct @0 BlackList[]
AudioUnitEffect::mDialog
wxDialog * mDialog
Definition: AudioUnitEffect.h:208
AudioUnitEffectOptionsDialog::OnOk
void OnOk(wxCommandEvent &evt)
Definition: AudioUnitEffect.cpp:607
ParameterInfo::name
wxString name
Definition: AudioUnitEffect.cpp:220
AudioUnitEffectsModule::GetPath
PluginPath GetPath() override
Definition: AudioUnitEffect.cpp:263
CFReleaser::operator()
void operator()(const void *p) const
Definition: AudioUnitEffect.cpp:93
AudioUnitEffect::EventListenerCallback
static void EventListenerCallback(void *inCallbackRefCon, void *inObject, const AudioUnitEvent *inEvent, UInt64 inEventHostTime, AudioUnitParameterValue inParameterValue)
Definition: AudioUnitEffect.cpp:2511
AudioUnitEffect::RealtimeSuspend
bool RealtimeSuspend() override
Definition: AudioUnitEffect.cpp:1383
eIsGettingFromDialog
@ eIsGettingFromDialog
Definition: ShuttleGui.h:39
AudioUnitEffect::ExportPresets
void ExportPresets() override
Definition: AudioUnitEffect.cpp:1847
EffectHostInterface
EffectHostInterface is a decorator of a EffectUIClientInterface. It adds virtual (abstract) functions...
Definition: EffectInterface.h:121
fn
static const auto fn
Definition: WaveformView.cpp:1114
AudioUnitEffectOptionsDialog::mUseLatency
bool mUseLatency
Definition: AudioUnitEffect.cpp:510
AudioUnitEffect::ShowOptions
void ShowOptions() override
Definition: AudioUnitEffect.cpp:1942
AudioUnitEffect::IsInteractive
bool IsInteractive() override
Definition: AudioUnitEffect.cpp:936
AudioUnitEffectsModule::AutoRegisterPlugins
bool AutoRegisterPlugins(PluginManagerInterface &pm) override
Definition: AudioUnitEffect.cpp:321
AudioUnitEffect::SetHost
bool SetHost(EffectHostInterface *host) override
Definition: AudioUnitEffect.cpp:1008
AUDIOUNITEFFECTS_VERSION
#define AUDIOUNITEFFECTS_VERSION
Definition: AudioUnitEffect.h:30
AudioUnitEffectImportDialog::mList
wxListCtrl * mList
Definition: AudioUnitEffect.cpp:648
AudioUnitEffect::mIsGraphical
bool mIsGraphical
Definition: AudioUnitEffect.h:210
AudioUnitEffect.h
ParameterInfo::~ParameterInfo
virtual ~ParameterInfo()
Definition: AudioUnitEffect.cpp:113
AudioUnitEffectsModule::FindAudioUnit
AudioComponent FindAudioUnit(const PluginPath &path, wxString &name)
Definition: AudioUnitEffect.cpp:452
AudioUnitEffect::IsReady
bool IsReady() override
Definition: AudioUnitEffect.cpp:1235
AudioUnitEffect::mInteractive
bool mInteractive
Definition: AudioUnitEffect.h:192
AudioUnitEffect::GetAudioInCount
unsigned GetAudioInCount() override
Definition: AudioUnitEffect.cpp:1163
wxPanelWrapper
Definition: wxPanelWrapper.h:41
AudioUnitEffect::RealtimeProcess
size_t RealtimeProcess(int group, float **inbuf, float **outbuf, size_t numSamples) override
Definition: AudioUnitEffect.cpp:1431
Effect
Base class for many of the effects in Audacity.
Definition: Effect.h:72
AudioUnitEffectImportDialog::mParent
wxWindow * mParent
Definition: AudioUnitEffect.cpp:645
EffectTypeGenerate
@ EffectTypeGenerate
Definition: EffectInterface.h:58
AudioUnitEffect::SavePreset
bool SavePreset(const RegistryPath &group)
Definition: AudioUnitEffect.cpp:2053
RegistryPaths
std::vector< RegistryPath > RegistryPaths
Definition: Identifier.h:219
ShuttleGuiBase::TieCheckBox
wxCheckBox * TieCheckBox(const TranslatableString &Prompt, bool &Var)
Definition: ShuttleGui.cpp:1629
PluginPath
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
Definition: Identifier.h:214
AudioUnitEffect::SetRateAndChannels
bool SetRateAndChannels()
Definition: AudioUnitEffect.cpp:2113
AudioUnitEffect::mpControl
AUControl * mpControl
Definition: AudioUnitEffect.h:220
Format
Abstract base class used in importing a file.
DECLARE_BUILTIN_MODULE
DECLARE_BUILTIN_MODULE(AudioUnitEffectsBuiltin)
AudioUnitEffect::GetBlockSize
size_t GetBlockSize() const override
Definition: AudioUnitEffect.cpp:1193
ArrayOf::reinit
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:57
EffectTypeNone
@ EffectTypeNone
Definition: EffectInterface.h:56
AudioUnitEffect::AudioUnitEffect
AudioUnitEffect(const PluginPath &path, const wxString &name, AudioComponent component, AudioUnitEffect *master=NULL)
Definition: AudioUnitEffect.cpp:823
AudioUnitEffect::mParent
wxWindow * mParent
Definition: AudioUnitEffect.h:207
AUControl::Close
void Close()
AudioUnitEffect::GetLatency
sampleCount GetLatency() override
Definition: AudioUnitEffect.cpp:1198
XO
#define XO(s)
Definition: Internat.h:31
AudioUnitEffect::EventListener
void EventListener(const AudioUnitEvent *inEvent, AudioUnitParameterValue inParameterValue)
Definition: AudioUnitEffect.cpp:2472
AudioUnitEffectsModule::IsPluginValid
bool IsPluginValid(const PluginPath &path, bool bFast) override
Definition: AudioUnitEffect.cpp:370
AudioUnitEffect::GetAutomationParameters
bool GetAutomationParameters(CommandParameters &parms) override
Definition: AudioUnitEffect.cpp:1498
AudioUnitEffectsModule
Definition: AudioUnitEffect.h:233
EffectHostInterface::GetCurrentSettingsGroup
virtual RegistryPath GetCurrentSettingsGroup()=0
AudioUnitEffect::mOutputList
ArrayOf< AudioBufferList > mOutputList
Definition: AudioUnitEffect.h:204
AudioUnitEffect::mUIHost
EffectUIHostInterface * mUIHost
Definition: AudioUnitEffect.h:206
AudioUnitEffect::GetDescription
TranslatableString GetDescription() override
Definition: AudioUnitEffect.cpp:901
AudioUnitEffect::IsLegacy
bool IsLegacy() override
Definition: AudioUnitEffect.cpp:946
AudioUnitEffect::RenderCallback
static OSStatus RenderCallback(void *inRefCon, AudioUnitRenderActionFlags *inActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList *ioData)
Definition: AudioUnitEffect.cpp:2458
AudioUnitEffectsModule::CreateInstance
std::unique_ptr< ComponentInterface > CreateInstance(const PluginPath &path) override
Definition: AudioUnitEffect.cpp:382
AudioUnitEffect::ValidateUI
bool ValidateUI() override
Definition: AudioUnitEffect.cpp:1785
AudioUnitEffect::mAudioOuts
unsigned mAudioOuts
Definition: AudioUnitEffect.h:191
AudioUnitEffect::SetBlockSize
size_t SetBlockSize(size_t maxBlockSize) override
Definition: AudioUnitEffect.cpp:1188
AudioUnitEffect::IsDefault
bool IsDefault() override
Definition: AudioUnitEffect.cpp:941
componentManufacturer
OSType componentManufacturer
Definition: AudioUnitEffect.cpp:74
AudioUnitEffectOptionsDialog::~AudioUnitEffectOptionsDialog
virtual ~AudioUnitEffectOptionsDialog()
Definition: AudioUnitEffect.cpp:538
AudioUnitEffect::mUseLatency
bool mUseLatency
Definition: AudioUnitEffect.h:198
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
AudioUnitEffectsModule::FromOSType
wxString FromOSType(OSType type)
Definition: AudioUnitEffect.cpp:469
desc
const TranslatableString desc
Definition: ExportPCM.cpp:58
AudioUnitEffect::GetMidiInCount
int GetMidiInCount() override
Definition: AudioUnitEffect.cpp:1173
AudioUnitEffect::RealtimeInitialize
bool RealtimeInitialize() override
Definition: AudioUnitEffect.cpp:1339
AudioUnitEffect::CanExportPresets
bool CanExportPresets() override
Definition: AudioUnitEffect.cpp:1842
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterfaceSymbol.h:27
AudioUnitEffectImportDialog::Import
TranslatableString Import(const wxString &path, const wxString &name)
Definition: AudioUnitEffect.cpp:745
AudioUnitEffectOptionsDialog::mUIType
TranslatableString mUIType
Definition: AudioUnitEffect.cpp:511
AudioUnitEffect::RealtimeProcessEnd
bool RealtimeProcessEnd() override
Definition: AudioUnitEffect.cpp:1450
AudioUnitEffect::ImportPresets
void ImportPresets() override
Definition: AudioUnitEffect.cpp:1895
AudioUnitEffect::GetAudioOutCount
unsigned GetAudioOutCount() override
Definition: AudioUnitEffect.cpp:1168
AudioUnitEffect::SetHostUI
void SetHostUI(EffectUIHostInterface *host) override
Definition: AudioUnitEffect.cpp:1709
AudioUnitEffect::HideUI
bool HideUI() override
Definition: AudioUnitEffect.cpp:1809
AudioUnitEffect::Import
TranslatableString Import(const wxString &path)
Definition: AudioUnitEffect.cpp:2370
AudioUnitEffect::ShowInterface
bool ShowInterface(wxWindow &parent, const EffectDialogFactory &factory, bool forceModal=false) override
Definition: AudioUnitEffect.cpp:1459
AudioUnitEffect::mMasterOut
ArraysOf< float > mMasterOut
Definition: AudioUnitEffect.h:215
AudioUnitEffectImportDialog::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S)
Definition: AudioUnitEffect.cpp:670
ArraysOf::reinit
void reinit(Integral count)
Definition: MemoryX.h:109
SampleCount.h
ShuttleGui::Style
ShuttleGui & Style(long iStyle)
Definition: ShuttleGui.h:727
AudioUnitEffectOptionsDialog::PopulateOrExchange
void PopulateOrExchange(ShuttleGui &S)
Definition: AudioUnitEffect.cpp:542
AudioUnitEffectImportDialog::OnOk
void OnOk(wxCommandEvent &evt)
Definition: AudioUnitEffect.cpp:785
AudioUnitEffectsModule::~AudioUnitEffectsModule
virtual ~AudioUnitEffectsModule()
Definition: AudioUnitEffect.cpp:255
AudioUnitEffect::mSlaves
AudioUnitEffectArray mSlaves
Definition: AudioUnitEffect.h:213
componentType
OSType componentType
Definition: AudioUnitEffect.cpp:75
AudioUnitEffectsModule::DiscoverPluginsAtPath
unsigned DiscoverPluginsAtPath(const PluginPath &path, TranslatableString &errMsg, const RegistrationCallback &callback) override
Definition: AudioUnitEffect.cpp:340
AudioUnitEffectImportDialog::~AudioUnitEffectImportDialog
virtual ~AudioUnitEffectImportDialog()
Definition: AudioUnitEffect.cpp:666
AUDIOUNITEFFECTS_FAMILY
#define AUDIOUNITEFFECTS_FAMILY
Definition: AudioUnitEffect.h:32
AudioUnitEffect::RealtimeAddProcessor
bool RealtimeAddProcessor(unsigned numChannels, float sampleRate) override
Definition: AudioUnitEffect.cpp:1346
AudioUnitEffect::PopulateUI
bool PopulateUI(ShuttleGui &S) override
Definition: AudioUnitEffect.cpp:1714
XXO
#define XXO(s)
Definition: Internat.h:44
ParameterInfo::ParameterInfo
ParameterInfo()
Definition: AudioUnitEffect.cpp:108
ShuttleGuiBase::EndHorizontalLay
void EndHorizontalLay()
Definition: ShuttleGui.cpp:1177
AudioUnitEffect::LoadFactoryPreset
bool LoadFactoryPreset(int id) override
Definition: AudioUnitEffect.cpp:1632
PluginManagerInterface
Definition: PluginInterface.h:55
factory
static RegisteredToolbarFactory factory
Definition: ControlToolBar.cpp:806
PRESET_LOCAL_PATH
#define PRESET_LOCAL_PATH
Definition: AudioUnitEffect.cpp:69
AudioUnitEffect::GetChannelCount
unsigned GetChannelCount()
Definition: AudioUnitEffect.cpp:2283
AudioUnitEffect::mHost
EffectHostInterface * mHost
Definition: AudioUnitEffect.h:189
ShuttleGuiBase::StartHorizontalLay
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:1167
AudioUnitEffect::LoadPreset
bool LoadPreset(const RegistryPath &group)
Definition: AudioUnitEffect.cpp:1957
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1203
PRESET_USER_PATH
#define PRESET_USER_PATH
Definition: AudioUnitEffect.cpp:70
PRESET_KEY
#define PRESET_KEY
Definition: AudioUnitEffect.cpp:66
AudioUnitEffectsModule::GetFileExtensions
const FileExtensions & GetFileExtensions() override
Definition: AudioUnitEffect.cpp:294
AudioUnitEffect::CopyParameters
bool CopyParameters(AudioUnit srcUnit, AudioUnit dstUnit)
Definition: AudioUnitEffect.cpp:2244
AudioUnitEffect::RealtimeFinalize
bool RealtimeFinalize() override
Definition: AudioUnitEffect.cpp:1369
AudioUnitEffect::Render
OSStatus Render(AudioUnitRenderActionFlags *inActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList *ioData)
Definition: AudioUnitEffect.cpp:2445
componentSubType
OSType componentSubType
Definition: AudioUnitEffect.cpp:76
name
const TranslatableString name
Definition: Distortion.cpp:98
ShuttleGuiBase::GetParent
wxWindow * GetParent()
Definition: ShuttleGui.h:496
AudioUnitEffectsModule::FindPluginPaths
PluginPaths FindPluginPaths(PluginManagerInterface &pm) override
Definition: AudioUnitEffect.cpp:327
AudioUnitEffectOptionsDialog::AudioUnitEffectOptionsDialog
AudioUnitEffectOptionsDialog(wxWindow *parent, EffectHostInterface *host)
Definition: AudioUnitEffect.cpp:520
AudioUnitEffectsModule::GetDescription
TranslatableString GetDescription() override
Definition: AudioUnitEffect.cpp:285
AudioUnitEffect::SupportsRealtime
bool SupportsRealtime() override
Definition: AudioUnitEffect.cpp:951
ParameterInfo
Definition: AudioUnitEffect.cpp:106
CFunique_ptr
std::unique_ptr< T, CFReleaser > CFunique_ptr
Definition: AudioUnitEffect.cpp:98
ParameterInfo::info
AudioUnitParameterInfo info
Definition: AudioUnitEffect.cpp:221
AudioUnitEffect::SetAutomationParameters
bool SetAutomationParameters(CommandParameters &parms) override
Definition: AudioUnitEffect.cpp:1561
EffectClientInterface::EffectDialogFactory
std::function< wxDialog *(wxWindow &parent, EffectHostInterface *, EffectUIClientInterface *) > EffectDialogFactory
Definition: EffectInterface.h:190
ParameterInfo::idSep
static const char idSep
Definition: AudioUnitEffect.cpp:217
AudioUnitEffect::mBlockSize
UInt32 mBlockSize
Definition: AudioUnitEffect.h:194
ConfigClientInterface::GetSharedConfig
virtual bool GetSharedConfig(const RegistryPath &group, const RegistryPath &key, wxString &value, const wxString &defval)=0
ChannelNames
enum ChannelName * ChannelNames
AUControl::ForceRedraw
void ForceRedraw()
AudioUnitEffect::mReady
bool mReady
Definition: AudioUnitEffect.h:201
AudioUnitEffect::mAudioIns
unsigned mAudioIns
Definition: AudioUnitEffect.h:190
EffectUIHostInterface
EffectUIHostInterface has nothing in it. It is provided so that an Effect can call SetHostUI passing ...
Definition: EffectInterface.h:257
AudioUnitEffectsModule::Initialize
bool Initialize() override
Definition: AudioUnitEffect.cpp:300
AudioUnitEffect::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: AudioUnitEffect.cpp:879
RegistryPath
wxString RegistryPath
Definition: Identifier.h:218
Identifier::GET
const wxString & GET() const
Explicit conversion to wxString, meant to be ugly-looking and demanding of a comment why it's correct...
Definition: Identifier.h:66
AudioUnitEffect::mSampleRate
double mSampleRate
Definition: AudioUnitEffect.h:195
AudioUnitEffect::Notify
void Notify(AudioUnit unit, AudioUnitParameterID parm)
Definition: AudioUnitEffect.cpp:2434
AudioUnitEffectOptionsDialog
Definition: AudioUnitEffect.cpp:498
ShuttleGuiBase::StartStatic
wxStaticBox * StartStatic(const TranslatableString &Str, int iProp=0)
Definition: ShuttleGui.cpp:893
CFReleaser
Definition: AudioUnitEffect.cpp:92
AudioUnitEffectImportDialog::AudioUnitEffectImportDialog
AudioUnitEffectImportDialog(wxWindow *parent, AudioUnitEffect *effect)
Definition: AudioUnitEffect.cpp:657
wxDialogWrapper
Definition: wxPanelWrapper.h:81
AudioUnitEffect::mUnitInitialized
bool mUnitInitialized
Definition: AudioUnitEffect.h:184
ParameterInfo::Get
bool Get(AudioUnit mUnit, AudioUnitParameterID parmID)
Definition: AudioUnitEffect.cpp:124
DECLARE_MODULE_ENTRY
DECLARE_MODULE_ENTRY(AudacityModule)
Definition: AudioUnitEffect.cpp:233
ConfigClientInterface::RemovePrivateConfig
virtual bool RemovePrivateConfig(const RegistryPath &group, const RegistryPath &key)=0
AudioUnitEffect::GetVersion
wxString GetVersion() override
Definition: AudioUnitEffect.cpp:889
EffectHostInterface::GetUserPresetsGroup
virtual RegistryPath GetUserPresetsGroup(const RegistryPath &name)=0
AudioUnitEffect
An Effect class that handles a wide range of effects. ??Mac only??
Definition: AudioUnitEffect.h:43
PluginPaths
std::vector< PluginPath > PluginPaths
Definition: Identifier.h:215
AUControl
a wxControl with Cocoa/Carbon support
Definition: AUControl.h:40
ConfigClientInterface::SetPrivateConfig
virtual bool SetPrivateConfig(const RegistryPath &group, const RegistryPath &key, const wxString &value)=0
FileNames::SelectFile
AUDACITY_DLL_API FilePath SelectFile(Operation op, const TranslatableString &message, const FilePath &default_path, const FilePath &default_filename, const FileExtension &default_extension, const FileTypes &fileTypes, int flags, wxWindow *parent)
AudioUnitEffect::mUnit
AudioUnit mUnit
Definition: AudioUnitEffect.h:183
AudioUnitEffect::GetFactoryPresets
RegistryPaths GetFactoryPresets() override
Definition: AudioUnitEffect.cpp:1678
ShuttleGuiBase::AddListControlReportMode
wxListCtrl * AddListControlReportMode(std::initializer_list< const ListControlColumn > columns={}, long listControlStyles=0)
Definition: ShuttleGui.cpp:802
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
AudioUnitEffect::GetTailSize
size_t GetTailSize() override
Definition: AudioUnitEffect.cpp:1220
AudioUnitEffect::mUIType
wxString mUIType
Definition: AudioUnitEffect.h:209
AudioUnitEffect::SaveUserPreset
bool SaveUserPreset(const RegistryPath &name) override
Definition: AudioUnitEffect.cpp:1627
EffectTypeAnalyze
@ EffectTypeAnalyze
Definition: EffectInterface.h:60
AudioUnitEffect::HasOptions
bool HasOptions() override
Definition: AudioUnitEffect.cpp:1937
AudioUnitEffect::mComponent
AudioComponent mComponent
Definition: AudioUnitEffect.h:182
ConfigClientInterface::SetSharedConfig
virtual bool SetSharedConfig(const RegistryPath &group, const RegistryPath &key, const wxString &value)=0
AudioUnitEffect::ProcessInitialize
bool ProcessInitialize(sampleCount totalLen, ChannelNames chanMap=NULL) override
Definition: AudioUnitEffect.cpp:1240
AudioUnitEffect::mMaster
AudioUnitEffect * mMaster
Definition: AudioUnitEffect.h:212
PRESET_FORMAT
#define PRESET_FORMAT
Definition: AudioUnitEffect.cpp:63
AudioUnitEffect::ProcessFinalize
bool ProcessFinalize() override
Definition: AudioUnitEffect.cpp:1293
AudioUnitEffect::mInputList
ArrayOf< AudioBufferList > mInputList
Definition: AudioUnitEffect.h:203
AudioUnitEffectOptionsDialog::mHost
EffectHostInterface * mHost
Definition: AudioUnitEffect.cpp:508
AudioUnitEffectImportDialog::mEffect
AudioUnitEffect * mEffect
Definition: AudioUnitEffect.cpp:646
ExceptionType::Internal
@ Internal
Indicates internal failure from Audacity.
AudioUnitEffect::mMasterIn
ArraysOf< float > mMasterIn
Definition: AudioUnitEffect.h:215
AudioUnitEffectsModule::ToOSType
OSType ToOSType(const wxString &type)
Definition: AudioUnitEffect.cpp:479
AudioUnitEffect::mLatencyDone
bool mLatencyDone
Definition: AudioUnitEffect.h:193
TranslatableString::MSGID
Identifier MSGID() const
MSGID is the English lookup key in the catalog, not necessarily for user's eyes if locale is some oth...
Definition: TranslatableString.cpp:17
AudioUnitEffect::ProcessBlock
size_t ProcessBlock(float **inBlock, float **outBlock, size_t blockLen) override
Definition: AudioUnitEffect.cpp:1303
ShuttleGui::AddStandardButtons
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxWindow *extra=NULL)
Definition: ShuttleGui.cpp:2432
AudioUnitEffect::mVendor
wxString mVendor
Definition: AudioUnitEffect.h:181
AudioUnitEffect::mNumChannels
unsigned mNumChannels
Definition: AudioUnitEffect.h:214
AudioUnitEffect::CloseUI
bool CloseUI() override
Definition: AudioUnitEffect.cpp:1820
AudioUnitEffect::BypassEffect
bool BypassEffect(bool bypass)
Definition: AudioUnitEffect.cpp:2681
AudioUnitEffect::GetVendor
VendorSymbol GetVendor() override
Definition: AudioUnitEffect.cpp:884
AudioUnitEffect::SupportsAutomation
bool SupportsAutomation() override
Definition: AudioUnitEffect.cpp:956
ShuttleGuiBase::SetBorder
void SetBorder(int Border)
Definition: ShuttleGui.h:489
ComponentInterface::GetName
TranslatableString GetName()
Definition: PluginManager.cpp:2083
AudioUnitEffect::mNumSamples
size_t mNumSamples
Definition: AudioUnitEffect.h:216
AudioUnitEffect::~AudioUnitEffect
virtual ~AudioUnitEffect()
Definition: AudioUnitEffect.cpp:852
ShuttleGuiBase::AddVariableText
wxStaticText * AddVariableText(const TranslatableString &Str, bool bCenter=false, int PositionFlags=0, int wrapWidth=0)
Definition: ShuttleGui.cpp:463
ConfigClientInterface::GetPrivateConfig
virtual bool GetPrivateConfig(const RegistryPath &group, const RegistryPath &key, wxString &value, const wxString &defval)=0
AudioUnitEffect::mTimeStamp
AudioTimeStamp mTimeStamp
Definition: AudioUnitEffect.h:200
ModuleInterface::RegistrationCallback
std::function< const PluginID &(ModuleInterface *, ComponentInterface *) > RegistrationCallback
Definition: ModuleInterface.h:123
ShuttleGuiBase::EndStatic
void EndStatic()
Definition: ShuttleGui.cpp:922
Destroy_ptr
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
Definition: MemoryX.h:290
AudioUnitEffectsModule::GetVersion
wxString GetVersion() override
Definition: AudioUnitEffect.cpp:279
EffectType
EffectType
Definition: EffectInterface.h:55
safenew
#define safenew
Definition: MemoryX.h:10
AudioUnitEffect::RealtimeProcessStart
bool RealtimeProcessStart() override
Definition: AudioUnitEffect.cpp:1419
AudioUnitEffect::GetType
EffectType GetType() override
Definition: AudioUnitEffect.cpp:911
AudioUnitEffect::GetPath
PluginPath GetPath() override
Definition: AudioUnitEffect.cpp:874
AudioUnitEffect::RealtimeResume
bool RealtimeResume() override
Definition: AudioUnitEffect.cpp:1401
anonymous_namespace{Menus.cpp}::Options
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:526
END_EVENT_TABLE
END_EVENT_TABLE()
ShuttleGuiBase::TieChoice
wxChoice * TieChoice(const TranslatableString &Prompt, TranslatableString &Selected, const TranslatableStrings &choices)
Definition: ShuttleGui.cpp:1727
ArrayOf
Memory.h template class for making an array of float, bool, etc.
Definition: MemoryX.h:27
AudioUnitEffectsModule::AudioUnitEffectsModule
AudioUnitEffectsModule()
Definition: AudioUnitEffect.cpp:251
AudioUnitEffectsModule::GetVendor
VendorSymbol GetVendor() override
Definition: AudioUnitEffect.cpp:274
AudioUnitEffect::Export
TranslatableString Export(const wxString &path)
Definition: AudioUnitEffect.cpp:2293
AudioUnitEffectImportDialog
Definition: AudioUnitEffect.cpp:633
EffectHostInterface::SetDuration
virtual void SetDuration(double seconds)=0
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
EffectHostInterface::GetFactoryDefaultsGroup
virtual RegistryPath GetFactoryDefaultsGroup()=0
AudioUnitEffect::SetChannelCount
void SetChannelCount(unsigned numChannels)
Definition: AudioUnitEffect.cpp:2288
AudioUnitEffect::LoadFactoryDefaults
bool LoadFactoryDefaults() override
Definition: AudioUnitEffect.cpp:1673
AudioUnitEffect::IsGraphicalUI
bool IsGraphicalUI() override
Definition: AudioUnitEffect.cpp:1780
AudioUnitEffect::mName
wxString mName
Definition: AudioUnitEffect.h:180
AudioUnitEffect::GetMidiOutCount
int GetMidiOutCount() override
Definition: AudioUnitEffect.cpp:1178
AudioUnitEffectsModule::Terminate
void Terminate() override
Definition: AudioUnitEffect.cpp:306
AudioUnitEffect::mEventListenerRef
AUEventListenerRef mEventListenerRef
Definition: AudioUnitEffect.h:218