annotate plugin/DSSIPluginInstance.h @ 1881:b504df98c3be

Ensure completion on output model is started at zero, so if it's checked before the input model has become ready and the transform has begun, it is not accidentally reported as complete (affected re-aligning models in Sonic Lineup when replacing the session)
author Chris Cannam
date Fri, 26 Jun 2020 11:45:39 +0100
parents ad5f892c0c4d
children
rev   line source
Chris@49 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@52 4 Sonic Visualiser
Chris@52 5 An audio file viewer and annotation editor.
Chris@52 6 Centre for Digital Music, Queen Mary, University of London.
Chris@0 7
Chris@52 8 This program is free software; you can redistribute it and/or
Chris@52 9 modify it under the terms of the GNU General Public License as
Chris@52 10 published by the Free Software Foundation; either version 2 of the
Chris@52 11 License, or (at your option) any later version. See the file
Chris@52 12 COPYING included with this distribution for more information.
Chris@0 13 */
Chris@0 14
Chris@0 15 /*
Chris@0 16 This is a modified version of a source file from the
Chris@0 17 Rosegarden MIDI and audio sequencer and notation editor.
Chris@17 18 This file copyright 2000-2006 Chris Cannam.
Chris@0 19 */
Chris@0 20
Chris@1581 21 #ifndef SV_DSSIPLUGININSTANCE_H
Chris@1581 22 #define SV_DSSIPLUGININSTANCE_H
Chris@0 23
Chris@0 24 #define DSSI_API_LEVEL 2
Chris@0 25
Chris@0 26 #include <vector>
Chris@0 27 #include <set>
Chris@0 28 #include <map>
Chris@0 29 #include <QString>
Chris@0 30 #include <QMutex>
Chris@0 31
Chris@0 32 #include "api/dssi.h"
Chris@0 33
Chris@0 34 #include "base/RingBuffer.h"
Chris@109 35 #include "base/Thread.h"
Chris@0 36 #include "RealTimePluginInstance.h"
Chris@0 37 #include "base/Scavenger.h"
Chris@0 38
Chris@0 39 class DSSIPluginInstance : public RealTimePluginInstance
Chris@0 40 {
Chris@0 41 public:
Chris@0 42 virtual ~DSSIPluginInstance();
Chris@0 43
Chris@1580 44 bool isOK() const override { return m_instanceHandle != 0; }
Chris@0 45
Chris@0 46 int getClientId() const { return m_client; }
Chris@1580 47 QString getPluginIdentifier() const override { return m_identifier; }
Chris@0 48 int getPosition() const { return m_position; }
Chris@0 49
Chris@1580 50 std::string getIdentifier() const override;
Chris@1580 51 std::string getName() const override;
Chris@1580 52 std::string getDescription() const override;
Chris@1580 53 std::string getMaker() const override;
Chris@1580 54 int getPluginVersion() const override;
Chris@1580 55 std::string getCopyright() const override;
Chris@51 56
Chris@1580 57 void run(const RealTime &, int count = 0) override;
Chris@0 58
Chris@1580 59 int getParameterCount() const override;
Chris@1580 60 void setParameterValue(int parameter, float value) override;
Chris@1580 61 float getParameterValue(int parameter) const override;
Chris@1580 62 float getParameterDefault(int parameter) const override;
Chris@1580 63 int getParameterDisplayHint(int parameter) const override;
Chris@51 64
Chris@1580 65 ParameterList getParameterDescriptors() const override;
Chris@1580 66 float getParameter(std::string) const override;
Chris@1580 67 void setParameter(std::string, float) override;
Chris@51 68
Chris@1580 69 std::string configure(std::string key, std::string value) override;
Chris@1580 70 void sendEvent(const RealTime &eventTime,
Chris@1580 71 const void *event) override;
Chris@1580 72 void clearEvents() override;
Chris@0 73
Chris@1580 74 int getBufferSize() const override { return m_blockSize; }
Chris@1580 75 int getAudioInputCount() const override { return (int)m_audioPortsIn.size(); }
Chris@1580 76 int getAudioOutputCount() const override { return m_idealChannelCount; }
Chris@1580 77 sample_t **getAudioInputBuffers() override { return m_inputBuffers; }
Chris@1580 78 sample_t **getAudioOutputBuffers() override { return m_outputBuffers; }
Chris@0 79
Chris@1580 80 int getControlOutputCount() const override { return (int)m_controlPortsOut.size(); }
Chris@1580 81 float getControlOutputValue(int n) const override;
Chris@60 82
Chris@1580 83 ProgramList getPrograms() const override;
Chris@1580 84 std::string getCurrentProgram() const override;
Chris@1580 85 std::string getProgram(int bank, int program) const override;
Chris@1038 86 virtual int getProgram(std::string name) const;
Chris@1580 87 void selectProgram(std::string program) override;
Chris@0 88
Chris@1580 89 bool isBypassed() const override { return m_bypassed; }
Chris@1580 90 void setBypassed(bool bypassed) override { m_bypassed = bypassed; }
Chris@0 91
Chris@1580 92 sv_frame_t getLatency() override;
Chris@0 93
Chris@1580 94 void silence() override;
Chris@1580 95 void discardEvents() override;
Chris@1580 96 void setIdealChannelCount(int channels) override; // may re-instantiate
Chris@0 97
Chris@0 98 virtual bool isInGroup() const { return m_grouped; }
Chris@0 99 virtual void detachFromGroup();
Chris@0 100
Chris@1580 101 std::string getType() const override { return "DSSI Real-Time Plugin"; }
Chris@57 102
Chris@0 103 protected:
Chris@0 104 // To be constructed only by DSSIPluginFactory
Chris@0 105 friend class DSSIPluginFactory;
Chris@0 106
Chris@0 107 // Constructor that creates the buffers internally
Chris@0 108 //
Chris@0 109 DSSIPluginInstance(RealTimePluginFactory *factory,
Chris@1429 110 int client,
Chris@1429 111 QString identifier,
Chris@1429 112 int position,
Chris@1429 113 sv_samplerate_t sampleRate,
Chris@1429 114 int blockSize,
Chris@1429 115 int idealChannelCount,
Chris@1429 116 const DSSI_Descriptor* descriptor);
Chris@0 117
Chris@0 118 void init();
Chris@1040 119 void instantiate(sv_samplerate_t sampleRate);
Chris@0 120 void cleanup();
Chris@0 121 void activate();
Chris@0 122 void deactivate();
Chris@0 123 void connectPorts();
Chris@0 124
Chris@0 125 bool handleController(snd_seq_event_t *ev);
Chris@1038 126 void setPortValueFromController(int portNumber, int controlValue);
Chris@51 127 void selectProgramAux(std::string program, bool backupPortValues);
Chris@0 128 void checkProgramCache() const;
Chris@0 129
Chris@0 130 void initialiseGroupMembership();
Chris@1040 131 void runGrouped(const RealTime &);
Chris@0 132
Chris@0 133 // For use in DSSIPluginFactory (set in the DSSI_Host_Descriptor):
Chris@0 134 static int requestMidiSend(LADSPA_Handle instance,
Chris@1429 135 unsigned char ports,
Chris@1429 136 unsigned char channels);
Chris@0 137 static void midiSend(LADSPA_Handle instance,
Chris@1429 138 snd_seq_event_t *events,
Chris@1429 139 unsigned long eventCount);
Chris@0 140 static int requestNonRTThread(LADSPA_Handle instance,
Chris@1429 141 void (*runFunction)(LADSPA_Handle));
Chris@0 142
Chris@0 143 int m_client;
Chris@0 144 int m_position;
Chris@0 145 LADSPA_Handle m_instanceHandle;
Chris@0 146 const DSSI_Descriptor *m_descriptor;
Chris@0 147
Chris@1038 148 std::vector<std::pair<int, LADSPA_Data*> > m_controlPortsIn;
Chris@1038 149 std::vector<std::pair<int, LADSPA_Data*> > m_controlPortsOut;
Chris@0 150
Chris@0 151 std::vector<LADSPA_Data> m_backupControlPortsIn;
Chris@0 152
Chris@0 153 std::map<int, int> m_controllerMap;
Chris@0 154
Chris@0 155 std::vector<int> m_audioPortsIn;
Chris@0 156 std::vector<int> m_audioPortsOut;
Chris@0 157
Chris@0 158 struct ProgramControl {
Chris@1429 159 int msb;
Chris@1429 160 int lsb;
Chris@1429 161 int program;
Chris@0 162 };
Chris@0 163 ProgramControl m_pending;
Chris@0 164
Chris@0 165 struct ProgramDescriptor {
Chris@1429 166 int bank;
Chris@1429 167 int program;
Chris@1429 168 std::string name;
Chris@0 169 };
Chris@0 170 mutable std::vector<ProgramDescriptor> m_cachedPrograms;
Chris@0 171 mutable bool m_programCacheValid;
Chris@0 172
Chris@0 173 RingBuffer<snd_seq_event_t> m_eventBuffer;
Chris@0 174
Chris@1040 175 int m_blockSize;
Chris@0 176 sample_t **m_inputBuffers;
Chris@0 177 sample_t **m_outputBuffers;
Chris@0 178 bool m_ownBuffers;
Chris@1040 179 int m_idealChannelCount;
Chris@1040 180 int m_outputBufferCount;
Chris@1040 181 sv_samplerate_t m_sampleRate;
Chris@0 182 float *m_latencyPort;
Chris@0 183 bool m_run;
Chris@0 184
Chris@0 185 bool m_bypassed;
Chris@51 186 std::string m_program;
Chris@0 187 bool m_grouped;
Chris@1040 188 RealTime m_lastRunTime;
Chris@0 189
Chris@1040 190 RealTime m_lastEventSendTime;
Chris@10 191 bool m_haveLastEventSendTime;
Chris@10 192
Chris@0 193 QMutex m_processLock;
Chris@0 194
Chris@0 195 typedef std::set<DSSIPluginInstance *> PluginSet;
Chris@0 196 typedef std::map<QString, PluginSet> GroupMap;
Chris@0 197 static GroupMap m_groupMap;
Chris@0 198 static snd_seq_event_t **m_groupLocalEventBuffers;
Chris@0 199 static size_t m_groupLocalEventBufferCount;
Chris@0 200
Chris@0 201 static Scavenger<ScavengerArrayWrapper<snd_seq_event_t *> > m_bufferScavenger;
Chris@0 202
Chris@109 203 class NonRTPluginThread : public Thread
Chris@0 204 {
Chris@0 205 public:
Chris@1429 206 NonRTPluginThread(LADSPA_Handle handle,
Chris@1429 207 void (*runFunction)(LADSPA_Handle)) :
Chris@1429 208 m_handle(handle),
Chris@1429 209 m_runFunction(runFunction),
Chris@1429 210 m_exiting(false) { }
Chris@0 211
Chris@1580 212 void run() override;
Chris@1429 213 void setExiting() { m_exiting = true; }
Chris@0 214
Chris@0 215 protected:
Chris@1429 216 LADSPA_Handle m_handle;
Chris@1429 217 void (*m_runFunction)(LADSPA_Handle);
Chris@1429 218 bool m_exiting;
Chris@0 219 };
Chris@0 220 static std::map<LADSPA_Handle, std::set<NonRTPluginThread *> > m_threads;
Chris@0 221 };
Chris@0 222
Chris@0 223 #endif // _DSSIPLUGININSTANCE_H_
Chris@0 224