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