619 |
} |
} |
620 |
} |
} |
621 |
|
|
622 |
|
void AbstractEngineChannel::SendChannelPressure(uint8_t Value, uint8_t MidiChannel) { |
623 |
|
if (pEngine) { |
624 |
|
// protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel |
625 |
|
LockGuard g; |
626 |
|
if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex); |
627 |
|
|
628 |
|
Event event = pEngine->pEventGenerator->CreateEvent(); |
629 |
|
event.Type = Event::type_channel_pressure; |
630 |
|
event.Param.ChannelPressure.Value = Value; |
631 |
|
event.Param.ChannelPressure.Channel = MidiChannel; |
632 |
|
event.pEngineChannel = this; |
633 |
|
if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event); |
634 |
|
else dmsg(1,("AbstractEngineChannel: Input event queue full!")); |
635 |
|
} |
636 |
|
} |
637 |
|
|
638 |
|
void AbstractEngineChannel::SendChannelPressure(uint8_t Value, uint8_t MidiChannel, int32_t FragmentPos) { |
639 |
|
if (pEngine) { |
640 |
|
// protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel |
641 |
|
LockGuard g; |
642 |
|
if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex); |
643 |
|
|
644 |
|
Event event = pEngine->pEventGenerator->CreateEvent(FragmentPos); |
645 |
|
event.Type = Event::type_channel_pressure; |
646 |
|
event.Param.ChannelPressure.Value = Value; |
647 |
|
event.Param.ChannelPressure.Channel = MidiChannel; |
648 |
|
event.pEngineChannel = this; |
649 |
|
if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event); |
650 |
|
else dmsg(1,("AbstractEngineChannel: Input event queue full!")); |
651 |
|
} |
652 |
|
} |
653 |
|
|
654 |
|
void AbstractEngineChannel::SendPolyphonicKeyPressure(uint8_t Key, uint8_t Value, uint8_t MidiChannel) { |
655 |
|
if (pEngine) { |
656 |
|
// protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel |
657 |
|
LockGuard g; |
658 |
|
if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex); |
659 |
|
|
660 |
|
Event event = pEngine->pEventGenerator->CreateEvent(); |
661 |
|
event.Type = Event::type_note_pressure; |
662 |
|
event.Param.NotePressure.Key = Key; |
663 |
|
event.Param.NotePressure.Value = Value; |
664 |
|
event.Param.NotePressure.Channel = MidiChannel; |
665 |
|
event.pEngineChannel = this; |
666 |
|
if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event); |
667 |
|
else dmsg(1,("AbstractEngineChannel: Input event queue full!")); |
668 |
|
} |
669 |
|
} |
670 |
|
|
671 |
|
void AbstractEngineChannel::SendPolyphonicKeyPressure(uint8_t Key, uint8_t Value, uint8_t MidiChannel, int32_t FragmentPos) { |
672 |
|
if (pEngine) { |
673 |
|
// protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel |
674 |
|
LockGuard g; |
675 |
|
if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex); |
676 |
|
|
677 |
|
Event event = pEngine->pEventGenerator->CreateEvent(FragmentPos); |
678 |
|
event.Type = Event::type_note_pressure; |
679 |
|
event.Param.NotePressure.Key = Key; |
680 |
|
event.Param.NotePressure.Value = Value; |
681 |
|
event.Param.NotePressure.Channel = MidiChannel; |
682 |
|
event.pEngineChannel = this; |
683 |
|
if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event); |
684 |
|
else dmsg(1,("AbstractEngineChannel: Input event queue full!")); |
685 |
|
} |
686 |
|
} |
687 |
|
|
688 |
/** |
/** |
689 |
* Copy all events from the engine channel's input event queue buffer to |
* Copy all events from the engine channel's input event queue buffer to |
690 |
* the internal event list. This will be done at the beginning of each |
* the internal event list. This will be done at the beginning of each |
729 |
event.Param.Note.Channel = channel; |
event.Param.Note.Channel = channel; |
730 |
break; |
break; |
731 |
case VirtualMidiDevice::EVENT_TYPE_CC: |
case VirtualMidiDevice::EVENT_TYPE_CC: |
732 |
event.Type = Event::type_control_change; |
switch (devEvent.Arg1) { |
733 |
event.Param.CC.Controller = devEvent.Arg1; |
case 0: // bank select MSB ... |
734 |
event.Param.CC.Value = devEvent.Arg2; |
SetMidiBankMsb(devEvent.Arg2); |
735 |
event.Param.CC.Channel = channel; |
continue; // don't push this event into FIFO |
736 |
|
case 32: // bank select LSB ... |
737 |
|
SetMidiBankLsb(devEvent.Arg2); |
738 |
|
continue; // don't push this event into FIFO |
739 |
|
default: // regular MIDI CC ... |
740 |
|
event.Type = Event::type_control_change; |
741 |
|
event.Param.CC.Controller = devEvent.Arg1; |
742 |
|
event.Param.CC.Value = devEvent.Arg2; |
743 |
|
event.Param.CC.Channel = channel; |
744 |
|
} |
745 |
|
break; |
746 |
|
case VirtualMidiDevice::EVENT_TYPE_PITCHBEND: |
747 |
|
event.Type = Event::type_pitchbend; |
748 |
|
event.Param.Pitch.Pitch = int(devEvent.Arg2 << 7 | devEvent.Arg1) - 8192; |
749 |
|
event.Param.Pitch.Channel = channel; |
750 |
break; |
break; |
751 |
|
case VirtualMidiDevice::EVENT_TYPE_PROGRAM: |
752 |
|
SendProgramChange(devEvent.Arg1); |
753 |
|
continue; // don't push this event into FIFO |
754 |
default: |
default: |
755 |
std::cerr << "AbstractEngineChannel::ImportEvents() ERROR: unknown event type (" |
std::cerr << "AbstractEngineChannel::ImportEvents() ERROR: unknown event type (" |
756 |
<< devEvent.Type << "). This is a bug!"; |
<< devEvent.Type << "). This is a bug!"; |