File: VST2Plugin.h

package info (click to toggle)
pd-vstplugin 0.6.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,008 kB
  • sloc: cpp: 22,794; lisp: 2,860; makefile: 37; sh: 26
file content (184 lines) | stat: -rw-r--r-- 7,307 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// VST2Plugin
#pragma once

#include "Interface.h"
#include "PluginFactory.h"

#define VST_FORCE_DEPRECATED 0
#include "aeffectx.h"

namespace vst {

class VST2Plugin;

class VST2Factory final : public PluginFactory {
 public:
    static VstInt32 shellPluginID;

    VST2Factory(const std::string& path, bool probe);
    ~VST2Factory();
    // probe a single plugin
    PluginDesc::const_ptr probePlugin(int id) const override;
    // create a new plugin instance
    IPlugin::ptr create(const std::string& name, bool editor) const override;
 private:
    void doLoad();
    std::unique_ptr<VST2Plugin> doCreate(PluginDesc::const_ptr desc, bool editor) const;
    // Although calling convention specifiers like __cdecl and __stdcall
    // should be meaningless on x86-64 platforms, Wine apparantely treats
    // them as a hint that a function (pointer) uses the Microsoft x64 calling
    // convention instead of System V! I couldn't find any documentation
    // to confirm this, but it seems to work in practice. Otherwise,
    // calling the entry point would crash immediately with stack corruption.
    using EntryPoint = AEffect *(VSTCALLBACK *)(audioMasterCallback);
    EntryPoint entry_;
};

//-----------------------------------------------------------------------------

class VST2Plugin final : public IPlugin {
    friend class VST2Factory;
 public:
    static VstIntPtr VSTCALLBACK hostCallback(AEffect *plugin, VstInt32 opcode,
        VstInt32 index, VstIntPtr value, void *p, float opt);

    VST2Plugin(AEffect* plugin, IFactory::const_ptr f, PluginDesc::const_ptr desc, bool editor);
    ~VST2Plugin();

    const PluginDesc& info() const override { return *info_; }
    PluginDesc::const_ptr getInfo() const { return info_; }

    int canDo(const char *what) const override;
    intptr_t vendorSpecific(int index, intptr_t value, void *p, float opt) override;

    void setupProcessing(double sampleRate, int maxBlockSize,
                         ProcessPrecision precision, ProcessMode mode) override;
    void process(ProcessData& data) override;
    void suspend() override;
    void resume() override;
    void setBypass(Bypass state) override;
    void setNumSpeakers(int *input, int numInputs,
                        int *output, int numOutputs) override;
    int getLatencySamples() override;

    void setListener(IPluginListener* listener) override {
        listener_ = listener;
    }

    void setTempoBPM(double tempo) override;
    void setTimeSignature(int numerator, int denominator) override;
    void setTransportPlaying(bool play) override;
    void setTransportRecording(bool record) override;
    void setTransportAutomationWriting(bool writing) override;
    void setTransportAutomationReading(bool reading) override;
    void setTransportCycleActive(bool active) override;
    void setTransportCycleStart(double beat) override;
    void setTransportCycleEnd(double beat) override;
    void setTransportPosition(double beat) override;
    double getTransportPosition() const override {
        return timeInfo_.ppqPos;
    }
    void sendMidiEvent(const MidiEvent& event) override;
    void sendSysexEvent(const SysexEvent& event) override;

    void setParameter(int index, float value, int sampleOffset = 0) override;
    bool setParameter(int index, std::string_view str, int sampleOffset = 0) override;
    float getParameter(int index) const override;
    size_t getParameterString(int index, ParamStringBuffer& buffer) const override;

    void setProgram(int program) override;
    void setProgramName(std::string_view name) override;
    int getProgram() const override;
    std::string getProgramName() const override;
    std::string getProgramNameIndexed(int index) const override;

    void readProgramFile(const std::string& path) override;
    void readProgramData(const char *data, size_t size) override;
    void writeProgramFile(const std::string& path) override;
    void writeProgramData(std::string& buffer) override;
    void readBankFile(const std::string& path) override;
    void readBankData(const char *data, size_t size) override;
    void writeBankFile(const std::string& path) override;
    void writeBankData(std::string& buffer) override;

    void openEditor(void *window) override;
    void closeEditor() override;
    bool getEditorRect(Rect& rect) const override;
    void updateEditor() override;
    void checkEditorSize(int &width, int &height) const override;
    void resizeEditor(int width, int height) override;

    IWindow *getWindow() const override {
        return window_.get();
    }
 private:
    std::string getPluginName() const;
    std::string getPluginVendor() const;
    std::string getPluginCategory() const;
    std::string getPluginVersion() const;
    std::string getSDKVersion() const;
    std::string getParameterName(int index) const;
    std::string getParameterLabel(int index) const;
    int getNumInputs() const;
    int getNumOutputs() const;
    int getNumParameters() const;
    int getNumPrograms() const;
    bool hasEditor() const;
    bool hasPrecision(ProcessPrecision precision) const;
    bool isSynth() const;
    bool hasTail() const;
    int getTailSize() const;
    bool hasBypass() const;
    int getNumMidiInputChannels() const;
    int getNumMidiOutputChannels() const;
    bool hasMidiInput() const;
    bool hasMidiOutput() const;
    // other helpers
    static bool canHostDo(const char *what);
    bool hasFlag(VstAEffectFlags flag) const;
    void checkLatency();
    VstTimeInfo * getTimeInfo(VstInt32 flags);
    bool hasChunkData() const;
    void setProgramChunkData(const void *data, size_t size);
    void getProgramChunkData(void **data, size_t *size) const;
    void setBankChunkData(const void *data, size_t size);
    void getBankChunkData(void **data, size_t *size) const;
    // processing
    void preProcess(int nsamples);
    template<typename T, typename TProc>
    void doProcess(ProcessData& data, TProc processRoutine);
    template<typename T, typename TProc>
    void bypassProcess(ProcessData& data, TProc processRoutine,
                       Bypass state, bool ramp);
    void postProcess(int nsample);
    // process VST events from plugin
    void processEvents(VstEvents *events);
    // dispatch to plugin
    VstIntPtr dispatch(VstInt32 opCode, VstInt32 index = 0, VstIntPtr value = 0,
        void *p = 0, float opt = 0) const;
    // data members
    VstIntPtr callback(VstInt32 opcode, VstInt32 index,
                           VstIntPtr value, void *ptr, float opt);
    IFactory::const_ptr factory_; // keep alive
    PluginDesc::const_ptr info_;
    AEffect *plugin_ = nullptr;
    // processing
    int latency_ = 0;
    ProcessMode mode_ = ProcessMode::Realtime;
    VstTimeInfo timeInfo_;
    Bypass bypass_ = Bypass::Off;
    Bypass lastBypass_ = Bypass::Off;
    bool haveBypass_ = false;
    bool bypassSilent_ = false; // check if we can stop processing
    // buffers for incoming MIDI and SysEx events
    std::vector<VstMidiEvent> midiQueue_;
    std::vector<VstMidiSysexEvent> sysexQueue_;
    VstEvents *vstEvents_; // VstEvents is basically an array of VstEvent pointers
    int vstEventBufferSize_ = 0;
    bool editor_ = false;
    // UI
    IWindow::ptr window_;
    IPluginListener* listener_ = nullptr;
};

} // vst