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 
8   This program is free software; you can redistribute it and/or
9   modify it under the terms of the GNU General Public License as
10   published by the Free Software Foundation; either version 2 of the
11   License, or (at your option) any later version.  See the file
12   COPYING included with this distribution for more information.
13 */
14 
15 #ifndef RG_MAPPEDSTUDIO_H
16 #define RG_MAPPEDSTUDIO_H
17 
18 #include <map>
19 #include <string>
20 #include <vector>
21 #include <QDataStream>
22 #include <QString>
23 
24 #include "MappedCommon.h"
25 #include "base/Instrument.h"
26 #include "base/Device.h"
27 
28 #include "base/AudioPluginInstance.h" // for PluginPort::PortDisplayHint //!!!???
29 
30 
31 namespace Rosegarden
32 {
33 
34 
35 class SoundDriver;
36 
37 
38 // Types are in MappedCommon.h
39 //
40 class MappedObject
41 {
42 public:
43 
44     // Some common properties
45     //
46     static const MappedObjectProperty Name;
47     static const MappedObjectProperty Instrument;
48     static const MappedObjectProperty Position;
49 
50     // The object we can create
51     //
52     typedef enum
53     {
54         Studio,
55         AudioFader,          // connectable fader - interfaces with devices
56         AudioBuss,           // connectable buss - inferfaces with faders
57         AudioInput,          // connectable record input
58         PluginSlot,
59         PluginPort
60 
61     } MappedObjectType;
62 
MappedObject(MappedObject * parent,const std::string & name,MappedObjectType type,MappedObjectId id)63     MappedObject(MappedObject *parent,
64                  const std::string &name,
65                  MappedObjectType type,
66                  MappedObjectId id):
67         m_type(type),
68         m_id(id),
69         m_name(name),
70         m_parent(parent) {;}
71 
~MappedObject()72     virtual ~MappedObject() {;}
73 
getId()74     MappedObjectId getId() { return m_id; }
getType()75     MappedObjectType getType() { return m_type; }
76 
getName()77     std::string getName() { return m_name; }
setName(const std::string & name)78     void setName(const std::string &name) { m_name= name; }
79 
80     // Get and set properties
81     //
82     virtual MappedObjectPropertyList
83         getPropertyList(const MappedObjectProperty &property) = 0;
84 
85     virtual bool getProperty(const MappedObjectProperty &property,
86                              MappedObjectValue &value) = 0;
87 
88     // Only relevant to objects that have string properties
89     //
getStringProperty(const MappedObjectProperty &,QString &)90     virtual bool getStringProperty(const MappedObjectProperty &/* property */,
91                                    QString &/* value */) { return false; }
92 
93     virtual void setProperty(const MappedObjectProperty &property,
94                              MappedObjectValue value) = 0;
95 
96     // Only relevant to objects that have string properties
97     //
setStringProperty(const MappedObjectProperty &,QString)98     virtual void setStringProperty(const MappedObjectProperty &/* property */,
99                                    QString /* value */) { }
100 
101     // Only relevant to objects that have list properties
102     //
setPropertyList(const MappedObjectProperty &,const MappedObjectPropertyList &)103     virtual void setPropertyList(const MappedObjectProperty &/* property */,
104                                  const MappedObjectPropertyList &/* values */) { }
105 
106     // Ownership
107     //
getParent()108     MappedObject* getParent() { return m_parent; }
getParent()109     const MappedObject* getParent() const { return m_parent; }
setParent(MappedObject * parent)110     void setParent(MappedObject *parent) { m_parent = parent; }
111 
112     // Get a list of child ids - get a list of a certain type
113     //
114     MappedObjectPropertyList getChildren();
115     MappedObjectPropertyList getChildren(MappedObjectType type);
116 
117     // Child management
118     //
119     void addChild(MappedObject *mO);
120     void removeChild(MappedObject *mO);
121 
122     // Destruction
123     //
124     void destroy();
125     void destroyChildren();
126 
getChildObjects()127     std::vector<MappedObject*> getChildObjects() { return m_children; }
128 
129 protected:
130 
131     MappedObjectType m_type;
132     MappedObjectId   m_id;
133     std::string      m_name;
134 
135     MappedObject                *m_parent;
136     std::vector<MappedObject*>   m_children;
137 };
138 
139 
140 class MappedAudioFader;
141 class MappedAudioBuss;
142 class MappedAudioInput;
143 
144 
145 /// Sequencer-side representation of the audio portion of the Studio.
146 /**
147  * Factory and virtual plug-board for Audio (and MIDI?) objects.
148  *
149  * A sequencer-side representation of certain elements in the
150  * gui that enables us to control outgoing or incoming audio
151  * and MIDI with run-time only persistence.  Placeholders for
152  * our Studio elements on the sequencer.
153  *
154  * Container of MappedAudioFader, MappedAudioInput, MappedAudioBuss,
155  * MappedPluginPort, and MappedPluginSlot instances.
156  *
157  * Thread-safe so that the UI and sequencer threads can freely work
158  * with this.
159  *
160  * ??? A better name for this might be SequencerStudio.  Throughout
161  *     Rosegarden, the software term "Mapped" is overused in class names.
162  *     "Mapped" should either be dropped or something related to the problem
163  *     domain should be used in its place.
164  */
165 class MappedStudio : public MappedObject
166 {
167 public:
168     MappedStudio();
169     ~MappedStudio() override;
170 
171     // *** Create
172 
173     MappedObject *createObject(MappedObjectType type);
174 
175     MappedObject *createObject(MappedObjectType type,
176                                MappedObjectId id);
177 
178     // *** Destroy
179 
180     /// Call destroy() on the object.
181     bool destroyObject(MappedObjectId id);
182     // Clear a MappedObject reference from the Studio
183     bool clearObject(MappedObjectId id);
184     // Empty the studio of everything
185     void clear();
186 
187     // *** Get
188 
189     MappedObject *getObjectById(MappedObjectId id);
190 
191     // Get an object by ID and type.  (Returns 0 if the ID does not
192     // exist or exists but is not of the correct type.)  This is
193     // faster than getObjectById if you know the type already.
194     MappedObject *getObjectByIdAndType(MappedObjectId id,
195                                        MappedObjectType type);
196 
197     // Get an arbitrary object of a given type - to see if any exist
198     MappedObject *getObjectOfType(MappedObjectType type);
199 
200     // Get an audio fader for an InstrumentId.  Convenience function.
201     MappedAudioFader *getAudioFader(InstrumentId id);
202     MappedAudioBuss *getAudioBuss(int bussNumber); // not buss no., not object id
203     MappedAudioInput *getAudioInput(int inputNumber); // likewise
204 
205     // Find out how many objects there are of a certain type
206     unsigned int getObjectCount(MappedObjectType type);
207 
208     // iterators
209     MappedObject *getFirst(MappedObjectType type);
210     MappedObject *getNext(MappedObject *object);
211 
212     std::vector<MappedObject *> getObjectsOfType(MappedObjectType type);
213 
214     // *** Properties
215 
216     MappedObjectPropertyList getPropertyList(
217             const MappedObjectProperty &property) override;
218 
219     bool getProperty(const MappedObjectProperty &property,
220                              MappedObjectValue &value) override;
221 
222     void setProperty(const MappedObjectProperty &property,
223                              MappedObjectValue value) override;
224 
225     // *** Connections
226 
227     bool connectObjects(MappedObjectId mId1, MappedObjectId mId2);
228     bool disconnectObjects(MappedObjectId mId1, MappedObjectId mId2);
229     bool disconnectObject(MappedObjectId mId);
230 
231     // *** SoundDriver
232 
233     // Set the driver object so that we can do things like
234     // initialise plugins etc.
setSoundDriver(SoundDriver * driver)235     void setSoundDriver(SoundDriver *driver)  { m_soundDriver = driver; }
getSoundDriver()236     SoundDriver *getSoundDriver()  { return m_soundDriver; }
getSoundDriver()237     const SoundDriver *getSoundDriver() const  { return m_soundDriver; }
238 
239 private:
240 
241     /// Next object ID for assigning unique IDs to each object.
242     MappedObjectId m_runningObjectId;
243 
244     // All of our mapped (virtual) studio resides in this container as
245     // well as having all their parent/child relationships.  Because
246     // some things are just blobs with no connections we need to
247     // maintain both - don't forget about this.
248     //
249     // Note that object IDs are globally unique, not just unique within
250     // a category.
251     //
252     typedef std::map<MappedObjectId, MappedObject *> MappedObjectCategory;
253     typedef std::map<MappedObjectType, MappedObjectCategory> MappedObjectMap;
254     MappedObjectMap m_objects;
255 
256     SoundDriver *m_soundDriver;
257 };
258 
259 
260 // A connectable AudioObject that provides a connection framework
261 // for MappedAudioFader and MappedAudioBuss (for example).  An
262 // abstract base class.
263 //
264 // n input connections and m output connections - subclasses
265 // can do the cleverness if n != m
266 //
267 
268 class MappedConnectableObject : public MappedObject
269 {
270 public:
271     static const MappedObjectProperty ConnectionsIn;
272     static const MappedObjectProperty ConnectionsOut;
273 
274     typedef enum
275     {
276         In,
277         Out
278     } ConnectionDirection;
279 
280     MappedConnectableObject(MappedObject *parent,
281                             const std::string &name,
282                             MappedObjectType type,
283                             MappedObjectId id);
284 
285     ~MappedConnectableObject() override;
286 
287     void setConnections(ConnectionDirection dir,
288                         MappedObjectValueList conns);
289 
290     void addConnection(ConnectionDirection dir, MappedObjectId id);
291     void removeConnection(ConnectionDirection dir, MappedObjectId id);
292 
293     MappedObjectValueList getConnections (ConnectionDirection dir);
294 
295 protected:
296 
297     // Which audio connections we have
298     //
299     MappedObjectValueList      m_connectionsIn;
300     MappedObjectValueList      m_connectionsOut;
301 };
302 
303 // Audio fader
304 //
305 class MappedAudioFader : public MappedConnectableObject
306 {
307 public:
308     static const MappedObjectProperty Channels;
309 
310     // properties
311     //
312     static const MappedObjectProperty FaderLevel;
313     static const MappedObjectProperty FaderRecordLevel;
314     static const MappedObjectProperty Pan;
315     static const MappedObjectProperty InputChannel;
316 
317     MappedAudioFader(MappedObject *parent,
318                      MappedObjectId id,
319                      MappedObjectValue channels = 2); // stereo default
320     ~MappedAudioFader() override;
321 
322     MappedObjectPropertyList getPropertyList(
323                         const MappedObjectProperty &property) override;
324 
325     bool getProperty(const MappedObjectProperty &property,
326                              MappedObjectValue &value) override;
327 
328     void setProperty(const MappedObjectProperty &property,
329                              MappedObjectValue value) override;
330 
getInstrument()331     InstrumentId getInstrument() const { return m_instrumentId; }
332 
333 protected:
334 
335     MappedObjectValue             m_level;
336     MappedObjectValue             m_recordLevel;
337     InstrumentId      m_instrumentId;
338 
339     // Stereo pan (-1.0 to +1.0)
340     //
341     MappedObjectValue             m_pan;
342 
343     // How many channels we carry
344     //
345     MappedObjectValue             m_channels;
346 
347     // If we have an input, which channel we take from it (if we are
348     // a mono fader at least)
349     //
350     MappedObjectValue             m_inputChannel;
351 };
352 
353 class MappedAudioBuss : public MappedConnectableObject
354 {
355 public:
356     // A buss is much simpler than an instrument fader.  It's always
357     // stereo, and just has a level and pan associated with it.  The
358     // level may be a submaster fader level or a send mix level, it
359     // depends on what the purpose of the buss is.  At the moment we
360     // just have a 1-1 relationship between busses and submasters, and
361     // no send channels.
362 
363     static const MappedObjectProperty BussId;
364     static const MappedObjectProperty Pan;
365     static const MappedObjectProperty Level;
366 
367     MappedAudioBuss(MappedObject *parent,
368                     MappedObjectId id);
369     ~MappedAudioBuss() override;
370 
371     MappedObjectPropertyList getPropertyList(
372                         const MappedObjectProperty &property) override;
373 
374     bool getProperty(const MappedObjectProperty &property,
375                              MappedObjectValue &value) override;
376 
377     void setProperty(const MappedObjectProperty &property,
378                              MappedObjectValue value) override;
379 
getBussId()380     MappedObjectValue getBussId() { return m_bussId; }
381 
382     // super-convenience function: retrieve the ids of the instruments
383     // connected to this buss
384     std::vector<InstrumentId> getInstruments();
385 
386 protected:
387     int m_bussId;
388     MappedObjectValue m_level;
389     MappedObjectValue m_pan;
390 };
391 
392 class MappedAudioInput : public MappedConnectableObject
393 {
394 public:
395     // An input is simpler still -- no properties at all, apart from
396     // the input number, otherwise just the connections
397 
398     static const MappedObjectProperty InputNumber;
399 
400     MappedAudioInput(MappedObject *parent,
401                      MappedObjectId id);
402     ~MappedAudioInput() override;
403 
404     MappedObjectPropertyList getPropertyList(
405                         const MappedObjectProperty &property) override;
406 
407     bool getProperty(const MappedObjectProperty &property,
408                              MappedObjectValue &value) override;
409 
410     void setProperty(const MappedObjectProperty &property,
411                              MappedObjectValue value) override;
412 
getInputNumber()413     MappedObjectValue getInputNumber() { return m_inputNumber; }
414 
415 protected:
416     MappedObjectValue m_inputNumber;
417 };
418 
419 class MappedPluginSlot : public MappedObject
420 {
421 public:
422     static const MappedObjectProperty Identifier;
423     static const MappedObjectProperty PluginName;
424     static const MappedObjectProperty Label;
425     static const MappedObjectProperty Author;
426     static const MappedObjectProperty Copyright;
427     static const MappedObjectProperty Category;
428     static const MappedObjectProperty PortCount;
429     static const MappedObjectProperty Ports;
430     static const MappedObjectProperty Program;
431     static const MappedObjectProperty Programs; // list property
432     static const MappedObjectProperty Instrument;
433     static const MappedObjectProperty Position;
434     static const MappedObjectProperty Bypassed;
435     static const MappedObjectProperty Configuration; // list property
436 
437     MappedPluginSlot(MappedObject *parent, MappedObjectId id);
438     ~MappedPluginSlot() override;
439 
440     MappedObjectPropertyList getPropertyList(
441                         const MappedObjectProperty &property) override;
442 
443     bool getProperty(const MappedObjectProperty &property,
444                              MappedObjectValue &value) override;
445 
446     bool getStringProperty(const MappedObjectProperty &property,
447                                    QString &value) override;
448 
449     void setProperty(const MappedObjectProperty &property,
450                              MappedObjectValue value) override;
451 
452     void setStringProperty(const MappedObjectProperty &property,
453                                    QString value) override;
454 
455     void setPropertyList(const MappedObjectProperty &,
456                                  const MappedObjectPropertyList &) override;
457 
458     void  setPort(unsigned long portNumber, float value);
459     float getPort(unsigned long portNumber);
460 
getInstrument()461     InstrumentId getInstrument() const { return m_instrument; }
getPosition()462     int getPosition() const { return m_position; }
463 
464     QString getProgram(int bank, int program);
465     unsigned long getProgram(QString name); // rv is bank << 16 + program
466 
467 protected:
468     QString                   m_identifier;
469 
470     QString                   m_name;
471     QString                   m_label;
472     QString                   m_author;
473     QString                   m_copyright;
474     QString                   m_category;
475     unsigned long             m_portCount;
476 
477     InstrumentId              m_instrument;
478     int                       m_position;
479     bool                      m_bypassed;
480 
481     std::map<QString, QString> m_configuration;
482 };
483 
484 class MappedPluginPort : public MappedObject
485 {
486 public:
487     static const MappedObjectProperty PortNumber;
488     static const MappedObjectProperty Name;
489     static const MappedObjectProperty Minimum;
490     static const MappedObjectProperty Maximum;
491     static const MappedObjectProperty Default;
492     static const MappedObjectProperty DisplayHint;
493     static const MappedObjectProperty Value;
494 
495     MappedPluginPort(MappedObject *parent, MappedObjectId id);
496     ~MappedPluginPort() override;
497 
498     MappedObjectPropertyList getPropertyList(
499                         const MappedObjectProperty &property) override;
500 
501     bool getProperty(const MappedObjectProperty &property,
502                              MappedObjectValue &value) override;
503 
504     bool getStringProperty(const MappedObjectProperty &property,
505                                    QString &value) override;
506 
507     void setProperty(const MappedObjectProperty &property,
508                              MappedObjectValue value) override;
509 
510     void setStringProperty(const MappedObjectProperty &property,
511                                    QString value) override;
512 
513     void setValue(MappedObjectValue value);
514     MappedObjectValue getValue() const;
515 
getPortNumber()516     int getPortNumber() const { return m_portNumber; }
517 
518 protected:
519     int                     m_portNumber;
520     QString                 m_name;
521     MappedObjectValue       m_minimum;
522     MappedObjectValue       m_maximum;
523     MappedObjectValue       m_default;
524     PluginPort::PortDisplayHint m_displayHint;
525 
526 };
527 
528 
529 }
530 
531 #endif // RG_MAPPEDSTUDIO_H
532