24 |
#include "MidiInputPort.h" |
#include "MidiInputPort.h" |
25 |
|
|
26 |
#include "../../Sampler.h" |
#include "../../Sampler.h" |
27 |
|
#include "../../engines/EngineFactory.h" |
28 |
|
|
29 |
namespace LinuxSampler { |
namespace LinuxSampler { |
30 |
|
|
63 |
MidiInputPort::~MidiInputPort() { |
MidiInputPort::~MidiInputPort() { |
64 |
std::map<String,DeviceRuntimeParameter*>::iterator iter = Parameters.begin(); |
std::map<String,DeviceRuntimeParameter*>::iterator iter = Parameters.begin(); |
65 |
while (iter != Parameters.end()) { |
while (iter != Parameters.end()) { |
|
Parameters.erase(iter); |
|
66 |
delete iter->second; |
delete iter->second; |
67 |
iter++; |
iter++; |
68 |
} |
} |
69 |
|
Parameters.clear(); |
70 |
} |
} |
71 |
|
|
72 |
MidiInputPort::MidiInputPort(MidiInputDevice* pDevice, int portNumber) { |
MidiInputPort::MidiInputPort(MidiInputDevice* pDevice, int portNumber) { |
89 |
} |
} |
90 |
|
|
91 |
void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel) { |
void MidiInputPort::DispatchNoteOn(uint8_t Key, uint8_t Velocity, uint MidiChannel) { |
92 |
|
const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock(); |
93 |
// dispatch event for engines listening to the same MIDI channel |
// dispatch event for engines listening to the same MIDI channel |
94 |
{ |
{ |
95 |
std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin(); |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin(); |
96 |
std::set<EngineChannel*>::iterator end = MidiChannelMap[MidiChannel].end(); |
std::set<EngineChannel*>::iterator end = midiChannelMap[MidiChannel].end(); |
97 |
for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity); |
for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity); |
98 |
} |
} |
99 |
// dispatch event for engines listening to ALL MIDI channels |
// dispatch event for engines listening to ALL MIDI channels |
100 |
{ |
{ |
101 |
std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin(); |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin(); |
102 |
std::set<EngineChannel*>::iterator end = MidiChannelMap[midi_chan_all].end(); |
std::set<EngineChannel*>::iterator end = midiChannelMap[midi_chan_all].end(); |
103 |
for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity); |
for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOn(Key, Velocity); |
104 |
} |
} |
105 |
|
MidiChannelMap.Unlock(); |
106 |
} |
} |
107 |
|
|
108 |
void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel) { |
void MidiInputPort::DispatchNoteOff(uint8_t Key, uint8_t Velocity, uint MidiChannel) { |
109 |
|
const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock(); |
110 |
// dispatch event for engines listening to the same MIDI channel |
// dispatch event for engines listening to the same MIDI channel |
111 |
{ |
{ |
112 |
std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin(); |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin(); |
113 |
std::set<EngineChannel*>::iterator end = MidiChannelMap[MidiChannel].end(); |
std::set<EngineChannel*>::iterator end = midiChannelMap[MidiChannel].end(); |
114 |
for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity); |
for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity); |
115 |
} |
} |
116 |
// dispatch event for engines listening to ALL MIDI channels |
// dispatch event for engines listening to ALL MIDI channels |
117 |
{ |
{ |
118 |
std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin(); |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin(); |
119 |
std::set<EngineChannel*>::iterator end = MidiChannelMap[midi_chan_all].end(); |
std::set<EngineChannel*>::iterator end = midiChannelMap[midi_chan_all].end(); |
120 |
for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity); |
for (; engineiter != end; engineiter++) (*engineiter)->SendNoteOff(Key, Velocity); |
121 |
} |
} |
122 |
|
MidiChannelMap.Unlock(); |
123 |
} |
} |
124 |
|
|
125 |
void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel) { |
void MidiInputPort::DispatchPitchbend(int Pitch, uint MidiChannel) { |
126 |
|
const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock(); |
127 |
// dispatch event for engines listening to the same MIDI channel |
// dispatch event for engines listening to the same MIDI channel |
128 |
{ |
{ |
129 |
std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin(); |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin(); |
130 |
std::set<EngineChannel*>::iterator end = MidiChannelMap[MidiChannel].end(); |
std::set<EngineChannel*>::iterator end = midiChannelMap[MidiChannel].end(); |
131 |
for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch); |
for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch); |
132 |
} |
} |
133 |
// dispatch event for engines listening to ALL MIDI channels |
// dispatch event for engines listening to ALL MIDI channels |
134 |
{ |
{ |
135 |
std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin(); |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin(); |
136 |
std::set<EngineChannel*>::iterator end = MidiChannelMap[midi_chan_all].end(); |
std::set<EngineChannel*>::iterator end = midiChannelMap[midi_chan_all].end(); |
137 |
for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch); |
for (; engineiter != end; engineiter++) (*engineiter)->SendPitchbend(Pitch); |
138 |
} |
} |
139 |
|
MidiChannelMap.Unlock(); |
140 |
} |
} |
141 |
|
|
142 |
void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel) { |
void MidiInputPort::DispatchControlChange(uint8_t Controller, uint8_t Value, uint MidiChannel) { |
143 |
|
const MidiChannelMap_t& midiChannelMap = MidiChannelMap.Lock(); |
144 |
// dispatch event for engines listening to the same MIDI channel |
// dispatch event for engines listening to the same MIDI channel |
145 |
{ |
{ |
146 |
std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin(); |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[MidiChannel].begin(); |
147 |
std::set<EngineChannel*>::iterator end = MidiChannelMap[MidiChannel].end(); |
std::set<EngineChannel*>::iterator end = midiChannelMap[MidiChannel].end(); |
148 |
for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value); |
for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value); |
149 |
} |
} |
150 |
// dispatch event for engines listening to ALL MIDI channels |
// dispatch event for engines listening to ALL MIDI channels |
151 |
{ |
{ |
152 |
std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin(); |
std::set<EngineChannel*>::iterator engineiter = midiChannelMap[midi_chan_all].begin(); |
153 |
std::set<EngineChannel*>::iterator end = MidiChannelMap[midi_chan_all].end(); |
std::set<EngineChannel*>::iterator end = midiChannelMap[midi_chan_all].end(); |
154 |
for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value); |
for (; engineiter != end; engineiter++) (*engineiter)->SendControlChange(Controller, Value); |
155 |
} |
} |
156 |
|
MidiChannelMap.Unlock(); |
157 |
} |
} |
158 |
|
|
159 |
void MidiInputPort::DispatchSysex(void* pData, uint Size) { |
void MidiInputPort::DispatchSysex(void* pData, uint Size) { |
160 |
// dispatch event for engines listening to the same MIDI channel |
// dispatch event to all engine instances |
161 |
{ |
std::set<Engine*>::iterator engineiter = EngineFactory::EngineInstances().begin(); |
162 |
for (uint MidiChannel = 0; MidiChannel <= 16; MidiChannel++) { |
std::set<Engine*>::iterator end = EngineFactory::EngineInstances().end(); |
163 |
std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[MidiChannel].begin(); |
for (; engineiter != end; engineiter++) (*engineiter)->SendSysex(pData, Size); |
|
std::set<EngineChannel*>::iterator end = MidiChannelMap[MidiChannel].end(); |
|
|
for (; engineiter != end; engineiter++) { |
|
|
Engine* pEngine = (*engineiter)->GetEngine(); |
|
|
if (pEngine) pEngine->SendSysex(pData, Size); |
|
|
} |
|
|
} |
|
|
} |
|
|
// dispatch event for engines listening to ALL MIDI channels |
|
|
{ |
|
|
for (uint MidiChannel = 0; MidiChannel <= 16; MidiChannel++) { |
|
|
std::set<EngineChannel*>::iterator engineiter = MidiChannelMap[midi_chan_all].begin(); |
|
|
std::set<EngineChannel*>::iterator end = MidiChannelMap[midi_chan_all].end(); |
|
|
for (; engineiter != end; engineiter++) { |
|
|
Engine* pEngine = (*engineiter)->GetEngine(); |
|
|
if (pEngine) pEngine->SendSysex(pData, Size); |
|
|
} |
|
|
} |
|
|
} |
|
164 |
} |
} |
165 |
|
|
166 |
void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) { |
void MidiInputPort::DispatchProgramChange(uint8_t Program, uint MidiChannel) { |
193 |
if (MidiChannel < 0 || MidiChannel > 16) |
if (MidiChannel < 0 || MidiChannel > 16) |
194 |
throw MidiInputException("MIDI channel index out of bounds"); |
throw MidiInputException("MIDI channel index out of bounds"); |
195 |
|
|
196 |
// firt check if desired connection is already established |
// first check if desired connection is already established |
197 |
MidiChannelMapMutex.Lock(); |
MidiChannelMapMutex.Lock(); |
198 |
bool bAlreadyDone = MidiChannelMap[MidiChannel].count(pEngineChannel); |
MidiChannelMap_t& midiChannelMap = MidiChannelMap.GetConfigForUpdate(); |
199 |
|
bool bAlreadyDone = midiChannelMap[MidiChannel].count(pEngineChannel); |
200 |
MidiChannelMapMutex.Unlock(); |
MidiChannelMapMutex.Unlock(); |
201 |
if (bAlreadyDone) return; |
if (bAlreadyDone) return; |
202 |
|
|
205 |
|
|
206 |
// register engine channel on the desired MIDI channel |
// register engine channel on the desired MIDI channel |
207 |
MidiChannelMapMutex.Lock(); |
MidiChannelMapMutex.Lock(); |
208 |
MidiChannelMap[MidiChannel].insert(pEngineChannel); |
MidiChannelMap.GetConfigForUpdate()[MidiChannel].insert(pEngineChannel); |
209 |
|
MidiChannelMap.SwitchConfig()[MidiChannel].insert(pEngineChannel); |
210 |
MidiChannelMapMutex.Unlock(); |
MidiChannelMapMutex.Unlock(); |
211 |
|
|
212 |
// inform engine channel about this connection |
// inform engine channel about this connection |
224 |
// unregister engine channel from all MIDI channels |
// unregister engine channel from all MIDI channels |
225 |
MidiChannelMapMutex.Lock(); |
MidiChannelMapMutex.Lock(); |
226 |
try { |
try { |
227 |
for (int i = 0; i <= 16; i++) { |
{ |
228 |
bChannelFound |= MidiChannelMap[i].count(pEngineChannel); |
MidiChannelMap_t& midiChannelMap = MidiChannelMap.GetConfigForUpdate(); |
229 |
MidiChannelMap[i].erase(pEngineChannel); |
for (int i = 0; i <= 16; i++) { |
230 |
|
bChannelFound |= midiChannelMap[i].count(pEngineChannel); |
231 |
|
midiChannelMap[i].erase(pEngineChannel); |
232 |
|
} |
233 |
|
} |
234 |
|
// do the same update again, after switching to the other config |
235 |
|
{ |
236 |
|
MidiChannelMap_t& midiChannelMap = MidiChannelMap.SwitchConfig(); |
237 |
|
for (int i = 0; i <= 16; i++) { |
238 |
|
bChannelFound |= midiChannelMap[i].count(pEngineChannel); |
239 |
|
midiChannelMap[i].erase(pEngineChannel); |
240 |
|
} |
241 |
} |
} |
242 |
} |
} |
243 |
catch(...) { /* NOOP */ } |
catch(...) { /* NOOP */ } |