/[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 3561 by schoenebeck, Fri Aug 23 11:44:00 2019 UTC revision 3588 by schoenebeck, Sun Sep 1 16:06:48 2019 UTC
# Line 21  namespace LinuxSampler { Line 21  namespace LinuxSampler {
21      {      {
22      }      }
23    
24        bool InstrumentScriptVMFunction_play_note::acceptsArgType(vmint iArg, ExprType_t type) const {
25            if (iArg == 2 || iArg == 3)
26                return type == INT_EXPR || type == REAL_EXPR;
27            else
28                return type == INT_EXPR;
29        }
30    
31        bool InstrumentScriptVMFunction_play_note::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
32            if (iArg == 2 || iArg == 3)
33                return type == VM_NO_UNIT || type == VM_SECOND;
34            else
35                return type == VM_NO_UNIT;
36        }
37    
38        bool InstrumentScriptVMFunction_play_note::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
39            if (iArg == 2 || iArg == 3)
40                return type == VM_SECOND; // only allow metric prefix(es) if 'seconds' is used as unit type
41            else
42                return false;
43        }
44    
45        void InstrumentScriptVMFunction_play_note::checkArgs(VMFnArgs* args,
46                                                             std::function<void(String)> err,
47                                                             std::function<void(String)> wrn)
48        {
49            // super class checks
50            Super::checkArgs(args, err, wrn);
51    
52            // own checks ...
53            if (args->arg(0)->isConstExpr()) {
54                vmint note = args->arg(0)->asNumber()->evalCastInt();
55                if (note < 0 || note > 127) {
56                    err("MIDI note number value for argument 1 must be between 0..127");
57                    return;
58                }
59            }
60            if (args->argsCount() >= 2 && args->arg(1)->isConstExpr()) {
61                vmint velocity = args->arg(1)->asNumber()->evalCastInt();
62                if (velocity < 0 || velocity > 127) {
63                    err("MIDI velocity value for argument 2 must be between 0..127");
64                    return;
65                }
66            }
67            if (args->argsCount() >= 3 && args->arg(2)->isConstExpr()) {
68                VMNumberExpr* argSampleOffset = args->arg(2)->asNumber();
69                vmint sampleoffset =
70                    (argSampleOffset->unitType()) ?
71                        argSampleOffset->evalCastInt(VM_MICRO) :
72                        argSampleOffset->evalCastInt();
73                if (sampleoffset < -1) {
74                    err("Sample offset of argument 3 may not be less than -1");
75                    return;
76                }
77            }
78            if (args->argsCount() >= 4 && args->arg(3)->isConstExpr()) {
79                VMNumberExpr* argDuration = args->arg(3)->asNumber();
80                vmint duration =
81                    (argDuration->unitType()) ?
82                        argDuration->evalCastInt(VM_MICRO) :
83                        argDuration->evalCastInt();
84                if (duration < -2) {
85                    err("Argument 4 must be a duration value of at least -2 or higher");
86                    return;
87                }
88            }
89        }
90    
91      VMFnResult* InstrumentScriptVMFunction_play_note::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_play_note::exec(VMFnArgs* args) {
92          vmint note = args->arg(0)->asInt()->evalInt();          vmint note = args->arg(0)->asInt()->evalInt();
93          vmint velocity = (args->argsCount() >= 2) ? args->arg(1)->asInt()->evalInt() : 127;          vmint velocity = (args->argsCount() >= 2) ? args->arg(1)->asInt()->evalInt() : 127;
94          vmint duration = (args->argsCount() >= 4) ? args->arg(3)->asInt()->evalInt() : 0; //TODO: -1 might be a better default value instead of 0          VMNumberExpr* argDuration = (args->argsCount() >= 4) ? args->arg(3)->asNumber() : NULL;
95            vmint duration =
96                (argDuration) ?
97                    (argDuration->unitType()) ?
98                        argDuration->evalCastInt(VM_MICRO) :
99                        argDuration->evalCastInt() : 0; //TODO: -1 might be a better default value instead of 0
100    
101          if (note < 0 || note > 127) {          if (note < 0 || note > 127) {
102              errMsg("play_note(): argument 1 is an invalid note number");              errMsg("play_note(): argument 1 is an invalid note number");
# Line 69  namespace LinuxSampler { Line 141  namespace LinuxSampler {
141          // if a sample offset is supplied, assign the offset as override          // if a sample offset is supplied, assign the offset as override
142          // to the previously created Note object          // to the previously created Note object
143          if (args->argsCount() >= 3) {          if (args->argsCount() >= 3) {
144              vmint sampleoffset = args->arg(2)->asInt()->evalInt();              VMNumberExpr* argSampleOffset = args->arg(2)->asNumber();
145                vmint sampleoffset =
146                    (argSampleOffset->unitType()) ?
147                        argSampleOffset->evalCastInt(VM_MICRO) :
148                        argSampleOffset->evalCastInt();
149              if (sampleoffset >= 0) {              if (sampleoffset >= 0) {
150                  NoteBase* pNote = pEngineChannel->pEngine->NoteByID(id);                  NoteBase* pNote = pEngineChannel->pEngine->NoteByID(id);
151                  if (pNote) {                  if (pNote) {
# Line 202  namespace LinuxSampler { Line 278  namespace LinuxSampler {
278          return type == INT_EXPR || type == INT_ARR_EXPR;          return type == INT_EXPR || type == INT_ARR_EXPR;
279      }      }
280    
281        void InstrumentScriptVMFunction_note_off::checkArgs(VMFnArgs* args,
282                                                            std::function<void(String)> err,
283                                                            std::function<void(String)> wrn)
284        {
285            // super class checks
286            Super::checkArgs(args, err, wrn);
287    
288            // own checks ...
289            if (args->argsCount() >= 2 && args->arg(1)->isConstExpr() && args->arg(1)->exprType() == INT_EXPR) {
290                vmint velocity = args->arg(1)->asInt()->evalInt();
291                if (velocity < 0 || velocity > 127) {
292                    err("MIDI velocity value for argument 2 must be between 0..127");
293                    return;
294                }
295            }
296        }
297    
298      VMFnResult* InstrumentScriptVMFunction_note_off::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_note_off::exec(VMFnArgs* args) {
299          AbstractEngineChannel* pEngineChannel =          AbstractEngineChannel* pEngineChannel =
300              static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);              static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
# Line 266  namespace LinuxSampler { Line 359  namespace LinuxSampler {
359      {      {
360      }      }
361    
362        void InstrumentScriptVMFunction_set_event_mark::checkArgs(VMFnArgs* args,
363                                                                  std::function<void(String)> err,
364                                                                  std::function<void(String)> wrn)
365        {
366            // super class checks
367            Super::checkArgs(args, err, wrn);
368    
369            // own checks ...
370            if (args->argsCount() >= 2 && args->arg(1)->isConstExpr()) {
371                const vmint groupID = args->arg(1)->asInt()->evalInt();
372                if (groupID < 0 || groupID >= INSTR_SCRIPT_EVENT_GROUPS) {
373                    err("Argument 2 value is an invalid group id.");
374                    return;
375                }
376            }
377        }
378    
379      VMFnResult* InstrumentScriptVMFunction_set_event_mark::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_set_event_mark::exec(VMFnArgs* args) {
380          const ScriptID id = args->arg(0)->asInt()->evalInt();          const ScriptID id = args->arg(0)->asInt()->evalInt();
381          const vmint groupID = args->arg(1)->asInt()->evalInt();          const vmint groupID = args->arg(1)->asInt()->evalInt();
# Line 304  namespace LinuxSampler { Line 414  namespace LinuxSampler {
414      {      {
415      }      }
416    
417        void InstrumentScriptVMFunction_delete_event_mark::checkArgs(VMFnArgs* args,
418                                                                     std::function<void(String)> err,
419                                                                     std::function<void(String)> wrn)
420        {
421            // super class checks
422            Super::checkArgs(args, err, wrn);
423    
424            // own checks ...
425            if (args->argsCount() >= 2 && args->arg(1)->isConstExpr()) {
426                const vmint groupID = args->arg(1)->asInt()->evalInt();
427                if (groupID < 0 || groupID >= INSTR_SCRIPT_EVENT_GROUPS) {
428                    err("Argument 2 value is an invalid group id.");
429                    return;
430                }
431            }
432        }
433    
434      VMFnResult* InstrumentScriptVMFunction_delete_event_mark::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_delete_event_mark::exec(VMFnArgs* args) {
435          const ScriptID id = args->arg(0)->asInt()->evalInt();          const ScriptID id = args->arg(0)->asInt()->evalInt();
436          const vmint groupID = args->arg(1)->asInt()->evalInt();          const vmint groupID = args->arg(1)->asInt()->evalInt();
# Line 348  namespace LinuxSampler { Line 475  namespace LinuxSampler {
475          return &m_result;          return &m_result;
476      }      }
477    
478        void InstrumentScriptVMFunction_by_marks::checkArgs(VMFnArgs* args,
479                                                            std::function<void(String)> err,
480                                                            std::function<void(String)> wrn)
481        {
482            // super class checks
483            Super::checkArgs(args, err, wrn);
484    
485            // own checks ...
486            if (args->arg(0)->isConstExpr()) {
487                const vmint groupID = args->arg(0)->asInt()->evalInt();
488                if (groupID < 0 || groupID >= INSTR_SCRIPT_EVENT_GROUPS) {
489                    err("Argument value is an invalid group id.");
490                    return;
491                }
492            }
493        }
494    
495      VMFnResult* InstrumentScriptVMFunction_by_marks::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_by_marks::exec(VMFnArgs* args) {
496          vmint groupID = args->arg(0)->asInt()->evalInt();          vmint groupID = args->arg(0)->asInt()->evalInt();
497    
# Line 372  namespace LinuxSampler { Line 516  namespace LinuxSampler {
516      bool InstrumentScriptVMFunction_change_vol::acceptsArgType(vmint iArg, ExprType_t type) const {      bool InstrumentScriptVMFunction_change_vol::acceptsArgType(vmint iArg, ExprType_t type) const {
517          if (iArg == 0)          if (iArg == 0)
518              return type == INT_EXPR || type == INT_ARR_EXPR;              return type == INT_EXPR || type == INT_ARR_EXPR;
519            else if (iArg == 1)
520                return type == INT_EXPR || type == REAL_EXPR;
521          else          else
522              return type == INT_EXPR;              return type == INT_EXPR;
523      }      }
# Line 383  namespace LinuxSampler { Line 529  namespace LinuxSampler {
529              return type == VM_NO_UNIT;              return type == VM_NO_UNIT;
530      }      }
531    
532      bool InstrumentScriptVMFunction_change_vol::acceptsArgUnitPrefix(vmint iArg) const {      bool InstrumentScriptVMFunction_change_vol::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
533          return iArg == 1;          return iArg == 1 && type == VM_BEL; // only allow metric prefix(es) if 'Bel' is used as unit type
534      }      }
535    
536      bool InstrumentScriptVMFunction_change_vol::acceptsArgFinal(vmint iArg) const {      bool InstrumentScriptVMFunction_change_vol::acceptsArgFinal(vmint iArg) const {
# Line 392  namespace LinuxSampler { Line 538  namespace LinuxSampler {
538      }      }
539    
540      VMFnResult* InstrumentScriptVMFunction_change_vol::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_vol::exec(VMFnArgs* args) {
541          vmint volume   = args->arg(1)->asInt()->evalInt(VM_MILLI,VM_DECI); // volume change in milli dB          StdUnit_t unit = args->arg(1)->asNumber()->unitType();
542          bool isFinal   = args->arg(1)->asInt()->isFinal();          vmint volume =
543          StdUnit_t unit = args->arg(1)->asInt()->unitType();              (unit) ?
544                    args->arg(1)->asNumber()->evalCastInt(VM_MILLI,VM_DECI) :
545                    args->arg(1)->asNumber()->evalCastInt(); // volume change in milli dB
546            bool isFinal = args->arg(1)->asNumber()->isFinal();
547          bool relative = (args->argsCount() >= 3) ? (args->arg(2)->asInt()->evalInt() & 1) : false;          bool relative = (args->argsCount() >= 3) ? (args->arg(2)->asInt()->evalInt() & 1) : false;
548          const float fVolumeLin = RTMath::DecibelToLinRatio(float(volume) / 1000.f);          const float fVolumeLin = RTMath::DecibelToLinRatio(float(volume) / 1000.f);
549    
# Line 486  namespace LinuxSampler { Line 635  namespace LinuxSampler {
635      bool InstrumentScriptVMFunction_change_tune::acceptsArgType(vmint iArg, ExprType_t type) const {      bool InstrumentScriptVMFunction_change_tune::acceptsArgType(vmint iArg, ExprType_t type) const {
636          if (iArg == 0)          if (iArg == 0)
637              return type == INT_EXPR || type == INT_ARR_EXPR;              return type == INT_EXPR || type == INT_ARR_EXPR;
638            else if (iArg == 1)
639                return type == INT_EXPR || type == REAL_EXPR;
640          else          else
641              return type == INT_EXPR;              return type == INT_EXPR;
642      }      }
643    
644      bool InstrumentScriptVMFunction_change_tune::acceptsArgUnitPrefix(vmint iArg) const {      bool InstrumentScriptVMFunction_change_tune::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
645          return iArg == 1;          return iArg == 1;
646      }      }
647    
# Line 499  namespace LinuxSampler { Line 650  namespace LinuxSampler {
650      }      }
651    
652      VMFnResult* InstrumentScriptVMFunction_change_tune::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_tune::exec(VMFnArgs* args) {
653          vmint tune     = args->arg(1)->asInt()->evalInt(VM_MILLI,VM_CENTI); // tuning change in milli cents          vmint tune =
654          bool isFinal   = args->arg(1)->asInt()->isFinal();              (args->arg(1)->asNumber()->hasUnitFactorNow())
655          StdUnit_t unit = args->arg(1)->asInt()->unitType();                  ? args->arg(1)->asNumber()->evalCastInt(VM_MILLI,VM_CENTI)
656                    : args->arg(1)->asNumber()->evalCastInt(); // tuning change in milli cents
657            bool isFinal = args->arg(1)->asNumber()->isFinal();
658            StdUnit_t unit = args->arg(1)->asNumber()->unitType();
659          bool relative = (args->argsCount() >= 3) ? (args->arg(2)->asInt()->evalInt() & 1) : false;          bool relative = (args->argsCount() >= 3) ? (args->arg(2)->asInt()->evalInt() & 1) : false;
660          const float fFreqRatio = RTMath::CentsToFreqRatioUnlimited(float(tune) / 1000.f);          const float fFreqRatio = RTMath::CentsToFreqRatioUnlimited(float(tune) / 1000.f);
661    
# Line 705  namespace LinuxSampler { Line 859  namespace LinuxSampler {
859      bool InstrumentScriptVMFunction_change_cutoff::acceptsArgType(vmint iArg, ExprType_t type) const {      bool InstrumentScriptVMFunction_change_cutoff::acceptsArgType(vmint iArg, ExprType_t type) const {
860          if (iArg == 0)          if (iArg == 0)
861              return type == INT_EXPR || type == INT_ARR_EXPR;              return type == INT_EXPR || type == INT_ARR_EXPR;
862            else if (iArg == 1)
863                return type == INT_EXPR || type == REAL_EXPR;
864          else          else
865              return type == INT_EXPR;              return type == INT_EXPR;
866      }      }
# Line 716  namespace LinuxSampler { Line 872  namespace LinuxSampler {
872              return type == VM_NO_UNIT;              return type == VM_NO_UNIT;
873      }      }
874    
875      bool InstrumentScriptVMFunction_change_cutoff::acceptsArgUnitPrefix(vmint iArg) const {      bool InstrumentScriptVMFunction_change_cutoff::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
876          return iArg == 1;          return iArg == 1 && type == VM_HERTZ; // only allow metric prefix(es) if 'Hz' is used as unit type
877      }      }
878    
879      bool InstrumentScriptVMFunction_change_cutoff::acceptsArgFinal(vmint iArg) const {      bool InstrumentScriptVMFunction_change_cutoff::acceptsArgFinal(vmint iArg) const {
880          return iArg == 1;          return iArg == 1;
881      }      }
882    
883        void InstrumentScriptVMFunction_change_cutoff::checkArgs(VMFnArgs* args,
884                                                                 std::function<void(String)> err,
885                                                                 std::function<void(String)> wrn)
886        {
887            // super class checks
888            Super::checkArgs(args, err, wrn);
889    
890            // own checks ...
891            if (args->argsCount() >= 2) {
892                VMNumberExpr* argCutoff = args->arg(1)->asNumber();
893                if (argCutoff->unitType() && !argCutoff->isFinal()) {
894                    wrn("Argument 2 implies 'final' value when using Hz as unit for cutoff frequency.");
895                }
896            }
897        }
898    
899      VMFnResult* InstrumentScriptVMFunction_change_cutoff::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_cutoff::exec(VMFnArgs* args) {
900          vmint cutoff   = args->arg(1)->asInt()->evalInt(VM_NO_PREFIX);          const StdUnit_t unit = args->arg(1)->asNumber()->unitType();
901          bool isFinal   = args->arg(1)->asInt()->isFinal();          vmint cutoff =
902          StdUnit_t unit = args->arg(1)->asInt()->unitType();              (unit) ?
903                    args->arg(1)->asNumber()->evalCastInt(VM_NO_PREFIX) :
904                    args->arg(1)->asNumber()->evalCastInt();
905            const bool isFinal =
906                (unit) ?
907                    true : // imply 'final' value if unit type is used
908                    args->arg(1)->asNumber()->isFinal();
909          if (!unit && cutoff > VM_FILTER_PAR_MAX_VALUE) {          if (!unit && cutoff > VM_FILTER_PAR_MAX_VALUE) {
910              wrnMsg("change_cutoff(): argument 2 may not be larger than " strfy(VM_FILTER_PAR_MAX_VALUE));              wrnMsg("change_cutoff(): argument 2 may not be larger than " strfy(VM_FILTER_PAR_MAX_VALUE));
911              cutoff = VM_FILTER_PAR_MAX_VALUE;              cutoff = VM_FILTER_PAR_MAX_VALUE;
# Line 741  namespace LinuxSampler { Line 919  namespace LinuxSampler {
919          const float fCutoff =          const float fCutoff =
920              (unit) ? cutoff : float(cutoff) / float(VM_FILTER_PAR_MAX_VALUE);              (unit) ? cutoff : float(cutoff) / float(VM_FILTER_PAR_MAX_VALUE);
921    
         if (unit && !isFinal) {  
             wrnMsg("change_cutoff(): you must pass argument 2 as 'final' value when using Hz as unit");  
             return successResult();  
         }  
   
922          AbstractEngineChannel* pEngineChannel =          AbstractEngineChannel* pEngineChannel =
923              static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);              static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
924    
# Line 919  namespace LinuxSampler { Line 1092  namespace LinuxSampler {
1092          if (iArg == 0)          if (iArg == 0)
1093              return type == INT_EXPR || type == INT_ARR_EXPR;              return type == INT_EXPR || type == INT_ARR_EXPR;
1094          else          else
1095              return type == INT_EXPR;              return type == INT_EXPR || type == REAL_EXPR;
1096      }      }
1097    
1098      bool InstrumentScriptVMFunction_change_attack::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {      bool InstrumentScriptVMFunction_change_attack::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
# Line 929  namespace LinuxSampler { Line 1102  namespace LinuxSampler {
1102              return type == VM_NO_UNIT;              return type == VM_NO_UNIT;
1103      }      }
1104    
1105      bool InstrumentScriptVMFunction_change_attack::acceptsArgUnitPrefix(vmint iArg) const {      bool InstrumentScriptVMFunction_change_attack::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
1106          return iArg == 1;          return iArg == 1 && type == VM_SECOND; // only allow metric prefix(es) if 'seconds' is used as unit type
1107      }      }
1108    
1109      bool InstrumentScriptVMFunction_change_attack::acceptsArgFinal(vmint iArg) const {      bool InstrumentScriptVMFunction_change_attack::acceptsArgFinal(vmint iArg) const {
1110          return iArg == 1;          return iArg == 1;
1111      }      }
1112    
1113        void InstrumentScriptVMFunction_change_attack::checkArgs(VMFnArgs* args,
1114                                                                 std::function<void(String)> err,
1115                                                                 std::function<void(String)> wrn)
1116        {
1117            // super class checks
1118            Super::checkArgs(args, err, wrn);
1119    
1120            // own checks ...
1121            if (args->argsCount() >= 2) {
1122                VMNumberExpr* argTime = args->arg(1)->asNumber();
1123                if (argTime->unitType() && !argTime->isFinal()) {
1124                    wrn("Argument 2 implies 'final' value when using seconds as unit for attack time.");
1125                }
1126            }
1127        }
1128    
1129      VMFnResult* InstrumentScriptVMFunction_change_attack::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_attack::exec(VMFnArgs* args) {
1130          vmint attack   = args->arg(1)->asInt()->evalInt(VM_MICRO);          const StdUnit_t unit = args->arg(1)->asNumber()->unitType();
1131          bool isFinal   = args->arg(1)->asInt()->isFinal();          vmint attack =
1132          StdUnit_t unit = args->arg(1)->asInt()->unitType();              (unit) ?
1133                    args->arg(1)->asNumber()->evalCastInt(VM_MICRO) :
1134                    args->arg(1)->asNumber()->evalCastInt();
1135            const bool isFinal =
1136                (unit) ?
1137                    true : // imply 'final' value if unit type is used
1138                    args->arg(1)->asNumber()->isFinal();
1139          // note: intentionally not checking against a max. value here!          // note: intentionally not checking against a max. value here!
1140          // (to allow i.e. passing 2000000 for doubling the attack time)          // (to allow i.e. passing 2000000 for doubling the attack time)
1141          if (attack < 0) {          if (attack < 0) {
1142              wrnMsg("change_attack(): argument 2 may not be negative");              wrnMsg("change_attack(): argument 2 may not be negative");
1143              attack = 0;              attack = 0;
1144          }          }
1145          const float fAttack = float(attack) / float(VM_EG_PAR_MAX_VALUE);          const float fAttack =
1146                (unit) ? attack : float(attack) / float(VM_EG_PAR_MAX_VALUE);
         if (unit && !isFinal) {  
             wrnMsg("change_attack(): you must pass argument 2 as 'final' value when using seconds as unit");  
             return successResult();  
         }  
1147    
1148          AbstractEngineChannel* pEngineChannel =          AbstractEngineChannel* pEngineChannel =
1149              static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);              static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
# Line 1031  namespace LinuxSampler { Line 1222  namespace LinuxSampler {
1222          if (iArg == 0)          if (iArg == 0)
1223              return type == INT_EXPR || type == INT_ARR_EXPR;              return type == INT_EXPR || type == INT_ARR_EXPR;
1224          else          else
1225              return type == INT_EXPR;              return type == INT_EXPR || type == REAL_EXPR;
1226      }      }
1227    
1228      bool InstrumentScriptVMFunction_change_decay::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {      bool InstrumentScriptVMFunction_change_decay::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
# Line 1041  namespace LinuxSampler { Line 1232  namespace LinuxSampler {
1232              return type == VM_NO_UNIT;              return type == VM_NO_UNIT;
1233      }      }
1234    
1235      bool InstrumentScriptVMFunction_change_decay::acceptsArgUnitPrefix(vmint iArg) const {      bool InstrumentScriptVMFunction_change_decay::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
1236          return iArg == 1;          return iArg == 1 && type == VM_SECOND; // only allow metric prefix(es) if 'seconds' is used as unit type
1237      }      }
1238    
1239      bool InstrumentScriptVMFunction_change_decay::acceptsArgFinal(vmint iArg) const {      bool InstrumentScriptVMFunction_change_decay::acceptsArgFinal(vmint iArg) const {
1240          return iArg == 1;          return iArg == 1;
1241      }      }
1242    
1243        void InstrumentScriptVMFunction_change_decay::checkArgs(VMFnArgs* args,
1244                                                                std::function<void(String)> err,
1245                                                                std::function<void(String)> wrn)
1246        {
1247            // super class checks
1248            Super::checkArgs(args, err, wrn);
1249    
1250            // own checks ...
1251            if (args->argsCount() >= 2) {
1252                VMNumberExpr* argTime = args->arg(1)->asNumber();
1253                if (argTime->unitType() && !argTime->isFinal()) {
1254                    wrn("Argument 2 implies 'final' value when using seconds as unit for decay time.");
1255                }
1256            }
1257        }
1258    
1259      VMFnResult* InstrumentScriptVMFunction_change_decay::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_decay::exec(VMFnArgs* args) {
1260          vmint decay    = args->arg(1)->asInt()->evalInt(VM_MICRO);          const StdUnit_t unit = args->arg(1)->asNumber()->unitType();
1261          bool isFinal   = args->arg(1)->asInt()->isFinal();          vmint decay =
1262          StdUnit_t unit = args->arg(1)->asInt()->unitType();              (unit) ?
1263                    args->arg(1)->asNumber()->evalCastInt(VM_MICRO) :
1264                    args->arg(1)->asNumber()->evalCastInt();
1265            const bool isFinal =
1266                (unit) ?
1267                    true : // imply 'final' value if unit type is used
1268                    args->arg(1)->asNumber()->isFinal();
1269          // note: intentionally not checking against a max. value here!          // note: intentionally not checking against a max. value here!
1270          // (to allow i.e. passing 2000000 for doubling the decay time)          // (to allow i.e. passing 2000000 for doubling the decay time)
1271          if (decay < 0) {          if (decay < 0) {
1272              wrnMsg("change_decay(): argument 2 may not be negative");              wrnMsg("change_decay(): argument 2 may not be negative");
1273              decay = 0;              decay = 0;
1274          }          }
1275          const float fDecay = float(decay) / float(VM_EG_PAR_MAX_VALUE);          const float fDecay =
1276                (unit) ? decay : float(decay) / float(VM_EG_PAR_MAX_VALUE);
         if (unit && !isFinal) {  
             wrnMsg("change_decay(): you must pass argument 2 as 'final' value when using seconds as unit");  
             return successResult();  
         }  
1277    
1278          AbstractEngineChannel* pEngineChannel =          AbstractEngineChannel* pEngineChannel =
1279              static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);              static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
# Line 1143  namespace LinuxSampler { Line 1352  namespace LinuxSampler {
1352          if (iArg == 0)          if (iArg == 0)
1353              return type == INT_EXPR || type == INT_ARR_EXPR;              return type == INT_EXPR || type == INT_ARR_EXPR;
1354          else          else
1355              return type == INT_EXPR;              return type == INT_EXPR || type == REAL_EXPR;
1356      }      }
1357    
1358      bool InstrumentScriptVMFunction_change_release::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {      bool InstrumentScriptVMFunction_change_release::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
# Line 1153  namespace LinuxSampler { Line 1362  namespace LinuxSampler {
1362              return type == VM_NO_UNIT;              return type == VM_NO_UNIT;
1363      }      }
1364    
1365      bool InstrumentScriptVMFunction_change_release::acceptsArgUnitPrefix(vmint iArg) const {      bool InstrumentScriptVMFunction_change_release::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
1366          return iArg == 1;          return iArg == 1 && type == VM_SECOND; // only allow metric prefix(es) if 'seconds' is used as unit type
1367      }      }
1368    
1369      bool InstrumentScriptVMFunction_change_release::acceptsArgFinal(vmint iArg) const {      bool InstrumentScriptVMFunction_change_release::acceptsArgFinal(vmint iArg) const {
1370          return iArg == 1;          return iArg == 1;
1371      }      }
1372    
1373        void InstrumentScriptVMFunction_change_release::checkArgs(VMFnArgs* args,
1374                                                                  std::function<void(String)> err,
1375                                                                  std::function<void(String)> wrn)
1376        {
1377            // super class checks
1378            Super::checkArgs(args, err, wrn);
1379    
1380            // own checks ...
1381            if (args->argsCount() >= 2) {
1382                VMNumberExpr* argTime = args->arg(1)->asNumber();
1383                if (argTime->unitType() && !argTime->isFinal()) {
1384                    wrn("Argument 2 implies 'final' value when using seconds as unit for release time.");
1385                }
1386            }
1387        }
1388    
1389      VMFnResult* InstrumentScriptVMFunction_change_release::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_release::exec(VMFnArgs* args) {
1390          vmint release  = args->arg(1)->asInt()->evalInt(VM_MICRO);          const StdUnit_t unit = args->arg(1)->asNumber()->unitType();
1391          bool isFinal   = args->arg(1)->asInt()->isFinal();          vmint release =
1392          StdUnit_t unit = args->arg(1)->asInt()->unitType();              (unit) ?
1393                    args->arg(1)->asNumber()->evalCastInt(VM_MICRO) :
1394                    args->arg(1)->asNumber()->evalCastInt();
1395            const bool isFinal =
1396                (unit) ?
1397                    true : // imply 'final' value if unit type is used
1398                    args->arg(1)->asNumber()->isFinal();
1399          // note: intentionally not checking against a max. value here!          // note: intentionally not checking against a max. value here!
1400          // (to allow i.e. passing 2000000 for doubling the release time)          // (to allow i.e. passing 2000000 for doubling the release time)
1401          if (release < 0) {          if (release < 0) {
1402              wrnMsg("change_release(): argument 2 may not be negative");              wrnMsg("change_release(): argument 2 may not be negative");
1403              release = 0;              release = 0;
1404          }          }
1405          const float fRelease = float(release) / float(VM_EG_PAR_MAX_VALUE);          const float fRelease =
1406                (unit) ? release : float(release) / float(VM_EG_PAR_MAX_VALUE);
         if (unit && !isFinal) {  
             wrnMsg("change_release(): you must pass argument 2 as 'final' value when using seconds as unit");  
             return successResult();  
         }  
1407    
1408          AbstractEngineChannel* pEngineChannel =          AbstractEngineChannel* pEngineChannel =
1409              static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);              static_cast<AbstractEngineChannel*>(m_vm->m_event->cause.pEngineChannel);
# Line 1250  namespace LinuxSampler { Line 1477  namespace LinuxSampler {
1477          if (iArg == 0)          if (iArg == 0)
1478              return type == INT_EXPR || type == INT_ARR_EXPR;              return type == INT_EXPR || type == INT_ARR_EXPR;
1479          else          else
1480              return type == INT_EXPR;              return type == INT_EXPR || (m_acceptReal && type == REAL_EXPR);
1481      }      }
1482    
1483      bool VMChangeSynthParamFunction::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {      bool VMChangeSynthParamFunction::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
# Line 1260  namespace LinuxSampler { Line 1487  namespace LinuxSampler {
1487              return type == VM_NO_UNIT;              return type == VM_NO_UNIT;
1488      }      }
1489    
1490      bool VMChangeSynthParamFunction::acceptsArgUnitPrefix(vmint iArg) const {      bool VMChangeSynthParamFunction::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
1491          return m_unit && iArg == 1;          return m_acceptUnitPrefix && iArg == 1 && type == m_unit; // only allow metric prefix(es) if approprirate unit type is used (e.g. Hz)
1492      }      }
1493    
1494      bool VMChangeSynthParamFunction::acceptsArgFinal(vmint iArg) const {      bool VMChangeSynthParamFunction::acceptsArgFinal(vmint iArg) const {
# Line 1289  namespace LinuxSampler { Line 1516  namespace LinuxSampler {
1516          param = value;          param = value;
1517      }      }
1518    
1519        void VMChangeSynthParamFunction::checkArgs(VMFnArgs* args,
1520                                                   std::function<void(String)> err,
1521                                                   std::function<void(String)> wrn)
1522        {
1523            // super class checks
1524            Super::checkArgs(args, err, wrn);
1525    
1526            // own checks ...
1527            if (m_unit && m_unit != VM_BEL && args->argsCount() >= 2) {
1528                VMNumberExpr* arg = args->arg(1)->asNumber();
1529                if (arg && arg->unitType() && !arg->isFinal()) {
1530                    wrn("Argument 2 implies 'final' value when unit type " +
1531                        unitTypeStr(arg->unitType()) + " is used.");
1532                }
1533            }
1534        }
1535    
1536      // Arbitrarily chosen constant value symbolizing "no limit".      // Arbitrarily chosen constant value symbolizing "no limit".
1537      #define NO_LIMIT 1315916909      #define NO_LIMIT 1315916909
1538    
# Line 1299  namespace LinuxSampler { Line 1543  namespace LinuxSampler {
1543               MetricPrefix_t T_unitPrefix0, MetricPrefix_t ... T_unitPrefixN>               MetricPrefix_t T_unitPrefix0, MetricPrefix_t ... T_unitPrefixN>
1544      VMFnResult* VMChangeSynthParamFunction::execTemplate(VMFnArgs* args, const char* functionName)      VMFnResult* VMChangeSynthParamFunction::execTemplate(VMFnArgs* args, const char* functionName)
1545      {      {
1546          const StdUnit_t unit = args->arg(1)->asInt()->unitType();          const StdUnit_t unit = args->arg(1)->asNumber()->unitType();
1547          const bool isFinal   = args->arg(1)->asInt()->isFinal();          const bool isFinal =
1548                (m_unit && m_unit != VM_BEL && unit) ?
1549                    true : // imply 'final' value if unit type is used (except of 'Bel' which may be relative)
1550                    args->arg(1)->asNumber()->isFinal();
1551          vmint value =          vmint value =
1552              (unit & m_unit) ?              (m_acceptUnitPrefix && ((m_unit && unit) || (!m_unit && args->arg(1)->asNumber()->hasUnitFactorNow())))
1553                  args->arg(1)->asInt()->evalInt(T_unitPrefix0, T_unitPrefixN ...) :                  ? args->arg(1)->asNumber()->evalCastInt(T_unitPrefix0, T_unitPrefixN ...)
1554                  args->arg(1)->asInt()->evalInt(VM_NO_PREFIX);                  : args->arg(1)->asNumber()->evalCastInt();
   
         if (unit && !isFinal && m_unit != VM_BEL && m_unit) {  
             wrnMsg(String(functionName) + "(): you must pass argument 2 as 'final' value when using a unit");  
             return successResult();  
         }  
1555    
1556          // check if passed value is in allowed range          // check if passed value is in allowed range
1557          if (unit && m_unit) {          if (unit && m_unit) {
# Line 1722  namespace LinuxSampler { Line 1964  namespace LinuxSampler {
1964          if (iArg == 0)          if (iArg == 0)
1965              return type == INT_EXPR || type == INT_ARR_EXPR;              return type == INT_EXPR || type == INT_ARR_EXPR;
1966          else          else
1967              return type == INT_EXPR;              return type == INT_EXPR || type == REAL_EXPR;
1968      }      }
1969    
1970      bool InstrumentScriptVMFunction_fade_in::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {      bool InstrumentScriptVMFunction_fade_in::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
# Line 1732  namespace LinuxSampler { Line 1974  namespace LinuxSampler {
1974              return type == VM_NO_UNIT;              return type == VM_NO_UNIT;
1975      }      }
1976    
1977      bool InstrumentScriptVMFunction_fade_in::acceptsArgUnitPrefix(vmint iArg) const {      bool InstrumentScriptVMFunction_fade_in::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
1978          return iArg == 1;          return iArg == 1 && type == VM_SECOND; // only allow metric prefix(es) if 'seconds' is used as unit type
1979      }      }
1980    
1981      VMFnResult* InstrumentScriptVMFunction_fade_in::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_fade_in::exec(VMFnArgs* args) {
1982          vmint duration = args->arg(1)->asInt()->evalInt(VM_MICRO);          StdUnit_t unit = args->arg(1)->asNumber()->unitType();
1983            vmint duration =
1984                (unit) ?
1985                    args->arg(1)->asNumber()->evalCastInt(VM_MICRO) :
1986                    args->arg(1)->asNumber()->evalCastInt();
1987          if (duration < 0) {          if (duration < 0) {
1988              wrnMsg("fade_in(): argument 2 may not be negative");              wrnMsg("fade_in(): argument 2 may not be negative");
1989              duration = 0;              duration = 0;
# Line 1853  namespace LinuxSampler { Line 2099  namespace LinuxSampler {
2099          if (iArg == 0)          if (iArg == 0)
2100              return type == INT_EXPR || type == INT_ARR_EXPR;              return type == INT_EXPR || type == INT_ARR_EXPR;
2101          else          else
2102              return type == INT_EXPR;              return type == INT_EXPR || type == REAL_EXPR;
2103      }      }
2104    
2105      bool InstrumentScriptVMFunction_fade_out::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {      bool InstrumentScriptVMFunction_fade_out::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
# Line 1863  namespace LinuxSampler { Line 2109  namespace LinuxSampler {
2109              return type == VM_NO_UNIT;              return type == VM_NO_UNIT;
2110      }      }
2111    
2112      bool InstrumentScriptVMFunction_fade_out::acceptsArgUnitPrefix(vmint iArg) const {      bool InstrumentScriptVMFunction_fade_out::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
2113          return iArg == 1;          return iArg == 1 && type == VM_SECOND; // only allow metric prefix(es) if 'seconds' is used as unit type
2114      }      }
2115    
2116      VMFnResult* InstrumentScriptVMFunction_fade_out::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_fade_out::exec(VMFnArgs* args) {
2117          vmint duration = args->arg(1)->asInt()->evalInt(VM_MICRO);          StdUnit_t unit = args->arg(1)->asNumber()->unitType();
2118            vmint duration =
2119                (unit) ?
2120                    args->arg(1)->asNumber()->evalCastInt(VM_MICRO) :
2121                    args->arg(1)->asNumber()->evalCastInt();
2122          if (duration < 0) {          if (duration < 0) {
2123              wrnMsg("fade_out(): argument 2 may not be negative");              wrnMsg("fade_out(): argument 2 may not be negative");
2124              duration = 0;              duration = 0;
# Line 2209  namespace LinuxSampler { Line 2459  namespace LinuxSampler {
2459      // change_play_pos() function      // change_play_pos() function
2460    
2461      InstrumentScriptVMFunction_change_play_pos::InstrumentScriptVMFunction_change_play_pos(InstrumentScriptVM* parent)      InstrumentScriptVMFunction_change_play_pos::InstrumentScriptVMFunction_change_play_pos(InstrumentScriptVM* parent)
2462      : m_vm(parent)          : m_vm(parent)
2463      {      {
2464      }      }
2465    
2466        bool InstrumentScriptVMFunction_change_play_pos::acceptsArgType(vmint iArg, ExprType_t type) const {
2467            if (iArg == 0)
2468                return type == INT_EXPR;
2469            else
2470                return type == INT_EXPR || type == REAL_EXPR;
2471        }
2472    
2473      bool InstrumentScriptVMFunction_change_play_pos::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {      bool InstrumentScriptVMFunction_change_play_pos::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
2474          if (iArg == 1)          if (iArg == 1)
2475              return type == VM_NO_UNIT || type == VM_SECOND;              return type == VM_NO_UNIT || type == VM_SECOND;
# Line 2220  namespace LinuxSampler { Line 2477  namespace LinuxSampler {
2477              return type == VM_NO_UNIT;              return type == VM_NO_UNIT;
2478      }      }
2479    
2480      bool InstrumentScriptVMFunction_change_play_pos::acceptsArgUnitPrefix(vmint iArg) const {      bool InstrumentScriptVMFunction_change_play_pos::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
2481          return iArg == 1;          return iArg == 1 && type == VM_SECOND; // only allow metric prefix(es) if 'seconds' is used as unit type
2482      }      }
2483    
2484      VMFnResult* InstrumentScriptVMFunction_change_play_pos::exec(VMFnArgs* args) {      VMFnResult* InstrumentScriptVMFunction_change_play_pos::exec(VMFnArgs* args) {
2485          const ScriptID id = args->arg(0)->asInt()->evalInt(VM_MICRO);          const ScriptID id = args->arg(0)->asInt()->evalInt();
2486          if (!id) {          if (!id) {
2487              wrnMsg("change_play_pos(): note ID for argument 1 may not be zero");              wrnMsg("change_play_pos(): note ID for argument 1 may not be zero");
2488              return successResult();              return successResult();
# Line 2235  namespace LinuxSampler { Line 2492  namespace LinuxSampler {
2492              return successResult();              return successResult();
2493          }          }
2494    
2495          const vmint pos = args->arg(1)->asInt()->evalInt();          StdUnit_t unit = args->arg(1)->asNumber()->unitType();
2496            const vmint pos =
2497                (unit) ?
2498                    args->arg(1)->asNumber()->evalCastInt(VM_MICRO) :
2499                    args->arg(1)->asNumber()->evalCastInt();
2500          if (pos < 0) {          if (pos < 0) {
2501              wrnMsg("change_play_pos(): playback position of argument 2 may not be negative");              wrnMsg("change_play_pos(): playback position of argument 2 may not be negative");
2502              return successResult();              return successResult();

Legend:
Removed from v.3561  
changed lines
  Added in v.3588

  ViewVC Help
Powered by ViewVC