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