204 |
InstrumentEditorProxiesMutex.Unlock(); |
InstrumentEditorProxiesMutex.Unlock(); |
205 |
// launch the instrument editor for the given instrument |
// launch the instrument editor for the given instrument |
206 |
pEditor->Launch(pInstrument, sDataType, sDataVersion); |
pEditor->Launch(pInstrument, sDataType, sDataVersion); |
207 |
|
|
208 |
|
// register the instrument editor as virtual MIDI device as well ... |
209 |
|
VirtualMidiDevice* pVirtualMidiDevice = |
210 |
|
dynamic_cast<VirtualMidiDevice*>(pEditor); |
211 |
|
if (!pVirtualMidiDevice) { |
212 |
|
std::cerr << "Instrument editor not a virtual MIDI device\n" << std::flush; |
213 |
|
return; |
214 |
|
} |
215 |
|
// NOTE: for now connect the virtual MIDI keyboard of the instrument editor (if any) with all engine channels that have the same instrument as the editor was opened for ( other ideas ? ) |
216 |
|
Lock(); |
217 |
|
std::set<gig::EngineChannel*> engineChannels = |
218 |
|
GetEngineChannelsUsing(pInstrument, false/*don't lock again*/); |
219 |
|
std::set<gig::EngineChannel*>::iterator iter = engineChannels.begin(); |
220 |
|
std::set<gig::EngineChannel*>::iterator end = engineChannels.end(); |
221 |
|
for (; iter != end; ++iter) (*iter)->Connect(pVirtualMidiDevice); |
222 |
|
Unlock(); |
223 |
} |
} |
224 |
|
|
225 |
/** |
/** |
231 |
*/ |
*/ |
232 |
void InstrumentResourceManager::OnInstrumentEditorQuit(InstrumentEditor* pSender) { |
void InstrumentResourceManager::OnInstrumentEditorQuit(InstrumentEditor* pSender) { |
233 |
dmsg(1,("InstrumentResourceManager: instrument editor quit, doing cleanup\n")); |
dmsg(1,("InstrumentResourceManager: instrument editor quit, doing cleanup\n")); |
234 |
// hand back instrument and free proxy |
|
235 |
|
::gig::Instrument* pInstrument = NULL; |
236 |
|
InstrumentEditorProxy* pProxy = NULL; |
237 |
|
int iProxyIndex = -1; |
238 |
|
|
239 |
|
// first find the editor proxy entry for this editor |
240 |
InstrumentEditorProxiesMutex.Lock(); |
InstrumentEditorProxiesMutex.Lock(); |
241 |
for (int i = 0; i < InstrumentEditorProxies.size(); i++) { |
for (int i = 0; i < InstrumentEditorProxies.size(); i++) { |
242 |
InstrumentEditorProxy* pProxy = |
InstrumentEditorProxy* pCurProxy = |
243 |
dynamic_cast<InstrumentEditorProxy*>( |
dynamic_cast<InstrumentEditorProxy*>( |
244 |
InstrumentEditorProxies[i] |
InstrumentEditorProxies[i] |
245 |
); |
); |
246 |
if (pProxy->pEditor == pSender) { |
if (pCurProxy->pEditor == pSender) { |
247 |
InstrumentEditorProxies.remove(i); |
pProxy = pCurProxy; |
248 |
InstrumentEditorProxiesMutex.Unlock(); |
iProxyIndex = i; |
249 |
HandBack(pProxy->pInstrument, pProxy); |
pInstrument = pCurProxy->pInstrument; |
|
if (pProxy) delete pProxy; |
|
|
return; |
|
250 |
} |
} |
251 |
} |
} |
252 |
InstrumentEditorProxiesMutex.Unlock(); |
InstrumentEditorProxiesMutex.Unlock(); |
253 |
std::cerr << "Eeeek, could not find instrument editor proxy, this is a bug!\n" << std::flush; |
|
254 |
|
if (!pProxy) { |
255 |
|
std::cerr << "Eeeek, could not find instrument editor proxy, " |
256 |
|
"this is a bug!\n" << std::flush; |
257 |
|
return; |
258 |
|
} |
259 |
|
|
260 |
|
// now unregister editor as not being available as a virtual MIDI device anymore |
261 |
|
VirtualMidiDevice* pVirtualMidiDevice = |
262 |
|
dynamic_cast<VirtualMidiDevice*>(pSender); |
263 |
|
if (pVirtualMidiDevice) { |
264 |
|
Lock(); |
265 |
|
// NOTE: see note in LaunchInstrumentEditor() |
266 |
|
std::set<gig::EngineChannel*> engineChannels = |
267 |
|
GetEngineChannelsUsing(pInstrument, false/*don't lock again*/); |
268 |
|
std::set<gig::EngineChannel*>::iterator iter = engineChannels.begin(); |
269 |
|
std::set<gig::EngineChannel*>::iterator end = engineChannels.end(); |
270 |
|
for (; iter != end; ++iter) (*iter)->Disconnect(pVirtualMidiDevice); |
271 |
|
Unlock(); |
272 |
|
} else { |
273 |
|
std::cerr << "Could not unregister editor as not longer acting as " |
274 |
|
"virtual MIDI device. Wasn't it registered?\n" |
275 |
|
<< std::flush; |
276 |
|
} |
277 |
|
|
278 |
|
// finally delete proxy entry and hand back instrument |
279 |
|
if (pInstrument) { |
280 |
|
InstrumentEditorProxiesMutex.Lock(); |
281 |
|
InstrumentEditorProxies.remove(iProxyIndex); |
282 |
|
InstrumentEditorProxiesMutex.Unlock(); |
283 |
|
|
284 |
|
HandBack(pInstrument, pProxy); |
285 |
|
delete pProxy; |
286 |
|
} |
287 |
|
|
288 |
// Note that we don't need to free the editor here. As it |
// Note that we don't need to free the editor here. As it |
289 |
// derives from Thread, it will delete itself when the thread |
// derives from Thread, it will delete itself when the thread |
306 |
InstrumentEditorProxies[i] |
InstrumentEditorProxies[i] |
307 |
); |
); |
308 |
if (pProxy->pInstrument == pInstrument) |
if (pProxy->pInstrument == pInstrument) |
309 |
pProxy->pEditor->SendNoteOnToEditor(Key, Velocity); |
pProxy->pEditor->SendNoteOnToDevice(Key, Velocity); |
310 |
} |
} |
311 |
InstrumentEditorProxiesMutex.Unlock(); // naively assumes RT safe implementation |
InstrumentEditorProxiesMutex.Unlock(); // naively assumes RT safe implementation |
312 |
} |
} |
327 |
InstrumentEditorProxies[i] |
InstrumentEditorProxies[i] |
328 |
); |
); |
329 |
if (pProxy->pInstrument == pInstrument) |
if (pProxy->pInstrument == pInstrument) |
330 |
pProxy->pEditor->SendNoteOffToEditor(Key, Velocity); |
pProxy->pEditor->SendNoteOffToDevice(Key, Velocity); |
331 |
} |
} |
332 |
InstrumentEditorProxiesMutex.Unlock(); // naively assumes RT safe implementation |
InstrumentEditorProxiesMutex.Unlock(); // naively assumes RT safe implementation |
333 |
} |
} |
690 |
if (bLock) Unlock(); |
if (bLock) Unlock(); |
691 |
return result; |
return result; |
692 |
} |
} |
693 |
|
|
694 |
|
/** |
695 |
|
* Returns a list with all gig engine channels that are currently using |
696 |
|
* the given instrument. |
697 |
|
* |
698 |
|
* @param pInstrument - search criteria |
699 |
|
* @param bLock - whether we should lock (mutex) the instrument manager |
700 |
|
* during this call and unlock at the end of this call |
701 |
|
*/ |
702 |
|
std::set<gig::EngineChannel*> InstrumentResourceManager::GetEngineChannelsUsing(::gig::Instrument* pInstrument, bool bLock) { |
703 |
|
if (bLock) Lock(); |
704 |
|
std::set<gig::EngineChannel*> result; |
705 |
|
std::set<ResourceConsumer< ::gig::Instrument>*> consumers = ConsumersOf(pInstrument); |
706 |
|
std::set<ResourceConsumer< ::gig::Instrument>*>::iterator iter = consumers.begin(); |
707 |
|
std::set<ResourceConsumer< ::gig::Instrument>*>::iterator end = consumers.end(); |
708 |
|
for (; iter != end; ++iter) { |
709 |
|
gig::EngineChannel* pEngineChannel = dynamic_cast<gig::EngineChannel*>(*iter); |
710 |
|
if (!pEngineChannel) continue; |
711 |
|
result.insert(pEngineChannel); |
712 |
|
} |
713 |
|
if (bLock) Unlock(); |
714 |
|
return result; |
715 |
|
} |
716 |
|
|
717 |
/** |
/** |
718 |
* Returns a list with all gig Engines that are currently using the given |
* Returns a list with all gig Engines that are currently using the given |