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-2009 Christian Schoenebeck * |
* Copyright (C) 2005-2008 Christian Schoenebeck * |
7 |
* Copyright (C) 2009 Grigor Iliev * |
* Copyright (C) 2009-2010 Christian Schoenebeck and Grigor Iliev * |
8 |
* * |
* * |
9 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
10 |
* 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 * |
49 |
} |
} |
50 |
|
|
51 |
AbstractEngineChannel::~AbstractEngineChannel() { |
AbstractEngineChannel::~AbstractEngineChannel() { |
52 |
|
delete pEventQueue; |
53 |
if (pEventQueue) delete pEventQueue; |
DeleteGroupEventLists(); |
54 |
RemoveAllFxSends(); |
RemoveAllFxSends(); |
55 |
} |
} |
56 |
|
|
522 |
VirtualMidiDevice* pDev = devices[i]; |
VirtualMidiDevice* pDev = devices[i]; |
523 |
// I think we can simply flush the whole FIFO(s), the user shouldn't be so fast ;-) |
// I think we can simply flush the whole FIFO(s), the user shouldn't be so fast ;-) |
524 |
while (pDev->GetMidiEventFromDevice(devEvent)) { |
while (pDev->GetMidiEventFromDevice(devEvent)) { |
525 |
event.Type = |
switch (devEvent.Type) { |
526 |
(devEvent.Type == VirtualMidiDevice::EVENT_TYPE_NOTEON) ? |
case VirtualMidiDevice::EVENT_TYPE_NOTEON: |
527 |
Event::type_note_on : Event::type_note_off; |
event.Type = Event::type_note_on; |
528 |
event.Param.Note.Key = devEvent.Key; |
event.Param.Note.Key = devEvent.Arg1; |
529 |
event.Param.Note.Velocity = devEvent.Velocity; |
event.Param.Note.Velocity = devEvent.Arg2; |
530 |
event.pEngineChannel = this; |
break; |
531 |
|
case VirtualMidiDevice::EVENT_TYPE_NOTEOFF: |
532 |
|
event.Type = Event::type_note_off; |
533 |
|
event.Param.Note.Key = devEvent.Arg1; |
534 |
|
event.Param.Note.Velocity = devEvent.Arg2; |
535 |
|
break; |
536 |
|
case VirtualMidiDevice::EVENT_TYPE_CC: |
537 |
|
event.Type = Event::type_control_change; |
538 |
|
event.Param.CC.Controller = devEvent.Arg1; |
539 |
|
event.Param.CC.Value = devEvent.Arg2; |
540 |
|
break; |
541 |
|
default: |
542 |
|
std::cerr << "AbstractEngineChannel::ImportEvents() ERROR: unknown event type (" |
543 |
|
<< devEvent.Type << "). This is a bug!"; |
544 |
|
continue; |
545 |
|
} |
546 |
|
event.pEngineChannel = this; |
547 |
// copy event to internal event list |
// copy event to internal event list |
548 |
if (pEvents->poolIsEmpty()) { |
if (pEvents->poolIsEmpty()) { |
549 |
dmsg(1,("Event pool emtpy!\n")); |
dmsg(1,("Event pool emtpy!\n")); |
661 |
if (pEngine) pEngine->Enable(); |
if (pEngine) pEngine->Enable(); |
662 |
} |
} |
663 |
|
|
664 |
|
/** |
665 |
|
* Add a group number to the set of key groups. Should be called |
666 |
|
* when an instrument is loaded to make sure there are event lists |
667 |
|
* for all key groups. |
668 |
|
*/ |
669 |
|
void AbstractEngineChannel::AddGroup(uint group) { |
670 |
|
if (group) { |
671 |
|
std::pair<ActiveKeyGroupMap::iterator, bool> p = |
672 |
|
ActiveKeyGroups.insert(ActiveKeyGroupMap::value_type(group, 0)); |
673 |
|
if (p.second) { |
674 |
|
// If the engine channel is pending deletion (see bug |
675 |
|
// #113), pEngine will be null, so we can't use |
676 |
|
// pEngine->pEventPool here. Instead we're using a |
677 |
|
// specialized RTList that allows specifying the pool |
678 |
|
// later. |
679 |
|
(*p.first).second = new LazyList<Event>; |
680 |
|
} |
681 |
|
} |
682 |
|
} |
683 |
|
|
684 |
|
/** |
685 |
|
* Handle key group (a.k.a. exclusive group) conflicts. |
686 |
|
*/ |
687 |
|
void AbstractEngineChannel::HandleKeyGroupConflicts(uint KeyGroup, Pool<Event>::Iterator& itNoteOnEvent) { |
688 |
|
dmsg(4,("HandelKeyGroupConflicts KeyGroup=%d\n", KeyGroup)); |
689 |
|
if (KeyGroup) { |
690 |
|
// send a release event to all active voices in the group |
691 |
|
RTList<Event>::Iterator itEvent = ActiveKeyGroups[KeyGroup]->allocAppend(pEngine->pEventPool); |
692 |
|
*itEvent = *itNoteOnEvent; |
693 |
|
} |
694 |
|
} |
695 |
|
|
696 |
|
/** |
697 |
|
* Empty the lists of group events. Should be called from the |
698 |
|
* audio thread, after all voices have been rendered. |
699 |
|
*/ |
700 |
|
void AbstractEngineChannel::ClearGroupEventLists() { |
701 |
|
for (ActiveKeyGroupMap::iterator iter = ActiveKeyGroups.begin(); |
702 |
|
iter != ActiveKeyGroups.end(); iter++) { |
703 |
|
if (iter->second) { |
704 |
|
iter->second->clear(); |
705 |
|
} else { |
706 |
|
dmsg(1,("EngineChannel: group event list was NULL")); |
707 |
|
} |
708 |
|
} |
709 |
|
} |
710 |
|
|
711 |
|
/** |
712 |
|
* Remove all lists with group events. |
713 |
|
*/ |
714 |
|
void AbstractEngineChannel::DeleteGroupEventLists() { |
715 |
|
for (ActiveKeyGroupMap::iterator iter = ActiveKeyGroups.begin(); |
716 |
|
iter != ActiveKeyGroups.end(); iter++) { |
717 |
|
delete iter->second; |
718 |
|
} |
719 |
|
ActiveKeyGroups.clear(); |
720 |
|
} |
721 |
|
|
722 |
} // namespace LinuxSampler |
} // namespace LinuxSampler |