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_SOUNDDRIVER_H
17 #define RG_SOUNDDRIVER_H
18 
19 #include "base/Device.h"
20 #include "base/Instrument.h"  // For InstrumentId...
21 #include "base/MidiProgram.h"  // For MidiByte...
22 #include "base/RealTime.h"
23 #include "MappedEvent.h"
24 #include "MappedInstrument.h"
25 #include "MappedDevice.h"
26 #include "Scavenger.h"
27 #include "AudioPlayQueue.h"
28 
29 #include "RIFFAudioFile.h"  // For SubFormat enum
30 
31 #include <QString>
32 #include <QStringList>
33 
34 #include <set>
35 #include <vector>
36 
37 
38 namespace Rosegarden
39 {
40 
41 
42 // Current recording status - whether we're monitoring anything
43 // or recording.
44 enum RecordStatus  { RECORD_OFF, RECORD_ON };
45 
46 typedef unsigned SoundDriverStatus;
47 enum
48 {
49     NO_DRIVER = 0x00,  // Nothing's OK
50     AUDIO_OK  = 0x01,
51     MIDI_OK   = 0x02
52 };
53 
54 /// Used for MMC and MTC, not for JACK transport
55 enum TransportSyncStatus
56 {
57     TRANSPORT_OFF,
58     TRANSPORT_SOURCE,
59     TRANSPORT_FOLLOWER
60 };
61 
62 
63 class RosegardenSequencer;
64 class MappedEventList;
65 class MappedStudio;
66 
67 
68 /// Abstract Base Class (ABC) to support sound drivers, such as ALSA.
69 /**
70  * This ABC provides the generic driver support for
71  * these drivers with the Sequencer class owning an instance
72  * of a sub class of this class and directing it as required
73  * by RosegardenSequencer itself.
74  */
75 class SoundDriver
76 {
77 public:
78     SoundDriver(MappedStudio *studio, const QString &name);
79     virtual ~SoundDriver();
80 
81 
82     // *** General ***
83 
initialise()84     virtual bool initialise()  { return true; }
getStatus()85     SoundDriverStatus getStatus() const  { return m_driverStatus; }
getStatusLog()86     virtual QString getStatusLog()  { return ""; }
shutdown()87     virtual void shutdown()  { }
88 
89 
90     // *** Devices and Connections ***
91 
addDevice(Device::DeviceType,DeviceId,InstrumentId,MidiDevice::DeviceDirection)92     virtual bool addDevice(Device::DeviceType,
93                            DeviceId,
94                            InstrumentId,
95                            MidiDevice::DeviceDirection)
96         { return false; }
removeDevice(DeviceId)97     virtual void removeDevice(DeviceId) { }
removeAllDevices()98     virtual void removeAllDevices() { }
renameDevice(DeviceId,QString)99     virtual void renameDevice(DeviceId, QString) { }
100 
101     /// Poll for new clients (for new Devices/Instruments)
checkForNewClients()102     virtual void checkForNewClients()  { }
103 
getConnections(Device::DeviceType,MidiDevice::DeviceDirection)104     virtual unsigned int getConnections(Device::DeviceType,
105                                         MidiDevice::DeviceDirection) { return 0; }
getConnection(Device::DeviceType,MidiDevice::DeviceDirection,unsigned int)106     virtual QString getConnection(Device::DeviceType,
107                                   MidiDevice::DeviceDirection,
108                                   unsigned int) { return ""; }
getConnection(DeviceId)109     virtual QString getConnection(DeviceId) { return ""; }
setConnection(DeviceId,QString)110     virtual void setConnection(
111             DeviceId /* deviceId */,
112             QString /* idealConnection */) { }
setPlausibleConnection(DeviceId deviceId,QString idealConnection,bool)113     virtual void setPlausibleConnection(
114             DeviceId deviceId,
115             QString idealConnection,
116             bool /* recordDevice */)
117                     { setConnection(deviceId, idealConnection); }
connectSomething()118     virtual void connectSomething() { }
119 
120 
121     // *** Sequencer ***
122 
getTimers()123     virtual unsigned int getTimers() { return 0; }
getTimer(unsigned int)124     virtual QString getTimer(unsigned int) { return ""; }
getCurrentTimer()125     virtual QString getCurrentTimer() { return ""; }
setCurrentTimer(QString)126     virtual void setCurrentTimer(QString) { }
127 
initialisePlayback(const RealTime &)128     virtual void initialisePlayback(const RealTime & /*position*/)  { }
129     void setMappedInstrument(MappedInstrument *mI);
stopPlayback()130     virtual void stopPlayback()  { }
record(RecordStatus,const std::vector<InstrumentId> &,const std::vector<QString> &)131     virtual bool record(
132             RecordStatus /*recordStatus*/,
133             const std::vector<InstrumentId> & /*armedInstruments*/,
134             const std::vector<QString> & /*audioFileNames*/)
135         { return false; }
136     /// stop recording, continue playing
punchOut()137     virtual void punchOut()  { }
resetPlayback(const RealTime &,const RealTime &)138     virtual void resetPlayback(const RealTime & /*oldPosition*/,
139                                const RealTime & /*position*/)  { }
140 
isPlaying()141     bool isPlaying() const  { return m_playing; }
getStartPosition()142     RealTime getStartPosition() const { return m_playStartPosition; }
getRecordStatus()143     RecordStatus getRecordStatus() const { return m_recordStatus; }
144 
getSequencerTime()145     virtual RealTime getSequencerTime()  { return RealTime(0, 0); }
146 
147     /// Get incoming MIDI events from ALSA.
getMappedEventList(MappedEventList &)148     virtual bool getMappedEventList(MappedEventList &)  { return true; }
149 
startClocks()150     virtual void startClocks() { }
stopClocks()151     virtual void stopClocks() { }
152     // Are we counting?  By default a subclass probably wants to
153     // return true, if it doesn't know better.
areClocksRunning()154     virtual bool areClocksRunning() const  { return true; }
155 
156     // Process some asynchronous events
processEventsOut(const MappedEventList &)157     virtual void processEventsOut(const MappedEventList & /*mC*/)  { }
158 
159     // Process some scheduled events on the output queue.  The
160     // slice times are here so that the driver can interleave
161     // note-off events as appropriate.
processEventsOut(const MappedEventList &,const RealTime &,const RealTime &)162     virtual void processEventsOut(const MappedEventList & /*mC*/,
163                                   const RealTime & /*sliceStart*/,
164                                   const RealTime & /*sliceEnd*/)  { }
165 
processPending()166     virtual void processPending()  { }
167 
168     /// Set a loop position at the driver (used for transport)
setLoop(const RealTime &,const RealTime &)169     virtual void setLoop(const RealTime & /*start*/,
170                          const RealTime & /*end*/)  { }
171 
172     virtual void sleep(const RealTime &rt);
173 
174     // Set MIDI clock interval - allow redefinition above to ensure
175     // we handle this reset correctly.
setMIDIClockInterval(RealTime interval)176     virtual void setMIDIClockInterval(RealTime interval)
177         { m_midiClockInterval = interval; }
178 
179     // Do any bits and bobs of work that need to be done continuously
180     // (this is called repeatedly whether playing or not).
runTasks()181     virtual void runTasks() { }
182 
183 
184     // *** Audio ***
185 
setAudioBufferSizes(RealTime mix,RealTime read,RealTime write,int smallFileSize)186     void setAudioBufferSizes(RealTime mix, RealTime read, RealTime write,
187                              int smallFileSize) {
188         m_audioMixBufferLength = mix;
189         m_audioReadBufferLength = read;
190         m_audioWriteBufferLength = write;
191         m_smallFileSize = smallFileSize;
192     }
193 
194     // Get the driver's operating sample rate
getSampleRate()195     virtual unsigned int getSampleRate() const  { return 0; }
196 
setAudioBussLevels(int,float,float)197     virtual void setAudioBussLevels(int /*bussId*/,
198                                     float /*dB*/,
199                                     float /*pan*/)  { }
200 
setAudioInstrumentLevels(InstrumentId,float,float)201     virtual void setAudioInstrumentLevels(InstrumentId /*id*/,
202                                           float /*dB*/,
203                                           float /*pan*/)  { }
204 
205     // Handle audio file references
206     //
207     void clearAudioFiles();
208     bool addAudioFile(const QString &fileName, unsigned int id);
209     bool removeAudioFile(unsigned int id);
210 
211     void initialiseAudioQueue(const std::vector<MappedEvent> &audioEvents);
212     const AudioPlayQueue *getAudioQueue() const;
213 
getAudioRecFileFormat()214     RIFFAudioFile::SubFormat getAudioRecFileFormat() const
215         { return m_audioRecFileFormat; }
216 
217     // Latencies
218     //
getAudioPlayLatency()219     virtual RealTime getAudioPlayLatency() { return RealTime::zeroTime; }
getAudioRecordLatency()220     virtual RealTime getAudioRecordLatency() { return RealTime::zeroTime; }
getInstrumentPlayLatency(InstrumentId)221     virtual RealTime getInstrumentPlayLatency(InstrumentId) { return RealTime::zeroTime; }
getMaximumPlayLatency()222     virtual RealTime getMaximumPlayLatency() { return RealTime::zeroTime; }
223 
224     // Buffer sizes
225     //
getAudioMixBufferLength()226     RealTime getAudioMixBufferLength() { return m_audioMixBufferLength; }
getAudioReadBufferLength()227     RealTime getAudioReadBufferLength() { return m_audioReadBufferLength; }
getAudioWriteBufferLength()228     RealTime getAudioWriteBufferLength() { return m_audioWriteBufferLength; }
229 
getLowLatencyMode()230     bool getLowLatencyMode() const  { return true; }
231 
getAudioInstrumentNumbers(InstrumentId & base,int & count)232     virtual void getAudioInstrumentNumbers(InstrumentId &base, int &count)
233         { base = 0; count = 0; }
getSoftSynthInstrumentNumbers(InstrumentId & base,int & count)234     virtual void getSoftSynthInstrumentNumbers(InstrumentId &base, int &count)
235         { base = 0; count = 0; }
236 
getMappedStudio()237     MappedStudio *getMappedStudio() { return m_studio; }
238 
239     // Report a failure back to the GUI - ideally.  Default does nothing.
reportFailure(MappedEvent::FailureCode)240     virtual void reportFailure(MappedEvent::FailureCode) { }
241 
242 
243     // *** Plugins ***
244 
setPluginInstance(InstrumentId,QString,int)245     virtual void setPluginInstance(InstrumentId /*id*/,
246                                    QString /*identifier*/,
247                                    int /*position*/)  { }
248 
removePluginInstance(InstrumentId,int)249     virtual void removePluginInstance(InstrumentId /*id*/,
250                                       int /*position*/)  { }
251 
setPluginInstancePortValue(InstrumentId,int,unsigned long,float)252     virtual void setPluginInstancePortValue(InstrumentId /*id*/,
253                                             int /*position*/,
254                                             unsigned long /*portNumber*/,
255                                             float /*value*/)  { }
256 
getPluginInstancePortValue(InstrumentId,int,unsigned long)257     virtual float getPluginInstancePortValue(InstrumentId /*id*/,
258                                              int /*position*/,
259                                              unsigned long /*portNumber*/)
260         { return 0; }
261 
setPluginInstanceBypass(InstrumentId,int,bool)262     virtual void setPluginInstanceBypass(InstrumentId /*id*/,
263                                          int /*position*/,
264                                          bool /*value*/)  { }
265 
getPluginInstancePrograms(InstrumentId,int)266     virtual QStringList getPluginInstancePrograms(InstrumentId /*id*/,
267                                                   int /*position*/)
268         { return QStringList(); }
269 
getPluginInstanceProgram(InstrumentId,int)270     virtual QString getPluginInstanceProgram(InstrumentId /*id*/,
271                                              int /*position*/)
272         { return QString(); }
273 
getPluginInstanceProgram(InstrumentId,int,int,int)274     virtual QString getPluginInstanceProgram(InstrumentId /*id*/,
275                                              int /*position*/,
276                                              int /*bank*/,
277                                              int /*program*/)
278         { return QString(); }
279 
getPluginInstanceProgram(InstrumentId,int,QString)280     virtual unsigned long getPluginInstanceProgram(InstrumentId /*id*/,
281                                                    int /*position*/,
282                                                    QString /*name*/)
283         { return 0; }
284 
setPluginInstanceProgram(InstrumentId,int,QString)285     virtual void setPluginInstanceProgram(InstrumentId /*id*/,
286                                           int /*position*/,
287                                           QString /*program*/)  { }
288 
configurePlugin(InstrumentId,int,QString,QString)289     virtual QString configurePlugin(InstrumentId /*id*/,
290                                     int /*position*/,
291                                     QString /*key*/,
292                                     QString /*value*/)  { return QString(); }
293 
294     // Plugin management -- SoundDrivers should maintain a plugin
295     // scavenger which the audio process code can use for defunct
296     // plugins.  Ownership of plugin is passed to the SoundDriver.
claimUnwantedPlugin(void *)297     virtual void claimUnwantedPlugin(void * /*plugin*/)  { }
298 
299     // This causes all scavenged plugins to be destroyed.  It
300     // should only be called in non-RT contexts.
scavengePlugins()301     virtual void scavengePlugins()  { }
302 
303 
304     // *** Miscellaneous ***
305 
306 /*!DEVPUSH
307 
308     // ??? The m_devices that these two functions used has been moved
309     //     down to AlsaDriver.
310 
311     // Return a MappedDevice full of the Instrument mappings
312     // that the driver has discovered.  The gui can then use
313     // this list (complete with names) to generate its proper
314     // Instruments under the MidiDevice and AudioDevice.
315     //
316     MappedDevice getMappedDevice(DeviceId id);
317 
318     // Return the number of devices we've found
319     //
320     unsigned int getDevices();
321 */
322 
323 protected:
324 
325     // *** General ***
326 
327     /// Driver name for the audit log.
328     QString m_name;
329 
330     SoundDriverStatus m_driverStatus;
331 
332 
333     // *** Sequencer ***
334 
335     typedef std::vector<MappedInstrument *> MappedInstrumentList;
336     // This is our driver's own list of MappedInstruments and MappedDevices.
337     // These are uncoupled at this level - the Instruments and Devices float
338     // free and only index each other - the Devices hold information only like
339     // name, id and if the device is duplex capable.
340     MappedInstrumentList m_instruments;
341 
342     RealTime m_playStartPosition;
343     bool m_playing;
344     RecordStatus m_recordStatus;
345 
346     /// 24 MIDI clocks per quarter note.  MIDI Spec section 2, page 30.
347     /**
348      * If the Composition has tempo changes, this single interval is
349      * insufficient.  We should instead compute SPP based on bar/beat/pulse
350      * from the Composition.  Since the GUI and sequencer are separated,
351      * the bar/beat/pulse values would need to be pushed in at play and
352      * record time.  See RosegardenSequencer::m_songPosition.
353      */
354     RealTime m_midiClockInterval;
355 
356 
357     // *** Audio ***
358 
359     // Subclass _MUST_ scavenge this regularly.
360     Scavenger<AudioPlayQueue> m_audioQueueScavenger;
361 
362     AudioPlayQueue *m_audioQueue;
363 
364     /// A list of AudioFile's that we can play.
365     std::vector<AudioFile *> m_audioFiles;
366     AudioFile *getAudioFile(unsigned int id);
367 
368     RealTime m_audioMixBufferLength;
369     RealTime m_audioReadBufferLength;
370     RealTime m_audioWriteBufferLength;
371 
372     int m_smallFileSize;
373 
374     RIFFAudioFile::SubFormat m_audioRecFileFormat;
375 
376     /// Sequencer-side representation of the audio portion of the Studio.
377     MappedStudio *m_studio;
378 
379 };
380 
381 
382 }
383 
384 #endif // RG_SOUNDDRIVER_H
385