3 |
* LinuxSampler - modular, streaming capable sampler * |
* LinuxSampler - modular, streaming capable sampler * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
6 |
* Copyright (C) 2005, 2006 Christian Schoenebeck * |
* Copyright (C) 2005 - 2012 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 * |
38 |
// just symbol prototyping |
// just symbol prototyping |
39 |
class MidiInputDevice; |
class MidiInputDevice; |
40 |
class EngineChannel; |
class EngineChannel; |
41 |
|
class VirtualMidiDevice; |
42 |
|
|
43 |
class MidiInputPort { |
class MidiInputPort { |
44 |
public: |
public: |
69 |
// (usually not to be overriden by descendant) |
// (usually not to be overriden by descendant) |
70 |
|
|
71 |
/** |
/** |
72 |
* Connect given sampler engine with this MIDI input device. |
* Connect given sampler engine channel with this MIDI input |
73 |
* The engine can either be connected to one specific MIDI |
* device. The engine channel can either be connected to one |
74 |
* channel or all MIDI channels. If an engine gets connected |
* specific MIDI channel or all MIDI channels. If an engine |
75 |
* twice to this MIDI input device, then the engine's old |
* channel gets connected twice to this MIDI input device, then |
76 |
* connection will be detached (no matter on which MIDI channel). |
* the engine's old connection will be detached (no matter on |
77 |
|
* which MIDI channel). |
78 |
* |
* |
79 |
* @param pEngine - sampler engine |
* @param pEngineChannel - sampler engine |
80 |
* @param MidiChannel - MIDI channel to connect to |
* @param MidiChannel - MIDI channel to connect to |
81 |
* @throws MidiInputException if MidiChannel argument invalid |
* @throws MidiInputException if MidiChannel argument invalid |
82 |
*/ |
*/ |
83 |
void Connect(EngineChannel* pEngineChannel, midi_chan_t MidiChannel); |
void Connect(EngineChannel* pEngineChannel, midi_chan_t MidiChannel); |
84 |
|
|
85 |
/** |
/** |
86 |
* Disconnect given sampler engine from this MIDI input device. |
* Disconnect given sampler engine channel from this MIDI input |
87 |
* If the given engine was not connected with this device, |
* device. If the given engine channel was not connected with |
88 |
* nothing happens. |
* this device, nothing happens. |
89 |
* |
* |
90 |
* @param pEngine - sampler engine |
* @param pEngineChannel - sampler engine |
91 |
*/ |
*/ |
92 |
void Disconnect(EngineChannel* pEngineChannel); |
void Disconnect(EngineChannel* pEngineChannel); |
93 |
|
|
121 |
*/ |
*/ |
122 |
static bool RemoveSysexListener(Engine* engine); |
static bool RemoveSysexListener(Engine* engine); |
123 |
|
|
124 |
|
/** |
125 |
|
* Connects the given virtual MIDI device to this MIDI input |
126 |
|
* device. This can be used to listen to MIDI data arriving on |
127 |
|
* the MIDI input device's MIDI ports, e.g. to show an MIDI |
128 |
|
* activity indicator somewhere. |
129 |
|
*/ |
130 |
|
void Connect(VirtualMidiDevice* pDevice); |
131 |
|
|
132 |
|
/** |
133 |
|
* Disconnect the previously connected virtual MIDI device. |
134 |
|
*/ |
135 |
|
void Disconnect(VirtualMidiDevice* pDevice); |
136 |
|
|
137 |
|
/** |
138 |
|
* Registers the given @a filter to be applied against all note on |
139 |
|
* events, adjusting their MIDI velocity data. The vector supplied |
140 |
|
* here must exactly be either of size 128 or 0. In case the given |
141 |
|
* vector is of size 128, it will be used as lookup table by this |
142 |
|
* MIDI inpurt port to remap any incoming MIDI note on velocity |
143 |
|
* data to the respective value in that vector, or exactly: |
144 |
|
* @code |
145 |
|
* velocity = filter[velocity]; |
146 |
|
* @endcode |
147 |
|
* Accordingly the values in the vector have to be in the range |
148 |
|
* 0..127, however note that a value 0 should actually never be |
149 |
|
* used, since by MIDI specification, a note on with velocity 0 is |
150 |
|
* interpreted as note off event instead! |
151 |
|
* |
152 |
|
* If a vector of size 0 is supplied, this note on velocity filter |
153 |
|
* mechanism will be disabled. |
154 |
|
* |
155 |
|
* @param filter - lookup table in the format described above |
156 |
|
* @throws MidiInputException - if filter is in invalid format |
157 |
|
*/ |
158 |
|
void SetNoteOnVelocityFilter(const std::vector<uint8_t>& filter); |
159 |
|
|
160 |
|
|
161 |
///////////////////////////////////////////////////////////////// |
///////////////////////////////////////////////////////////////// |
162 |
// dispatch methods |
// dispatch methods |
300 |
|
|
301 |
/** |
/** |
302 |
* Should be called by the implementing MIDI input device |
* Should be called by the implementing MIDI input device |
303 |
* whenever a program change event arrived, this will cause the |
* whenever a program change event arrived. In case the |
304 |
* appropriate sampler channel to be connected with this MIDI |
* respective sampler channel(s) are enabled for MIDI |
305 |
* device. |
* instrument mapping, the respective sampler engine and |
306 |
* |
* instrument will be loaded on the connected sampler |
307 |
* For example consider a program change event on MIDI channel |
* channel(s) as defined by the respective entry in the |
308 |
* 3 for program number 18. This would cause this MIDI input |
* MIDI instrument map. |
309 |
* device to be connected to sampler channel 18 and would cause |
* |
310 |
* sampler channel 18 to listen to MIDI channel 3. |
* @e Note: the MIDI instrument map is empty by default on |
311 |
* |
* sampler startup. It has to be explicitly filled with |
312 |
* This is the current, general implementation of program |
* entries and the sampler channel(s) have to be enabled for |
313 |
* change events. It might change in future, e.g to allow |
* a certain MIDI instrument table, otherwise program change |
314 |
* sampler engines to allow by themselfes how to act on a |
* messages are ignored! |
315 |
* program change event. |
* |
316 |
* |
* @param Program - MIDI program change number |
317 |
* @param Program - sampler channel to connect to this MIDI |
* @param MidiChannel - MIDI channel on which this program |
318 |
* input device |
* change occured |
319 |
* @param MidiChannel - MIDI channel on which sampler channel |
* @see MidiInstrumentMapper |
|
* \a Program should listen to |
|
320 |
*/ |
*/ |
321 |
void DispatchProgramChange(uint8_t Program, uint MidiChannel); |
void DispatchProgramChange(uint8_t Program, uint MidiChannel); |
322 |
|
|
334 |
*/ |
*/ |
335 |
void DispatchSysex(void* pData, uint Size); |
void DispatchSysex(void* pData, uint Size); |
336 |
|
|
337 |
|
/** |
338 |
|
* Helper function for MIDI input devices that have the |
339 |
|
* MIDI data as raw bytes. |
340 |
|
* |
341 |
|
* @param pData - pointer to the raw MIDI data |
342 |
|
*/ |
343 |
|
void DispatchRaw(uint8_t* pData); |
344 |
|
|
345 |
|
/** |
346 |
|
* Helper function for MIDI input devices that have the |
347 |
|
* MIDI data as raw bytes. |
348 |
|
* |
349 |
|
* @param pData - pointer to the raw MIDI data |
350 |
|
* @param FragmentPos - event's sample point position in the |
351 |
|
* current audio fragment |
352 |
|
*/ |
353 |
|
void DispatchRaw(uint8_t* pData, int32_t FragmentPos); |
354 |
|
|
355 |
protected: |
protected: |
356 |
MidiInputDevice* pDevice; |
MidiInputDevice* pDevice; |
357 |
int portNumber; |
int portNumber; |
361 |
SynchronizedConfig<MidiChannelMap_t>::Reader MidiChannelMapReader; ///< MIDI thread access to MidiChannelMap |
SynchronizedConfig<MidiChannelMap_t>::Reader MidiChannelMapReader; ///< MIDI thread access to MidiChannelMap |
362 |
Mutex MidiChannelMapMutex; ///< Used to protect the MidiChannelMap from being used at the same time by different threads. |
Mutex MidiChannelMapMutex; ///< Used to protect the MidiChannelMap from being used at the same time by different threads. |
363 |
SynchronizedConfig<std::set<Engine*> >::Reader SysexListenersReader; ///< MIDI thread access to SysexListeners |
SynchronizedConfig<std::set<Engine*> >::Reader SysexListenersReader; ///< MIDI thread access to SysexListeners |
364 |
|
SynchronizedConfig<std::vector<VirtualMidiDevice*> > virtualMidiDevices; |
365 |
|
SynchronizedConfig<std::vector<VirtualMidiDevice*> >::Reader virtualMidiDevicesReader; |
366 |
|
Mutex virtualMidiDevicesMutex; |
367 |
|
SynchronizedConfig<std::vector<uint8_t> > noteOnVelocityFilter; |
368 |
|
SynchronizedConfig<std::vector<uint8_t> >::Reader noteOnVelocityFilterReader; |
369 |
|
Mutex noteOnVelocityFilterMutex; |
370 |
|
|
371 |
/** |
/** |
372 |
* Constructor |
* Constructor |