summaryrefslogtreecommitdiffstats
path: root/src/sound/SoundDriver.h
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
commit145364a8af6a1fec06556221e66d4b724a62fc9a (patch)
tree53bd71a544008c518034f208d64c932dc2883f50 /src/sound/SoundDriver.h
downloadrosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.tar.gz
rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.zip
Added old abandoned KDE3 version of the RoseGarden MIDI tool
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/rosegarden@1097595 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/sound/SoundDriver.h')
-rw-r--r--src/sound/SoundDriver.h529
1 files changed, 529 insertions, 0 deletions
diff --git a/src/sound/SoundDriver.h b/src/sound/SoundDriver.h
new file mode 100644
index 0000000..fabbaef
--- /dev/null
+++ b/src/sound/SoundDriver.h
@@ -0,0 +1,529 @@
+// -*- c-indentation-style:"stroustrup" c-basic-offset: 4 -*-
+/*
+ Rosegarden
+ A sequencer and musical notation editor.
+
+ This program is Copyright 2000-2008
+ Guillaume Laurent <[email protected]>,
+ Chris Cannam <[email protected]>,
+ Richard Bown <[email protected]>
+
+ The moral right of the authors to claim authorship of this work
+ has been asserted.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. See the file
+ COPYING included with this distribution for more information.
+*/
+
+#include <string>
+#include <vector>
+#include <list>
+#include <qstringlist.h>
+
+#include "Device.h"
+#include "MappedComposition.h"
+#include "MappedInstrument.h"
+#include "MappedDevice.h"
+#include "SequencerDataBlock.h"
+#include "PlayableAudioFile.h"
+#include "Scavenger.h"
+#include "RIFFAudioFile.h" // for SubFormat enum
+
+// Abstract base to support SoundDrivers, such as ALSA.
+//
+// This base class provides the generic driver support for
+// these drivers with the Sequencer class owning an instance
+// of a sub class of this class and directing it and required
+// by the rosegardensequencer itself.
+//
+//
+
+#ifndef _SOUNDDRIVER_H_
+#define _SOUNDDRIVER_H_
+
+namespace Rosegarden
+{
+
+// Current recording status - whether we're monitoring anything
+// or recording.
+//
+typedef enum
+{
+ RECORD_OFF,
+ RECORD_ON,
+} RecordStatus;
+
+
+// Status of a SoundDriver - whether we're got an audio and
+// MIDI subsystem or not. This is reported right up to the
+// gui.
+//
+typedef enum
+{
+ NO_DRIVER = 0x00, // Nothing's OK
+ AUDIO_OK = 0x01, // AUDIO's OK
+ MIDI_OK = 0x02, // MIDI's OK
+ VERSION_OK = 0x04 // GUI and sequencer versions match
+} SoundDriverStatus;
+
+
+// Used for MMC and MTC, not for JACK transport
+//
+typedef enum
+{
+ TRANSPORT_OFF,
+ TRANSPORT_MASTER,
+ TRANSPORT_SLAVE
+} TransportSyncStatus;
+
+
+// The NoteOffQueue holds a time ordered set of
+// pending MIDI NOTE OFF events.
+//
+class NoteOffEvent
+{
+public:
+ NoteOffEvent() {;}
+ NoteOffEvent(const RealTime &realTime,
+ unsigned int pitch,
+ MidiByte channel,
+ InstrumentId instrument):
+ m_realTime(realTime),
+ m_pitch(pitch),
+ m_channel(channel),
+ m_instrument(instrument) {;}
+ ~NoteOffEvent() {;}
+
+ struct NoteOffEventCmp
+ {
+ bool operator()(NoteOffEvent *nO1, NoteOffEvent *nO2)
+ {
+ return nO1->getRealTime() < nO2->getRealTime();
+ }
+ };
+
+ void setRealTime(const RealTime &time) { m_realTime = time; }
+ RealTime getRealTime() const { return m_realTime; }
+
+ MidiByte getPitch() const { return m_pitch; }
+ MidiByte getChannel() const { return m_channel; }
+ InstrumentId getInstrument() const { return m_instrument; }
+
+private:
+ RealTime m_realTime;
+ MidiByte m_pitch;
+ MidiByte m_channel;
+ InstrumentId m_instrument;
+
+};
+
+
+// The queue itself
+//
+class NoteOffQueue : public std::multiset<NoteOffEvent *,
+ NoteOffEvent::NoteOffEventCmp>
+{
+public:
+ NoteOffQueue() {;}
+ ~NoteOffQueue() {;}
+private:
+};
+
+
+class MappedStudio;
+class ExternalTransport;
+class AudioPlayQueue;
+
+typedef std::vector<PlayableAudioFile *> PlayableAudioFileList;
+
+// The abstract SoundDriver
+//
+//
+class SoundDriver
+{
+public:
+ SoundDriver(MappedStudio *studio, const std::string &name);
+ virtual ~SoundDriver();
+
+ virtual bool initialise() = 0;
+ virtual void shutdown() { }
+
+ virtual void initialisePlayback(const RealTime &position) = 0;
+ virtual void stopPlayback() = 0;
+ virtual void punchOut() = 0; // stop recording, continue playing
+ virtual void resetPlayback(const RealTime &oldPosition, const RealTime &position) = 0;
+ virtual void allNotesOff() = 0;
+
+ virtual RealTime getSequencerTime() = 0;
+
+ virtual MappedComposition *getMappedComposition() = 0;
+
+ virtual void startClocks() { }
+ virtual void stopClocks() { }
+
+ // Process some asynchronous events
+ //
+ virtual void processEventsOut(const MappedComposition &mC) = 0;
+
+ // Process some scheduled events on the output queue. The
+ // slice times are here so that the driver can interleave
+ // note-off events as appropriate.
+ //
+ virtual void processEventsOut(const MappedComposition &mC,
+ const RealTime &sliceStart,
+ const RealTime &sliceEnd) = 0;
+
+ // Activate a recording state. armedInstruments and audioFileNames
+ // can be NULL if no audio tracks recording.
+ //
+ virtual bool record(RecordStatus recordStatus,
+ const std::vector<InstrumentId> *armedInstruments = 0,
+ const std::vector<QString> *audioFileNames = 0) = 0;
+
+ // Process anything that's pending
+ //
+ virtual void processPending() = 0;
+
+ // Get the driver's operating sample rate
+ //
+ virtual unsigned int getSampleRate() const = 0;
+
+ // Plugin instance management
+ //
+ virtual void setPluginInstance(InstrumentId id,
+ QString identifier,
+ int position) = 0;
+
+ virtual void removePluginInstance(InstrumentId id,
+ int position) = 0;
+
+ // Clear down and remove all plugin instances
+ //
+ virtual void removePluginInstances() = 0;
+
+ virtual void setPluginInstancePortValue(InstrumentId id,
+ int position,
+ unsigned long portNumber,
+ float value) = 0;
+
+ virtual float getPluginInstancePortValue(InstrumentId id,
+ int position,
+ unsigned long portNumber) = 0;
+
+ virtual void setPluginInstanceBypass(InstrumentId id,
+ int position,
+ bool value) = 0;
+
+ virtual QStringList getPluginInstancePrograms(InstrumentId id,
+ int position) = 0;
+
+ virtual QString getPluginInstanceProgram(InstrumentId id,
+ int position) = 0;
+
+ virtual QString getPluginInstanceProgram(InstrumentId id,
+ int position,
+ int bank,
+ int program) = 0;
+
+ virtual unsigned long getPluginInstanceProgram(InstrumentId id,
+ int position,
+ QString name) = 0;
+
+ virtual void setPluginInstanceProgram(InstrumentId id,
+ int position,
+ QString program) = 0;
+
+ virtual QString configurePlugin(InstrumentId id,
+ int position,
+ QString key,
+ QString value) = 0;
+
+ virtual void setAudioBussLevels(int bussId,
+ float dB,
+ float pan) = 0;
+
+ virtual void setAudioInstrumentLevels(InstrumentId id,
+ float dB,
+ float pan) = 0;
+
+ // Poll for new clients (for new Devices/Instruments)
+ //
+ virtual bool checkForNewClients() = 0;
+
+ // Set a loop position at the driver (used for transport)
+ //
+ virtual void setLoop(const RealTime &loopStart, const RealTime &loopEnd)
+ = 0;
+
+ virtual void sleep(const RealTime &rt);
+
+ virtual QString getStatusLog() { return ""; }
+
+ // Mapped Instruments
+ //
+ void setMappedInstrument(MappedInstrument *mI);
+ MappedInstrument* getMappedInstrument(InstrumentId id);
+
+ // Return the current status of the driver
+ //
+ unsigned int getStatus() const { return m_driverStatus; }
+
+ // Are we playing?
+ //
+ bool isPlaying() const { return m_playing; }
+
+ // Are we counting? By default a subclass probably wants to
+ // return true, if it doesn't know better.
+ //
+ virtual bool areClocksRunning() const = 0;
+
+ RealTime getStartPosition() const { return m_playStartPosition; }
+ RecordStatus getRecordStatus() const { return m_recordStatus; }
+
+ // Return a MappedDevice full of the Instrument mappings
+ // that the driver has discovered. The gui can then use
+ // this list (complete with names) to generate its proper
+ // Instruments under the MidiDevice and AudioDevice.
+ //
+ MappedDevice getMappedDevice(DeviceId id);
+
+ // Return the number of devices we've found
+ //
+ unsigned int getDevices();
+
+ virtual bool canReconnect(Device::DeviceType) { return false; }
+
+ virtual DeviceId addDevice(Device::DeviceType,
+ MidiDevice::DeviceDirection) {
+ return Device::NO_DEVICE;
+ }
+ virtual void removeDevice(DeviceId) { }
+ virtual void renameDevice(DeviceId, QString) { }
+
+ virtual unsigned int getConnections(Device::DeviceType,
+ MidiDevice::DeviceDirection) { return 0; }
+ virtual QString getConnection(Device::DeviceType,
+ MidiDevice::DeviceDirection,
+ unsigned int) { return ""; }
+ virtual void setConnection(DeviceId, QString) { }
+ virtual void setPlausibleConnection(DeviceId id, QString c) { setConnection(id, c); }
+
+ virtual unsigned int getTimers() { return 0; }
+ virtual QString getTimer(unsigned int) { return ""; }
+ virtual QString getCurrentTimer() { return ""; }
+ virtual void setCurrentTimer(QString) { }
+
+ virtual void getAudioInstrumentNumbers(InstrumentId &, int &) = 0;
+ virtual void getSoftSynthInstrumentNumbers(InstrumentId &, int &) = 0;
+
+ // Plugin management -- SoundDrivers should maintain a plugin
+ // scavenger which the audio process code can use for defunct
+ // plugins. Ownership of plugin is passed to the SoundDriver.
+ //
+ virtual void claimUnwantedPlugin(void *plugin) = 0;
+
+ // This causes all scavenged plugins to be destroyed. It
+ // should only be called in non-RT contexts.
+ //
+ virtual void scavengePlugins() = 0;
+
+ // Handle audio file references
+ //
+ void clearAudioFiles();
+ bool addAudioFile(const std::string &fileName, unsigned int id);
+ bool removeAudioFile(unsigned int id);
+
+ void initialiseAudioQueue(const std::vector<MappedEvent> &audioEvents);
+ void clearAudioQueue();
+ const AudioPlayQueue *getAudioQueue() const;
+
+ RIFFAudioFile::SubFormat getAudioRecFileFormat() const { return m_audioRecFileFormat; }
+
+
+ // Latencies
+ //
+ virtual RealTime getAudioPlayLatency() { return RealTime::zeroTime; }
+ virtual RealTime getAudioRecordLatency() { return RealTime::zeroTime; }
+ virtual RealTime getInstrumentPlayLatency(InstrumentId) { return RealTime::zeroTime; }
+ virtual RealTime getMaximumPlayLatency() { return RealTime::zeroTime; }
+
+ // Buffer sizes
+ //
+ void setAudioBufferSizes(RealTime mix, RealTime read, RealTime write,
+ int smallFileSize) {
+ m_audioMixBufferLength = mix;
+ m_audioReadBufferLength = read;
+ m_audioWriteBufferLength = write;
+ m_smallFileSize = smallFileSize;
+ }
+
+ RealTime getAudioMixBufferLength() { return m_audioMixBufferLength; }
+ RealTime getAudioReadBufferLength() { return m_audioReadBufferLength; }
+ RealTime getAudioWriteBufferLength() { return m_audioWriteBufferLength; }
+ int getSmallFileSize() { return m_smallFileSize; }
+
+ void setLowLatencyMode(bool ll) { m_lowLatencyMode = ll; }
+ bool getLowLatencyMode() const { return m_lowLatencyMode; }
+
+ // Cancel the playback of an audio file - either by instrument and audio file id
+ // or by audio segment id.
+ //
+ void cancelAudioFile(MappedEvent *mE);
+
+ // Studio linkage
+ //
+ MappedStudio* getMappedStudio() { return m_studio; }
+ void setMappedStudio(MappedStudio *studio) { m_studio = studio; }
+
+ // Modify MIDI record device
+ //
+ void setMidiRecordDevice(DeviceId id) { m_midiRecordDevice = id; }
+ DeviceId getMIDIRecordDevice() const { return m_midiRecordDevice; }
+
+ // MIDI Realtime Sync setting
+ //
+ TransportSyncStatus getMIDISyncStatus() const { return m_midiSyncStatus; }
+ void setMIDISyncStatus(TransportSyncStatus status) { m_midiSyncStatus = status; }
+
+ // MMC master/slave setting
+ //
+ TransportSyncStatus getMMCStatus() const { return m_mmcStatus; }
+ void setMMCStatus(TransportSyncStatus status) { m_mmcStatus = status; }
+
+ // MTC master/slave setting
+ //
+ TransportSyncStatus getMTCStatus() const { return m_mtcStatus; }
+ void setMTCStatus(TransportSyncStatus status) { m_mtcStatus = status; }
+
+ // MMC Id
+ //
+ int getMMCId() const { return ((int)(m_mmcId)); }
+ void setMMCId(int id) { m_mmcId = (MidiByte)(id); }
+
+ // Set MIDI clock interval - allow redefinition above to ensure
+ // we handle this reset correctly.
+ //
+ virtual void setMIDIClockInterval(RealTime interval)
+ { m_midiClockInterval = interval; }
+
+ // Get and set the mapper which may optionally be used to
+ // store recording levels etc for communication back to the GUI.
+ // (If a subclass wants this and finds it's not there, it should
+ // simply continue without.)
+ //
+ SequencerDataBlock *getSequencerDataBlock() { return m_sequencerDataBlock; }
+ void setSequencerDataBlock(SequencerDataBlock *d) { m_sequencerDataBlock = d; }
+
+ ExternalTransport *getExternalTransportControl() const {
+ return m_externalTransport;
+ }
+ void setExternalTransportControl(ExternalTransport *transport) {
+ m_externalTransport = transport;
+ }
+
+ // Do any bits and bobs of work that need to be done continuously
+ // (this is called repeatedly whether playing or not).
+ //
+ virtual void runTasks() { }
+
+ // Report a failure back to the GUI - ideally. Default does nothing.
+ //
+ virtual void reportFailure(MappedEvent::FailureCode) { }
+
+protected:
+ // Helper functions to be implemented by subclasses
+ //
+ virtual void processMidiOut(const MappedComposition &mC,
+ const RealTime &sliceStart,
+ const RealTime &sliceEnd) = 0;
+ virtual void generateInstruments() = 0;
+
+ // Audio
+ //
+ AudioFile* getAudioFile(unsigned int id);
+
+ std::string m_name;
+ unsigned int m_driverStatus;
+ RealTime m_playStartPosition;
+ bool m_startPlayback;
+ bool m_playing;
+
+ // MIDI Note-off handling
+ //
+ NoteOffQueue m_noteOffQueue;
+
+ // This is our driver's own list of MappedInstruments and MappedDevices.
+ // These are uncoupled at this level - the Instruments and Devices float
+ // free and only index each other - the Devices hold information only like
+ // name, id and if the device is duplex capable.
+ //
+ typedef std::vector<MappedInstrument*> MappedInstrumentList;
+ MappedInstrumentList m_instruments;
+
+ typedef std::vector<MappedDevice*> MappedDeviceList;
+ MappedDeviceList m_devices;
+
+ DeviceId m_midiRecordDevice;
+
+ MappedComposition m_recordComposition;
+ MappedComposition m_returnComposition;
+ RecordStatus m_recordStatus;
+
+
+ InstrumentId m_midiRunningId;
+ InstrumentId m_audioRunningId;
+
+ // Subclass _MUST_ scavenge this regularly:
+ Scavenger<AudioPlayQueue> m_audioQueueScavenger;
+ AudioPlayQueue *m_audioQueue;
+
+ // A list of AudioFiles that we can play.
+ //
+ std::vector<AudioFile*> m_audioFiles;
+
+ RealTime m_audioMixBufferLength;
+ RealTime m_audioReadBufferLength;
+ RealTime m_audioWriteBufferLength;
+ int m_smallFileSize;
+ bool m_lowLatencyMode;
+
+ RIFFAudioFile::SubFormat m_audioRecFileFormat;
+
+ // Virtual studio hook
+ //
+ MappedStudio *m_studio;
+
+ // Sequencer data block for communication back to GUI
+ //
+ SequencerDataBlock *m_sequencerDataBlock;
+
+ // Controller to make externally originated transport requests on
+ //
+ ExternalTransport *m_externalTransport;
+
+ // MMC and MTC status and ID
+ //
+ TransportSyncStatus m_midiSyncStatus;
+ TransportSyncStatus m_mmcStatus;
+ TransportSyncStatus m_mtcStatus;
+ MidiByte m_mmcId; // device id
+
+ // MIDI clock interval
+ //
+ bool m_midiClockEnabled;
+ RealTime m_midiClockInterval;
+ RealTime m_midiClockSendTime;
+
+ // MIDI Song Position pointer
+ //
+ long m_midiSongPositionPointer;
+
+};
+
+}
+
+#endif // _SOUNDDRIVER_H_
+