1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 3 /* 4 Rosegarden 5 A sequencer and musical notation editor. 6 Copyright 2000-2021 the Rosegarden development team. 7 See the AUTHORS file for more details. 8 9 This program is free software; you can redistribute it and/or 10 modify it under the terms of the GNU General Public License as 11 published by the Free Software Foundation; either version 2 of the 12 License, or (at your option) any later version. See the file 13 COPYING included with this distribution for more information. 14 */ 15 16 #ifndef RG_DSSIPLUGININSTANCE_H 17 #define RG_DSSIPLUGININSTANCE_H 18 19 #include <vector> 20 #include <set> 21 #include <map> 22 #include <QString> 23 #include "base/Instrument.h" 24 25 #include <dssi.h> 26 #include "RingBuffer.h" 27 #include "RunnablePluginInstance.h" 28 #include "Scavenger.h" 29 #include <pthread.h> 30 31 namespace Rosegarden 32 { 33 34 class DSSIPluginInstance : public RunnablePluginInstance 35 { 36 public: 37 ~DSSIPluginInstance() override; 38 isOK()39 bool isOK() const override { return m_instanceHandle != nullptr; } 40 getInstrument()41 InstrumentId getInstrument() const { return m_instrument; } getIdentifier()42 QString getIdentifier() const override { return m_identifier; } getPosition()43 int getPosition() const { return m_position; } 44 45 void run(const RealTime &) override; 46 47 void setPortValue(unsigned int portNumber, float value) override; 48 float getPortValue(unsigned int portNumber) override; 49 QString configure(QString key, QString value) override; 50 void sendEvent(const RealTime &eventTime, 51 const void *event) override; 52 getBufferSize()53 size_t getBufferSize() override { return m_blockSize; } getAudioInputCount()54 size_t getAudioInputCount() override { return m_audioPortsIn.size(); } getAudioOutputCount()55 size_t getAudioOutputCount() override { return m_idealChannelCount; } getAudioInputBuffers()56 sample_t **getAudioInputBuffers() override { return m_inputBuffers; } getAudioOutputBuffers()57 sample_t **getAudioOutputBuffers() override { return m_outputBuffers; } 58 59 QStringList getPrograms() override; 60 QString getCurrentProgram() override; 61 QString getProgram(int bank, int program) override; 62 unsigned long getProgram(QString name) override; 63 void selectProgram(QString program) override; 64 isBypassed()65 bool isBypassed() const override { return m_bypassed; } setBypassed(bool bypassed)66 void setBypassed(bool bypassed) override { m_bypassed = bypassed; } 67 68 size_t getLatency() override; 69 70 void silence() override; 71 void discardEvents() override; 72 void setIdealChannelCount(size_t channels) override; // may re-instantiate 73 isInGroup()74 virtual bool isInGroup() const { return m_grouped; } 75 virtual void detachFromGroup(); 76 77 protected: 78 // To be constructed only by DSSIPluginFactory 79 friend class DSSIPluginFactory; 80 81 // Constructor that creates the buffers internally 82 // 83 DSSIPluginInstance(PluginFactory *factory, 84 InstrumentId instrument, 85 QString identifier, 86 int position, 87 unsigned long sampleRate, 88 size_t blockSize, 89 int idealChannelCount, 90 const DSSI_Descriptor* descriptor); 91 92 // Constructor that uses shared buffers 93 // 94 DSSIPluginInstance(PluginFactory *factory, 95 InstrumentId instrument, 96 QString identifier, 97 int position, 98 unsigned long sampleRate, 99 size_t blockSize, 100 sample_t **inputBuffers, 101 sample_t **outputBuffers, 102 const DSSI_Descriptor* descriptor); 103 104 void init(); 105 void instantiate(unsigned long sampleRate); 106 void cleanup(); 107 void activate(); 108 void deactivate(); 109 void connectPorts(); 110 111 bool handleController(snd_seq_event_t *ev); 112 void setPortValueFromController(unsigned int portNumber, int controlValue); 113 void selectProgramAux(QString program, bool backupPortValues); 114 void checkProgramCache(); 115 116 void initialiseGroupMembership(); 117 void runGrouped(const RealTime &); 118 119 InstrumentId m_instrument; 120 int m_position; 121 LADSPA_Handle m_instanceHandle; 122 const DSSI_Descriptor *m_descriptor; 123 124 std::vector<std::pair<unsigned long, LADSPA_Data*> > m_controlPortsIn; 125 std::vector<std::pair<unsigned long, LADSPA_Data*> > m_controlPortsOut; 126 127 std::vector<LADSPA_Data> m_backupControlPortsIn; 128 std::vector<bool> m_portChangedSinceProgramChange; 129 130 std::map<int, int> m_controllerMap; 131 132 std::vector<int> m_audioPortsIn; 133 std::vector<int> m_audioPortsOut; 134 135 struct ProgramControl { 136 int msb; 137 int lsb; 138 int program; 139 }; 140 ProgramControl m_pending; 141 142 struct ProgramDescriptor { 143 int bank; 144 int program; 145 QString name; 146 }; 147 std::vector<ProgramDescriptor> m_cachedPrograms; 148 bool m_programCacheValid; 149 150 RingBuffer<snd_seq_event_t> m_eventBuffer; 151 152 size_t m_blockSize; 153 sample_t **m_inputBuffers; 154 sample_t **m_outputBuffers; 155 bool m_ownBuffers; 156 size_t m_idealChannelCount; 157 size_t m_outputBufferCount; 158 size_t m_sampleRate; 159 float *m_latencyPort; 160 161 bool m_run; 162 bool m_runSinceReset; 163 164 bool m_bypassed; 165 QString m_program; 166 bool m_grouped; 167 RealTime m_lastRunTime; 168 169 pthread_mutex_t m_processLock; 170 171 typedef std::set<DSSIPluginInstance *> PluginSet; 172 typedef std::map<QString, PluginSet> GroupMap; 173 static GroupMap m_groupMap; 174 static snd_seq_event_t **m_groupLocalEventBuffers; 175 static size_t m_groupLocalEventBufferCount; 176 177 static Scavenger<ScavengerArrayWrapper<snd_seq_event_t *> > m_bufferScavenger; 178 }; 179 180 }; 181 182 #endif // RG_DSSIPLUGININSTANCE_H 183 184