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

Diff of /linuxsampler/trunk/src/engines/EngineBase.h

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

revision 3844 by schoenebeck, Sat Aug 29 16:37:35 2020 UTC revision 3845 by schoenebeck, Tue Jan 5 20:42:32 2021 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-2020 Christian Schoenebeck                         *   *   Copyright (C) 2005-2021 Christian Schoenebeck                         *
7   *   Copyright (C) 2009-2012 Grigor Iliev                                  *   *   Copyright (C) 2009-2012 Grigor Iliev                                  *
8   *   Copyright (C) 2012-2017 Andreas Persson                               *   *   Copyright (C) 2012-2017 Andreas Persson                               *
9   *                                                                         *   *                                                                         *
# Line 1006  namespace LinuxSampler { Line 1006  namespace LinuxSampler {
1006                  if (pEventHandler == pChannel->pScript->handlerRelease &&                  if (pEventHandler == pChannel->pScript->handlerRelease &&
1007                      pChannel->pScript->handlerNote &&                      pChannel->pScript->handlerNote &&
1008                      pChannel->pScript->handlerNote->isPolyphonic() &&                      pChannel->pScript->handlerNote->isPolyphonic() &&
1009                      pChannel->pScript->handlerRelease->isPolyphonic() &&                      pChannel->pScript->handlerRelease->isPolyphonic())
                     !pChannel->pScript->pKeyEvents[key]->isEmpty())  
