text: /**********************************************************************
  
    Audacity: A Digital Audio Editor
  
    AudioUnitEffect.h
  
    Dominic Mazzoni
    Leland Lucius
  
  **********************************************************************/
  #ifndef AUDACITY_AUDIOUNIT_EFFECT_H
  
  #include "../../Audacity.h"
  
  #if USE_AUDIO_UNITS
  
  #include "../../MemoryX.h"
  #include <vector>
  #include <wx/dialog.h>
  
  #include <AudioToolbox/AudioUnitUtilities.h>
  #include <AudioUnit/AudioUnit.h>
  #include <AudioUnit/AudioUnitProperties.h>
  
  #include "audacity/EffectInterface.h"
  #include "audacity/ModuleInterface.h"
  #include "audacity/PluginInterface.h"
  
  #include "AUControl.h"
  
  #define AUDIOUNITEFFECTS_VERSION wxT("1.0.0.0")
  #define AUDIOUNITEFFECTS_FAMILY wxT("AudioUnit")
  
  class AudioUnitEffect;
  
  using AudioUnitEffectArray = std::vector<movable_ptr<AudioUnitEffect>>;
  
  class AudioUnitEffectExportDialog;
  class AudioUnitEffectImportDialog;
  
  class AudioUnitEffect : public wxEvtHandler,
                          public EffectClientInterface,
                          public EffectUIClientInterface
  {
  public:
     AudioUnitEffect(const wxString & path,
                     const wxString & name,
                     AudioComponent component,
                     AudioUnitEffect *master = NULL);
     virtual ~AudioUnitEffect();
  
     // IdentInterface implementation
  
     wxString GetPath() override;
     wxString GetSymbol() override;
     wxString GetName() override;
     wxString GetVendor() override;
     wxString GetVersion() override;
     wxString GetDescription() override;
  
     // EffectIdentInterface implementation
  
     EffectType GetType() override;
     wxString GetFamily() override;
     bool IsInteractive() override;
     bool IsDefault() override;
     bool IsLegacy() override;
     bool SupportsRealtime() override;
     bool SupportsAutomation() override;
  
     // EffectClientInterface implementation
  
     bool SetHost(EffectHostInterface *host) override;
  
     int GetAudioInCount() override;
     int GetAudioOutCount() override;
  
     int GetMidiInCount() override;
     int GetMidiOutCount() override;
  
     void SetSampleRate(double rate) override;
     sampleCount SetBlockSize(sampleCount maxBlockSize) override;
  
     sampleCount GetLatency() override;
     sampleCount GetTailSize() override;
  
     bool IsReady() override;
     bool ProcessInitialize(sampleCount totalLen, ChannelNames chanMap = NULL) override;
     bool ProcessFinalize() override;
     sampleCount ProcessBlock(float **inBlock, float **outBlock, sampleCount blockLen) override;
  
     bool RealtimeInitialize() override;
     bool RealtimeAddProcessor(int numChannels, float sampleRate) override;
     bool RealtimeFinalize() override;
     bool RealtimeSuspend() override;
     bool RealtimeResume() override;
     bool RealtimeProcessStart() override;
     sampleCount RealtimeProcess(int group,
                                         float **inbuf,
                                         float **outbuf,
                                         sampleCount numSamples) override;
     bool RealtimeProcessEnd() override;
  
     bool ShowInterface(wxWindow *parent, bool forceModal = false) override;
  
     bool GetAutomationParameters(EffectAutomationParameters & parms) override;
     bool SetAutomationParameters(EffectAutomationParameters & parms) override;
  
     bool LoadUserPreset(const wxString & name) override;
     bool SaveUserPreset(const wxString & name) override;
  
     bool LoadFactoryPreset(int id) override;
     bool LoadFactoryDefaults() override;
     wxArrayString GetFactoryPresets() override;
  
     // EffectUIClientInterface implementation
  
     void SetHostUI(EffectUIHostInterface *host) override;
     bool PopulateUI(wxWindow *parent) override;
     bool IsGraphicalUI() override;
     bool ValidateUI() override;
     bool HideUI() override;
     bool CloseUI() override;
  
     bool CanExportPresets() override;
     void ExportPresets() override;
     void ImportPresets() override;
  
     bool HasOptions() override;
     void ShowOptions() override;
  
     // AudioUnitEffect implementation
     
  private:
     bool SetRateAndChannels();
  
     bool CopyParameters(AudioUnit srcUnit, AudioUnit dstUnit);
  
     // Realtime
     int GetChannelCount();
     void SetChannelCount(int numChannels);
     
     static OSStatus RenderCallback(void *inRefCon,
                                    AudioUnitRenderActionFlags *inActionFlags,
                                    const AudioTimeStamp *inTimeStamp,
                                    UInt32 inBusNumber,
                                    UInt32 inNumFrames,
                                    AudioBufferList *ioData);
     OSStatus Render(AudioUnitRenderActionFlags *inActionFlags,
                     const AudioTimeStamp *inTimeStamp,
                     UInt32 inBusNumber,
                     UInt32 inNumFrames,
                     AudioBufferList *ioData);
  
     static void EventListenerCallback(void *inCallbackRefCon,
                                       void *inObject,
                                       const AudioUnitEvent *inEvent,
                                       UInt64 inEventHostTime,
                                       AudioUnitParameterValue inParameterValue);
     void EventListener(const AudioUnitEvent *inEvent,
                        AudioUnitParameterValue inParameterValue);
  
     void GetChannelCounts();
  
     bool LoadParameters(const wxString & group);
     bool SaveParameters(const wxString & group);
  
  
     bool CreatePlain(wxWindow *parent);
  
  private:
  
     wxString mPath;
     wxString mName;
     wxString mVendor;
     AudioComponent mComponent;
     AudioUnit mUnit;
     bool mUnitInitialized;
  
     bool mSupportsMono;
     bool mSupportsStereo;
  
     EffectHostInterface *mHost;
     int mAudioIns;
     int mAudioOuts;
     bool mInteractive;
     bool mLatencyDone;
     UInt32 mBlockSize;
     double mSampleRate;
  
     int mBufferSize;
     bool mUseLatency;
  
     AudioTimeStamp mTimeStamp;
     bool mReady;
  
     AudioBufferList *mInputList;
     AudioBufferList *mOutputList;
  
     EffectUIHostInterface *mUIHost;
     wxWindow *mParent;
     wxDialog *mDialog;
     wxString mUIType;
     bool mIsGraphical;
  
     AudioUnitEffect *mMaster;     // non-NULL if a slave
     AudioUnitEffectArray mSlaves;
     int mNumChannels;
     float **mMasterIn;
     float **mMasterOut;
     sampleCount mNumSamples;
     
     AUEventListenerRef mEventListenerRef;
  
     friend class AudioUnitEffectExportDialog;
     friend class AudioUnitEffectImportDialog;
  };
  
  ///////////////////////////////////////////////////////////////////////////////
  //
  // AudioUnitEffectsModule
  //
  ///////////////////////////////////////////////////////////////////////////////
  
  class AudioUnitEffectsModule final : public ModuleInterface
  {
  public:
     AudioUnitEffectsModule(ModuleManagerInterface *moduleManager, const wxString *path);
     virtual ~AudioUnitEffectsModule();
  
     // IdentInterface implementatino
  
     wxString GetPath() override;
     wxString GetSymbol() override;
     wxString GetName() override;
     wxString GetVendor() override;
     wxString GetVersion() override;
     wxString GetDescription() override;
  
     // ModuleInterface implementation
  
     bool Initialize() override;
     void Terminate() override;
  
     bool AutoRegisterPlugins(PluginManagerInterface & pm) override;
     wxArrayString FindPlugins(PluginManagerInterface & pm) override;
     bool RegisterPlugin(PluginManagerInterface & pm, const wxString & path) override;
  
     bool IsPluginValid(const wxString & path) override;
  
     IdentInterface *CreateInstance(const wxString & path) override;
     void DeleteInstance(IdentInterface *instance) override;
  
     // AudioUnitEffectModule implementation
  
     void LoadAudioUnitsOfType(OSType inAUType, wxArrayString & effects);
     AudioComponent FindAudioUnit(const wxString & path, wxString & name);
  
     wxString FromOSType(OSType type);
     OSType ToOSType(const wxString & type);
  
  private:
     ModuleManagerInterface *mModMan;
     wxString mPath;
  };
  
  #endif
  
  #endif
  