/[svn]/linuxsampler/trunk/src/engines/AbstractEngineChannel.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/AbstractEngineChannel.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2382 by persson, Sun Dec 2 16:30:42 2012 UTC revision 2612 by schoenebeck, Tue Jun 10 13:32:16 2014 UTC
# Line 5  Line 5 
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-2008 Christian Schoenebeck                         *   *   Copyright (C) 2005-2008 Christian Schoenebeck                         *
7   *   Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev        *   *   Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev        *
8     *   Copyright (C) 2013-2014 Christian Schoenebeck and Andreas Persson     *
9   *                                                                         *   *                                                                         *
10   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
11   *   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  *
# Line 41  namespace LinuxSampler { Line 42  namespace LinuxSampler {
42          pChannelRight = NULL;          pChannelRight = NULL;
43          AudioDeviceChannelLeft  = -1;          AudioDeviceChannelLeft  = -1;
44          AudioDeviceChannelRight = -1;          AudioDeviceChannelRight = -1;
         pMidiInputPort = NULL;  
45          midiChannel = midi_chan_all;          midiChannel = midi_chan_all;
46          ResetControllers();          ResetControllers();
47          PortamentoMode = false;          PortamentoMode = false;
48          PortamentoTime = CONFIG_PORTAMENTO_TIME_DEFAULT;          PortamentoTime = CONFIG_PORTAMENTO_TIME_DEFAULT;
49            pScript = NULL;
50      }      }
51    
52      AbstractEngineChannel::~AbstractEngineChannel() {      AbstractEngineChannel::~AbstractEngineChannel() {
53            if (pScript) pScript->resetAll(); // unloads script (in case one is loaded)
54          delete pEventQueue;          delete pEventQueue;
55          DeleteGroupEventLists();          DeleteGroupEventLists();
56          RemoveAllFxSends();          RemoveAllFxSends();
# Line 192  namespace LinuxSampler { Line 194  namespace LinuxSampler {
194       * device from other threads than the lscp thread.       * device from other threads than the lscp thread.
195       */       */
196      AudioOutputDevice* AbstractEngineChannel::GetAudioOutputDeviceSafe() {      AudioOutputDevice* AbstractEngineChannel::GetAudioOutputDeviceSafe() {
197          EngineMutex.Lock();          LockGuard lock(EngineMutex);
198          AudioOutputDevice* res = GetAudioOutputDevice();          return GetAudioOutputDevice();
         EngineMutex.Unlock();  
         return res;  
199      }      }
200    
201      void AbstractEngineChannel::SetOutputChannel(uint EngineAudioChannel, uint AudioDeviceChannel) {      void AbstractEngineChannel::SetOutputChannel(uint EngineAudioChannel, uint AudioDeviceChannel) {
# Line 230  namespace LinuxSampler { Line 230  namespace LinuxSampler {
230          }          }
231      }      }
232    
233        void AbstractEngineChannel::Connect(MidiInputPort* pMidiPort) {
234            if (!pMidiPort) return;
235    
236            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
237    
238            // check if connection already exists
239            for (int i = 0; i < connections->size(); ++i)
240                if ((*connections)[i] == pMidiPort)
241                    return; // to avoid endless recursion
242    
243            connections->add(pMidiPort);
244    
245            // inform MIDI port about this new connection
246            pMidiPort->Connect(this, MidiChannel());
247        }
248    
249        void AbstractEngineChannel::Disconnect(MidiInputPort* pMidiPort) {
250            if (!pMidiPort) return;
251    
252            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
253    
254            for (int i = 0; i < connections->size(); ++i) {
255                if ((*connections)[i] == pMidiPort) {
256                    connections->remove(i);
257                    // inform MIDI port about this disconnection
258                    pMidiPort->Disconnect(this);
259                    return;
260                }
261            }
262        }
263    
264        void AbstractEngineChannel::DisconnectAllMidiInputPorts() {
265            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
266            ArrayList<MidiInputPort*> clonedList = *connections;
267            connections->clear();
268            for (int i = 0; i < clonedList.size(); ++i) clonedList[i]->Disconnect(this);
269        }
270    
271        uint AbstractEngineChannel::GetMidiInputPortCount() {
272            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
273            return connections->size();
274        }
275    
276        MidiInputPort* AbstractEngineChannel::GetMidiInputPort(uint index) {
277            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
278            return (index < connections->size()) ? (*connections)[index] : NULL;
279        }
280    
281        // deprecated (just for API backward compatibility) - may be removed in future
282      void AbstractEngineChannel::Connect(MidiInputPort* pMidiPort, midi_chan_t MidiChannel) {      void AbstractEngineChannel::Connect(MidiInputPort* pMidiPort, midi_chan_t MidiChannel) {
283          if (!pMidiPort || pMidiPort == this->pMidiInputPort) return;          if (!pMidiPort) return;
284          DisconnectMidiInputPort();  
285          this->pMidiInputPort = pMidiPort;          Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
286          this->midiChannel    = MidiChannel;  
287            // check against endless recursion
288            if (connections->size() == 1 && (*connections)[0] == pMidiPort && this->midiChannel == MidiChannel)
289                return;
290            
291            if (!isValidMidiChan(MidiChannel))
292                throw MidiInputException("Invalid MIDI channel (" + ToString(int(MidiChannel)) + ")");
293    
294            this->midiChannel = MidiChannel;
295    
296            // disconnect all currently connected MIDI ports
297            ArrayList<MidiInputPort*> clonedList = *connections;
298            connections->clear();
299            for (int i = 0; i < clonedList.size(); ++i)
300                clonedList[i]->Disconnect(this);
301    
302            // connect the new port
303            connections->add(pMidiPort);
304          pMidiPort->Connect(this, MidiChannel);          pMidiPort->Connect(this, MidiChannel);
305      }      }
306    
307        // deprecated (just for API backward compatibility) - may be removed in future
308      void AbstractEngineChannel::DisconnectMidiInputPort() {      void AbstractEngineChannel::DisconnectMidiInputPort() {
309          MidiInputPort* pOldPort = this->pMidiInputPort;          DisconnectAllMidiInputPorts();
         this->pMidiInputPort = NULL;  
         if (pOldPort) pOldPort->Disconnect(this);  
310      }      }
311    
312        // deprecated (just for API backward compatibility) - may be removed in future
313      MidiInputPort* AbstractEngineChannel::GetMidiInputPort() {      MidiInputPort* AbstractEngineChannel::GetMidiInputPort() {
314          return pMidiInputPort;          return GetMidiInputPort(0);
315      }      }
316    
317      midi_chan_t AbstractEngineChannel::MidiChannel() {      midi_chan_t AbstractEngineChannel::MidiChannel() {
318          return midiChannel;          return midiChannel;
319      }      }
320    
321        void AbstractEngineChannel::SetMidiChannel(midi_chan_t MidiChannel) {
322            if (this->midiChannel == MidiChannel) return;
323            if (!isValidMidiChan(MidiChannel))
324                throw MidiInputException("Invalid MIDI channel (" + ToString(int(MidiChannel)) + ")");
325    
326            this->midiChannel = MidiChannel;
327            
328            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
329            ArrayList<MidiInputPort*> clonedList = *connections;
330    
331            DisconnectAllMidiInputPorts();
332    
333            for (int i = 0; i < clonedList.size(); ++i) Connect(clonedList[i]);
334        }
335    
336      void AbstractEngineChannel::Connect(VirtualMidiDevice* pDevice) {      void AbstractEngineChannel::Connect(VirtualMidiDevice* pDevice) {
337          // double buffer ... double work ...          // double buffer ... double work ...
338          {          {
# Line 287  namespace LinuxSampler { Line 368  namespace LinuxSampler {
368       */       */
369      void AbstractEngineChannel::SendNoteOn(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {      void AbstractEngineChannel::SendNoteOn(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {
370          if (pEngine) {          if (pEngine) {
371                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
372                LockGuard g;
373                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
374    
375              Event event               = pEngine->pEventGenerator->CreateEvent();              Event event               = pEngine->pEventGenerator->CreateEvent();
376              event.Type                = Event::type_note_on;              event.Type                = Event::type_note_on;
377              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
378              event.Param.Note.Velocity = Velocity;              event.Param.Note.Velocity = Velocity;
379              event.Param.Note.Channel  = MidiChannel;              event.Param.Note.Channel  = MidiChannel;
380                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
381              event.pEngineChannel      = this;              event.pEngineChannel      = this;
382              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
383              else dmsg(1,("EngineChannel: Input event queue full!"));              else dmsg(1,("EngineChannel: Input event queue full!"));
# Line 324  namespace LinuxSampler { Line 410  namespace LinuxSampler {
410              dmsg(1,("EngineChannel::SendNoteOn(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("EngineChannel::SendNoteOn(): negative FragmentPos! Seems MIDI driver is buggy!"));
411          }          }
412          else if (pEngine) {          else if (pEngine) {
413                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
414                LockGuard g;
415                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
416    
417              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);
418              event.Type                = Event::type_note_on;              event.Type                = Event::type_note_on;
419              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
420              event.Param.Note.Velocity = Velocity;              event.Param.Note.Velocity = Velocity;
421              event.Param.Note.Channel  = MidiChannel;              event.Param.Note.Channel  = MidiChannel;
422                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
423              event.pEngineChannel      = this;              event.pEngineChannel      = this;
424              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
425              else dmsg(1,("EngineChannel: Input event queue full!"));              else dmsg(1,("EngineChannel: Input event queue full!"));
# Line 356  namespace LinuxSampler { Line 447  namespace LinuxSampler {
447       */       */
448      void AbstractEngineChannel::SendNoteOff(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {      void AbstractEngineChannel::SendNoteOff(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {
449          if (pEngine) {          if (pEngine) {
450                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
451                LockGuard g;
452                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
453    
454              Event event               = pEngine->pEventGenerator->CreateEvent();              Event event               = pEngine->pEventGenerator->CreateEvent();
455              event.Type                = Event::type_note_off;              event.Type                = Event::type_note_off;
456              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
457              event.Param.Note.Velocity = Velocity;              event.Param.Note.Velocity = Velocity;
458              event.Param.Note.Channel  = MidiChannel;              event.Param.Note.Channel  = MidiChannel;
459                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
460              event.pEngineChannel      = this;              event.pEngineChannel      = this;
461              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
462              else dmsg(1,("EngineChannel: Input event queue full!"));              else dmsg(1,("EngineChannel: Input event queue full!"));
# Line 393  namespace LinuxSampler { Line 489  namespace LinuxSampler {
489              dmsg(1,("EngineChannel::SendNoteOff(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("EngineChannel::SendNoteOff(): negative FragmentPos! Seems MIDI driver is buggy!"));
490          }          }
491          else if (pEngine) {          else if (pEngine) {
492                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
493                LockGuard g;
494                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
495    
496              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);
497              event.Type                = Event::type_note_off;              event.Type                = Event::type_note_off;
498              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
499              event.Param.Note.Velocity = Velocity;              event.Param.Note.Velocity = Velocity;
500              event.Param.Note.Channel  = MidiChannel;              event.Param.Note.Channel  = MidiChannel;
501                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
502              event.pEngineChannel      = this;              event.pEngineChannel      = this;
503              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
504              else dmsg(1,("EngineChannel: Input event queue full!"));              else dmsg(1,("EngineChannel: Input event queue full!"));
# Line 424  namespace LinuxSampler { Line 525  namespace LinuxSampler {
525       */       */
526      void AbstractEngineChannel::SendPitchbend(int Pitch, uint8_t MidiChannel) {      void AbstractEngineChannel::SendPitchbend(int Pitch, uint8_t MidiChannel) {
527          if (pEngine) {          if (pEngine) {
528                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
529                LockGuard g;
530                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
531    
532              Event event             = pEngine->pEventGenerator->CreateEvent();              Event event             = pEngine->pEventGenerator->CreateEvent();
533              event.Type              = Event::type_pitchbend;              event.Type              = Event::type_pitchbend;
534              event.Param.Pitch.Pitch = Pitch;              event.Param.Pitch.Pitch = Pitch;
535              event.Param.Pitch.Channel = MidiChannel;              event.Param.Pitch.Channel = MidiChannel;
536                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
537              event.pEngineChannel    = this;              event.pEngineChannel    = this;
538              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
539              else dmsg(1,("EngineChannel: Input event queue full!"));              else dmsg(1,("EngineChannel: Input event queue full!"));
# Line 449  namespace LinuxSampler { Line 555  namespace LinuxSampler {
555              dmsg(1,("AbstractEngineChannel::SendPitchBend(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("AbstractEngineChannel::SendPitchBend(): negative FragmentPos! Seems MIDI driver is buggy!"));
556          }          }
557          else if (pEngine) {          else if (pEngine) {
558                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
559                LockGuard g;
560                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
561    
562              Event event             = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event             = pEngine->pEventGenerator->CreateEvent(FragmentPos);
563              event.Type              = Event::type_pitchbend;              event.Type              = Event::type_pitchbend;
564              event.Param.Pitch.Pitch = Pitch;              event.Param.Pitch.Pitch = Pitch;
565              event.Param.Pitch.Channel = MidiChannel;              event.Param.Pitch.Channel = MidiChannel;
566                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
567              event.pEngineChannel    = this;              event.pEngineChannel    = this;
568              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
569              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
# Line 470  namespace LinuxSampler { Line 581  namespace LinuxSampler {
581       */       */
582      void AbstractEngineChannel::SendControlChange(uint8_t Controller, uint8_t Value, uint8_t MidiChannel) {      void AbstractEngineChannel::SendControlChange(uint8_t Controller, uint8_t Value, uint8_t MidiChannel) {
583          if (pEngine) {          if (pEngine) {
584                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
585                LockGuard g;
586                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
587    
588              Event event               = pEngine->pEventGenerator->CreateEvent();              Event event               = pEngine->pEventGenerator->CreateEvent();
589              event.Type                = Event::type_control_change;              event.Type                = Event::type_control_change;
590              event.Param.CC.Controller = Controller;              event.Param.CC.Controller = Controller;
591              event.Param.CC.Value      = Value;              event.Param.CC.Value      = Value;
592              event.Param.CC.Channel    = MidiChannel;              event.Param.CC.Channel    = MidiChannel;
593                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
594              event.pEngineChannel      = this;              event.pEngineChannel      = this;
595              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
596              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
# Line 497  namespace LinuxSampler { Line 613  namespace LinuxSampler {
613              dmsg(1,("AbstractEngineChannel::SendControlChange(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("AbstractEngineChannel::SendControlChange(): negative FragmentPos! Seems MIDI driver is buggy!"));
614          }          }
615          else if (pEngine) {          else if (pEngine) {
616                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
617                LockGuard g;
618                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
619    
620              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);
621              event.Type                = Event::type_control_change;              event.Type                = Event::type_control_change;
622              event.Param.CC.Controller = Controller;              event.Param.CC.Controller = Controller;
623              event.Param.CC.Value      = Value;              event.Param.CC.Value      = Value;
624              event.Param.CC.Channel    = MidiChannel;              event.Param.CC.Channel    = MidiChannel;
625                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
626              event.pEngineChannel      = this;              event.pEngineChannel      = this;
627              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
628              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
629          }          }
630      }      }
631    
632        void AbstractEngineChannel::SendChannelPressure(uint8_t Value, uint8_t MidiChannel) {
633            if (pEngine) {
634                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
635                LockGuard g;
636                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
637    
638                Event event = pEngine->pEventGenerator->CreateEvent();
639                event.Type                          = Event::type_channel_pressure;
640                event.Param.ChannelPressure.Controller = CTRL_TABLE_IDX_AFTERTOUCH; // required for instrument scripts
641                event.Param.ChannelPressure.Value   = Value;
642                event.Param.ChannelPressure.Channel = MidiChannel;
643                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
644                event.pEngineChannel                = this;
645                if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
646                else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
647            }
648        }
649    
650        void AbstractEngineChannel::SendChannelPressure(uint8_t Value, uint8_t MidiChannel, int32_t FragmentPos) {
651            if (pEngine) {
652                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
653                LockGuard g;
654                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
655    
656                Event event = pEngine->pEventGenerator->CreateEvent(FragmentPos);
657                event.Type                          = Event::type_channel_pressure;
658                event.Param.ChannelPressure.Controller = CTRL_TABLE_IDX_AFTERTOUCH; // required for instrument scripts
659                event.Param.ChannelPressure.Value   = Value;
660                event.Param.ChannelPressure.Channel = MidiChannel;
661                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
662                event.pEngineChannel                = this;
663                if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
664                else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
665            }
666        }
667    
668        void AbstractEngineChannel::SendPolyphonicKeyPressure(uint8_t Key, uint8_t Value, uint8_t MidiChannel) {
669            if (pEngine) {
670                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
671                LockGuard g;
672                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
673    
674                Event event = pEngine->pEventGenerator->CreateEvent();
675                event.Type                       = Event::type_note_pressure;
676                event.Param.NotePressure.Key     = Key;
677                event.Param.NotePressure.Value   = Value;
678                event.Param.NotePressure.Channel = MidiChannel;
679                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
680                event.pEngineChannel             = this;
681                if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
682                else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
683            }
684        }
685    
686        void AbstractEngineChannel::SendPolyphonicKeyPressure(uint8_t Key, uint8_t Value, uint8_t MidiChannel, int32_t FragmentPos) {
687            if (pEngine) {
688                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
689                LockGuard g;
690                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
691    
692                Event event = pEngine->pEventGenerator->CreateEvent(FragmentPos);
693                event.Type                       = Event::type_note_pressure;
694                event.Param.NotePressure.Key     = Key;
695                event.Param.NotePressure.Value   = Value;
696                event.Param.NotePressure.Channel = MidiChannel;
697                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
698                event.pEngineChannel             = this;
699                if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
700                else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
701            }
702        }
703    
704      /**      /**
705       * 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
706       * 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
# Line 552  namespace LinuxSampler { Line 745  namespace LinuxSampler {
745                              event.Param.Note.Channel  = channel;                              event.Param.Note.Channel  = channel;
746                              break;                              break;
747                          case VirtualMidiDevice::EVENT_TYPE_CC:                          case VirtualMidiDevice::EVENT_TYPE_CC:
748                              event.Type = Event::type_control_change;                              switch (devEvent.Arg1) {
749                              event.Param.CC.Controller = devEvent.Arg1;                                  case 0: // bank select MSB ...
750                              event.Param.CC.Value      = devEvent.Arg2;                                      SetMidiBankMsb(devEvent.Arg2);
751                              event.Param.CC.Channel    = channel;                                      continue; // don't push this event into FIFO
752                                    case 32: // bank select LSB ...
753                                        SetMidiBankLsb(devEvent.Arg2);
754                                        continue; // don't push this event into FIFO
755                                    default: // regular MIDI CC ...
756                                        event.Type = Event::type_control_change;
757                                        event.Param.CC.Controller = devEvent.Arg1;
758                                        event.Param.CC.Value      = devEvent.Arg2;
759                                        event.Param.CC.Channel    = channel;
760                                }
761                              break;                              break;
762                            case VirtualMidiDevice::EVENT_TYPE_PITCHBEND:
763                                event.Type = Event::type_pitchbend;
764                                event.Param.Pitch.Pitch = int(devEvent.Arg2 << 7 | devEvent.Arg1) - 8192;
765                                event.Param.Pitch.Channel = channel;
766                                break;
767                            case VirtualMidiDevice::EVENT_TYPE_PROGRAM:
768                                SendProgramChange(devEvent.Arg1);
769                                continue; // don't push this event into FIFO
770                          default:                          default:
771                              std::cerr << "AbstractEngineChannel::ImportEvents() ERROR: unknown event type ("                              std::cerr << "AbstractEngineChannel::ImportEvents() ERROR: unknown event type ("
772                                        << devEvent.Type << "). This is a bug!";                                        << devEvent.Type << "). This is a bug!";
# Line 598  namespace LinuxSampler { Line 808  namespace LinuxSampler {
808          eventQueueReader.free(); // free all copied events from input queue          eventQueueReader.free(); // free all copied events from input queue
809      }      }
810    
811        /**
812         * Called by real-time instrument script functions to schedule a new event
813         * somewhere in future.
814         *
815         * @returns unique event ID of scheduled new event
816         */
817        int AbstractEngineChannel::ScheduleEvent(const Event* pEvent, int delay) { //TODO: delay not implemented yet
818            // since delay is not implemented yet, we simply add the new event
819            // to the event list of the current audio fragmet cycle for now
820            RTList<Event>::Iterator itEvent = pEvents->allocAppend();
821            if (itEvent) *itEvent = *pEvent; // copy event
822            return pEvents->getID(itEvent);
823        }
824    
825        /**
826         * Called by real-time instrument script functions to ignore the event
827         * reflected by given event ID. The event will be freed immediately to its
828         * pool and cannot be dereferenced by its old ID anymore. Even if its
829         * allocated back from the Pool later on, it will have a different ID.
830         */
831        void AbstractEngineChannel::IgnoreEvent(int id) {
832            RTList<Event>::Iterator it = pEvents->fromID(id);
833            if (it) pEvents->free(it);
834        }
835    
836      FxSend* AbstractEngineChannel::AddFxSend(uint8_t MidiCtrl, String Name) throw (Exception) {      FxSend* AbstractEngineChannel::AddFxSend(uint8_t MidiCtrl, String Name) throw (Exception) {
837          if (pEngine) pEngine->DisableAndLock();          if (pEngine) pEngine->DisableAndLock();
838          FxSend* pFxSend = new FxSend(this, MidiCtrl, Name);          FxSend* pFxSend = new FxSend(this, MidiCtrl, Name);

Legend:
Removed from v.2382  
changed lines
  Added in v.2612

  ViewVC Help
Powered by ViewVC