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