/[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 2611 by schoenebeck, Mon Jun 9 19:20:37 2014 UTC revision 3971 by schoenebeck, Fri Jun 25 09:26:00 2021 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 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"
16    #include "Fade.h"
17    
18  namespace LinuxSampler {  namespace LinuxSampler {
19    
20      ///////////////////////////////////////////////////////////////////////      ///////////////////////////////////////////////////////////////////////
21        // class 'EventGroup'
22    
23        void EventGroup::insert(vmint eventID) {
24            if (contains(eventID)) return;
25    
26            AbstractEngine* pEngine = m_script->pEngineChannel->pEngine;
27    
28            // before adding the new event ID, check if there are any dead events
29            // and remove them in that case, before otherwise we might run in danger
30            // to run out of free space on this group for event IDs if a lot of
31            // 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?
34            ssize_t firstDead = -1;
35            for (size_t i = 0; i < size(); ++i) {
36                if (firstDead >= 0) {
37                    if (pEngine->EventByID(eventID)) {
38                        remove(firstDead, i - firstDead);
39                        firstDead = -1;
40                    }
41                } else {
42                    if (!pEngine->EventByID(eventID)) firstDead = i;
43                }
44            }
45            if (firstDead >= 0)
46                remove(firstDead, size() - firstDead);
47    
48            append(eventID);
49        }
50    
51        void EventGroup::erase(vmint eventID) {
52            size_t index = find(eventID);
53            remove(index);
54        }
55    
56        ///////////////////////////////////////////////////////////////////////
57      // class 'InstrumentScript'      // class 'InstrumentScript'
58    
59        InstrumentScript::InstrumentScript(AbstractEngineChannel* pEngineChannel) {
60            parserContext = NULL;
61            bHasValidScript = false;
62            handlerInit = NULL;
63            handlerNote = NULL;
64            handlerRelease = NULL;
65            handlerController = NULL;
66            handlerRpn = NULL;
67            handlerNrpn = NULL;
68            pEvents = NULL;
69            for (int i = 0; i < 128; ++i)
70                pKeyEvents[i] = NULL;
71            this->pEngineChannel = pEngineChannel;
72            for (int i = 0; i < INSTR_SCRIPT_EVENT_GROUPS; ++i)
73                eventGroups[i].setScript(this);
74        }
75    
76        InstrumentScript::~InstrumentScript() {
77            resetAll();
78            if (pEvents) {
79                for (int i = 0; i < 128; ++i) delete pKeyEvents[i];
80                delete pEvents;
81            }
82        }
83    
84      /** @brief Load real-time instrument script.      /** @brief Load real-time instrument script.
85       *       *
86       * Loads the real-time instrument script given by @a text on the engine       * Loads the real-time instrument script given by @a text on the engine
# Line 26  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
101          // (if not done already)          // (if not done already)
102          reset();          unload();
103    
104            code = text;
105    
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 52  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)
167          if (!pEvents)          if (!pEvents) {
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)
170                    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 84  namespace LinuxSampler { Line 197  namespace LinuxSampler {
197       * is used to share equivalent scripts among multiple sampler channels, and       * is used to share equivalent scripts among multiple sampler channels, and
198       * to deallocate the parsed script once not used on any engine channel       * to deallocate the parsed script once not used on any engine channel
199       * anymore.       * anymore.
200         *
201         * Calling this method will however not clear the @c code member variable.
202         * Thus, the script can be parsed again afterwards.
203       */       */
204      void InstrumentScript::reset() {      void InstrumentScript::unload() {
205            //dmsg(1,("InstrumentScript::unload(this=0x%llx)\n", this));
206    
207          if (parserContext)          if (parserContext)
208              dmsg(1,("Unloading current instrument script."));              dmsg(1,("Unloading current instrument script.\n"));
209    
210            resetEvents();
211    
212          // free allocated VM execution contexts          // free allocated VM execution contexts
213          if (pEvents) {          if (pEvents) {
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 115  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      }      }
245    
246        /**
247         * Same as unload(), but this one also empties the @c code member variable
248         * to an empty string.
249         */
250        void InstrumentScript::resetAll() {
251            unload();
252            code.clear();
253        }
254        
255        /**
256         * Clears all currently active script events. This should be called
257         * whenever the engine or engine channel was reset for some reason.
258         */
259        void InstrumentScript::resetEvents() {
260            for (int i = 0; i < INSTR_SCRIPT_EVENT_GROUPS; ++i)
261                eventGroups[i].clear();
262    
263            for (int i = 0; i < 128; ++i)
264                if (pKeyEvents[i])
265                    pKeyEvents[i]->clear();
266    
267            suspendedEvents.clear();
268    
269            if (pEvents) pEvents->clear();
270        }
271    
272      ///////////////////////////////////////////////////////////////////////      ///////////////////////////////////////////////////////////////////////
273      // class 'InstrumentScriptVM'      // class 'InstrumentScriptVM'
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_fnIgnoreEvent(this), m_fnIgnoreController(this)          m_fnSetRpn(this), m_fnSetNrpn(this),
278            m_fnIgnoreEvent(this), m_fnIgnoreController(this), m_fnNoteOff(this),
279            m_fnSetEventMark(this), m_fnDeleteEventMark(this), m_fnByMarks(this),
280            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;
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 140  namespace LinuxSampler { Line 317  namespace LinuxSampler {
317          // prepare built-in script variables for script execution          // prepare built-in script variables for script execution
318          m_event = event;          m_event = event;
319          m_CC.data = (int8_t*) &pEngineChannel->ControllerTable[0];          m_CC.data = (int8_t*) &pEngineChannel->ControllerTable[0];
320            m_KEY_DOWN.data = &pEngineChannel->GetMidiKeyboardManager()->KeyDown[0];
321    
322          // if script is in start condition, then do mandatory MIDI event          // if script is in start condition, then do mandatory MIDI event
323          // preprocessing tasks, which essentially means updating i.e. controller          // preprocessing tasks, which essentially means updating i.e. controller
# Line 159  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 169  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 185  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
394          m["%CC"] = &m_CC;          m["%CC"] = &m_CC;
395          //m["%KEY_DOWN"] = &m_KEY_DOWN;          m["%KEY_DOWN"] = &m_KEY_DOWN;
396          //m["%POLY_AT"] = &m_POLY_AT;          //m["%POLY_AT"] = &m_POLY_AT;
397    
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) {
410                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 215  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;
450            else if (name == "set_event_mark") return &m_fnSetEventMark;
451            else if (name == "delete_event_mark") return &m_fnDeleteEventMark;
452            else if (name == "by_marks") return &m_fnByMarks;
453            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;
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;
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.2611  
changed lines
  Added in v.3971

  ViewVC Help
Powered by ViewVC