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 |
|
typedef std::map<uint, RTList<Event>*> map_t; |
672 |
|
|
673 |
|
std::pair<map_t::iterator, bool> p = |
674 |
|
ActiveKeyGroups.insert(map_t::value_type(group, 0)); |
675 |
|
if (p.second) { |
676 |
|
(*p.first).second = new RTList<Event>(pEngine->pEventPool); |
677 |
|
} |
678 |
|
} |
679 |
|
} |
680 |
|
|
681 |
|
/** |
682 |
|
* Handle key group (a.k.a. exclusive group) conflicts. |
683 |
|
*/ |
684 |
|
void AbstractEngineChannel::HandleKeyGroupConflicts(uint KeyGroup, Pool<Event>::Iterator& itNoteOnEvent) { |
685 |
|
dmsg(4,("HandelKeyGroupConflicts KeyGroup=%d\n", KeyGroup)); |
686 |
|
if (KeyGroup) { |
687 |
|
// send a release event to all active voices in the group |
688 |
|
RTList<Event>::Iterator itEvent = ActiveKeyGroups[KeyGroup]->allocAppend(); |
689 |
|
*itEvent = *itNoteOnEvent; |
690 |
|
} |
691 |
|
} |
692 |
|
|
693 |
|
/** |
694 |
|
* Empty the lists of group events. Should be called from the |
695 |
|
* audio thread, after all voices have been rendered. |
696 |
|
*/ |
697 |
|
void AbstractEngineChannel::ClearGroupEventLists() { |
698 |
|
for (std::map<uint,RTList<Event>*>::iterator iter = ActiveKeyGroups.begin(); |
699 |
|
iter != ActiveKeyGroups.end(); iter++) { |
700 |
|
if (iter->second) { |
701 |
|
iter->second->clear(); |
702 |
|
} else { |
703 |
|
dmsg(1,("EngineChannel: group event list was NULL")); |
704 |
|
} |
705 |
|
} |
706 |
|
} |
707 |
|
|
708 |
|
/** |
709 |
|
* Remove all lists with group events. |
710 |
|
*/ |
711 |
|
void AbstractEngineChannel::DeleteGroupEventLists() { |
712 |
|
for (std::map<uint,RTList<Event>*>::iterator iter = ActiveKeyGroups.begin(); |
713 |
|
iter != ActiveKeyGroups.end(); iter++) { |
714 |
|
delete iter->second; |
715 |
|
} |
716 |
|
ActiveKeyGroups.clear(); |
717 |
|
} |
718 |
|
|
719 |
} // namespace LinuxSampler |
} // namespace LinuxSampler |