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

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

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

revision 3246 by schoenebeck, Sun May 28 22:22:56 2017 UTC revision 3360 by schoenebeck, Fri Oct 27 21:19:18 2017 UTC
# Line 23  namespace LinuxSampler { Line 23  namespace LinuxSampler {
23      VMFnResult* InstrumentScriptVMFunction_play_note::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_play_note::exec(VMFnArgs* args) {
24          int note = args->arg(0)->asInt()->evalInt();          int note = args->arg(0)->asInt()->evalInt();
25          int velocity = (args->argsCount() >= 2) ? args->arg(1)->asInt()->evalInt() : 127;          int velocity = (args->argsCount() >= 2) ? args->arg(1)->asInt()->evalInt() : 127;
         int sampleoffset = (args->argsCount() >= 3) ? args->arg(2)->asInt()->evalInt() : 0;  
26          int duration = (args->argsCount() >= 4) ? args->arg(3)->asInt()->evalInt() : 0; //TODO: -1 might be a better default value instead of 0          int duration = (args->argsCount() >= 4) ? args->arg(3)->asInt()->evalInt() : 0; //TODO: -1 might be a better default value instead of 0
27    
28          if (note < 0 || note > 127) {          if (note < 0 || note > 127) {
# Line 36  namespace LinuxSampler { Line 35  namespace LinuxSampler {
35              return errorResult(0);              return errorResult(0);
36          }          }
37    
38          if (sampleoffset < 0) {          if (duration < -2) {
39              errMsg("play_note(): argument 3 may not be a negative sample offset");              errMsg("play_note(): argument 4 must be a duration value of at least -2 or higher");
             return errorResult(0);  
         } else if (sampleoffset != 0) {  
             wrnMsg("play_note(): argument 3 does not support a sample offset other than 0 yet");  
         }  
   
         if (duration < -1) {  
             errMsg("play_note(): argument 4 must be a duration value of at least -1 or higher");  
40              return errorResult(0);              return errorResult(0);
41          }          }
42    
# Line 63  namespace LinuxSampler { Line 55  namespace LinuxSampler {
55                  return errorResult(0);                  return errorResult(0);
56              }              }
57              e.Param.Note.ParentNoteID = m_vm->m_event->cause.Param.Note.ID;              e.Param.Note.ParentNoteID = m_vm->m_event->cause.Param.Note.ID;
58                // check if that requested parent note is actually still alive
59                NoteBase* pParentNote =
60                    pEngineChannel->pEngine->NoteByID( e.Param.Note.ParentNoteID );
61                // if parent note is already gone then this new note is not required anymore
62                if (!pParentNote)
63                    return successResult(0);
64          }          }
65    
66          const note_id_t id = pEngineChannel->ScheduleNoteMicroSec(&e, 0);          const note_id_t id = pEngineChannel->ScheduleNoteMicroSec(&e, 0);
67    
68            // if a sample offset is supplied, assign the offset as override
69            // to the previously created Note object
70            if (args->argsCount() >= 3) {
71                int sampleoffset = args->arg(2)->asInt()->evalInt();
72                if (sampleoffset >= 0) {
73                    NoteBase* pNote = pEngineChannel->pEngine->NoteByID(id);
74                    if (pNote) {
75                        pNote->Override.SampleOffset = sampleoffset;
76                    }
77                } else if (sampleoffset < -1) {
78                    errMsg("play_note(): sample offset of argument 3 may not be less than -1");
79                }
80            }
81    
82          // if a duration is supplied (and play-note event was scheduled          // if a duration is supplied (and play-note event was scheduled
83          // successfully above), then schedule a subsequent stop-note event          // successfully above), then schedule a subsequent stop-note event
84          if (id && duration > 0) {          if (id && duration > 0) {
# Line 826  namespace LinuxSampler { Line 838  namespace LinuxSampler {
838    
839      VMFnResult* InstrumentScriptVMFunction_change_attack::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_attack::exec(VMFnArgs* args) {
840          int attack = args->arg(1)->asInt()->evalInt();          int attack = args->arg(1)->asInt()->evalInt();
841          if (attack > VM_EG_PAR_MAX_VALUE) {          // note: intentionally not checking against a max. value here!
842              wrnMsg("change_attack(): argument 2 may not be larger than 1000000");          // (to allow i.e. passing 2000000 for doubling the attack time)
843              attack = VM_EG_PAR_MAX_VALUE;          if (attack < 0) {
         } else if (attack < 0) {  
844              wrnMsg("change_attack(): argument 2 may not be negative");              wrnMsg("change_attack(): argument 2 may not be negative");
845              attack = 0;              attack = 0;
846          }          }
# Line 913  namespace LinuxSampler { Line 924  namespace LinuxSampler {
924    
925      VMFnResult* InstrumentScriptVMFunction_change_decay::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_decay::exec(VMFnArgs* args) {
926          int decay = args->arg(1)->asInt()->evalInt();          int decay = args->arg(1)->asInt()->evalInt();
927          if (decay > VM_EG_PAR_MAX_VALUE) {          // note: intentionally not checking against a max. value here!
928              wrnMsg("change_decay(): argument 2 may not be larger than 1000000");          // (to allow i.e. passing 2000000 for doubling the decay time)
929              decay = VM_EG_PAR_MAX_VALUE;          if (decay < 0) {
         } else if (decay < 0) {  
930              wrnMsg("change_decay(): argument 2 may not be negative");              wrnMsg("change_decay(): argument 2 may not be negative");
931              decay = 0;              decay = 0;
932          }          }
# Line 1000  namespace LinuxSampler { Line 1010  namespace LinuxSampler {
1010    
1011      VMFnResult* InstrumentScriptVMFunction_change_release::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_release::exec(VMFnArgs* args) {
1012          int release = args->arg(1)->asInt()->evalInt();          int release = args->arg(1)->asInt()->evalInt();
1013          if (release > VM_EG_PAR_MAX_VALUE) {          // note: intentionally not checking against a max. value here!
1014              wrnMsg("change_release(): argument 2 may not be larger than 1000000");          // (to allow i.e. passing 2000000 for doubling the release time)
1015              release = VM_EG_PAR_MAX_VALUE;          if (release < 0) {
         } else if (release < 0) {  
1016              wrnMsg("change_release(): argument 2 may not be negative");              wrnMsg("change_release(): argument 2 may not be negative");
1017              release = 0;              release = 0;
1018          }          }
# Line 1165  namespace LinuxSampler { Line 1174  namespace LinuxSampler {
1174          return successResult();          return successResult();
1175      }      }
1176    
1177        // change_sustain() function
1178    
1179        VMFnResult* InstrumentScriptVMFunction_change_sustain::exec(VMFnArgs* args) {
1180            return VMChangeSynthParamFunction::execTemplate<
1181                        &NoteBase::_Override::Sustain,
1182                        Event::synth_param_sustain,
1183                        true, NO_LIMIT, 0>( args, "change_sustain" );
1184        }
1185    
1186        // change_cutoff_attack() function
1187    
1188        VMFnResult* InstrumentScriptVMFunction_change_cutoff_attack::exec(VMFnArgs* args) {
1189            return VMChangeSynthParamFunction::execTemplate<
1190                        &NoteBase::_Override::CutoffAttack,
1191                        Event::synth_param_cutoff_attack,
1192                        true, NO_LIMIT, 0>( args, "change_cutoff_attack" );
1193        }
1194    
1195        // change_cutoff_decay() function
1196    
1197        VMFnResult* InstrumentScriptVMFunction_change_cutoff_decay::exec(VMFnArgs* args) {
1198            return VMChangeSynthParamFunction::execTemplate<
1199                        &NoteBase::_Override::CutoffDecay,
1200                        Event::synth_param_cutoff_decay,
1201                        true, NO_LIMIT, 0>( args, "change_cutoff_decay" );
1202        }
1203    
1204        // change_cutoff_sustain() function
1205    
1206        VMFnResult* InstrumentScriptVMFunction_change_cutoff_sustain::exec(VMFnArgs* args) {
1207            return VMChangeSynthParamFunction::execTemplate<
1208                        &NoteBase::_Override::CutoffSustain,
1209                        Event::synth_param_cutoff_sustain,
1210                        true, NO_LIMIT, 0>( args, "change_cutoff_sustain" );
1211        }
1212    
1213        // change_cutoff_release() function
1214    
1215        VMFnResult* InstrumentScriptVMFunction_change_cutoff_release::exec(VMFnArgs* args) {
1216            return VMChangeSynthParamFunction::execTemplate<
1217                        &NoteBase::_Override::CutoffRelease,
1218                        Event::synth_param_cutoff_release,
1219                        true, NO_LIMIT, 0>( args, "change_cutoff_release" );
1220        }
1221    
1222      // change_amp_lfo_depth() function      // change_amp_lfo_depth() function
1223    
1224      VMFnResult* InstrumentScriptVMFunction_change_amp_lfo_depth::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_amp_lfo_depth::exec(VMFnArgs* args) {
# Line 1183  namespace LinuxSampler { Line 1237  namespace LinuxSampler {
1237                      true, 1000000, 0>( args, "change_amp_lfo_freq" );                      true, 1000000, 0>( args, "change_amp_lfo_freq" );
1238      }      }
1239    
1240        // change_cutoff_lfo_depth() function
1241    
1242        VMFnResult* InstrumentScriptVMFunction_change_cutoff_lfo_depth::exec(VMFnArgs* args) {
1243            return VMChangeSynthParamFunction::execTemplate<
1244                        &NoteBase::_Override::CutoffLFODepth,
1245                        Event::synth_param_cutoff_lfo_depth,
1246                        true, 1000000, 0>( args, "change_cutoff_lfo_depth" );
1247        }
1248    
1249        // change_cutoff_lfo_freq() function
1250    
1251        VMFnResult* InstrumentScriptVMFunction_change_cutoff_lfo_freq::exec(VMFnArgs* args) {
1252            return VMChangeSynthParamFunction::execTemplate<
1253                        &NoteBase::_Override::CutoffLFOFreq,
1254                        Event::synth_param_cutoff_lfo_freq,
1255                        true, 1000000, 0>( args, "change_cutoff_lfo_freq" );
1256        }
1257    
1258      // change_pitch_lfo_depth() function      // change_pitch_lfo_depth() function
1259    
1260      VMFnResult* InstrumentScriptVMFunction_change_pitch_lfo_depth::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_pitch_lfo_depth::exec(VMFnArgs* args) {
# Line 1219  namespace LinuxSampler { Line 1291  namespace LinuxSampler {
1291                      false, NO_LIMIT, 0>( args, "change_tune_time" );                      false, NO_LIMIT, 0>( args, "change_tune_time" );
1292      }      }
1293    
1294        // change_pan_time() function
1295    
1296        VMFnResult* InstrumentScriptVMFunction_change_pan_time::exec(VMFnArgs* args) {
1297            return VMChangeSynthParamFunction::execTemplate<
1298            &NoteBase::_Override::PanTime,
1299            Event::synth_param_pan_time,
1300            false, NO_LIMIT, 0>( args, "change_pan_time" );
1301        }
1302    
1303      // template for change_*_curve() functions      // template for change_*_curve() functions
1304    
1305      bool VMChangeFadeCurveFunction::acceptsArgType(int iArg, ExprType_t type) const {      bool VMChangeFadeCurveFunction::acceptsArgType(int iArg, ExprType_t type) const {
# Line 1320  namespace LinuxSampler { Line 1401  namespace LinuxSampler {
1401                      Event::synth_param_pitch_curve>( args, "change_tune_curve" );                      Event::synth_param_pitch_curve>( args, "change_tune_curve" );
1402      }      }
1403    
1404        // change_pan_curve() function
1405    
1406        VMFnResult* InstrumentScriptVMFunction_change_pan_curve::exec(VMFnArgs* args) {
1407            return VMChangeFadeCurveFunction::execTemplate<
1408            &NoteBase::_Override::PanCurve,
1409            Event::synth_param_pan_curve>( args, "change_pan_curve" );
1410        }
1411    
1412      // fade_in() function      // fade_in() function
1413    
1414      InstrumentScriptVMFunction_fade_in::InstrumentScriptVMFunction_fade_in(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_fade_in::InstrumentScriptVMFunction_fade_in(InstrumentScriptVM* parent)
# Line 1793  namespace LinuxSampler { Line 1882  namespace LinuxSampler {
1882          return successResult();          return successResult();
1883      }      }
1884    
1885        // change_play_pos() function
1886    
1887        InstrumentScriptVMFunction_change_play_pos::InstrumentScriptVMFunction_change_play_pos(InstrumentScriptVM* parent)
1888        : m_vm(parent)
1889        {
1890        }
1891    
1892        VMFnResult* InstrumentScriptVMFunction_change_play_pos::exec(VMFnArgs* args) {
1893            const ScriptID id = args->arg(0)->asInt()->evalInt();
1894            if (!id) {
1895                wrnMsg("change_play_pos(): note ID for argument 1 may not be zero");
1896                return successResult();
1897            }
1898            if (!id.isNoteID()) {
1899                wrnMsg("change_play_pos(): argument 1 is not a note ID");
1900                return successResult();
1901            }
1902    
1903            const int pos = args->arg(1)->asInt()->evalInt();
1904            if (pos < 0) {
1905                wrnMsg("change_play_pos(): playback position of argument 2 may not be negative");
1906                return successResult();
1907            }
1908    
1909            AbstractEngineChannel* pEngineChannel =
1910                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
1911    
1912            NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
1913            if (!pNote) return successResult();
1914    
1915            pNote->Override.SampleOffset = pos;
1916    
1917            return successResult();
1918        }
1919    
1920      // event_status() function      // event_status() function
1921    
1922      InstrumentScriptVMFunction_event_status::InstrumentScriptVMFunction_event_status(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_event_status::InstrumentScriptVMFunction_event_status(InstrumentScriptVM* parent)
# Line 1818  namespace LinuxSampler { Line 1942  namespace LinuxSampler {
1942          return successResult(pNote ? EVENT_STATUS_NOTE_QUEUE : EVENT_STATUS_INACTIVE);          return successResult(pNote ? EVENT_STATUS_NOTE_QUEUE : EVENT_STATUS_INACTIVE);
1943      }      }
1944    
1945        // callback_status() function
1946    
1947        InstrumentScriptVMFunction_callback_status::InstrumentScriptVMFunction_callback_status(InstrumentScriptVM* parent)
1948            : m_vm(parent)
1949        {
1950        }
1951    
1952        VMFnResult* InstrumentScriptVMFunction_callback_status::exec(VMFnArgs* args) {
1953            const script_callback_id_t id = args->arg(0)->asInt()->evalInt();
1954            if (!id) {
1955                wrnMsg("callback_status(): callback ID for argument 1 may not be zero");
1956                return successResult();
1957            }
1958    
1959            AbstractEngineChannel* pEngineChannel =
1960                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
1961    
1962            RTList<ScriptEvent>::Iterator itCallback = pEngineChannel->ScriptCallbackByID(id);
1963            if (!itCallback)
1964                return successResult(CALLBACK_STATUS_TERMINATED);
1965    
1966            return successResult(
1967                (m_vm->m_event->execCtx == itCallback->execCtx) ?
1968                    CALLBACK_STATUS_RUNNING : CALLBACK_STATUS_QUEUE
1969            );
1970        }
1971    
1972      // wait() function (overrides core wait() implementation)      // wait() function (overrides core wait() implementation)
1973    
1974      InstrumentScriptVMFunction_wait::InstrumentScriptVMFunction_wait(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_wait::InstrumentScriptVMFunction_wait(InstrumentScriptVM* parent)
# Line 1864  namespace LinuxSampler { Line 2015  namespace LinuxSampler {
2015          return successResult();          return successResult();
2016      }      }
2017    
2018        // abort() function
2019    
2020        InstrumentScriptVMFunction_abort::InstrumentScriptVMFunction_abort(InstrumentScriptVM* parent)
2021            : m_vm(parent)
2022        {
2023        }
2024    
2025        VMFnResult* InstrumentScriptVMFunction_abort::exec(VMFnArgs* args) {
2026            const script_callback_id_t id = args->arg(0)->asInt()->evalInt();
2027            if (!id) {
2028                wrnMsg("abort(): callback ID for argument 1 may not be zero");
2029                return successResult();
2030            }
2031    
2032            AbstractEngineChannel* pEngineChannel =
2033                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
2034    
2035            RTList<ScriptEvent>::Iterator itCallback = pEngineChannel->ScriptCallbackByID(id);
2036            if (!itCallback) return successResult(); // ignore if callback is i.e. not alive anymore
2037    
2038            itCallback->execCtx->signalAbort();
2039    
2040            return successResult();
2041        }
2042    
2043        // fork() function
2044    
2045        InstrumentScriptVMFunction_fork::InstrumentScriptVMFunction_fork(InstrumentScriptVM* parent)
2046            : m_vm(parent)
2047        {
2048        }
2049    
2050        VMFnResult* InstrumentScriptVMFunction_fork::exec(VMFnArgs* args) {
2051            // check if this is actually the parent going to fork, or rather one of
2052            // the children which is already forked
2053            if (m_vm->m_event->forkIndex != 0) { // this is the entry point for a child ...
2054                int forkResult = m_vm->m_event->forkIndex;
2055                // reset so that this child may i.e. also call fork() later on
2056                m_vm->m_event->forkIndex = 0;
2057                return successResult(forkResult);
2058            }
2059    
2060            // if we are here, then this is the parent, so we must fork this parent
2061    
2062            const int n =
2063                (args->argsCount() >= 1) ? args->arg(0)->asInt()->evalInt() : 1;
2064            const bool bAutoAbort =
2065                (args->argsCount() >= 2) ? args->arg(1)->asInt()->evalInt() : true;
2066    
2067            if (m_vm->m_event->countChildHandlers() + n > MAX_FORK_PER_SCRIPT_HANDLER) {
2068                wrnMsg("fork(): requested amount would exceed allowed limit per event handler");
2069                return successResult(-1);
2070            }
2071    
2072            AbstractEngineChannel* pEngineChannel =
2073                static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
2074    
2075            if (!pEngineChannel->hasFreeScriptCallbacks(n)) {
2076                wrnMsg("fork(): global limit of event handlers exceeded");
2077                return successResult(-1);
2078            }
2079    
2080            for (int iChild = 0; iChild < n; ++iChild) {
2081                RTList<ScriptEvent>::Iterator itChild =
2082                    pEngineChannel->forkScriptCallback(m_vm->m_event, bAutoAbort);
2083                if (!itChild) { // should never happen, otherwise its a bug ...
2084                    errMsg("fork(): internal error while allocating child");
2085                    return errorResult(-1); // terminate script
2086                }
2087                // since both parent, as well all child script execution instances
2088                // all land in this exect() method, the following is (more or less)
2089                // the only feature that lets us distinguish the parent and
2090                // respective children from each other in this exect() method
2091                itChild->forkIndex = iChild + 1;
2092            }
2093    
2094            return successResult(0);
2095        }
2096    
2097  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.3246  
changed lines
  Added in v.3360

  ViewVC Help
Powered by ViewVC