2 |
* * |
* * |
3 |
* LinuxSampler - modular, streaming capable sampler * |
* LinuxSampler - modular, streaming capable sampler * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck * |
* 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 * |
* 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 * |
* it under the terms of the GNU General Public License as published by * |
26 |
|
|
27 |
#include <vector> |
#include <vector> |
28 |
#include <map> |
#include <map> |
29 |
|
#include "EventListeners.h" |
30 |
#include "common/global.h" |
#include "common/global.h" |
31 |
#include "common/LinuxSamplerException.h" |
#include "common/Exception.h" |
32 |
#include "engines/common/Engine.h" |
#include "engines/EngineChannel.h" |
33 |
#include "mididriver/MidiInputDevice.h" |
#include "drivers/midi/MidiInputDevice.h" |
34 |
#include "audiodriver/AudioOutputDevice.h" |
#include "drivers/audio/AudioOutputDevice.h" |
35 |
|
|
36 |
namespace LinuxSampler { |
namespace LinuxSampler { |
37 |
|
|
|
/** |
|
|
* Which sampler engine to be used. |
|
|
*/ |
|
|
enum engine_type_t { |
|
|
engine_type_gig |
|
|
}; |
|
|
|
|
|
/** |
|
|
* Which audio output system to be used. |
|
|
*/ |
|
|
enum audio_output_type_t { |
|
|
audio_output_type_alsa, |
|
|
audio_output_type_jack |
|
|
}; |
|
|
|
|
|
/** |
|
|
* Which MIDI input system to be used. |
|
|
*/ |
|
|
enum midi_input_type_t { |
|
|
midi_input_type_alsa |
|
|
}; |
|
|
|
|
38 |
// just symbol prototyping |
// just symbol prototyping |
39 |
class Sampler; |
class Sampler; |
40 |
|
|
41 |
/** LinuxSampler sampler channel |
/** @brief LinuxSampler sampler channel (a.k.a. "sampler part") |
42 |
* |
* |
43 |
* Encapsulates one sampler engine, one connection to a MIDI input |
* Encapsulates a channel of a specific sampler engine type, one |
44 |
* device and one connection to an audio output device. You cannot |
* connection to a MIDI input device and one connection to an audio |
45 |
* create an instance of this class on you own, you have to use the |
* output device. You cannot create an instance of this class on your |
46 |
* AddSamplerChannel() method of the Sampler object to create a new |
* own, you have to use the AddSamplerChannel() method of the Sampler |
47 |
* sampler channel. |
* object to create a new sampler channel. |
48 |
*/ |
*/ |
49 |
class SamplerChannel { |
class SamplerChannel { |
50 |
public: |
public: |
51 |
/** |
/** |
52 |
* Deploy a sampler engine of the given type for this sampler |
* Assign a sampler engine type to this sampler channel. |
53 |
* channnel. If there was already a sampler engine deployed on |
* |
54 |
* this sampler channel, then the old engine will automatically |
* @param EngineType - type of the engine to use |
55 |
* be destroyed. |
* @throws Exception - if \a EngineType is invalid |
56 |
|
* @see Sampler::AvailableEngineTypes() |
57 |
|
*/ |
58 |
|
void SetEngineType(String EngineType) throw (Exception); |
59 |
|
|
60 |
|
/** |
61 |
|
* Connect this sampler channel to an audio output device, that |
62 |
|
* is an instance of an audio output driver. If this sampler |
63 |
|
* channel was already connected to an audio output device, then |
64 |
|
* the old connection will automatically be removed before. |
65 |
|
* |
66 |
|
* @param pDevice - audio output device to connect to |
67 |
|
* @throws Exception in case the audio device is tried to be |
68 |
|
* changed while the sampler channel is used by a |
69 |
|
* host plugin (e.g. VST, AU, DSSI, LV2) which |
70 |
|
* don't allow to change the audio output device |
71 |
|
*/ |
72 |
|
void SetAudioOutputDevice(AudioOutputDevice* pDevice) throw (Exception); |
73 |
|
|
74 |
|
/** |
75 |
|
* Connect the given MIDIInputPort to this SamplerChannel. The |
76 |
|
* connection is added to the sampler channel. So other MIDI input |
77 |
|
* connections remain unaffected by this call. If the given port is |
78 |
|
* already connected to this sampler channel, then this call is |
79 |
|
* ignored. |
80 |
|
* |
81 |
|
* @param pPort - MIDI input port to connect to |
82 |
|
* @throws Exception in case the MIDI device is tried to be changed |
83 |
|
* while the sampler channel is being used by a |
84 |
|
* host plugin (e.g. VST, AU, DSSI, LV2) which |
85 |
|
* don't allow to change the MIDI port or even |
86 |
|
* device |
87 |
|
*/ |
88 |
|
void Connect(MidiInputPort* pPort) throw (Exception); |
89 |
|
|
90 |
|
/** |
91 |
|
* Disconnects the given MidiInputPort from this SamplerChannel. |
92 |
|
* All other MIDI input ports connected to this sampler channel |
93 |
|
* remain unaffected. If the given port is not currently connected |
94 |
|
* to this sampler channel, then this call is ignored. |
95 |
|
* |
96 |
|
* @param pPort - MIDI input port to disconnect |
97 |
|
* @throws Exception in case the MIDI device is tried to be changed |
98 |
|
* while the sampler channel is being used by a |
99 |
|
* host plugin (e.g. VST, AU, DSSI, LV2) which |
100 |
|
* don't allow to change the MIDI port or even |
101 |
|
* device |
102 |
|
*/ |
103 |
|
void Disconnect(MidiInputPort* pPort) throw (Exception); |
104 |
|
|
105 |
|
/** |
106 |
|
* Disconnects all MIDI input ports currently connected with this |
107 |
|
* SamplerChannel. |
108 |
|
* |
109 |
|
* @throws Exception in case the MIDI device is tried to be changed |
110 |
|
* while the sampler channel is being used by a |
111 |
|
* host plugin (e.g. VST, AU, DSSI, LV2) which |
112 |
|
* don't allow to change the MIDI port or even |
113 |
|
* device |
114 |
|
*/ |
115 |
|
void DisconnectAllMidiInputPorts() throw (Exception); |
116 |
|
|
117 |
|
/** |
118 |
|
* Returns all MIDI input ports currently connected to this sampler |
119 |
|
* channel. |
120 |
|
*/ |
121 |
|
std::vector<MidiInputPort*> GetMidiInputPorts(); |
122 |
|
|
123 |
|
/** |
124 |
|
* Connect this sampler channel to a MIDI input device. |
125 |
|
* |
126 |
|
* This call will also disconnect <b>all</b> existing MIDI input |
127 |
|
* connections from this sampler channel before establishing the |
128 |
|
* new connection! Disconnection of all previous connections is |
129 |
|
* done to preserve full behavior backward compatibility to times |
130 |
|
* when this API only allowed one MIDI input port per sampler |
131 |
|
* channel. |
132 |
|
* |
133 |
|
* @param pDevice - MIDI input device to connect to |
134 |
|
* @throws Exception in case the MIDI device is tried to be changed |
135 |
|
* while the sampler channel is being used by a |
136 |
|
* host plugin (e.g. VST, AU, DSSI, LV2) which |
137 |
|
* don't allow to change the MIDI port or even |
138 |
|
* device |
139 |
|
* @deprecated This method is only provided for backward |
140 |
|
* compatibility. It is a relict from days where there |
141 |
|
* was only 1 MIDI input allowed per SamplerChannel. |
142 |
|
*/ |
143 |
|
void SetMidiInputDevice(MidiInputDevice *pDevice) throw (Exception) DEPRECATED_API; |
144 |
|
|
145 |
|
/** |
146 |
|
* Change the MIDI input port connected to this sampler channel. |
147 |
|
* |
148 |
|
* Calling this method will switch the connection of the first |
149 |
|
* (and only the first) MIDIInputPort currently being connected to |
150 |
|
* this sampler channel, to another port of the same |
151 |
|
* MidiInputDevice. Or in other words: the first MIDIInputPort |
152 |
|
* currently connected to this sampler channel will be disconnected, |
153 |
|
* and the requested other port of its MIDIInputDevice will be |
154 |
|
* connected to this sampler channel instead. |
155 |
|
* |
156 |
|
* This behavior is implemented to preserve full behavior backward |
157 |
|
* compatibility to times when this API only allowed one MIDI input |
158 |
|
* port per SamplerChannel. |
159 |
* |
* |
160 |
* @param EngineType - type of the engine to deploy |
* @param MidiPort - MIDI port to connect to |
161 |
|
* @throws Exception in case the MIDI port is tried to be changed |
162 |
|
* while the sampler channel is being used by a |
163 |
|
* host plugin (e.g. VST, AU, DSSI, LV2) which |
164 |
|
* don't allow to change the MIDI port |
165 |
|
* @deprecated This method is only provided for backward |
166 |
|
* compatibility. It is a relict from days where there |
167 |
|
* was only 1 MIDI input allowed per SamplerChannel. |
168 |
*/ |
*/ |
169 |
void LoadEngine(engine_type_t EngineType); |
void SetMidiInputPort(int MidiPort) throw (Exception) DEPRECATED_API; |
170 |
|
|
171 |
/** |
/** |
172 |
* Connect this sampler channel to an audio output device (that |
* Define on which MIDI channel(s) this sampler channel should |
173 |
* is audio output driver) of the given type. If the audio |
* listen to (on all MIDI ports and all virtual MIDI devices |
174 |
* output for the desired audio output system is not yet |
* connected to this sampler channel). By default, that is after |
175 |
* created, then it will be created automatically, but with |
* creation of a new sampler channel, the sampler channel will |
176 |
* default settings though. If this sampler channel was already |
* listen to all MIDI channels (a.k.a. "MIDI Omni mode"). |
|
* connected to an audio output device, then the old connection |
|
|
* will automatically be removed before. |
|
177 |
* |
* |
178 |
* @param AudioType - audio output system to connect to |
* @param MidiChannel - MIDI channel to listen |
179 |
|
* @throws Exception if provided MidiChannel is not a valid constant |
180 |
|
* as defined by midi_chan_t |
181 |
*/ |
*/ |
182 |
void SetAudioOutputDevice(audio_output_type_t AudioType); |
void SetMidiInputChannel(midi_chan_t MidiChannel); |
183 |
|
|
184 |
/** |
/** |
185 |
* Connect this sampler channel to and MIDI input device (that |
* Connect this sampler channel to a MIDI input triplet. |
|
* is MIDI input driver) of the given type. If the MIDI input |
|
|
* driver for the desired MIDI input system is not yet created, |
|
|
* then it will be created automatically, but with default |
|
|
* settings though. If this sampler channel was already |
|
|
* connected to a MIDI input device, then the old connection |
|
|
* will automatically be removed before. |
|
186 |
* |
* |
187 |
* @param MidiType - MIDI input system to connect to |
* This call will also disconnect <b>all</b> existing MIDI input |
188 |
|
* connections from this sampler channel before establishing the |
189 |
|
* new connection! Disconnection of all previous connections is |
190 |
|
* done to preserve full behavior backward compatibility to times |
191 |
|
* when this API only allowed one MIDI input port per sampler |
192 |
|
* channel. |
193 |
|
* |
194 |
|
* @param pDevice - MIDI input device to connect to |
195 |
|
* @param iMidiPort - MIDI port to connect to |
196 |
* @param MidiChannel - optional: MIDI channel on which the |
* @param MidiChannel - optional: MIDI channel on which the |
197 |
* sampler channel should listen to |
* sampler channel should listen to |
198 |
* (default: listen on all MIDI channels) |
* (default: listen on all MIDI channels) |
199 |
|
* @throws Exception in case the MIDI port is tried to be changed |
200 |
|
* while the sampler channel is being used by a |
201 |
|
* host plugin (e.g. VST, AU, DSSI, LV2) which |
202 |
|
* don't allow to change the MIDI port |
203 |
|
* @deprecated This method is only provided for backward |
204 |
|
* compatibility. It is a relict from days where there |
205 |
|
* was only 1 MIDI input allowed per sampler channel. |
206 |
*/ |
*/ |
207 |
void SetMidiInputDevice(midi_input_type_t MidiType, MidiInputDevice::midi_chan_t MidiChannel = MidiInputDevice::midi_chan_all); |
void SetMidiInput(MidiInputDevice* pDevice, int iMidiPort, midi_chan_t MidiChannel = midi_chan_all) throw (Exception) DEPRECATED_API; |
208 |
|
|
209 |
/** |
/** |
210 |
* Returns the engine that was deployed on this sampler channel. |
* Returns the EngineChannel object that was deployed on this |
211 |
|
* sampler channel appropriate to the given sampler engine type. |
212 |
* |
* |
213 |
* @returns pointer to engine or NULL if no engine deployed |
* @returns pointer to engine or NULL if no engine deployed |
214 |
*/ |
*/ |
215 |
Engine* GetEngine(); |
EngineChannel* GetEngineChannel(); |
216 |
|
|
217 |
/** |
/** |
218 |
* Returns the MIDI input device to which this sampler channel |
* Returns the MIDI input channel to which this sampler |
219 |
* is currently connected to. |
* channel is currently connected to. |
220 |
* |
* |
221 |
* @returns pointer to MIDI input device or NULL if not |
* @returns The MIDI input channel on which the sampler |
222 |
* connected |
* channel is listening to. |
223 |
*/ |
*/ |
224 |
MidiInputDevice* GetMidiInputDevice(); |
midi_chan_t GetMidiInputChannel(); |
225 |
|
|
226 |
|
/** |
227 |
|
* Returns the MIDI input port number to which this sampler |
228 |
|
* channel is currently connected to. |
229 |
|
* |
230 |
|
* This method should not be used in new applications anymore! |
231 |
|
* |
232 |
|
* @returns MIDI input port number or -1 if not connected |
233 |
|
* @deprecated This method is only provided for backward |
234 |
|
* compatibility. It is a relict from days where there |
235 |
|
* was only 1 MIDI input allowed per sampler channel. |
236 |
|
*/ |
237 |
|
int GetMidiInputPort() DEPRECATED_API; |
238 |
|
|
239 |
/** |
/** |
240 |
* Returns the audio output device to which this sampler channel |
* Returns the audio output device to which this sampler channel |
246 |
AudioOutputDevice* GetAudioOutputDevice(); |
AudioOutputDevice* GetAudioOutputDevice(); |
247 |
|
|
248 |
/** |
/** |
249 |
|
* Returns the MIDI input device to which this sampler channel |
250 |
|
* is currently connected to. |
251 |
|
* |
252 |
|
* @returns pointer to MIDI input device or NULL if not |
253 |
|
* connected |
254 |
|
* @deprecated This method is only provided for backward |
255 |
|
* compatibility. It is a relict from days where there |
256 |
|
* was only 1 MIDI input allowed per sampler channel. |
257 |
|
*/ |
258 |
|
MidiInputDevice* GetMidiInputDevice() DEPRECATED_API; |
259 |
|
|
260 |
|
/** |
261 |
* Returns the index number of this sampler channel within the |
* Returns the index number of this sampler channel within the |
262 |
* Sampler instance. |
* Sampler instance. |
263 |
*/ |
*/ |
264 |
uint Index(); |
uint Index(); |
265 |
|
|
266 |
|
/** Returns the sampler to which this channel belongs */ |
267 |
|
Sampler* GetSampler(); |
268 |
|
|
269 |
|
/////////////////////////////////////////////////////////////// |
270 |
|
// Event Listener methods |
271 |
|
|
272 |
|
/** |
273 |
|
* Registers the specified listener to be notified |
274 |
|
* when the engine type of this sampler channel is changed. |
275 |
|
*/ |
276 |
|
void AddEngineChangeListener(EngineChangeListener* l); |
277 |
|
|
278 |
|
/** |
279 |
|
* Removes the specified listener. |
280 |
|
*/ |
281 |
|
void RemoveEngineChangeListener(EngineChangeListener* l); |
282 |
|
|
283 |
|
/** |
284 |
|
* Removes the specified listener. |
285 |
|
*/ |
286 |
|
void RemoveAllEngineChangeListeners(); |
287 |
|
|
288 |
|
/** |
289 |
|
* Notifies listeners that the engine type of this sampler |
290 |
|
* channel is going to be changed soon. |
291 |
|
*/ |
292 |
|
void fireEngineToBeChanged(); |
293 |
|
|
294 |
|
/** |
295 |
|
* Notifies listeners that the engine |
296 |
|
* type of this sampler channel is changed. |
297 |
|
*/ |
298 |
|
void fireEngineChanged(); |
299 |
|
|
300 |
|
|
301 |
protected: |
protected: |
302 |
SamplerChannel(Sampler* pS); |
SamplerChannel(Sampler* pS); |
303 |
~SamplerChannel(); |
virtual ~SamplerChannel(); |
304 |
|
|
305 |
Sampler* pSampler; |
Sampler* pSampler; |
306 |
Engine* pEngine; |
EngineChannel* pEngineChannel; |
307 |
MidiInputDevice* pMidiInputDevice; |
AudioOutputDevice* pAudioOutputDevice; //FIXME: should be stored as numeric device ID instead of raw pointer to avoid pointer invalidation problems |
|
AudioOutputDevice* pAudioOutputDevice; |
|
308 |
int iIndex; |
int iIndex; |
309 |
|
|
310 |
friend class Sampler; |
friend class Sampler; |
311 |
|
|
312 |
|
private: |
313 |
|
struct midi_conn_t { |
314 |
|
uint deviceID; |
315 |
|
uint portNr; |
316 |
|
|
317 |
|
bool operator== (const midi_conn_t& other) const { |
318 |
|
return other.deviceID == this->deviceID && |
319 |
|
other.portNr == this->portNr; |
320 |
|
} |
321 |
|
|
322 |
|
bool operator< (const midi_conn_t& other) const { |
323 |
|
return memcmp(this, &other, sizeof(midi_conn_t)) < 0; |
324 |
|
} |
325 |
|
}; |
326 |
|
|
327 |
|
int iMidiPort; ///< Don't access directly, read GetMidiInputPort() instead ! @deprecated This variable is just for backward compatibility from days when there was only one MIDI connection per SamplerChannel. |
328 |
|
midi_chan_t midiChannel; ///< Don't access directly, read GetMidiInputChannel() instead ! |
329 |
|
std::vector<midi_conn_t> vMidiInputs; ///< MIDI input ports connected to this sampler channel. Only used as "cache" (device id, port nr pair) in initial situation where no engine type is selected yet, and accordingly no EngineChannel instance exists which actually manages the device connections. This way users can "connect" MIDI input ports to this SamplerChannel before an engine type is chosen. |
330 |
|
ListenerList<EngineChangeListener*> llEngineChangeListeners; |
331 |
|
|
332 |
|
static MidiInputPort* _getPortForID(const midi_conn_t& c); |
333 |
}; |
}; |
334 |
|
|
335 |
/** LinuxSampler main class |
/** @brief LinuxSampler main class |
336 |
* |
* |
337 |
* This is the toplevel class for a LinuxSampler instance. |
* This is the toplevel class for a LinuxSampler instance. |
338 |
* |
* |
339 |
* LinuxSampler can have arbitrary numbers of sampler channels. Each |
* LinuxSampler can have arbitrary numbers of sampler channels. Each |
340 |
* sampler channel can individually be deployed with it's own sampler |
* sampler channel (a.k.a. "sampler part") can individually be deployed |
341 |
* engine, connected to an arbitrary MIDI input device and connected to |
* with it's own sampler engine, connected to an arbitrary MIDI input |
342 |
* an arbitrary audio output device. Here an example setup: |
* device and connected to an arbitrary audio output device. Here an |
343 |
* |
* example setup: |
344 |
* S.Channel. MIDI in S.Engine Audio out |
* @code |
345 |
* ------------------------------------------------------------------- |
* S.Channel MIDI in S.Engine Audio out |
346 |
* 0 Alsa -> gig::Engine -> Jack |
* ------------------------------------------------------------------- |
347 |
* 1 VSTi -> Akai::Engine -> VSTi |
* 0 Alsa -> gig::Engine -> Jack |
348 |
* 2 Jack -> DLS::Engine -> Jack |
* 1 VSTi -> gig::Engine -> VSTi |
349 |
* 3 Jack -> SF::Engine -> Alsa |
* 2 Jack -> sfz::Engine -> Jack |
350 |
|
* 3 Jack -> SF2::Engine -> Alsa |
351 |
|
* 4 LV2 -> sfz::Engine -> LV2 |
352 |
* |
* |
353 |
* ... (and so on) ... |
* ... (and so on) ... |
354 |
* |
* @endcode |
|
* Note that not all audio and MIDI backends and sampler engines listed |
|
|
* in the example above are already implemented! |
|
355 |
* |
* |
356 |
* As you can see in the example setup, LinuxSampler is capable to use |
* As you can see in the example setup, LinuxSampler is capable to use |
357 |
* several, different audio output and MIDI input systems |
* several, different audio output and MIDI input systems |
358 |
* simultaniously at the same time. Here the example setup shown in the |
* simultaniously at the same time. Here the example setup shown in the |
359 |
* ascpect of MIDI input and audio output devices / drivers: |
* aspect of MIDI input and audio output devices / drivers: |
360 |
* |
* @code |
361 |
* ######################### ######################### |
* ######################### ######################### |
362 |
* # AudioOutputDeviceJack # # AudioOutputDeviceVSTi # |
* # AudioOutputDeviceJack # # AudioOutputDeviceVSTi # |
363 |
* ######################### ######################### |
* ######################### ######################### |
364 |
* ^ ^ ^ |
* ^ ^ ^ |
365 |
* /------------>|Sampler Channel 0|-----/ | | |
* /------------>|Sampler Channel 0|-----/ | | |
366 |
* | /--------->|Sampler Channel 1|---------------------/ |
* | /--------->|Sampler Channel 1|---------------------/ |
367 |
* | | /---->|Sampler Channel 2|---------/ |
* | | /------>|Sampler Channel 2|---------/ |
368 |
* | | | /->|Sampler Channel 3|------------>######################### |
* | | | /--->|Sampler Channel 3|------------>######################### |
369 |
* | | | | ... (and so on) ... # AudioOutputDeviceAlsa # |
* | | | | ... (and so on) ... # AudioOutputDeviceAlsa # |
370 |
* | | | | ######################### |
* | | | | ######################### |
371 |
* | | | \----------------------------------------------------\ |
* | | | \-----------------------------------------------------\ |
372 |
* | | \-------------------------------------------\ | |
* | | \--------------------------------------------\ | |
373 |
* | \--------------------\ | | |
* | \--------------------\ | | |
374 |
* | | | | |
* | | | | |
375 |
* ####################### ####################### ####################### |
* ####################### ####################### ####################### |
376 |
* # MidiInputDeviceAlsa # # MidiInputDeviceVSTi # # MidiInputDeviceJack # |
* # MidiInputDeviceAlsa # # MidiInputDeviceVSTi # # MidiInputDeviceJack # |
377 |
* ####################### ####################### ####################### |
* ####################### ####################### ####################### |
378 |
|
* @endcode |
379 |
* |
* |
380 |
* As you can see in this example setup, one device (that is midi input |
* As you can see in this example setup, one device (that is midi input |
381 |
* driver / audio output driver) can be connected multiple times to |
* driver / audio output driver) can be connected multiple times to |
382 |
* different sampler channels. |
* different sampler channels. |
383 |
|
* |
384 |
|
* It's even possible to create multiple instances of the same driver, for |
385 |
|
* example multiple instances of the Alsa output driver to use multiple |
386 |
|
* sound cards at the same time, or multiple instances of the JACK audio |
387 |
|
* output driver to leverage SMP systems or boxes with several hard discs. |
388 |
*/ |
*/ |
389 |
class Sampler { |
class Sampler { |
390 |
public: |
public: |
396 |
/** |
/** |
397 |
* Destructor. |
* Destructor. |
398 |
*/ |
*/ |
399 |
~Sampler(); |
virtual ~Sampler(); |
400 |
|
|
401 |
/** |
/** |
402 |
* Returns the number of sampler channels currently allocated. |
* Returns the number of sampler channels currently allocated. |
404 |
uint SamplerChannels(); |
uint SamplerChannels(); |
405 |
|
|
406 |
/** |
/** |
407 |
* Create and add a new sampler channel to this Sampler instance. |
* Create and add a new sampler channel to this Sampler |
408 |
|
* instance. For race condition reasons the new channel will use |
409 |
|
* an index past the last already existing sampler channel |
410 |
|
* index (in case the index limit was not reached yet, otherwise |
411 |
|
* a free index starting from 0 is searched). |
412 |
* |
* |
413 |
* @returns pointer to new sampler channel |
* @returns pointer to new sampler channel |
414 |
*/ |
*/ |
423 |
SamplerChannel* GetSamplerChannel(uint uiSamplerChannel); |
SamplerChannel* GetSamplerChannel(uint uiSamplerChannel); |
424 |
|
|
425 |
/** |
/** |
426 |
|
* Returns all created sampler channels. |
427 |
|
*/ |
428 |
|
std::map<uint, SamplerChannel*> GetSamplerChannels(); |
429 |
|
|
430 |
|
/** |
431 |
* Destroy and remove the given sampler channel from this |
* Destroy and remove the given sampler channel from this |
432 |
* Sampler instance. |
* Sampler instance. |
433 |
* |
* |
445 |
void RemoveSamplerChannel(uint uiSamplerChannel); |
void RemoveSamplerChannel(uint uiSamplerChannel); |
446 |
|
|
447 |
/** |
/** |
448 |
* Create an audio output device of the given type. |
* Destroy and remove all sampler channels from this |
449 |
|
* Sampler instance. |
450 |
|
*/ |
451 |
|
void RemoveAllSamplerChannels(); |
452 |
|
|
453 |
|
/** |
454 |
|
* Returns the names of all available audio output drivers. |
455 |
|
*/ |
456 |
|
std::vector<String> AvailableAudioOutputDrivers(); |
457 |
|
|
458 |
|
/** |
459 |
|
* Returns the names of all available MIDI input drivers. |
460 |
|
*/ |
461 |
|
std::vector<String> AvailableMidiInputDrivers(); |
462 |
|
|
463 |
|
/** |
464 |
|
* Returns the names of all available sampler engine types. |
465 |
|
* @see SamplerChannel::SetEngineType() |
466 |
|
*/ |
467 |
|
std::vector<String> AvailableEngineTypes(); |
468 |
|
|
469 |
|
/** |
470 |
|
* Create an audio output device. |
471 |
* |
* |
472 |
* @param AudioType - desired audio output system to use |
* @param AudioDriver - name of the audio driver |
473 |
|
* @param Parameters - eventually needed driver parameters to |
474 |
|
* create the device |
475 |
* @returns pointer to created audio output device |
* @returns pointer to created audio output device |
476 |
|
* @throws Exception if device could not be created |
477 |
|
*/ |
478 |
|
AudioOutputDevice* CreateAudioOutputDevice(String AudioDriver, std::map<String,String> Parameters) throw (Exception); |
479 |
|
|
480 |
|
/** |
481 |
|
* Create a midi input device. |
482 |
|
* |
483 |
|
* @param MidiDriver - name of the midi driver |
484 |
|
* @param Parameters - eventually needed driver parameters to |
485 |
|
* create the device |
486 |
|
* @returns pointer to created midi input device |
487 |
|
* @throws Exception if device could not be created |
488 |
|
*/ |
489 |
|
MidiInputDevice* CreateMidiInputDevice(String MidiDriver, std::map<String,String> Parameters) throw (Exception); |
490 |
|
|
491 |
|
/** |
492 |
|
* Returns the number of all created audio output devices. |
493 |
|
*/ |
494 |
|
uint AudioOutputDevices(); |
495 |
|
|
496 |
|
/** |
497 |
|
* Returns the number of all created MIDI input devices. |
498 |
|
*/ |
499 |
|
uint MidiInputDevices(); |
500 |
|
|
501 |
|
/** |
502 |
|
* Returns all created audio output devices. |
503 |
|
*/ |
504 |
|
std::map<uint, AudioOutputDevice*> GetAudioOutputDevices(); |
505 |
|
|
506 |
|
/** |
507 |
|
* Returns all created MIDI input devices. |
508 |
|
*/ |
509 |
|
std::map<uint, MidiInputDevice*> GetMidiInputDevices(); |
510 |
|
|
511 |
|
/** |
512 |
|
* Destroy the given audio output device and takes care if there |
513 |
|
* are still sampler engines connected to this device, etc. |
514 |
|
* |
515 |
|
* @throws Exception if sampler channels are still |
516 |
|
* connected to the device |
517 |
|
*/ |
518 |
|
void DestroyAudioOutputDevice(AudioOutputDevice* pDevice) throw (Exception); |
519 |
|
|
520 |
|
/** |
521 |
|
* Destroy all audio output devices and takes care if there |
522 |
|
* are still sampler engines connected to devices, etc. |
523 |
|
* |
524 |
|
* Note: non-autonomous devices, that is devices associated with |
525 |
|
* host plugin instances like VST, AU, DSSI, LV2 are not |
526 |
|
* destroyed by this method. |
527 |
|
* |
528 |
|
* @throws Exception if sampler channels are still |
529 |
|
* connected to device |
530 |
|
*/ |
531 |
|
void DestroyAllAudioOutputDevices() throw (Exception); |
532 |
|
|
533 |
|
/** |
534 |
|
* Destroy the given MIDI input device and takes care if there |
535 |
|
* are still sampler engines connected to this device, etc. |
536 |
|
* |
537 |
|
* @throws Exception if sampler channels are still |
538 |
|
* connected to the device |
539 |
*/ |
*/ |
540 |
AudioOutputDevice* CreateAudioOutputDevice(audio_output_type_t AudioType); |
void DestroyMidiInputDevice(MidiInputDevice* pDevice) throw (Exception); |
541 |
|
|
542 |
/** |
/** |
543 |
* Returns the audio output device of the given type. |
* Destroy all MIDI input devices and take care if there |
544 |
|
* are still sampler engines connected to device, etc. |
545 |
* |
* |
546 |
* @param AudioType - desired audio output system to use |
* Note: non-autonomous devices, that is devices associated with |
547 |
* @returns pointer to audio output device or NULL if device of |
* host plugin instances like VST, AU, DSSI, LV2 are not |
548 |
* desired type is not yet created |
* destroyed by this method. |
549 |
|
* |
550 |
|
* @throws Exception if sampler channels are still |
551 |
|
* connected to device |
552 |
|
*/ |
553 |
|
void DestroyAllMidiInputDevices() throw (Exception); |
554 |
|
|
555 |
|
/** |
556 |
|
* Gets the current number of all active streams. |
557 |
|
* @returns The current number of all active streams. |
558 |
|
*/ |
559 |
|
int GetDiskStreamCount(); |
560 |
|
|
561 |
|
/** |
562 |
|
* Gets the current number of all active voices. |
563 |
|
* @returns The current number of all active voices. |
564 |
*/ |
*/ |
565 |
AudioOutputDevice* GetAudioOutputDevice(audio_output_type_t AudioType); |
int GetVoiceCount(); |
566 |
|
|
567 |
/** |
/** |
568 |
* Create a MIDI input device of the given type. |
* @see SetGlobalMaxVoices() |
569 |
|
*/ |
570 |
|
int GetGlobalMaxVoices(); |
571 |
|
|
572 |
|
/** |
573 |
|
* @see SetGlobalMaxStreams() |
574 |
|
*/ |
575 |
|
int GetGlobalMaxStreams(); |
576 |
|
|
577 |
|
/** |
578 |
|
* Sets the global maximum amount limit of voices. |
579 |
* |
* |
580 |
* @param MidiType - desired MIDI input system to use |
* Note that this voice limit can also be altered for |
581 |
* @returns pointer to created MIDI input device |
* each sampler engine instance individually instead. |
582 |
|
* |
583 |
|
* @throws Exception if \a n is invalid |
584 |
|
*/ |
585 |
|
void SetGlobalMaxVoices(int n) throw (Exception); |
586 |
|
|
587 |
|
/** |
588 |
|
* Sets the global maximum amount limit of disk streams. |
589 |
|
* |
590 |
|
* Note that this stream limit can also be altered for |
591 |
|
* each sampler engine instance individually instead. |
592 |
|
* |
593 |
|
* @throws Exception if \a n is invalid |
594 |
|
*/ |
595 |
|
void SetGlobalMaxStreams(int n) throw (Exception); |
596 |
|
|
597 |
|
/** |
598 |
|
* Reset the whole sampler. Destroy all engines, sampler |
599 |
|
* channels, MIDI input devices and audio output devices. |
600 |
|
*/ |
601 |
|
void Reset(); |
602 |
|
|
603 |
|
/////////////////////////////////////////////////////////////// |
604 |
|
// Event Listener methods |
605 |
|
|
606 |
|
/** |
607 |
|
* Registers the specified listener to be notified |
608 |
|
* when the number of sampler chanels is changed. |
609 |
|
*/ |
610 |
|
void AddChannelCountListener(ChannelCountListener* l); |
611 |
|
|
612 |
|
/** |
613 |
|
* Removes the specified listener. |
614 |
|
*/ |
615 |
|
void RemoveChannelCountListener(ChannelCountListener* l); |
616 |
|
|
617 |
|
/** |
618 |
|
* Registers the specified listener to be notified |
619 |
|
* when the number of audio output devices is changed. |
620 |
|
*/ |
621 |
|
void AddAudioDeviceCountListener(AudioDeviceCountListener* l); |
622 |
|
|
623 |
|
/** |
624 |
|
* Removes the specified listener. |
625 |
|
*/ |
626 |
|
void RemoveAudioDeviceCountListener(AudioDeviceCountListener* l); |
627 |
|
|
628 |
|
/** |
629 |
|
* Registers the specified listener to be notified |
630 |
|
* when the number of MIDI input devices is changed. |
631 |
|
*/ |
632 |
|
void AddMidiDeviceCountListener(MidiDeviceCountListener* l); |
633 |
|
|
634 |
|
/** |
635 |
|
* Removes the specified listener. |
636 |
|
*/ |
637 |
|
void RemoveMidiDeviceCountListener(MidiDeviceCountListener* l); |
638 |
|
|
639 |
|
/** |
640 |
|
* Registers the specified listener to be notified when the number |
641 |
|
* of active voices in a particular sampler channel is changed. |
642 |
|
*/ |
643 |
|
void AddVoiceCountListener(VoiceCountListener* l); |
644 |
|
|
645 |
|
/** |
646 |
|
* Removes the specified listener. |
647 |
|
*/ |
648 |
|
void RemoveVoiceCountListener(VoiceCountListener* l); |
649 |
|
|
650 |
|
/** |
651 |
|
* Notifies listeners that the number of active voices |
652 |
|
* on the specified sampler channel is changed. |
653 |
|
* @param ChannelId The numerical ID of the sampler channel. |
654 |
|
* @param NewCount The new number of active voices. |
655 |
|
*/ |
656 |
|
void fireVoiceCountChanged(int ChannelId, int NewCount); |
657 |
|
|
658 |
|
/** |
659 |
|
* Registers the specified listener to be notified when the number |
660 |
|
* of active disk streams in a particular sampler channel is changed. |
661 |
|
*/ |
662 |
|
void AddStreamCountListener(StreamCountListener* l); |
663 |
|
|
664 |
|
/** |
665 |
|
* Removes the specified listener. |
666 |
|
*/ |
667 |
|
void RemoveStreamCountListener(StreamCountListener* l); |
668 |
|
|
669 |
|
/** |
670 |
|
* Notifies listeners that the number of active disk streams |
671 |
|
* on the specified sampler channel is changed. |
672 |
|
* @param ChannelId The numerical ID of the sampler channel. |
673 |
|
* @param NewCount The new number of active disk streams. |
674 |
|
*/ |
675 |
|
void fireStreamCountChanged(int ChannelId, int NewCount); |
676 |
|
|
677 |
|
/** |
678 |
|
* Registers the specified listener to be |
679 |
|
* notified when the fill state of the disk stream |
680 |
|
* buffers on a specific sampler channel is changed. |
681 |
*/ |
*/ |
682 |
MidiInputDevice* CreateMidiInputDevice(midi_input_type_t MidiType); |
void AddBufferFillListener(BufferFillListener* l); |
683 |
|
|
684 |
/** |
/** |
685 |
* Returns the MIDI input device of the given type. |
* Removes the specified listener. |
686 |
|
*/ |
687 |
|
void RemoveBufferFillListener(BufferFillListener* l); |
688 |
|
|
689 |
|
/** |
690 |
|
* Notifies listeners that the fill state of the disk stream |
691 |
|
* buffers on the specified sampler channel is changed. |
692 |
|
* @param ChannelId The numerical ID of the sampler channel. |
693 |
|
* @param FillData The buffer fill data for the specified sampler channel. |
694 |
|
*/ |
695 |
|
void fireBufferFillChanged(int ChannelId, String FillData); |
696 |
|
|
697 |
|
/** |
698 |
|
* Registers the specified listener to be notified |
699 |
|
* when total number of active voices is changed. |
700 |
|
*/ |
701 |
|
void AddTotalVoiceCountListener(TotalVoiceCountListener* l); |
702 |
|
|
703 |
|
/** |
704 |
|
* Removes the specified listener. |
705 |
|
*/ |
706 |
|
void RemoveTotalVoiceCountListener(TotalVoiceCountListener* l); |
707 |
|
|
708 |
|
/** |
709 |
|
* Notifies listeners that the total number of active voices is changed. |
710 |
|
* @param NewCount The new number of active voices. |
711 |
|
*/ |
712 |
|
void fireTotalVoiceCountChanged(int NewCount); |
713 |
|
|
714 |
|
/** |
715 |
|
* Registers the specified listener to be notified when the number |
716 |
|
* of total streams is changed. |
717 |
|
*/ |
718 |
|
void AddTotalStreamCountListener(TotalStreamCountListener* l); |
719 |
|
|
720 |
|
/** |
721 |
|
* Removes the specified listener. |
722 |
|
*/ |
723 |
|
void RemoveTotalStreamCountListener(TotalStreamCountListener* l); |
724 |
|
|
725 |
|
/** |
726 |
|
* Notifies listeners that the total number of total streams changed. |
727 |
|
* @param NewCount The new number of total streams. |
728 |
|
*/ |
729 |
|
void fireTotalStreamCountChanged(int NewCount); |
730 |
|
|
731 |
|
/** |
732 |
|
* Registers the specified listener to be notified when the number |
733 |
|
* of effect sends on a particular sampler channel is changed. |
734 |
|
*/ |
735 |
|
void AddFxSendCountListener(FxSendCountListener* l); |
736 |
|
|
737 |
|
/** |
738 |
|
* Removes the specified listener. |
739 |
|
*/ |
740 |
|
void RemoveFxSendCountListener(FxSendCountListener* l); |
741 |
|
|
742 |
|
/** |
743 |
|
* Notifies listeners about the current number of voices, |
744 |
|
* streams and total voices, and the current fill state of |
745 |
|
* the disk stream buffers. |
746 |
|
*/ |
747 |
|
void fireStatistics(); |
748 |
|
|
749 |
|
/////////////////////////////////////////////////////////////// |
750 |
|
// system specific methods |
751 |
|
|
752 |
|
/** |
753 |
|
* Advise the FPU to treat denormal floating point numbers as |
754 |
|
* zero, to avoid severe performance penalty when dealing with |
755 |
|
* such extreme floating point values. |
756 |
* |
* |
757 |
* @param MidiType - desired MIDI input system to use |
* @returns @c true if FPU supports it, @c false otherwise |
|
* @returns pointer to MIDI input device or NULL if device of |
|
|
* desired type is not yet created |
|
758 |
*/ |
*/ |
759 |
MidiInputDevice* GetMidiInputDevice(midi_input_type_t MidiType); |
static bool EnableDenormalsAreZeroMode(); |
760 |
|
|
761 |
|
#if defined(WIN32) |
762 |
|
/** |
763 |
|
* Gets the directory where the liblinuxsampler dll is located. |
764 |
|
* Note: this method is currently only available for Windows. |
765 |
|
* @returns installation directory |
766 |
|
*/ |
767 |
|
static String GetInstallDir(); |
768 |
|
#endif |
769 |
protected: |
protected: |
770 |
typedef std::map<audio_output_type_t, AudioOutputDevice*> AudioOutputDeviceMap; |
/** |
771 |
typedef std::map<midi_input_type_t, MidiInputDevice*> MidiInputDeviceMap; |
* Notifies listeners that the number of sampler channels has been changed. |
772 |
|
* @param NewCount The new number of sampler channels. |
773 |
|
*/ |
774 |
|
void fireChannelCountChanged(int NewCount); |
775 |
|
|
776 |
|
/** |
777 |
|
* Notifies listeners that the specified sampler channel has just |
778 |
|
* been added. |
779 |
|
* @param pChannel The new sampler channel. |
780 |
|
*/ |
781 |
|
void fireChannelAdded(SamplerChannel* pChannel); |
782 |
|
|
783 |
|
/** |
784 |
|
* Notifies listeners that the specified sampler channel is |
785 |
|
* going to be removed soon. |
786 |
|
* @param pChannel sampler channel to be removed. |
787 |
|
*/ |
788 |
|
void fireChannelToBeRemoved(SamplerChannel* pChannel); |
789 |
|
|
790 |
std::vector<SamplerChannel*> vSamplerChannels; ///< contains all created sampler channels |
/** |
791 |
AudioOutputDeviceMap AudioOutputDevices; ///< contains all created audio output devices |
* Notifies listeners that the number of audio output devices has been changed. |
792 |
MidiInputDeviceMap MidiInputDevices; |
* @param NewCount The new number of audio output devices. |
793 |
|
*/ |
794 |
|
void fireAudioDeviceCountChanged(int NewCount); |
795 |
|
|
796 |
|
/** |
797 |
|
* Notifies listeners that the number of MIDI input devices has been changed. |
798 |
|
* @param NewCount The new number of MIDI input devices. |
799 |
|
*/ |
800 |
|
void fireMidiDeviceCountChanged(int NewCount); |
801 |
|
|
802 |
|
/** |
803 |
|
* Notifies listeners that the supplied MIDI input device is |
804 |
|
* going to be destroyed soon. |
805 |
|
* @param pDevice MIDI input device to be destroyed |
806 |
|
*/ |
807 |
|
void fireMidiDeviceToBeDestroyed(MidiInputDevice* pDevice); |
808 |
|
|
809 |
|
/** |
810 |
|
* Notifies listeners that the supplied MIDI input device was |
811 |
|
* just created. |
812 |
|
* @param pDevice new MIDI input device |
813 |
|
*/ |
814 |
|
void fireMidiDeviceCreated(MidiInputDevice* pDevice); |
815 |
|
|
816 |
|
/** |
817 |
|
* Notifies listeners that the number of effect sends |
818 |
|
* on a particular sampler channel is changed. |
819 |
|
* @param ChannelId The numerical ID of the sampler channel. |
820 |
|
* @param NewCount The new number of sampler channels. |
821 |
|
*/ |
822 |
|
void fireFxSendCountChanged(int ChannelId, int NewCount); |
823 |
|
|
824 |
|
typedef std::map<uint, SamplerChannel*> SamplerChannelMap; |
825 |
|
|
826 |
|
SamplerChannelMap mSamplerChannels; ///< contains all created sampler channels |
827 |
|
|
828 |
|
// statistics cache |
829 |
|
uint uiOldTotalVoiceCount; |
830 |
|
uint uiOldTotalStreamCount; |
831 |
|
std::map<uint, uint> mOldVoiceCounts; |
832 |
|
std::map<uint, uint> mOldStreamCounts; |
833 |
|
|
834 |
friend class SamplerChannel; |
friend class SamplerChannel; |
835 |
|
|
836 |
|
private: |
837 |
|
ListenerList<ChannelCountListener*> llChannelCountListeners; |
838 |
|
ListenerList<AudioDeviceCountListener*> llAudioDeviceCountListeners; |
839 |
|
ListenerList<MidiDeviceCountListener*> llMidiDeviceCountListeners; |
840 |
|
ListenerList<VoiceCountListener*> llVoiceCountListeners; |
841 |
|
ListenerList<StreamCountListener*> llStreamCountListeners; |
842 |
|
ListenerList<BufferFillListener*> llBufferFillListeners; |
843 |
|
ListenerList<TotalStreamCountListener*> llTotalStreamCountListeners; |
844 |
|
ListenerList<TotalVoiceCountListener*> llTotalVoiceCountListeners; |
845 |
|
ListenerList<FxSendCountListener*> llFxSendCountListeners; |
846 |
|
|
847 |
|
class EventHandler : public EngineChangeListener, public FxSendCountListener { |
848 |
|
public: |
849 |
|
void SetSampler(Sampler* pSampler) { this->pSampler = pSampler; } |
850 |
|
|
851 |
|
/** |
852 |
|
* Invoked when the engine type of the specified sampler |
853 |
|
* channel is going to be changed soon. |
854 |
|
* @param ChannelId The numerical ID of the sampler channel |
855 |
|
*/ |
856 |
|
virtual void EngineToBeChanged(int ChannelId); |
857 |
|
|
858 |
|
/** |
859 |
|
* Invoked when the engine type of the |
860 |
|
* specified sampler channel is changed. |
861 |
|
* @param ChannelId The numerical ID of the sampler |
862 |
|
* channel, which engine type has been changed. |
863 |
|
*/ |
864 |
|
virtual void EngineChanged(int ChannelId); |
865 |
|
|
866 |
|
/** |
867 |
|
* Invoked when the number of effect sends |
868 |
|
* on the specified sampler channel has changed. |
869 |
|
* @param ChannelId The numerical ID of the sampler channel. |
870 |
|
* @param NewCount The new number of effect sends. |
871 |
|
*/ |
872 |
|
virtual void FxSendCountChanged(int ChannelId, int NewCount); |
873 |
|
|
874 |
|
private: |
875 |
|
Sampler* pSampler; |
876 |
|
} eventHandler; |
877 |
}; |
}; |
878 |
} |
} |
879 |
|
|