1010                  {                  {
1011                      // polyphonic variable data is used/passed from "note" to                      // polyphonic variable data is used/passed from "note" to
1012                      // "release" script callback, so we have to recycle the                      // "release" script callback; first assume the "note" script
1013                      // original "note on" script event                      // callback already finished execution and waits for being
1014                        // recycled for the "release" script handler ...
1015                      RTList<ScriptEvent>::Iterator it  = pChannel->pScript->pKeyEvents[key]->first();                      RTList<ScriptEvent>::Iterator it  = pChannel->pScript->pKeyEvents[key]->first();
1016                      RTList<ScriptEvent>::Iterator end = pChannel->pScript->pKeyEvents[key]->end();                      RTList<ScriptEvent>::Iterator end = pChannel->pScript->pKeyEvents[key]->end();
1017                      for (; it != end; ++it) {                      for (; it != end; ++it) {
1018                          // Despite the loop, in fact we're just picking and                          // Despite the loop, in fact we're just picking and
1019                          // running EXACTLY ONE script event here and then leave                          // running EXACTLY ONE script event here and then leave
1020                          // the loop immediately. The following check, and with                          // the loop immediately.
                         // it the loop itself is probably overkill/redundant,  
                         // because once we executed the script here, the chosen  
                         // script event will be moved away from the pKeyEvents  
                         // list. Which means we could probably drop the loop and  
                         // simply always pick the very first script event from  
                         // pKeyEvents here and that's it.  
1021                          if (it->handlerType != VM_EVENT_HANDLER_NOTE)                          if (it->handlerType != VM_EVENT_HANDLER_NOTE)
1022                              continue;                              continue;
1023                            // Skip "note" script callbacks which have already been
1024                            // picked (in this loop) for a "release" callback
1025                            // before. This ensures that a "note" script callback is
1026                            // really just used once for a "release" callback.
1027                            if (it->releaseMatched)
1028                                continue;
1029                            it->releaseMatched = true;
1030                            // Now recycle the picked old "note" script callback for
1031                            // the "release" script callback.
1032                          ProcessScriptEvent(                          ProcessScriptEvent(
1033                              pChannel, itEvent, pEventHandler, it                              pChannel, itEvent, pEventHandler, it
1034                          );                          );
# Line 1038  namespace LinuxSampler { Line 1041  namespace LinuxSampler {
1041                          // might increment a script variable in the "note"                          // might increment a script variable in the "note"
1042                          // handler and decrement the variable in the "release"                          // handler and decrement the variable in the "release"
1043                          // handler to count the currently pressed down keys).                          // handler to count the currently pressed down keys).
1044                          break;                          return;
1045                        }
1046                        // If we're here then the original "note" script callback
1047                        // has not finished execution yet (i.e. it is currently
1048                        // suspended). This requires a more expensive solution:
1049                        // search on the list of all yet active script callbacks.
1050                        it  = pChannel->pScript->pEvents->first();
1051                        end = pChannel->pScript->pEvents->end();
1052                        for (; it != end; ++it) {
1053                            if (it->handlerType != VM_EVENT_HANDLER_NOTE)
1054                                continue;
1055                            if (it->cause.Param.Note.Key != itEvent->Param.Note.Key)
1056                                continue;
1057                            if (it->releaseMatched)
1058                                continue;
1059                            it->releaseMatched = true;
1060                            // As the original "note" callback is still running, we
1061                            // cannot recycle it, instead we spawn a completely new
1062                            // script handler and just copy the "note" handler's
1063                            // polyphonic data.
1064                            RTList<ScriptEvent>::Iterator itScriptEvent =
1065                                pChannel->pScript->pEvents->allocAppend();
1066                            itScriptEvent->execCtx->copyPolyphonicDataFrom(it->execCtx);
1067                            // Now run the new "release" handler with the polyphonic
1068                            // data copied from the original "note" handler.
1069                            ProcessScriptEvent(
1070                                pChannel, itEvent, pEventHandler, itScriptEvent
1071                            );
1072                            // Done. Matched exactly one note <-> release handler.
1073                            return;
1074                      }                      }
1075                        // This should never happen. Otherwise it's a bug.
1076                        dmsg(0,("[ScriptVM] WARNING: No matching previous \"note\" event handler found for polyphonic \"release\" event handler!\n"));
1077                  } else {                  } else {
1078                      // no polyphonic data is used/passed from "note" to                      // no polyphonic data is used/passed from "note" to
1079                      // "release" script callback, so just use a new fresh                      // "release" script callback, so just use a new fresh
# Line 1086  namespace LinuxSampler { Line 1120  namespace LinuxSampler {
1120                  itScriptEvent->currentHandler = 0;                  itScriptEvent->currentHandler = 0;
1121                  itScriptEvent->executionSlices = 0;                  itScriptEvent->executionSlices = 0;
1122                  itScriptEvent->ignoreAllWaitCalls = false;                  itScriptEvent->ignoreAllWaitCalls = false;
1123                    itScriptEvent->releaseMatched = false;
1124                  itScriptEvent->handlerType = pEventHandler->eventHandlerType();                  itScriptEvent->handlerType = pEventHandler->eventHandlerType();
1125                  itScriptEvent->parentHandlerID = 0;                  itScriptEvent->parentHandlerID = 0;
1126                  itScriptEvent->childHandlerID[0] = 0;                  itScriptEvent->childHandlerID[0] = 0;
# Line 1377  namespace LinuxSampler { Line 1412  namespace LinuxSampler {
1412                              itScriptEvent->currentHandler = 0;                              itScriptEvent->currentHandler = 0;
1413                              itScriptEvent->executionSlices = 0;                              itScriptEvent->executionSlices = 0;
1414                              itScriptEvent->ignoreAllWaitCalls = false;                              itScriptEvent->ignoreAllWaitCalls = false;
1415                                itScriptEvent->releaseMatched = false; // not relevant for init handler actually
1416                              itScriptEvent->handlerType = VM_EVENT_HANDLER_INIT;                              itScriptEvent->handlerType = VM_EVENT_HANDLER_INIT;
1417                              itScriptEvent->parentHandlerID = 0;                              itScriptEvent->parentHandlerID = 0;
1418                              itScriptEvent->childHandlerID[0] = 0;                              itScriptEvent->childHandlerID[0] = 0;

Legend:
Removed from v.3844  
changed lines
  Added in v.3845

  ViewVC Help
Powered by ViewVC