/[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 2618 by schoenebeck, Wed Jun 11 11:39:44 2014 UTC revision 2837 by persson, Sun Aug 23 06:14:00 2015 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-2015 Christian Schoenebeck and 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 432  namespace LinuxSampler { Line 432  namespace LinuxSampler {
432               * @param pRegion - region the engine shall stop using               * @param pRegion - region the engine shall stop using
433               */               */
434              virtual void Suspend(RR* pRegion) {              virtual void Suspend(RR* pRegion) {
435                  dmsg(2,("EngineBase: Suspending Region %x ...\n",pRegion));                  dmsg(2,("EngineBase: Suspending Region %p ...\n",(void*)pRegion));
436                  {                  {
437                      LockGuard lock(SuspendedRegionsMutex);                      LockGuard lock(SuspendedRegionsMutex);
438                      SuspensionChangeOngoing.Set(true);                      SuspensionChangeOngoing.Set(true);
439                      pPendingRegionSuspension = pRegion;                      pPendingRegionSuspension = pRegion;
440                      SuspensionChangeOngoing.WaitAndUnlockIf(true);                      SuspensionChangeOngoing.WaitAndUnlockIf(true);
441                  }                  }
442                  dmsg(2,("EngineBase: Region %x suspended.",pRegion));                  dmsg(2,("EngineBase: Region %p suspended.",(void*)pRegion));
443              }              }
444    
445              /**              /**
# Line 449  namespace LinuxSampler { Line 449  namespace LinuxSampler {
449               * @param pRegion - region the engine shall be allowed to use again               * @param pRegion - region the engine shall be allowed to use again
450               */               */
451              virtual void Resume(RR* pRegion) {              virtual void Resume(RR* pRegion) {
452                  dmsg(2,("EngineBase: Resuming Region %x ...\n",pRegion));                  dmsg(2,("EngineBase: Resuming Region %p ...\n",(void*)pRegion));
453                  {                  {
454                      LockGuard lock(SuspendedRegionsMutex);                      LockGuard lock(SuspendedRegionsMutex);
455                      SuspensionChangeOngoing.Set(true);                      SuspensionChangeOngoing.Set(true);
456                      pPendingRegionResumption = pRegion;                      pPendingRegionResumption = pRegion;
457                      SuspensionChangeOngoing.WaitAndUnlockIf(true);                      SuspensionChangeOngoing.WaitAndUnlockIf(true);
458                  }                  }
459                  dmsg(2,("EngineBase: Region %x resumed.\n",pRegion));                  dmsg(2,("EngineBase: Region %p resumed.\n",(void*)pRegion));
460              }              }
461    
462              virtual void ResetSuspendedRegions() {              virtual void ResetSuspendedRegions() {
# Line 634  namespace LinuxSampler { Line 634  namespace LinuxSampler {
634                  // if a valid real-time instrument script is loaded, pre-process                  // if a valid real-time instrument script is loaded, pre-process
635                  // the event list by running the script now, since the script                  // the event list by running the script now, since the script
636                  // might filter events or add new ones for this cycle                  // might filter events or add new ones for this cycle
637                  if (pChannel->pScript && pChannel->pScript->bHasValidScript) {                  if (pChannel->pScript) {
638                      // resume any suspended script executions still hanging                      // resume any suspended script executions still hanging
639                      // around of previous audio fragment cycles                      // around of previous audio fragment cycles
640                      for (RTList<ScriptEvent>::Iterator itEvent = pChannel->pScript->pEvents->first(),                      for (RTList<ScriptEvent>::Iterator itEvent = pChannel->pScript->pEvents->first(),
# Line 723  namespace LinuxSampler { Line 723  namespace LinuxSampler {
723               * @param pEventHandler - script's event handler to be executed               * @param pEventHandler - script's event handler to be executed
724               */               */
725              void ProcessEventByScript(AbstractEngineChannel* pChannel, RTList<Event>::Iterator& itEvent, VMEventHandler* pEventHandler) {              void ProcessEventByScript(AbstractEngineChannel* pChannel, RTList<Event>::Iterator& itEvent, VMEventHandler* pEventHandler) {
726                  RTList<ScriptEvent>::Iterator itScriptEvent =                  const int key = itEvent->Param.Note.Key; // even if this is not a note on/off event, accessing it does not mean any harm
727                      pChannel->pScript->pEvents->allocAppend();                  // check if polyphonic data is passed from "note" to "release"
728                    // script event handlers
729                    if (pEventHandler == pChannel->pScript->handlerRelease &&
730                        pChannel->pScript->handlerNote &&
731                        pChannel->pScript->handlerNote->isPolyphonic() &&
732                        pChannel->pScript->handlerRelease->isPolyphonic() &&
733                        !pChannel->pScript->pKeyEvents[key]->isEmpty())
734                    {
735                        // polyphonic variable data is used/passed from "note" to
736                        // "release" script callback, so we have to recycle the
737                        // original "note on" script event(s)
738                        RTList<ScriptEvent>::Iterator it  = pChannel->pScript->pKeyEvents[key]->first();
739                        RTList<ScriptEvent>::Iterator end = pChannel->pScript->pKeyEvents[key]->end();
740                        for (; it != end; ++it) {
741                            ProcessScriptEvent(
742                                pChannel, itEvent, pEventHandler, it
743                            );
744                        }
745                    } else {
746                        // no polyphonic data is used/passed from "note" to
747                        // "release" script callback, so just use a new fresh
748                        // script event object
749                        RTList<ScriptEvent>::Iterator itScriptEvent =
750                            pChannel->pScript->pEvents->allocAppend();
751                        ProcessScriptEvent(
752                            pChannel, itEvent, pEventHandler, itScriptEvent
753                        );
754                    }
755                }
756    
757                  if (!itScriptEvent) return; // no free script event left for execution              void ProcessScriptEvent(AbstractEngineChannel* pChannel, RTList<Event>::Iterator& itEvent, VMEventHandler* pEventHandler, RTList<ScriptEvent>::Iterator& itScriptEvent) {
758                    if (!itScriptEvent) return; // not a valid script event (i.e. because no free script event was left in the script event pool)
759    
760                  // fill the list of script handlers to be executed by this event                  // fill the list of script handlers to be executed by this event
761                  int i = 0;                  int i = 0;
# Line 745  namespace LinuxSampler { Line 774  namespace LinuxSampler {
774                  );                  );
775    
776                  // in case the script was suspended, keep it on the allocated                  // in case the script was suspended, keep it on the allocated
777                  // ScriptEvent list to be continued on the next audio cycle,                  // ScriptEvent list to be continued on the next audio cycle
778                  // otherwise if execution has been finished, free it for a new                  if (!(res & VM_EXEC_SUSPENDED)) { // script execution has finished without 'suspended' status ...
779                  // future script event to be triggered from start                      // if "polyphonic" variable data is passed from script's
780                  if (!(res & VM_EXEC_SUSPENDED))                      // "note" event handler to its "release" event handler, then
781                      pChannel->pScript->pEvents->free(itScriptEvent);                      // the script event must be kept and recycled for the later
782                        // occuring "release" script event ...
783                        if (pEventHandler == pChannel->pScript->handlerNote &&
784                            pChannel->pScript->handlerRelease &&
785                            pChannel->pScript->handlerNote->isPolyphonic() &&
786                            pChannel->pScript->handlerRelease->isPolyphonic())
787                        {
788                            const int key = itEvent->Param.Note.Key;
789                            itScriptEvent.moveToEndOf(pChannel->pScript->pKeyEvents[key & 127]);
790                        } else {
791                            // ... otherwise if no polyphonic data is passed and
792                            // script's execution has finished without suspension
793                            // status, then free the script event for a new future
794                            // script event to be triggered from start
795                            pChannel->pScript->pEvents->free(itScriptEvent);
796                        }
797                    }
798              }              }
799    
800              /** @brief Resume execution of instrument script.              /** @brief Resume execution of instrument script.
# Line 770  namespace LinuxSampler { Line 815  namespace LinuxSampler {
815               * @param itScriptEvent - script execution that shall be resumed               * @param itScriptEvent - script execution that shall be resumed
816               */               */
817              void ResumeScriptEvent(AbstractEngineChannel* pChannel, RTList<ScriptEvent>::Iterator& itScriptEvent) {              void ResumeScriptEvent(AbstractEngineChannel* pChannel, RTList<ScriptEvent>::Iterator& itScriptEvent) {
818                    VMEventHandler* handler = itScriptEvent->handlers[itScriptEvent->currentHandler];
819    
820                  // run script                  // run script
821                  VMExecStatus_t res = pScriptVM->exec(                  VMExecStatus_t res = pScriptVM->exec(
822                      pChannel->pScript->parserContext, &*itScriptEvent                      pChannel->pScript->parserContext, &*itScriptEvent
823                  );                  );
824                  // in case the script was again suspended, keep it on the allocated  
825                  // ScriptEvent list to be continued on the next audio cycle,                  // in case the script was suspended, keep it on the allocated
826                  // otherwise if execution has been finished, free it for a new                  // ScriptEvent list to be continued on the next audio cycle
827                  // future script event to be triggered from start                  if (!(res & VM_EXEC_SUSPENDED)) { // script execution has finished without 'suspended' status ...
828                  if (!(res & VM_EXEC_SUSPENDED))                      // if "polyphonic" variable data is passed from script's
829                      pChannel->pScript->pEvents->free(itScriptEvent);                      // "note" event handler to its "release" event handler, then
830                        // the script event must be kept and recycled for the later
831                        // occuring "release" script event ...
832                        if (handler && handler == pChannel->pScript->handlerNote &&
833                            pChannel->pScript->handlerRelease &&
834                            pChannel->pScript->handlerNote->isPolyphonic() &&
835                            pChannel->pScript->handlerRelease->isPolyphonic())
836                        {
837                            const int key = itScriptEvent->cause.Param.Note.Key;
838                            itScriptEvent.moveToEndOf(pChannel->pScript->pKeyEvents[key & 127]);
839                        } else {
840                            // ... otherwise if no polyphonic data is passed and
841                            // script's execution has finished without suspension
842                            // status, then free the script event for a new future
843                            // script event to be triggered from start
844                            pChannel->pScript->pEvents->free(itScriptEvent);
845                        }
846                    }
847              }              }
848    
849              /**              /**
# Line 914  namespace LinuxSampler { Line 978  namespace LinuxSampler {
978                          dmsg(5,("Engine: instrument change command received\n"));                          dmsg(5,("Engine: instrument change command received\n"));
979                          cmd.bChangeInstrument = false;                          cmd.bChangeInstrument = false;
980                          pEngineChannel->pInstrument = cmd.pInstrument;                          pEngineChannel->pInstrument = cmd.pInstrument;
981                          pEngineChannel->pScript = cmd.pScript;                          pEngineChannel->pScript =
982                                cmd.pScript->bHasValidScript ? cmd.pScript : NULL;
983                          instrumentChanged = true;                          instrumentChanged = true;
984    
985                          pEngineChannel->MarkAllActiveVoicesAsOrphans();                          pEngineChannel->MarkAllActiveVoicesAsOrphans();
# Line 1090  namespace LinuxSampler { Line 1155  namespace LinuxSampler {
1155                                  case 0x1d: { // reverb send of note (Roland GS NRPN)                                  case 0x1d: { // reverb send of note (Roland GS NRPN)
1156                                      const uint note = NrpnCtrlLSB;                                      const uint note = NrpnCtrlLSB;
1157                                      const float reverb = float(itControlChangeEvent->Param.CC.Value) / 127.0f;                                      const float reverb = float(itControlChangeEvent->Param.CC.Value) / 127.0f;
1158                                      dmsg(4,("Note Reverb Send NRPN received (note=%d,send=%d).\n", note, reverb));                                      dmsg(4,("Note Reverb Send NRPN received (note=%d,send=%f).\n", note, reverb));
1159                                      if (note < 128)                                      if (note < 128)
1160                                          pChannel->pMIDIKeyInfo[note].ReverbSend = reverb;                                          pChannel->pMIDIKeyInfo[note].ReverbSend = reverb;
1161                                      break;                                      break;
# Line 1098  namespace LinuxSampler { Line 1163  namespace LinuxSampler {
1163                                  case 0x1e: { // chorus send of note (Roland GS NRPN)                                  case 0x1e: { // chorus send of note (Roland GS NRPN)
1164                                      const uint note = NrpnCtrlLSB;                                      const uint note = NrpnCtrlLSB;
1165                                      const float chorus = float(itControlChangeEvent->Param.CC.Value) / 127.0f;                                      const float chorus = float(itControlChangeEvent->Param.CC.Value) / 127.0f;
1166                                      dmsg(4,("Note Chorus Send NRPN received (note=%d,send=%d).\n", note, chorus));                                      dmsg(4,("Note Chorus Send NRPN received (note=%d,send=%f).\n", note, chorus));
1167                                      if (note < 128)                                      if (note < 128)
1168                                          pChannel->pMIDIKeyInfo[note].ChorusSend = chorus;                                          pChannel->pMIDIKeyInfo[note].ChorusSend = chorus;
1169                                      break;                                      break;

Legend:
Removed from v.2618  
changed lines
  Added in v.2837

  ViewVC Help
Powered by ViewVC