1 /*************************************************************************** 2 * * 3 * LinuxSampler - modular, streaming capable sampler * 4 * * 5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * 6 * Copyright (C) 2005 - 2014 Christian Schoenebeck * 7 * * 8 * This program is free software; you can redistribute it and/or modify * 9 * it under the terms of the GNU General Public License as published by * 10 * the Free Software Foundation; either version 2 of the License, or * 11 * (at your option) any later version. * 12 * * 13 * This program is distributed in the hope that it will be useful, * 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 * GNU General Public License for more details. * 17 * * 18 * You should have received a copy of the GNU General Public License * 19 * along with this program; if not, write to the Free Software * 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 21 * MA 02111-1307 USA * 22 ***************************************************************************/ 23 24 #ifndef __LS_MIDIINPUTDEVICE_H__ 25 #define __LS_MIDIINPUTDEVICE_H__ 26 27 #include <stdexcept> 28 #include <set> 29 #include <map> 30 #include <vector> 31 32 #include "../../common/global.h" 33 #include "../../common/Exception.h" 34 #include "../DeviceParameter.h" 35 #include "MidiInputPort.h" 36 #include "../../engines/Engine.h" 37 #include "../../EventListeners.h" 38 39 namespace LinuxSampler { 40 41 // just symbol prototyping 42 class MidiInputPort; 43 class Engine; 44 class MidiInputDeviceFactory; 45 46 /** 47 * Midi input exception that should be thrown by the MidiInputDevice 48 * descendants in case initialization of the MIDI input system failed 49 * (which should be done in the constructor of the MidiInputDevice 50 * descendant). 51 */ 52 class MidiInputException : public Exception { 53 public: MidiInputException(const std::string & msg)54 MidiInputException(const std::string& msg) : Exception(msg) {} 55 }; 56 57 /** Abstract base class for MIDI input drivers in LinuxSampler 58 * 59 * This class will be derived by specialized classes which implement the 60 * connection to a specific MIDI input system (e.g. Alsa Sequencer, 61 * CoreMIDI). The MidiInputDevice desendant should just call the 62 * appropriate (protected) Dispatch* method here when an MIDI event 63 * occured. The dispatch* methods here will automatically forward the 64 * MIDI event to the appropriate, connected sampler engines. 65 */ 66 class MidiInputDevice : public Device { 67 public: 68 69 ///////////////////////////////////////////////////////////////// 70 // type definitions 71 72 /** Device Parameter 'ACTIVE' 73 * 74 * Used to activate / deactivate the MIDI input device. 75 */ 76 class ParameterActive : public DeviceCreationParameterBool { 77 public: 78 ParameterActive(); 79 ParameterActive(String active); 80 virtual String Description() OVERRIDE; 81 virtual bool Fix() OVERRIDE; 82 virtual bool Mandatory() OVERRIDE; 83 virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() OVERRIDE; 84 virtual optional<bool> DefaultAsBool(std::map<String,String> Parameters) OVERRIDE; 85 virtual void OnSetValue(bool b) throw (Exception) OVERRIDE; 86 static String Name(); 87 }; 88 89 /** Device Parameter 'PORTS' 90 * 91 * Used to increase / decrease the number of MIDI ports of the 92 * MIDI input device. 93 */ 94 class ParameterPorts : public DeviceCreationParameterInt { 95 public: 96 ParameterPorts(); 97 ParameterPorts(String val); 98 virtual String Description() OVERRIDE; 99 virtual bool Fix() OVERRIDE; 100 virtual bool Mandatory() OVERRIDE; 101 virtual std::map<String,DeviceCreationParameter*> DependsAsParameters() OVERRIDE; 102 virtual optional<int> DefaultAsInt(std::map<String,String> Parameters) OVERRIDE; 103 virtual optional<int> RangeMinAsInt(std::map<String,String> Parameters) OVERRIDE; 104 virtual optional<int> RangeMaxAsInt(std::map<String,String> Parameters) OVERRIDE; 105 virtual std::vector<int> PossibilitiesAsInt(std::map<String,String> Parameters) OVERRIDE; 106 virtual void OnSetValue(int i) throw (Exception) OVERRIDE; 107 static String Name(); 108 }; 109 110 111 112 ///////////////////////////////////////////////////////////////// 113 // abstract methods 114 // (these have to be implemented by the descendant) 115 116 /** 117 * Start listen to MIDI input events on the MIDI input port. 118 * The MIDIInputPort descendant should forward all MIDI input 119 * events by calling the appropriate (protected) Dispatch* 120 * method of class MidiInputPort. 121 */ 122 virtual void Listen() = 0; 123 124 /** 125 * Stop to listen to MIDI input events on the MIDI input port. 126 * After this method was called, the MidiInputPort descendant 127 * should ignore all MIDI input events. 128 */ 129 virtual void StopListen() = 0; 130 131 /** 132 * Return device driver name 133 */ 134 virtual String Driver() = 0; 135 136 /** 137 * Create new Midi port 138 * This will be called by AcquirePorts 139 * Each individual device must implement this. 140 */ 141 virtual MidiInputPort* CreateMidiPort() = 0; 142 143 144 145 ///////////////////////////////////////////////////////////////// 146 // normal methods 147 // (usually not to be overriden by descendant) 148 149 /** 150 * Return midi port \a iPort. 151 * 152 * @throws MidiInputException if index out of bounds 153 */ 154 MidiInputPort* GetPort(uint iPort) throw (MidiInputException); 155 156 /** 157 * Returns amount of MIDI ports this MIDI input device currently 158 * provides. 159 */ 160 uint PortCount(); 161 162 /** 163 * Return all device parameter settings. 164 */ 165 std::map<String,DeviceCreationParameter*> DeviceParameters(); 166 167 /** 168 * Returns the unique ID number associated with this MIDIInputDevice 169 * instance. This ID number is unique among all MIDIInputDevice 170 * instances of the same Sampler instance and during the whole 171 * lifetime of the Sampler instance. 172 * 173 * @returns a value equal or larger than 0, a negative value only 174 * on severe internal problems 175 */ 176 int MidiInputDeviceID(); 177 178 /** 179 * Registers the specified listener to be notified 180 * when the number of MIDI input ports is changed. 181 */ 182 void AddMidiPortCountListener(MidiPortCountListener* l); 183 184 /** 185 * Removes the specified listener, to stop being notified of 186 * further MIDI input port count chances. 187 */ 188 void RemoveMidiPortCountListener(MidiPortCountListener* l); 189 190 protected: 191 std::map<String,DeviceCreationParameter*> Parameters; ///< All device parameters. 192 std::map<int,MidiInputPort*> Ports; ///< All MIDI ports. 193 void* pSampler; ///< Sampler instance. FIXME: should actually be of type Sampler* 194 ListenerList<MidiPortCountListener*> portCountListeners; 195 196 /** 197 * Constructor 198 * 199 * FIXME: the pointer argument \a pSapmler should actually be of type Sampler*. 200 * Unfortunately the bidirectional relationship between this 201 * header and Sampler.h would clash on header file inclusion, 202 * so that's why I had to make it of type void* here. This is 203 * an annoying constraint of C++. 204 */ 205 MidiInputDevice(std::map<String,DeviceCreationParameter*> DriverParameters, void* pSampler); 206 207 /** 208 * Destructor 209 */ 210 virtual ~MidiInputDevice(); 211 212 /** 213 * Notifies listeners that the amount of MIDI inpurt ports have 214 * been changed. 215 * @param NewCount The new number of MIDI input ports. 216 */ 217 void fireMidiPortCountChanged(int NewCount); 218 219 /** 220 * Notifies listeners that the supplied MIDI input port is 221 * going to be removed soon. 222 * @param pPort The MIDI input port that is going to be removed. 223 */ 224 void fireMidiPortToBeRemoved(MidiInputPort* pPort); 225 226 /** 227 * Notifies listeners that the supplied MIDI input port has 228 * just been added. 229 * @param pPort The MIDI input port that has been added. 230 */ 231 void fireMidiPortAdded(MidiInputPort* pPort); 232 233 /** 234 * Set number of MIDI ports required by the engine 235 * This can either do nothing, create more ports 236 * or destroy ports depenging on the parameter 237 * and how many ports already exist on this driver. 238 * 239 * @param Ports - number of ports to be left on this driver after this call. 240 */ 241 void AcquirePorts(uint Ports); 242 243 friend class ParameterActive; 244 friend class ParameterPorts; 245 friend class MidiInputDeviceFactory; // allow MidiInputDeviceFactory class to destroy midi devices 246 friend class MidiInputPort; // allow MidiInputPort to access pSampler 247 }; 248 } 249 250 #endif // __LS_MIDIINPUTDEVICE_H__ 251