/[svn]/linuxsampler/trunk/src/engines/common/InstrumentScriptVM.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/common/InstrumentScriptVM.cpp

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

revision 2931 by schoenebeck, Sat Jul 9 14:38:33 2016 UTC revision 3971 by schoenebeck, Fri Jun 25 09:26:00 2021 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 - 2016 Christian Schoenebeck   * Copyright (c) 2014 - 2021 Christian Schoenebeck
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 7  Line 7 
7   * See README file for details.   * See README file for details.
8   */   */
9    
10    #include "../../common/global_private.h"
11  #include "InstrumentScriptVM.h"  #include "InstrumentScriptVM.h"
12  #include "../AbstractEngineChannel.h"  #include "../AbstractEngineChannel.h"
13  #include "../../common/global_private.h"  #include "../../common/global_private.h"
14  #include "AbstractInstrumentManager.h"  #include "AbstractInstrumentManager.h"
15  #include "MidiKeyboardManager.h"  #include "MidiKeyboardManager.h"
16    #include "Fade.h"
17    
18  namespace LinuxSampler {  namespace LinuxSampler {
19    
20      ///////////////////////////////////////////////////////////////////////      ///////////////////////////////////////////////////////////////////////
21      // class 'EventGroup'      // class 'EventGroup'
22    
23      void EventGroup::insert(int eventID) {      void EventGroup::insert(vmint eventID) {
24          if (contains(eventID)) return;          if (contains(eventID)) return;
25    
26          AbstractEngine* pEngine = m_script->pEngineChannel->pEngine;          AbstractEngine* pEngine = m_script->pEngineChannel->pEngine;
# Line 29  namespace LinuxSampler { Line 31  namespace LinuxSampler {
31          // events die before being removed explicitly from the group by script          // events die before being removed explicitly from the group by script
32          //          //
33          // NOTE: or should we do this "dead ones" check only once in a while?          // NOTE: or should we do this "dead ones" check only once in a while?
34          int firstDead = -1;          ssize_t firstDead = -1;
35          for (int i = 0; i < size(); ++i) {          for (size_t i = 0; i < size(); ++i) {
36              if (firstDead >= 0) {              if (firstDead >= 0) {
37                  if (pEngine->EventByID(eventID)) {                  if (pEngine->EventByID(eventID)) {
38                      remove(firstDead, i - firstDead);                      remove(firstDead, i - firstDead);
# Line 40  namespace LinuxSampler { Line 42  namespace LinuxSampler {
42                  if (!pEngine->EventByID(eventID)) firstDead = i;                  if (!pEngine->EventByID(eventID)) firstDead = i;
43              }              }
44          }          }
45            if (firstDead >= 0)
46                remove(firstDead, size() - firstDead);
47    
48          append(eventID);          append(eventID);
49      }      }
50    
51      void EventGroup::erase(int eventID) {      void EventGroup::erase(vmint eventID) {
52          int index = find(eventID);          size_t index = find(eventID);
53          remove(index);          remove(index);
54      }      }
55    
# Line 59  namespace LinuxSampler { Line 63  namespace LinuxSampler {
63          handlerNote = NULL;          handlerNote = NULL;
64          handlerRelease = NULL;          handlerRelease = NULL;
65          handlerController = NULL;          handlerController = NULL;
66            handlerRpn = NULL;
67            handlerNrpn = NULL;
68          pEvents = NULL;          pEvents = NULL;
69          for (int i = 0; i < 128; ++i)          for (int i = 0; i < 128; ++i)
70              pKeyEvents[i] = NULL;              pKeyEvents[i] = NULL;
# Line 84  namespace LinuxSampler { Line 90  namespace LinuxSampler {
90       * channels.       * channels.
91       *       *
92       * @param text - source code of script       * @param text - source code of script
93         * @param patchVars - 'patch' variables being overridden by instrument
94       */       */
95      void InstrumentScript::load(const String& text) {      void InstrumentScript::load(const String& text,
96                                    const std::map<String,String>& patchVars)
97        {
98          dmsg(1,("Loading real-time instrument script ... "));          dmsg(1,("Loading real-time instrument script ... "));
99    
100          // hand back old script reference and VM execution contexts          // hand back old script reference and VM execution contexts
# Line 97  namespace LinuxSampler { Line 106  namespace LinuxSampler {
106          AbstractInstrumentManager* pManager =          AbstractInstrumentManager* pManager =
107              dynamic_cast<AbstractInstrumentManager*>(pEngineChannel->pEngine->GetInstrumentManager());              dynamic_cast<AbstractInstrumentManager*>(pEngineChannel->pEngine->GetInstrumentManager());
108    
109          // get new script reference          /*
110          parserContext = pManager->scripts.Borrow(text, pEngineChannel);             Get new script reference.
111    
112               Note: every engine channel now has its own compiled script object
113               (a.k.a. VMParserContext). Originally a compiled script was shared by
114               multiple engine channels. This was wrong: we cannot share compiled
115               script instances among multiple engine channels (parts), for two
116               reasons:
117    
118               1. VMParserContext not only encompasses the compiled tree
119                  presentation of the requested script, but also global variables
120                  and we don't want those global variables to be modified by
121                  different sampler parts, as this would not be expected behaviour
122                  by instrument script authors.
123    
124               2. If there is more than one sampler engine instance (e.g. if there
125                  are multiple audio output device instances) this would even crash,
126                  because each sampler engine instance has its own ScriptVM
127                  instance, and a (VM)ParserContext is always tied to exactly one
128                  ScriptVM instance.
129    
130               We would not be buying much by sharing compiled scripts anyway, as a
131               script usually compiles in couple microseconds and RAM usage is also
132               neglectable.
133            */
134            parserContext = pManager->scripts.Borrow({
135                    .code = text,
136                    .patchVars = patchVars,
137                    .engineChannel = pEngineChannel /* unique owner of script */
138                },
139                pEngineChannel /* who is asking to borrow */
140            );
141          if (!parserContext->errors().empty()) {          if (!parserContext->errors().empty()) {
142              std::vector<ParserIssue> errors = parserContext->errors();              std::vector<ParserIssue> errors = parserContext->errors();
143              std::cerr << "[ScriptVM] Could not load instrument script, there were "              std::cerr << "[ScriptVM] Could not load instrument script, there were "
# Line 112  namespace LinuxSampler { Line 151  namespace LinuxSampler {
151          handlerNote = parserContext->eventHandlerByName("note");          handlerNote = parserContext->eventHandlerByName("note");
152          handlerRelease = parserContext->eventHandlerByName("release");          handlerRelease = parserContext->eventHandlerByName("release");
153          handlerController = parserContext->eventHandlerByName("controller");          handlerController = parserContext->eventHandlerByName("controller");
154            handlerRpn = parserContext->eventHandlerByName("rpn");
155            handlerNrpn = parserContext->eventHandlerByName("nrpn");
156          bHasValidScript =          bHasValidScript =
157              handlerInit || handlerNote || handlerRelease || handlerController;              handlerInit || handlerNote || handlerRelease || handlerController ||
158                handlerRpn || handlerNrpn;
159    
160          // amount of script handlers each script event has to execute          // amount of script handlers each script event has to execute
161          int handlerExecCount = 0;          int handlerExecCount = 0;
162          if (handlerNote || handlerRelease || handlerController) // only one of these are executed after "init" handler          if (handlerNote || handlerRelease || handlerController || handlerRpn ||
163                handlerNrpn) // only one of these are executed after "init" handler
164              handlerExecCount++;              handlerExecCount++;
165    
166          // create script event pool (if it doesn't exist already)          // create script event pool (if it doesn't exist already)
# Line 125  namespace LinuxSampler { Line 168  namespace LinuxSampler {
168              pEvents = new Pool<ScriptEvent>(CONFIG_MAX_EVENTS_PER_FRAGMENT);              pEvents = new Pool<ScriptEvent>(CONFIG_MAX_EVENTS_PER_FRAGMENT);
169              for (int i = 0; i < 128; ++i)              for (int i = 0; i < 128; ++i)
170                  pKeyEvents[i] = new RTList<ScriptEvent>(pEvents);                  pKeyEvents[i] = new RTList<ScriptEvent>(pEvents);
171                // reset RTAVLNode's tree node member variables after nodes are allocated
172                // (since we can't use a constructor right now, we do that initialization here)
173                while (!pEvents->poolIsEmpty()) {
174                    RTList<ScriptEvent>::Iterator it = pEvents->allocAppend();
175                    it->reset();
176                }
177          }          }
178            pEvents->clear(); // outside of upper block, as loop below must always start from cleared list
179    
180          // create new VM execution contexts for new script          // create new VM execution contexts for new script
181          while (!pEvents->poolIsEmpty()) {          while (!pEvents->poolIsEmpty()) {
# Line 164  namespace LinuxSampler { Line 214  namespace LinuxSampler {
214              pEvents->clear();              pEvents->clear();
215              while (!pEvents->poolIsEmpty()) {              while (!pEvents->poolIsEmpty()) {
216                  RTList<ScriptEvent>::Iterator it = pEvents->allocAppend();                  RTList<ScriptEvent>::Iterator it = pEvents->allocAppend();
217                    if (!it) break;
218                  if (it->execCtx) {                  if (it->execCtx) {
219                      // free VM execution context object                      // free VM execution context object
220                      delete it->execCtx;                      delete it->execCtx;
221                      it->execCtx = NULL;                      it->execCtx = NULL;
222                      // free C array of handler pointers                      // free C array of handler pointers
223                      delete [] it->handlers;                      delete [] it->handlers;
224                        it->handlers = NULL;
225                  }                  }
226              }              }
227              pEvents->clear();              pEvents->clear();
# Line 185  namespace LinuxSampler { Line 237  namespace LinuxSampler {
237              handlerNote = NULL;              handlerNote = NULL;
238              handlerRelease = NULL;              handlerRelease = NULL;
239              handlerController = NULL;              handlerController = NULL;
240                handlerRpn = NULL;
241                handlerNrpn = NULL;
242          }          }
243          bHasValidScript = false;          bHasValidScript = false;
244      }      }
# Line 220  namespace LinuxSampler { Line 274  namespace LinuxSampler {
274    
275      InstrumentScriptVM::InstrumentScriptVM() :      InstrumentScriptVM::InstrumentScriptVM() :
276          m_event(NULL), m_fnPlayNote(this), m_fnSetController(this),          m_event(NULL), m_fnPlayNote(this), m_fnSetController(this),
277            m_fnSetRpn(this), m_fnSetNrpn(this),
278          m_fnIgnoreEvent(this), m_fnIgnoreController(this), m_fnNoteOff(this),          m_fnIgnoreEvent(this), m_fnIgnoreController(this), m_fnNoteOff(this),
279          m_fnSetEventMark(this), m_fnDeleteEventMark(this), m_fnByMarks(this),          m_fnSetEventMark(this), m_fnDeleteEventMark(this), m_fnByMarks(this),
280          m_fnChangeVol(this), m_fnChangeTune(this), m_fnChangePan(this)          m_fnChangeVol(this), m_fnChangeVolTime(this),
281            m_fnChangeTune(this), m_fnChangeTuneTime(this), m_fnChangePan(this),
282            m_fnChangePanTime(this), m_fnChangePanCurve(this),
283            m_fnChangeCutoff(this), m_fnChangeReso(this),  m_fnChangeAttack(this),
284            m_fnChangeDecay(this), m_fnChangeSustain(this), m_fnChangeRelease(this),
285            m_fnChangeCutoffAttack(this), m_fnChangeCutoffDecay(this),
286            m_fnChangeCutoffSustain(this), m_fnChangeCutoffRelease(this),
287            m_fnChangeAmpLFODepth(this), m_fnChangeAmpLFOFreq(this),
288            m_fnChangeCutoffLFODepth(this), m_fnChangeCutoffLFOFreq(this),
289            m_fnChangePitchLFODepth(this), m_fnChangePitchLFOFreq(this),
290            m_fnChangeNote(this), m_fnChangeVelo(this), m_fnFork(this),
291            m_fnEventStatus(this), m_fnWait2(this), m_fnStopWait(this),
292            m_fnAbort(this), m_fnFadeIn(this), m_fnFadeOut(this),
293            m_fnChangeVolCurve(this), m_fnChangeTuneCurve(this),
294            m_fnGetEventPar(this), m_fnSetEventPar(this), m_fnChangePlayPos(this),
295            m_fnCallbackStatus(this),
296            m_varEngineUptime(this), m_varCallbackID(this), m_varAllEvents(this),
297            m_varCallbackChildID(this)
298      {      {
299          m_CC.size = _MEMBER_SIZEOF(AbstractEngineChannel, ControllerTable);          m_CC.size = _MEMBER_SIZEOF(AbstractEngineChannel, ControllerTable);
300          m_CC_NUM = DECLARE_VMINT(m_event, class ScriptEvent, cause.Param.CC.Controller);          m_CC_NUM = DECLARE_VMINT(m_event, class ScriptEvent, cause.Param.CC.Controller);
301          m_EVENT_ID = DECLARE_VMINT(m_event, class ScriptEvent, id);          m_EVENT_ID = DECLARE_VMINT_READONLY(m_event, class ScriptEvent, id);
302          m_EVENT_NOTE = DECLARE_VMINT(m_event, class ScriptEvent, cause.Param.Note.Key);          m_EVENT_NOTE = DECLARE_VMINT_READONLY(m_event, class ScriptEvent, cause.Param.Note.Key);
303          m_EVENT_VELOCITY = DECLARE_VMINT(m_event, class ScriptEvent, cause.Param.Note.Velocity);          m_EVENT_VELOCITY = DECLARE_VMINT_READONLY(m_event, class ScriptEvent, cause.Param.Note.Velocity);
304            m_RPN_ADDRESS = DECLARE_VMINT_READONLY(m_event, class ScriptEvent, cause.Param.RPN.Parameter);
305            m_RPN_VALUE = DECLARE_VMINT_READONLY(m_event, class ScriptEvent, cause.Param.RPN.Value);
306          m_KEY_DOWN.size = 128;          m_KEY_DOWN.size = 128;
307            m_KEY_DOWN.readonly = true;
308            m_NI_CALLBACK_TYPE = DECLARE_VMINT_READONLY(m_event, class ScriptEvent, handlerType);
309            m_NKSP_IGNORE_WAIT = DECLARE_VMINT(m_event, class ScriptEvent, ignoreAllWaitCalls);
310            m_NKSP_CALLBACK_PARENT_ID = DECLARE_VMINT_READONLY(m_event, class ScriptEvent, parentHandlerID);
311      }      }
312    
313      VMExecStatus_t InstrumentScriptVM::exec(VMParserContext* parserCtx, ScriptEvent* event) {      VMExecStatus_t InstrumentScriptVM::exec(VMParserContext* parserCtx, ScriptEvent* event) {
# Line 259  namespace LinuxSampler { Line 337  namespace LinuxSampler {
337                      pEngineChannel->ControllerTable[CTRL_TABLE_IDX_PITCHBEND] =                      pEngineChannel->ControllerTable[CTRL_TABLE_IDX_PITCHBEND] =
338                          event->cause.Param.Pitch.Pitch;                          event->cause.Param.Pitch.Pitch;
339                      break;                      break;
340                    default:
341                        ; // noop
342              }              }
343          }          }
344    
# Line 269  namespace LinuxSampler { Line 349  namespace LinuxSampler {
349                  parserCtx, event->execCtx, event->handlers[event->currentHandler]                  parserCtx, event->execCtx, event->handlers[event->currentHandler]
350              );              );
351              event->executionSlices++;              event->executionSlices++;
352                if (!(res & VM_EXEC_SUSPENDED)) { // if script terminated ...
353                    // check if this script handler instance has any forked children
354                    // to be auto aborted
355                    for (int iChild = 0; iChild < MAX_FORK_PER_SCRIPT_HANDLER &&
356                         event->childHandlerID[iChild]; ++iChild)
357                    {
358                        RTList<ScriptEvent>::Iterator itChild =
359                            pEngineChannel->ScriptCallbackByID(event->childHandlerID[iChild]);
360                        if (itChild && itChild->autoAbortByParent)
361                            itChild->execCtx->signalAbort();
362                    }
363                }
364              if (res & VM_EXEC_SUSPENDED || res & VM_EXEC_ERROR) return res;              if (res & VM_EXEC_SUSPENDED || res & VM_EXEC_ERROR) return res;
365          }          }
366    
367          return res;          return res;
368      }      }
369    
370      std::map<String,VMIntRelPtr*> InstrumentScriptVM::builtInIntVariables() {      std::map<String,VMIntPtr*> InstrumentScriptVM::builtInIntVariables() {
371          // first get buil-in integer variables of derived VM class          // first get built-in integer variables of derived VM class
372          std::map<String,VMIntRelPtr*> m = ScriptVM::builtInIntVariables();          std::map<String,VMIntPtr*> m = ScriptVM::builtInIntVariables();
373    
374          // now add own built-in variables          // now add own built-in variables
375          m["$CC_NUM"] = &m_CC_NUM;          m["$CC_NUM"] = &m_CC_NUM;
# Line 285  namespace LinuxSampler { Line 377  namespace LinuxSampler {
377          m["$EVENT_NOTE"] = &m_EVENT_NOTE;          m["$EVENT_NOTE"] = &m_EVENT_NOTE;
378          m["$EVENT_VELOCITY"] = &m_EVENT_VELOCITY;          m["$EVENT_VELOCITY"] = &m_EVENT_VELOCITY;
379  //         m["$POLY_AT_NUM"] = &m_POLY_AT_NUM;  //         m["$POLY_AT_NUM"] = &m_POLY_AT_NUM;
380            m["$RPN_ADDRESS"] = &m_RPN_ADDRESS; // used for both RPN and NRPN events
381            m["$RPN_VALUE"] = &m_RPN_VALUE;     // used for both RPN and NRPN events
382            m["$NI_CALLBACK_TYPE"] = &m_NI_CALLBACK_TYPE;
383            m["$NKSP_IGNORE_WAIT"] = &m_NKSP_IGNORE_WAIT;
384            m["$NKSP_CALLBACK_PARENT_ID"] = &m_NKSP_CALLBACK_PARENT_ID;
385    
386          return m;          return m;
387      }      }
388    
389      std::map<String,VMInt8Array*> InstrumentScriptVM::builtInIntArrayVariables() {      std::map<String,VMInt8Array*> InstrumentScriptVM::builtInIntArrayVariables() {
390          // first get buil-in integer array variables of derived VM class          // first get built-in integer array variables of derived VM class
391          std::map<String,VMInt8Array*> m = ScriptVM::builtInIntArrayVariables();          std::map<String,VMInt8Array*> m = ScriptVM::builtInIntArrayVariables();
392    
393          // now add own built-in variables          // now add own built-in variables
# Line 301  namespace LinuxSampler { Line 398  namespace LinuxSampler {
398          return m;          return m;
399      }      }
400    
401      std::map<String,int> InstrumentScriptVM::builtInConstIntVariables() {      std::map<String,vmint> InstrumentScriptVM::builtInConstIntVariables() {
402          // first get buil-in integer variables of derived VM class          // first get built-in integer variables of derived VM class
403          std::map<String,int> m = ScriptVM::builtInConstIntVariables();          std::map<String,vmint> m = ScriptVM::builtInConstIntVariables();
404    
405            m["$EVENT_STATUS_INACTIVE"] = EVENT_STATUS_INACTIVE;
406            m["$EVENT_STATUS_NOTE_QUEUE"] = EVENT_STATUS_NOTE_QUEUE;
407          m["$VCC_MONO_AT"] = CTRL_TABLE_IDX_AFTERTOUCH;          m["$VCC_MONO_AT"] = CTRL_TABLE_IDX_AFTERTOUCH;
408          m["$VCC_PITCH_BEND"] = CTRL_TABLE_IDX_PITCHBEND;          m["$VCC_PITCH_BEND"] = CTRL_TABLE_IDX_PITCHBEND;
409          for (int i = 0; i < INSTR_SCRIPT_EVENT_GROUPS; ++i) {          for (int i = 0; i < INSTR_SCRIPT_EVENT_GROUPS; ++i) {
410              m["$MARK_" + ToString(i+1)] = i;              m["$MARK_" + ToString(i+1)] = i;
411          }          }
412            m["$EVENT_PAR_NOTE"] = EVENT_PAR_NOTE;
413            m["$EVENT_PAR_VELOCITY"] = EVENT_PAR_VELOCITY;
414            m["$EVENT_PAR_VOLUME"] = EVENT_PAR_VOLUME;
415            m["$EVENT_PAR_TUNE"] = EVENT_PAR_TUNE;
416            m["$EVENT_PAR_0"] = EVENT_PAR_0;
417            m["$EVENT_PAR_1"] = EVENT_PAR_1;
418            m["$EVENT_PAR_2"] = EVENT_PAR_2;
419            m["$EVENT_PAR_3"] = EVENT_PAR_3;
420            m["$NKSP_LINEAR"] = FADE_CURVE_LINEAR;
421            m["$NKSP_EASE_IN_EASE_OUT"] = FADE_CURVE_EASE_IN_EASE_OUT;
422            m["$CALLBACK_STATUS_TERMINATED"] = CALLBACK_STATUS_TERMINATED;
423            m["$CALLBACK_STATUS_QUEUE"]      = CALLBACK_STATUS_QUEUE;
424            m["$CALLBACK_STATUS_RUNNING"]    = CALLBACK_STATUS_RUNNING;
425    
426            return m;
427        }
428    
429        std::map<String,VMDynVar*> InstrumentScriptVM::builtInDynamicVariables() {
430            // first get built-in dynamic variables of derived VM class
431            std::map<String,VMDynVar*> m = ScriptVM::builtInDynamicVariables();
432    
433            m["%ALL_EVENTS"] = &m_varAllEvents;
434            m["$ENGINE_UPTIME"] = &m_varEngineUptime;
435            m["$NI_CALLBACK_ID"] = &m_varCallbackID;
436            m["%NKSP_CALLBACK_CHILD_ID"] = &m_varCallbackChildID;
437    
438          return m;          return m;
439      }      }
# Line 318  namespace LinuxSampler { Line 442  namespace LinuxSampler {
442          // built-in script functions of this class          // built-in script functions of this class
443          if      (name == "play_note") return &m_fnPlayNote;          if      (name == "play_note") return &m_fnPlayNote;
444          else if (name == "set_controller") return &m_fnSetController;          else if (name == "set_controller") return &m_fnSetController;
445            else if (name == "set_rpn") return &m_fnSetRpn;
446            else if (name == "set_nrpn") return &m_fnSetNrpn;
447          else if (name == "ignore_event") return &m_fnIgnoreEvent;          else if (name == "ignore_event") return &m_fnIgnoreEvent;
448          else if (name == "ignore_controller") return &m_fnIgnoreController;          else if (name == "ignore_controller") return &m_fnIgnoreController;
449          else if (name == "note_off") return &m_fnNoteOff;          else if (name == "note_off") return &m_fnNoteOff;
# Line 325  namespace LinuxSampler { Line 451  namespace LinuxSampler {
451          else if (name == "delete_event_mark") return &m_fnDeleteEventMark;          else if (name == "delete_event_mark") return &m_fnDeleteEventMark;
452          else if (name == "by_marks") return &m_fnByMarks;          else if (name == "by_marks") return &m_fnByMarks;
453          else if (name == "change_vol") return &m_fnChangeVol;          else if (name == "change_vol") return &m_fnChangeVol;
454            else if (name == "change_vol_time") return &m_fnChangeVolTime;
455          else if (name == "change_tune") return &m_fnChangeTune;          else if (name == "change_tune") return &m_fnChangeTune;
456            else if (name == "change_tune_time") return &m_fnChangeTuneTime;
457            else if (name == "change_note") return &m_fnChangeNote;
458            else if (name == "change_velo") return &m_fnChangeVelo;
459          else if (name == "change_pan") return &m_fnChangePan;          else if (name == "change_pan") return &m_fnChangePan;
460            else if (name == "change_pan_time") return &m_fnChangePanTime;
461            else if (name == "change_pan_curve") return &m_fnChangePanCurve;
462            else if (name == "change_cutoff") return &m_fnChangeCutoff;
463            else if (name == "change_reso") return &m_fnChangeReso;
464            else if (name == "change_attack") return &m_fnChangeAttack;
465            else if (name == "change_decay") return &m_fnChangeDecay;
466            else if (name == "change_sustain") return &m_fnChangeSustain;
467            else if (name == "change_release") return &m_fnChangeRelease;
468            else if (name == "change_cutoff_attack") return &m_fnChangeCutoffAttack;
469            else if (name == "change_cutoff_decay") return &m_fnChangeCutoffDecay;
470            else if (name == "change_cutoff_sustain") return &m_fnChangeCutoffSustain;
471            else if (name == "change_cutoff_release") return &m_fnChangeCutoffRelease;
472            else if (name == "change_amp_lfo_depth") return &m_fnChangeAmpLFODepth;
473            else if (name == "change_amp_lfo_freq") return &m_fnChangeAmpLFOFreq;
474            else if (name == "change_cutoff_lfo_depth") return &m_fnChangeCutoffLFODepth;
475            else if (name == "change_cutoff_lfo_freq") return &m_fnChangeCutoffLFOFreq;
476            else if (name == "change_pitch_lfo_depth") return &m_fnChangePitchLFODepth;
477            else if (name == "change_pitch_lfo_freq") return &m_fnChangePitchLFOFreq;
478            else if (name == "fade_in") return &m_fnFadeIn;
479            else if (name == "fade_out") return &m_fnFadeOut;
480            else if (name == "change_vol_curve") return &m_fnChangeVolCurve;
481            else if (name == "change_tune_curve") return &m_fnChangeTuneCurve;
482            else if (name == "change_play_pos") return &m_fnChangePlayPos;
483            else if (name == "get_event_par") return &m_fnGetEventPar;
484            else if (name == "set_event_par") return &m_fnSetEventPar;
485            else if (name == "event_status") return &m_fnEventStatus;
486            else if (name == "wait") return &m_fnWait2; // override wait() core implementation
487            else if (name == "stop_wait") return &m_fnStopWait;
488            else if (name == "abort") return &m_fnAbort;
489            else if (name == "fork") return &m_fnFork;
490            else if (name == "callback_status") return &m_fnCallbackStatus;
491    
492          // built-in script functions of derived VM class          // built-in script functions of derived VM class
493          return ScriptVM::functionByName(name);          return ScriptVM::functionByName(name);

Legend:
Removed from v.2931  
changed lines
  Added in v.3971

  ViewVC Help
Powered by ViewVC