/[svn]/linuxsampler/trunk/src/engines/common/MidiKeyboardManager.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/common/MidiKeyboardManager.h

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

revision 2927 by schoenebeck, Thu Jun 30 16:44:46 2016 UTC revision 3706 by schoenebeck, Wed Jan 8 20:39:59 2020 UTC
# Line 3  Line 3 
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-2008 Christian Schoenebeck                         *   *   Copyright (C) 2005-2020 Christian Schoenebeck                         *
7   *   Copyright (C) 2009-2010 Christian Schoenebeck and Grigor Iliev        *   *   Copyright (C) 2009-2010 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  *
# Line 117  namespace LinuxSampler { Line 117  namespace LinuxSampler {
117          public:          public:
118              bool            KeyPressed;     ///< Is true if the respective MIDI key is currently pressed.              bool            KeyPressed;     ///< Is true if the respective MIDI key is currently pressed.
119              bool            Active;         ///< If the key contains active voices.              bool            Active;         ///< If the key contains active voices.
120              bool            ReleaseTrigger; ///< If we have to launch release triggered voice(s) when the key is released              release_trigger_t ReleaseTrigger; ///< If we have to launch release triggered voice(s) when either the key or sustain pedal is released.
121              Pool<uint>::Iterator itSelf;    ///< hack to allow fast deallocation of the key from the list of active keys              Pool<uint>::Iterator itSelf;    ///< hack to allow fast deallocation of the key from the list of active keys
122              RTList<Event>*  pEvents;        ///< Key specific events (only Note-on, Note-off and sustain pedal currently)              RTList<Event>*  pEvents;        ///< Key specific events (only Note-on, Note-off and sustain pedal currently)
123              int             VoiceTheftsQueued; ///< Amount of voices postponed due to shortage of voices.              int             VoiceTheftsQueued; ///< Amount of voices postponed due to shortage of voices.
# Line 143  namespace LinuxSampler { Line 143  namespace LinuxSampler {
143          uint32_t              RoundRobinIndexes[128];          uint32_t              RoundRobinIndexes[128];
144          int8_t                KeyDown[128]; ///< True if the respective key is currently pressed down. Currently only used as built-in instrument script array variable %KEY_DOWN. It is currently not used by the sampler for any other purpose.          int8_t                KeyDown[128]; ///< True if the respective key is currently pressed down. Currently only used as built-in instrument script array variable %KEY_DOWN. It is currently not used by the sampler for any other purpose.
145    
146          virtual void ProcessReleaseTrigger(RTList<Event>::Iterator& itEvent) = 0;          virtual void ProcessReleaseTriggerBySustain(RTList<Event>::Iterator& itEvent) = 0;
147      };      };
148    
149      template <class V>      template <class V>
# Line 172  namespace LinuxSampler { Line 172  namespace LinuxSampler {
172                      pActiveNotes   = NULL;                      pActiveNotes   = NULL;
173                      KeyPressed     = false;                      KeyPressed     = false;
174                      Active         = false;                      Active         = false;
175                      ReleaseTrigger = false;                      ReleaseTrigger = release_trigger_none;
176                      pEvents        = NULL;                      pEvents        = NULL;
177                      VoiceTheftsQueued = 0;                      VoiceTheftsQueued = 0;
178                      Volume = 1.0f;                      Volume = 1.0f;
# Line 192  namespace LinuxSampler { Line 192  namespace LinuxSampler {
192                      if (pEvents) pEvents->clear();                      if (pEvents) pEvents->clear();
193                      KeyPressed        = false;                      KeyPressed        = false;
194                      Active            = false;                      Active            = false;
195                      ReleaseTrigger    = false;                      ReleaseTrigger    = release_trigger_none;
196                      itSelf            = Pool<uint>::Iterator();                      itSelf            = Pool<uint>::Iterator();
197                      VoiceTheftsQueued = 0;                      VoiceTheftsQueued = 0;
198                      Volume = 1.0f;                      Volume = 1.0f;
# Line 317  namespace LinuxSampler { Line 317  namespace LinuxSampler {
317              }*/              }*/
318    
319              /**              /**
320                 * Make sure the passed MIDI key is part of the list of active keys,
321                 * if it is not already, then add it to that list. Accordingly it is
322                 * safe to call this method even if the requested key is already
323                 * marked as active.
324                 */
325                void markKeyAsActive(MidiKey* pKey) {
326                    if (!pKey->Active) { // mark as active key
327                        pKey->Active = true;
328                        pKey->itSelf = pActiveKeys->allocAppend();
329                        const int iKey = int( pKey - &pMIDIKeyInfo[0] );
330                        *pKey->itSelf = iKey;
331                    }
332                }
333    
334                /**
335               *  Removes the given voice from the MIDI key's list of active voices.               *  Removes the given voice from the MIDI key's list of active voices.
336               *  This method will be called when a voice went inactive, e.g. because               *  This method will be called when a voice went inactive, e.g. because
337               *  it finished to playback its sample, finished its release stage or               *  it finished to playback its sample, finished its release stage or
# Line 357  namespace LinuxSampler { Line 372  namespace LinuxSampler {
372                      pKey->Active = false;                      pKey->Active = false;
373                      pActiveKeys->free(pKey->itSelf); // remove key from list of active keys                      pActiveKeys->free(pKey->itSelf); // remove key from list of active keys
374                      pKey->itSelf = RTList<uint>::Iterator();                      pKey->itSelf = RTList<uint>::Iterator();
375                      pKey->ReleaseTrigger = false;                      pKey->ReleaseTrigger = release_trigger_none;
376                      pKey->pEvents->clear();                      pKey->pEvents->clear();
377                      dmsg(3,("Key has no more voices now\n"));                      dmsg(3,("Key has no more voices now\n"));
378                  }                  }
# Line 367  namespace LinuxSampler { Line 382  namespace LinuxSampler {
382              /**              /**
383               * Free all keys which have no active voices left               * Free all keys which have no active voices left
384               */               */
385              void FreeAllInactiveKyes() {              void FreeAllInactiveKeys() {
386                  RTList<uint>::Iterator iuiKey = pActiveKeys->first();                  RTList<uint>::Iterator iuiKey = pActiveKeys->first();
387                  RTList<uint>::Iterator end    = pActiveKeys->end();                  RTList<uint>::Iterator end    = pActiveKeys->end();
388                  while (iuiKey != end) { // iterate through all active keys                  while (iuiKey != end) { // iterate through all active keys
# Line 525  namespace LinuxSampler { Line 540  namespace LinuxSampler {
540                      RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();                      RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
541                      if (itNewEvent) {                      if (itNewEvent) {
542                          *itNewEvent = *itReleaseEvent; // copy original event (to the key's event list)                          *itNewEvent = *itReleaseEvent; // copy original event (to the key's event list)
543                          itNewEvent->Type = Event::type_release; // transform event type                          itNewEvent->Type = Event::type_release_key; // transform event type
544                      }                      }
545                      else dmsg(1,("Event pool emtpy!\n"));                      else dmsg(1,("Event pool emtpy!\n"));
546                  }                  }
# Line 667  namespace LinuxSampler { Line 682  namespace LinuxSampler {
682                          RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();                          RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
683                          if (itNewEvent) {                          if (itNewEvent) {
684                              *itNewEvent = *itEvent; // copy event to the key's own event list                              *itNewEvent = *itEvent; // copy event to the key's own event list
685                              itNewEvent->Type = Event::type_cancel_release; // transform event type                              itNewEvent->Type = Event::type_cancel_release_key; // transform event type
686                          }                          }
687                          else dmsg(1,("Event pool emtpy!\n"));                          else dmsg(1,("Event pool emtpy!\n"));
688                      }                      }
# Line 683  namespace LinuxSampler { Line 698  namespace LinuxSampler {
698                          RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();                          RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
699                          if (itNewEvent) {                          if (itNewEvent) {
700                              *itNewEvent = *itEvent; // copy event to the key's own event list                              *itNewEvent = *itEvent; // copy event to the key's own event list
701                              itNewEvent->Type = Event::type_release; // transform event type                              itNewEvent->Type = Event::type_release_key; // transform event type
702                              itNewEvent->Param.Note.Key = *iuiKey;                              itNewEvent->Param.Note.Key = *iuiKey;
703                              itNewEvent->Param.Note.Velocity = 127;                              itNewEvent->Param.Note.Velocity = 127;
704                              if (!SostenutoActiveOnKey(*iuiKey)) {  
705                                // process release trigger (if requested)
706                                if (pKey->ReleaseTrigger & release_trigger_sustain) {
707                                    if (pKey->ReleaseTrigger & release_trigger_sustain_keyvelocity)
708                                        itNewEvent->Param.Note.Velocity = pKey->Velocity;
709    
710                                  //HACK: set sustain CC (64) as "pressed down" for a short moment, so that release trigger voices can distinguish between note off and sustain pedal up cases                                  //HACK: set sustain CC (64) as "pressed down" for a short moment, so that release trigger voices can distinguish between note off and sustain pedal up cases
711                                  AbstractEngineChannel* pChannel = (AbstractEngineChannel*) itEvent->pEngineChannel;                                  AbstractEngineChannel* pChannel = (AbstractEngineChannel*) itEvent->pEngineChannel;
712                                  const int8_t CC64Value = pChannel->ControllerTable[64];                                  const int8_t CC64Value = pChannel->ControllerTable[64];
713                                  pChannel->ControllerTable[64] = 127;                                  pChannel->ControllerTable[64] = 127;
714    
715                                  // now spawn release trigger voices (if required)                                  // now spawn release trigger voices (if required)
716                                  ProcessReleaseTrigger(itNewEvent);                                  ProcessReleaseTriggerBySustain(itNewEvent);
717    
718                                  //HACK: reset sustain pedal CC value to old one (see comment above)                                  //HACK: reset sustain pedal CC value to old one (see comment above)
719                                  pChannel->ControllerTable[64] = CC64Value;                                  pChannel->ControllerTable[64] = CC64Value;  
720                              }                              }
721                          }                          }
722                          else dmsg(1,("Event pool emtpy!\n"));                          else dmsg(1,("Event pool emtpy!\n"));
# Line 748  namespace LinuxSampler { Line 768  namespace LinuxSampler {
768                          RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();                          RTList<Event>::Iterator itNewEvent = pKey->pEvents->allocAppend();
769                          if (itNewEvent) {                          if (itNewEvent) {
770                              *itNewEvent = *itEvent; // copy event to the key's own event list                              *itNewEvent = *itEvent; // copy event to the key's own event list
771                              itNewEvent->Type = Event::type_release; // transform event type                              itNewEvent->Type = Event::type_release_key; // transform event type
772                          }                          }
773                          else dmsg(1,("Event pool emtpy!\n"));                          else dmsg(1,("Event pool emtpy!\n"));
774                      }                      }

Legend:
Removed from v.2927  
changed lines
  Added in v.3706

  ViewVC Help
Powered by ViewVC