/[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 2665 by schoenebeck, Sun Jul 6 00:49:36 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() {
# Line 192  namespace LinuxSampler { Line 193  namespace LinuxSampler {
193       * device from other threads than the lscp thread.       * device from other threads than the lscp thread.
194       */       */
195      AudioOutputDevice* AbstractEngineChannel::GetAudioOutputDeviceSafe() {      AudioOutputDevice* AbstractEngineChannel::GetAudioOutputDeviceSafe() {
196          EngineMutex.Lock();          LockGuard lock(EngineMutex);
197          AudioOutputDevice* res = GetAudioOutputDevice();          return GetAudioOutputDevice();
         EngineMutex.Unlock();  
         return res;  
198      }      }
199    
200      void AbstractEngineChannel::SetOutputChannel(uint EngineAudioChannel, uint AudioDeviceChannel) {      void AbstractEngineChannel::SetOutputChannel(uint EngineAudioChannel, uint AudioDeviceChannel) {
# Line 230  namespace LinuxSampler { Line 229  namespace LinuxSampler {
229          }          }
230      }      }
231    
232        void AbstractEngineChannel::Connect(MidiInputPort* pMidiPort) {
233            if (!pMidiPort) return;
234    
235            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
236    
237            // check if connection already exists
238            for (int i = 0; i < connections->size(); ++i)
239                if ((*connections)[i] == pMidiPort)
240                    return; // to avoid endless recursion
241    
242            connections->add(pMidiPort);
243    
244            // inform MIDI port about this new connection
245            pMidiPort->Connect(this, MidiChannel());
246        }
247    
248        void AbstractEngineChannel::Disconnect(MidiInputPort* pMidiPort) {
249            if (!pMidiPort) return;
250    
251            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
252    
253            for (int i = 0; i < connections->size(); ++i) {
254                if ((*connections)[i] == pMidiPort) {
255                    connections->remove(i);
256                    // inform MIDI port about this disconnection
257                    pMidiPort->Disconnect(this);
258                    return;
259                }
260            }
261        }
262    
263        void AbstractEngineChannel::DisconnectAllMidiInputPorts() {
264            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
265            ArrayList<MidiInputPort*> clonedList = *connections;
266            connections->clear();
267            for (int i = 0; i < clonedList.size(); ++i) clonedList[i]->Disconnect(this);
268        }
269    
270        uint AbstractEngineChannel::GetMidiInputPortCount() {
271            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
272            return connections->size();
273        }
274    
275        MidiInputPort* AbstractEngineChannel::GetMidiInputPort(uint index) {
276            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
277            return (index < connections->size()) ? (*connections)[index] : NULL;
278        }
279    
280        // deprecated (just for API backward compatibility) - may be removed in future
281      void AbstractEngineChannel::Connect(MidiInputPort* pMidiPort, midi_chan_t MidiChannel) {      void AbstractEngineChannel::Connect(MidiInputPort* pMidiPort, midi_chan_t MidiChannel) {
282          if (!pMidiPort || pMidiPort == this->pMidiInputPort) return;          if (!pMidiPort) return;
283          DisconnectMidiInputPort();  
284          this->pMidiInputPort = pMidiPort;          Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
285          this->midiChannel    = MidiChannel;  
286            // check against endless recursion
287            if (connections->size() == 1 && (*connections)[0] == pMidiPort && this->midiChannel == MidiChannel)
288                return;
289            
290            if (!isValidMidiChan(MidiChannel))
291                throw MidiInputException("Invalid MIDI channel (" + ToString(int(MidiChannel)) + ")");
292    
293            this->midiChannel = MidiChannel;
294    
295            // disconnect all currently connected MIDI ports
296            ArrayList<MidiInputPort*> clonedList = *connections;
297            connections->clear();
298            for (int i = 0; i < clonedList.size(); ++i)
299                clonedList[i]->Disconnect(this);
300    
301            // connect the new port
302            connections->add(pMidiPort);
303          pMidiPort->Connect(this, MidiChannel);          pMidiPort->Connect(this, MidiChannel);
304      }      }
305    
306        // deprecated (just for API backward compatibility) - may be removed in future
307      void AbstractEngineChannel::DisconnectMidiInputPort() {      void AbstractEngineChannel::DisconnectMidiInputPort() {
308          MidiInputPort* pOldPort = this->pMidiInputPort;          DisconnectAllMidiInputPorts();
         this->pMidiInputPort = NULL;  
         if (pOldPort) pOldPort->Disconnect(this);  
309      }      }
310    
311        // deprecated (just for API backward compatibility) - may be removed in future
312      MidiInputPort* AbstractEngineChannel::GetMidiInputPort() {      MidiInputPort* AbstractEngineChannel::GetMidiInputPort() {
313          return pMidiInputPort;          return GetMidiInputPort(0);
314      }      }
315    
316      midi_chan_t AbstractEngineChannel::MidiChannel() {      midi_chan_t AbstractEngineChannel::MidiChannel() {
317          return midiChannel;          return midiChannel;
318      }      }
319    
320        void AbstractEngineChannel::SetMidiChannel(midi_chan_t MidiChannel) {
321            if (this->midiChannel == MidiChannel) return;
322            if (!isValidMidiChan(MidiChannel))
323                throw MidiInputException("Invalid MIDI channel (" + ToString(int(MidiChannel)) + ")");
324    
325            this->midiChannel = MidiChannel;
326            
327            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
328            ArrayList<MidiInputPort*> clonedList = *connections;
329    
330            DisconnectAllMidiInputPorts();
331    
332            for (int i = 0; i < clonedList.size(); ++i) Connect(clonedList[i]);
333        }
334    
335      void AbstractEngineChannel::Connect(VirtualMidiDevice* pDevice) {      void AbstractEngineChannel::Connect(VirtualMidiDevice* pDevice) {
336          // double buffer ... double work ...          // double buffer ... double work ...
337          {          {
# Line 287  namespace LinuxSampler { Line 367  namespace LinuxSampler {
367       */       */
368      void AbstractEngineChannel::SendNoteOn(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {      void AbstractEngineChannel::SendNoteOn(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {
369          if (pEngine) {          if (pEngine) {
370                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
371                LockGuard g;
372                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
373    
374              Event event               = pEngine->pEventGenerator->CreateEvent();              Event event               = pEngine->pEventGenerator->CreateEvent();
375              event.Type                = Event::type_note_on;              event.Type                = Event::type_note_on;
376              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
377              event.Param.Note.Velocity = Velocity;              event.Param.Note.Velocity = Velocity;
378              event.Param.Note.Channel  = MidiChannel;              event.Param.Note.Channel  = MidiChannel;
379                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
380              event.pEngineChannel      = this;              event.pEngineChannel      = this;
381              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
382              else dmsg(1,("EngineChannel: Input event queue full!"));              else dmsg(1,("EngineChannel: Input event queue full!"));
# Line 324  namespace LinuxSampler { Line 409  namespace LinuxSampler {
409              dmsg(1,("EngineChannel::SendNoteOn(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("EngineChannel::SendNoteOn(): negative FragmentPos! Seems MIDI driver is buggy!"));
410          }          }
411          else if (pEngine) {          else if (pEngine) {
412                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
413                LockGuard g;
414                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
415    
416              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);
417              event.Type                = Event::type_note_on;              event.Type                = Event::type_note_on;
418              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
419              event.Param.Note.Velocity = Velocity;              event.Param.Note.Velocity = Velocity;
420              event.Param.Note.Channel  = MidiChannel;              event.Param.Note.Channel  = MidiChannel;
421                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
422              event.pEngineChannel      = this;              event.pEngineChannel      = this;
423              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
424              else dmsg(1,("EngineChannel: Input event queue full!"));              else dmsg(1,("EngineChannel: Input event queue full!"));
# Line 356  namespace LinuxSampler { Line 446  namespace LinuxSampler {
446       */       */
447      void AbstractEngineChannel::SendNoteOff(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {      void AbstractEngineChannel::SendNoteOff(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {
448          if (pEngine) {          if (pEngine) {
449                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
450                LockGuard g;
451                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
452    
453              Event event               = pEngine->pEventGenerator->CreateEvent();              Event event               = pEngine->pEventGenerator->CreateEvent();
454              event.Type                = Event::type_note_off;              event.Type                = Event::type_note_off;
455              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
456              event.Param.Note.Velocity = Velocity;              event.Param.Note.Velocity = Velocity;
457              event.Param.Note.Channel  = MidiChannel;              event.Param.Note.Channel  = MidiChannel;
458                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
459              event.pEngineChannel      = this;              event.pEngineChannel      = this;
460              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
461              else dmsg(1,("EngineChannel: Input event queue full!"));              else dmsg(1,("EngineChannel: Input event queue full!"));
# Line 393  namespace LinuxSampler { Line 488  namespace LinuxSampler {
488              dmsg(1,("EngineChannel::SendNoteOff(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("EngineChannel::SendNoteOff(): negative FragmentPos! Seems MIDI driver is buggy!"));
489          }          }
490          else if (pEngine) {          else if (pEngine) {
491                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
492                LockGuard g;
493                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
494    
495              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);
496              event.Type                = Event::type_note_off;              event.Type                = Event::type_note_off;
497              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
498              event.Param.Note.Velocity = Velocity;              event.Param.Note.Velocity = Velocity;
499              event.Param.Note.Channel  = MidiChannel;              event.Param.Note.Channel  = MidiChannel;
500                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
501              event.pEngineChannel      = this;              event.pEngineChannel      = this;
502              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
503              else dmsg(1,("EngineChannel: Input event queue full!"));              else dmsg(1,("EngineChannel: Input event queue full!"));
# Line 424  namespace LinuxSampler { Line 524  namespace LinuxSampler {
524       */       */
525      void AbstractEngineChannel::SendPitchbend(int Pitch, uint8_t MidiChannel) {      void AbstractEngineChannel::SendPitchbend(int Pitch, uint8_t MidiChannel) {
526          if (pEngine) {          if (pEngine) {
527                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
528                LockGuard g;
529                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
530    
531              Event event             = pEngine->pEventGenerator->CreateEvent();              Event event             = pEngine->pEventGenerator->CreateEvent();
532              event.Type              = Event::type_pitchbend;              event.Type              = Event::type_pitchbend;
533              event.Param.Pitch.Pitch = Pitch;              event.Param.Pitch.Pitch = Pitch;
534              event.Param.Pitch.Channel = MidiChannel;              event.Param.Pitch.Channel = MidiChannel;
535                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
536              event.pEngineChannel    = this;              event.pEngineChannel    = this;
537              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
538              else dmsg(1,("EngineChannel: Input event queue full!"));              else dmsg(1,("EngineChannel: Input event queue full!"));
# Line 449  namespace LinuxSampler { Line 554  namespace LinuxSampler {
554              dmsg(1,("AbstractEngineChannel::SendPitchBend(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("AbstractEngineChannel::SendPitchBend(): negative FragmentPos! Seems MIDI driver is buggy!"));
555          }          }
556          else if (pEngine) {          else if (pEngine) {
557                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
558                LockGuard g;
559                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
560    
561              Event event             = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event             = pEngine->pEventGenerator->CreateEvent(FragmentPos);
562              event.Type              = Event::type_pitchbend;              event.Type              = Event::type_pitchbend;
563              event.Param.Pitch.Pitch = Pitch;              event.Param.Pitch.Pitch = Pitch;
564              event.Param.Pitch.Channel = MidiChannel;              event.Param.Pitch.Channel = MidiChannel;
565                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
566              event.pEngineChannel    = this;              event.pEngineChannel    = this;
567              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
568              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
# Line 470  namespace LinuxSampler { Line 580  namespace LinuxSampler {
580       */       */
581      void AbstractEngineChannel::SendControlChange(uint8_t Controller, uint8_t Value, uint8_t MidiChannel) {      void AbstractEngineChannel::SendControlChange(uint8_t Controller, uint8_t Value, uint8_t MidiChannel) {
582          if (pEngine) {          if (pEngine) {
583                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
584                LockGuard g;
585                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
586    
587              Event event               = pEngine->pEventGenerator->CreateEvent();              Event event               = pEngine->pEventGenerator->CreateEvent();
588              event.Type                = Event::type_control_change;              event.Type                = Event::type_control_change;
589              event.Param.CC.Controller = Controller;              event.Param.CC.Controller = Controller;
590              event.Param.CC.Value      = Value;              event.Param.CC.Value      = Value;
591              event.Param.CC.Channel    = MidiChannel;              event.Param.CC.Channel    = MidiChannel;
592                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
593              event.pEngineChannel      = this;              event.pEngineChannel      = this;
594              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
595              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
# Line 497  namespace LinuxSampler { Line 612  namespace LinuxSampler {
612              dmsg(1,("AbstractEngineChannel::SendControlChange(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("AbstractEngineChannel::SendControlChange(): negative FragmentPos! Seems MIDI driver is buggy!"));
613          }          }
614          else if (pEngine) {          else if (pEngine) {
615                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
616                LockGuard g;
617                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
618    
619              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);
620              event.Type                = Event::type_control_change;              event.Type                = Event::type_control_change;
621              event.Param.CC.Controller = Controller;              event.Param.CC.Controller = Controller;
622              event.Param.CC.Value      = Value;              event.Param.CC.Value      = Value;
623              event.Param.CC.Channel    = MidiChannel;              event.Param.CC.Channel    = MidiChannel;
624                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
625              event.pEngineChannel      = this;              event.pEngineChannel      = this;
626              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);              if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
627              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));              else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
628          }          }
629      }      }
630    
631        void AbstractEngineChannel::SendChannelPressure(uint8_t Value, uint8_t MidiChannel) {
632            if (pEngine) {
633                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
634                LockGuard g;
635                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
636    
637                Event event = pEngine->pEventGenerator->CreateEvent();
638                event.Type                          = Event::type_channel_pressure;
639                event.Param.ChannelPressure.Controller = CTRL_TABLE_IDX_AFTERTOUCH; // required for instrument scripts
640                event.Param.ChannelPressure.Value   = Value;
641                event.Param.ChannelPressure.Channel = MidiChannel;
642                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
643                event.pEngineChannel                = this;
644                if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
645                else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
646            }
647        }
648    
649        void AbstractEngineChannel::SendChannelPressure(uint8_t Value, uint8_t MidiChannel, int32_t FragmentPos) {
650            if (pEngine) {
651                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
652                LockGuard g;
653                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
654    
655                Event event = pEngine->pEventGenerator->CreateEvent(FragmentPos);
656                event.Type                          = Event::type_channel_pressure;
657                event.Param.ChannelPressure.Controller = CTRL_TABLE_IDX_AFTERTOUCH; // required for instrument scripts
658                event.Param.ChannelPressure.Value   = Value;
659                event.Param.ChannelPressure.Channel = MidiChannel;
660                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
661                event.pEngineChannel                = this;
662                if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
663                else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
664            }
665        }
666    
667        void AbstractEngineChannel::SendPolyphonicKeyPressure(uint8_t Key, uint8_t Value, uint8_t MidiChannel) {
668            if (pEngine) {
669                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
670                LockGuard g;
671                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
672    
673                Event event = pEngine->pEventGenerator->CreateEvent();
674                event.Type                       = Event::type_note_pressure;
675                event.Param.NotePressure.Key     = Key;
676                event.Param.NotePressure.Value   = Value;
677                event.Param.NotePressure.Channel = MidiChannel;
678                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
679                event.pEngineChannel             = this;
680                if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
681                else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
682            }
683        }
684    
685        void AbstractEngineChannel::SendPolyphonicKeyPressure(uint8_t Key, uint8_t Value, uint8_t MidiChannel, int32_t FragmentPos) {
686            if (pEngine) {
687                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
688                LockGuard g;
689                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
690    
691                Event event = pEngine->pEventGenerator->CreateEvent(FragmentPos);
692                event.Type                       = Event::type_note_pressure;
693                event.Param.NotePressure.Key     = Key;
694                event.Param.NotePressure.Value   = Value;
695                event.Param.NotePressure.Channel = MidiChannel;
696                memset(&event.Format, 0, sizeof(event.Format)); // init format speific stuff with zeroes
697                event.pEngineChannel             = this;
698                if (this->pEventQueue->write_space() > 0) this->pEventQueue->push(&event);
699                else dmsg(1,("AbstractEngineChannel: Input event queue full!"));
700            }
701        }
702    
703      /**      /**
704       * 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
705       * 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 744  namespace LinuxSampler {
744                              event.Param.Note.Channel  = channel;                              event.Param.Note.Channel  = channel;
745                              break;                              break;
746                          case VirtualMidiDevice::EVENT_TYPE_CC:                          case VirtualMidiDevice::EVENT_TYPE_CC:
747                              event.Type = Event::type_control_change;                              switch (devEvent.Arg1) {
748                              event.Param.CC.Controller = devEvent.Arg1;                                  case 0: // bank select MSB ...
749                              event.Param.CC.Value      = devEvent.Arg2;                                      SetMidiBankMsb(devEvent.Arg2);
750                              event.Param.CC.Channel    = channel;                                      continue; // don't push this event into FIFO
751                                    case 32: // bank select LSB ...
752                                        SetMidiBankLsb(devEvent.Arg2);
753                                        continue; // don't push this event into FIFO
754                                    default: // regular MIDI CC ...
755                                        event.Type = Event::type_control_change;
756                                        event.Param.CC.Controller = devEvent.Arg1;
757                                        event.Param.CC.Value      = devEvent.Arg2;
758                                        event.Param.CC.Channel    = channel;
759                                }
760                              break;                              break;
761                            case VirtualMidiDevice::EVENT_TYPE_PITCHBEND:
762                                event.Type = Event::type_pitchbend;
763                                event.Param.Pitch.Pitch = int(devEvent.Arg2 << 7 | devEvent.Arg1) - 8192;
764                                event.Param.Pitch.Channel = channel;
765                                break;
766                            case VirtualMidiDevice::EVENT_TYPE_PROGRAM:
767                                SendProgramChange(devEvent.Arg1);
768                                continue; // don't push this event into FIFO
769                          default:                          default:
770                              std::cerr << "AbstractEngineChannel::ImportEvents() ERROR: unknown event type ("                              std::cerr << "AbstractEngineChannel::ImportEvents() ERROR: unknown event type ("
771                                        << devEvent.Type << "). This is a bug!";                                        << devEvent.Type << "). This is a bug!";
772                              continue;                              continue;
773                      }                      }
774                        memset(&event.Format, 0, sizeof(event.Format)); // init format specific stuff with zeroes
775                      event.pEngineChannel = this;                      event.pEngineChannel = this;
776                      // copy event to internal event list                      // copy event to internal event list
777                      if (pEvents->poolIsEmpty()) {                      if (pEvents->poolIsEmpty()) {
# 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.2665

  ViewVC Help
Powered by ViewVC