/[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 2499 by persson, Sat Mar 2 07:03:04 2013 UTC revision 2500 by schoenebeck, Fri Jan 10 12:20:05 2014 UTC
# Line 4  Line 4 
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-2008 Christian Schoenebeck                         *   *   Copyright (C) 2005-2008 Christian Schoenebeck                         *
7   *   Copyright (C) 2009-2013 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;
# Line 228  namespace LinuxSampler { Line 228  namespace LinuxSampler {
228          }          }
229      }      }
230    
231        void AbstractEngineChannel::Connect(MidiInputPort* pMidiPort) {
232            if (!pMidiPort) return;
233    
234            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
235    
236            // check if connection already exists
237            for (int i = 0; i < connections->size(); ++i)
238                if ((*connections)[i] == pMidiPort)
239                    return; // to avoid endless recursion
240    
241            connections->add(pMidiPort);
242    
243            // inform MIDI port about this new connection
244            pMidiPort->Connect(this, MidiChannel());
245        }
246    
247        void AbstractEngineChannel::Disconnect(MidiInputPort* pMidiPort) {
248            if (!pMidiPort) return;
249    
250            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
251    
252            for (int i = 0; i < connections->size(); ++i) {
253                if ((*connections)[i] == pMidiPort) {
254                    connections->remove(i);
255                    // inform MIDI port about this disconnection
256                    pMidiPort->Disconnect(this);
257                    return;
258                }
259            }
260        }
261    
262        void AbstractEngineChannel::DisconnectAllMidiInputPorts() {
263            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
264            ArrayList<MidiInputPort*> clonedList = *connections;
265            connections->clear();
266            for (int i = 0; i < clonedList.size(); ++i) clonedList[i]->Disconnect(this);
267        }
268    
269        uint AbstractEngineChannel::GetMidiInputPortCount() {
270            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
271            return connections->size();
272        }
273    
274        MidiInputPort* AbstractEngineChannel::GetMidiInputPort(uint index) {
275            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
276            return (index < connections->size()) ? (*connections)[index] : NULL;
277        }
278    
279        // deprecated (just for API backward compatibility) - may be removed in future
280      void AbstractEngineChannel::Connect(MidiInputPort* pMidiPort, midi_chan_t MidiChannel) {      void AbstractEngineChannel::Connect(MidiInputPort* pMidiPort, midi_chan_t MidiChannel) {
281          if (!pMidiPort || pMidiPort == this->pMidiInputPort) return;          if (!pMidiPort) return;
282          DisconnectMidiInputPort();  
283          this->pMidiInputPort = pMidiPort;          Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
284          this->midiChannel    = MidiChannel;  
285            // check against endless recursion
286            if (connections->size() == 1 && (*connections)[0] == pMidiPort && this->midiChannel == MidiChannel)
287                return;
288            
289            if (!isValidMidiChan(MidiChannel))
290                throw MidiInputException("Invalid MIDI channel (" + ToString(int(MidiChannel)) + ")");
291    
292            this->midiChannel = MidiChannel;
293    
294            // disconnect all currently connected MIDI ports
295            ArrayList<MidiInputPort*> clonedList = *connections;
296            connections->clear();
297            for (int i = 0; i < clonedList.size(); ++i)
298                clonedList[i]->Disconnect(this);
299    
300            // connect the new port
301            connections->add(pMidiPort);
302          pMidiPort->Connect(this, MidiChannel);          pMidiPort->Connect(this, MidiChannel);
303      }      }
304    
305        // deprecated (just for API backward compatibility) - may be removed in future
306      void AbstractEngineChannel::DisconnectMidiInputPort() {      void AbstractEngineChannel::DisconnectMidiInputPort() {
307          MidiInputPort* pOldPort = this->pMidiInputPort;          DisconnectAllMidiInputPorts();
         this->pMidiInputPort = NULL;  
         if (pOldPort) pOldPort->Disconnect(this);  
308      }      }
309    
310        // deprecated (just for API backward compatibility) - may be removed in future
311      MidiInputPort* AbstractEngineChannel::GetMidiInputPort() {      MidiInputPort* AbstractEngineChannel::GetMidiInputPort() {
312          return pMidiInputPort;          return GetMidiInputPort(0);
313      }      }
314    
315      midi_chan_t AbstractEngineChannel::MidiChannel() {      midi_chan_t AbstractEngineChannel::MidiChannel() {
316          return midiChannel;          return midiChannel;
317      }      }
318    
319        void AbstractEngineChannel::SetMidiChannel(midi_chan_t MidiChannel) {
320            if (this->midiChannel == MidiChannel) return;
321            if (!isValidMidiChan(MidiChannel))
322                throw MidiInputException("Invalid MIDI channel (" + ToString(int(MidiChannel)) + ")");
323    
324            this->midiChannel = MidiChannel;
325            
326            Sync< ArrayList<MidiInputPort*> > connections = midiInputs.back();
327            ArrayList<MidiInputPort*> clonedList = *connections;
328    
329            DisconnectAllMidiInputPorts();
330    
331            for (int i = 0; i < clonedList.size(); ++i) Connect(clonedList[i]);
332        }
333    
334      void AbstractEngineChannel::Connect(VirtualMidiDevice* pDevice) {      void AbstractEngineChannel::Connect(VirtualMidiDevice* pDevice) {
335          // double buffer ... double work ...          // double buffer ... double work ...
336          {          {
# Line 285  namespace LinuxSampler { Line 366  namespace LinuxSampler {
366       */       */
367      void AbstractEngineChannel::SendNoteOn(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {      void AbstractEngineChannel::SendNoteOn(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {
368          if (pEngine) {          if (pEngine) {
369                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
370                LockGuard g;
371                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
372    
373              Event event               = pEngine->pEventGenerator->CreateEvent();              Event event               = pEngine->pEventGenerator->CreateEvent();
374              event.Type                = Event::type_note_on;              event.Type                = Event::type_note_on;
375              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
# Line 322  namespace LinuxSampler { Line 407  namespace LinuxSampler {
407              dmsg(1,("EngineChannel::SendNoteOn(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("EngineChannel::SendNoteOn(): negative FragmentPos! Seems MIDI driver is buggy!"));
408          }          }
409          else if (pEngine) {          else if (pEngine) {
410                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
411                LockGuard g;
412                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
413    
414              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);
415              event.Type                = Event::type_note_on;              event.Type                = Event::type_note_on;
416              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
# Line 354  namespace LinuxSampler { Line 443  namespace LinuxSampler {
443       */       */
444      void AbstractEngineChannel::SendNoteOff(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {      void AbstractEngineChannel::SendNoteOff(uint8_t Key, uint8_t Velocity, uint8_t MidiChannel) {
445          if (pEngine) {          if (pEngine) {
446                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
447                LockGuard g;
448                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
449    
450              Event event               = pEngine->pEventGenerator->CreateEvent();              Event event               = pEngine->pEventGenerator->CreateEvent();
451              event.Type                = Event::type_note_off;              event.Type                = Event::type_note_off;
452              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
# Line 391  namespace LinuxSampler { Line 484  namespace LinuxSampler {
484              dmsg(1,("EngineChannel::SendNoteOff(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("EngineChannel::SendNoteOff(): negative FragmentPos! Seems MIDI driver is buggy!"));
485          }          }
486          else if (pEngine) {          else if (pEngine) {
487                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
488                LockGuard g;
489                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
490    
491              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);
492              event.Type                = Event::type_note_off;              event.Type                = Event::type_note_off;
493              event.Param.Note.Key      = Key;              event.Param.Note.Key      = Key;
# Line 422  namespace LinuxSampler { Line 519  namespace LinuxSampler {
519       */       */
520      void AbstractEngineChannel::SendPitchbend(int Pitch, uint8_t MidiChannel) {      void AbstractEngineChannel::SendPitchbend(int Pitch, uint8_t MidiChannel) {
521          if (pEngine) {          if (pEngine) {
522                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
523                LockGuard g;
524                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
525    
526              Event event             = pEngine->pEventGenerator->CreateEvent();              Event event             = pEngine->pEventGenerator->CreateEvent();
527              event.Type              = Event::type_pitchbend;              event.Type              = Event::type_pitchbend;
528              event.Param.Pitch.Pitch = Pitch;              event.Param.Pitch.Pitch = Pitch;
# Line 447  namespace LinuxSampler { Line 548  namespace LinuxSampler {
548              dmsg(1,("AbstractEngineChannel::SendPitchBend(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("AbstractEngineChannel::SendPitchBend(): negative FragmentPos! Seems MIDI driver is buggy!"));
549          }          }
550          else if (pEngine) {          else if (pEngine) {
551                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
552                LockGuard g;
553                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
554    
555              Event event             = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event             = pEngine->pEventGenerator->CreateEvent(FragmentPos);
556              event.Type              = Event::type_pitchbend;              event.Type              = Event::type_pitchbend;
557              event.Param.Pitch.Pitch = Pitch;              event.Param.Pitch.Pitch = Pitch;
# Line 468  namespace LinuxSampler { Line 573  namespace LinuxSampler {
573       */       */
574      void AbstractEngineChannel::SendControlChange(uint8_t Controller, uint8_t Value, uint8_t MidiChannel) {      void AbstractEngineChannel::SendControlChange(uint8_t Controller, uint8_t Value, uint8_t MidiChannel) {
575          if (pEngine) {          if (pEngine) {
576                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
577                LockGuard g;
578                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
579    
580              Event event               = pEngine->pEventGenerator->CreateEvent();              Event event               = pEngine->pEventGenerator->CreateEvent();
581              event.Type                = Event::type_control_change;              event.Type                = Event::type_control_change;
582              event.Param.CC.Controller = Controller;              event.Param.CC.Controller = Controller;
# Line 495  namespace LinuxSampler { Line 604  namespace LinuxSampler {
604              dmsg(1,("AbstractEngineChannel::SendControlChange(): negative FragmentPos! Seems MIDI driver is buggy!"));              dmsg(1,("AbstractEngineChannel::SendControlChange(): negative FragmentPos! Seems MIDI driver is buggy!"));
605          }          }
606          else if (pEngine) {          else if (pEngine) {
607                // protection in case there are more than 1 MIDI input threads sending MIDI events to this EngineChannel
608                LockGuard g;
609                if (hasMultipleMIDIInputs()) g = LockGuard(MidiInputMutex);
610    
611              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);              Event event               = pEngine->pEventGenerator->CreateEvent(FragmentPos);
612              event.Type                = Event::type_control_change;              event.Type                = Event::type_control_change;
613              event.Param.CC.Controller = Controller;              event.Param.CC.Controller = Controller;

Legend:
Removed from v.2499  
changed lines
  Added in v.2500

  ViewVC Help
Powered by ViewVC