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_STUDIO_H
17 #define RG_STUDIO_H
18 
19 #include "XmlExportable.h"
20 #include "Instrument.h"
21 #include "Device.h"
22 #include "MidiProgram.h"
23 #include "MidiMetronome.h"
24 #include "ControlParameter.h"
25 
26 #include <QCoreApplication>
27 
28 #include <string>
29 #include <vector>
30 
31 namespace Rosegarden
32 {
33 
34 
35 class RecordIn;
36 class MidiDevice;
37 class Segment;
38 class Track;
39 
40 typedef std::vector<Instrument *> InstrumentList;
41 typedef std::vector<Device*> DeviceList;
42 typedef std::vector<Buss *> BussList;
43 typedef std::vector<RecordIn *> RecordInList;
44 typedef std::vector<Device*>::iterator DeviceListIterator;
45 typedef std::vector<Device*>::const_iterator DeviceListConstIterator;
46 
47 
48 /// Holds Device objects.
49 /**
50  * The Studio is where Midi and Audio devices live.  We can query
51  * them for a list of Instruments, connect them together or to
52  * effects units (eventually) and generally do real studio-type
53  * stuff to them.
54  *
55  * RosegardenDocument has an instance of Studio.  A reference can be obtained
56  * using RosegardenDocument::getStudio().
57  */
58 class Studio : public XmlExportable
59 {
60     Q_DECLARE_TR_FUNCTIONS(Rosegarden::Studio)
61 
62 public:
63     Studio();
64     ~Studio() override;
65 
66 private:
67     Studio(const Studio &);
68     Studio& operator=(const Studio &);
69 
70 public:
71     void addDevice(const std::string &name,
72                    DeviceId id,
73                    InstrumentId baseInstrumentId,
74                    Device::DeviceType type);
75 
76     void removeDevice(DeviceId id);
77 
78     void resyncDeviceConnections();
79 
80     DeviceId getSpareDeviceId(InstrumentId &baseInstrumentId);
81 
82     // Return the combined instrument list from all devices
83     //
84     InstrumentList getAllInstruments();
85     InstrumentList getPresentationInstruments() const;
86 
87     // Return an Instrument
88     Instrument* getInstrumentById(InstrumentId id) const;
89     Instrument* getInstrumentFromList(int index);
90 
91     // Convenience functions
92     Instrument *getInstrumentFor(const Segment *) const;
93     Instrument *getInstrumentFor(const Track *) const;
94 
95     // Return a Buss
96     BussList getBusses();
97     Buss *getBussById(BussId id);
98     void addBuss(Buss *buss);
99     //void removeBuss(BussId id);
100     void setBussCount(unsigned newBussCount);
101 
102     // Return an Instrument or a Buss
103     PluginContainer *getContainerById(InstrumentId id);
104 
getRecordIns()105     RecordInList getRecordIns() { return m_recordIns; }
106     RecordIn *getRecordIn(int number);
addRecordIn(RecordIn * ri)107     void addRecordIn(RecordIn *ri) { m_recordIns.push_back(ri); }
108     void setRecordInCount(unsigned newRecordInCount);
109 
110     // A clever method to best guess MIDI file program mappings
111     // to available MIDI channels across all MidiDevices.
112     //
113     // Set the percussion flag if it's a percussion channel (mapped
114     // channel) we're after.
115     //
assignMidiProgramToInstrument(MidiByte program,bool percussion)116     Instrument* assignMidiProgramToInstrument(MidiByte program,
117                                               bool percussion) {
118         return assignMidiProgramToInstrument(program, -1, -1, percussion);
119     }
120 
121     // Same again, but with bank select
122     //
123     Instrument* assignMidiProgramToInstrument(MidiByte program,
124                                               int msb, int lsb,
125                                               bool percussion);
126 
127     // Get a suitable name for a Segment belonging to this instrument.
128     // Takes into account ProgramChanges.
129     //
130     std::string getSegmentName(InstrumentId id);
131 
132     // Clear down all the ProgramChange flags in all MIDI Instruments
133     //
134     void unassignAllInstruments();
135 
136     // Clear down all MIDI banks and programs on all MidiDevices
137     // prior to reloading.  The Instruments and Devices are generated
138     // at the Sequencer - the Banks and Programs are loaded from the
139     // RG4 file.
140     //
141     void clearMidiBanksAndPrograms();
142 
143     void clearBusses();
144     void clearRecordIns();
145 
146     // Clear down
147     void clear();
148 
149     // Get a MIDI metronome from a given device
150     //
151     const MidiMetronome* getMetronomeFromDevice(DeviceId id);
152 
153     // Return the device list
154     //
getDevices()155     DeviceList* getDevices() { return &m_devices; }
156 
157     // Const iterators
158     //
begin()159     DeviceListConstIterator begin() const { return m_devices.begin(); }
end()160     DeviceListConstIterator end() const { return m_devices.end(); }
161 
162     // Get a device by ID
163     //
164     Device *getDevice(DeviceId id) const;
165 
166     // Get device of audio type (there is only one)
167     //
168     Device *getAudioDevice();
169 
170     // Get device of soft synth type (there is only one)
171     //
172     Device *getSoftSynthDevice();
173 
174     bool haveMidiDevices() const;
175 
176     // Export as XML string
177     //
178     std::string toXmlString() const override;
179 
180     // Export a subset of devices as XML string.  If devices is empty,
181     // exports all devices just as the above method does.
182     //
183     virtual std::string toXmlString(const std::vector<DeviceId> &devices) const;
184 
185     // Get an audio preview Instrument
186     //
187     InstrumentId getAudioPreviewInstrument();
188 
189     // MIDI filtering into and thru Rosegarden
190     //
setMIDIThruFilter(MidiFilter filter)191     void setMIDIThruFilter(MidiFilter filter) { m_midiThruFilter = filter; }
getMIDIThruFilter()192     MidiFilter getMIDIThruFilter() const { return m_midiThruFilter; }
193 
setMIDIRecordFilter(MidiFilter filter)194     void setMIDIRecordFilter(MidiFilter filter) { m_midiRecordFilter = filter; }
getMIDIRecordFilter()195     MidiFilter getMIDIRecordFilter() const { return m_midiRecordFilter; }
196 
197     /// For the AudioMixerWindow2.
198     bool amwShowAudioFaders;
199     bool amwShowSynthFaders;
200     bool amwShowAudioSubmasters;
201     bool amwShowUnassignedFaders;
202 
getMetronomeDevice()203     DeviceId getMetronomeDevice() const { return m_metronomeDevice; }
setMetronomeDevice(DeviceId device)204     void setMetronomeDevice(DeviceId device) { m_metronomeDevice = device; }
205 
206 private:
207 
208     DeviceList        m_devices;
209 
210     BussList          m_busses;
211     RecordInList      m_recordIns;
212 
213     int               m_audioInputs; // stereo pairs
214 
215     MidiFilter        m_midiThruFilter;
216     MidiFilter        m_midiRecordFilter;
217 
218     DeviceId          m_metronomeDevice;
219 };
220 
221 }
222 
223 #endif // RG_STUDIO_H
224