37 |
typedef uint64_t vmuint; |
typedef uint64_t vmuint; |
38 |
|
|
39 |
/** |
/** |
40 |
|
* Native data type used internally by the script engine for floating point |
41 |
|
* data types. This type is currently not exposed to scripts. |
42 |
|
*/ |
43 |
|
typedef float vmfloat; |
44 |
|
|
45 |
|
/** |
46 |
* Identifies the type of a noteworthy issue identified by the script |
* Identifies the type of a noteworthy issue identified by the script |
47 |
* parser. That's either a parser error or parser warning. |
* parser. That's either a parser error or parser warning. |
48 |
*/ |
*/ |
118 |
VM_EVENT_HANDLER_CONTROLLER, ///< Controller event handler, that is script's "on controller ... end on" code block. |
VM_EVENT_HANDLER_CONTROLLER, ///< Controller event handler, that is script's "on controller ... end on" code block. |
119 |
}; |
}; |
120 |
|
|
121 |
|
/** |
122 |
|
* All metric unit prefixes (actually just scale factors) supported by this |
123 |
|
* script engine. |
124 |
|
*/ |
125 |
|
enum MetricPrefix_t { |
126 |
|
VM_NO_PREFIX = 0, ///< = 1 |
127 |
|
VM_KILO, ///< = 10^3, short 'k' |
128 |
|
VM_HECTO, ///< = 10^2, short 'h' |
129 |
|
VM_DECA, ///< = 10, short 'da' |
130 |
|
VM_DECI, ///< = 10^-1, short 'd' |
131 |
|
VM_CENTI, ///< = 10^-2, short 'c' (this is also used for tuning "cents") |
132 |
|
VM_MILLI, ///< = 10^-3, short 'm' |
133 |
|
VM_MICRO, ///< = 10^-6, short 'u' |
134 |
|
}; |
135 |
|
|
136 |
|
/** |
137 |
|
* All measurement unit types supported by this script engine. |
138 |
|
* |
139 |
|
* @e Note: there is no standard unit "cents" here (for pitch/tuning), use |
140 |
|
* @c VM_CENTI for the latter instad. That's because the commonly cited |
141 |
|
* "cents" unit is actually no measurement unit type but rather a metric |
142 |
|
* unit prefix. |
143 |
|
* |
144 |
|
* @see MetricPrefix_t |
145 |
|
*/ |
146 |
|
enum StdUnit_t { |
147 |
|
VM_NO_UNIT = 0, ///< No unit used, the number is just an abstract number. |
148 |
|
VM_SECOND, ///< Measuring time. |
149 |
|
VM_HERTZ, ///< Measuring frequency. |
150 |
|
VM_BEL, ///< Measuring relation between two energy levels (in logarithmic scale). Since we are using it for accoustics, we are always referring to A-weighted Bels (i.e. dBA). |
151 |
|
}; |
152 |
|
|
153 |
// just symbol prototyping |
// just symbol prototyping |
154 |
class VMIntExpr; |
class VMIntExpr; |
155 |
class VMStringExpr; |
class VMStringExpr; |
157 |
class VMStringArrayExpr; |
class VMStringArrayExpr; |
158 |
class VMParserContext; |
class VMParserContext; |
159 |
|
|
160 |
|
/** @brief Virtual machine measuring unit. |
161 |
|
* |
162 |
|
* Abstract base class representing standard measurement units throughout |
163 |
|
* the script engine. These might be i.e. "dB" (deci Bel) for loudness, |
164 |
|
* "Hz" (Hertz) for frequencies or "s" for "seconds". |
165 |
|
* |
166 |
|
* Originally the script engine only supported abstract integer values for |
167 |
|
* controlling any synthesis parameter or built-in function argument or |
168 |
|
* variable. Under certain situations it makes sense though for an |
169 |
|
* instrument script author to provide values in real, standard measurement |
170 |
|
* units, for example setting the frequency of some LFO directly to "20Hz". |
171 |
|
* Hence support for standard units in scripts was added as an extension to |
172 |
|
* the NKSP script engine. |
173 |
|
*/ |
174 |
|
class VMUnit { |
175 |
|
public: |
176 |
|
/** |
177 |
|
* Returns the metric prefix of this unit. A metric prefix essentially |
178 |
|
* is just a mathematical scale factor that should be applied to the |
179 |
|
* number associated with the measurement unit. Usually a unit either |
180 |
|
* has exactly none or one prefix, but note that there might also be |
181 |
|
* units with more than one prefix, for example mdB (mili deci bel) |
182 |
|
* is used sometimes which has two prefixes. This is an exception though |
183 |
|
* and more than two prefixes is currently not supported by the script |
184 |
|
* engine. |
185 |
|
* |
186 |
|
* Start iterating over the prefixes of this unit by passing @c 0 as |
187 |
|
* argument to this method. The prefixes are terminated with return |
188 |
|
* value VM_NO_PREFIX being always the last element. |
189 |
|
* |
190 |
|
* @param i - index of prefix |
191 |
|
* @returns prefix of requested index or VM_NO_PREFIX otherwise |
192 |
|
* @see unitFactor() |
193 |
|
*/ |
194 |
|
virtual MetricPrefix_t unitPrefix(vmuint i) const = 0; |
195 |
|
|
196 |
|
/** |
197 |
|
* Conveniently returns the final mathematical factor that should be |
198 |
|
* multiplied against the number associated with this unit. This factor |
199 |
|
* results from the sequence of metric prefixes of this unit. |
200 |
|
* |
201 |
|
* @see unitPrefix() |
202 |
|
*/ |
203 |
|
vmfloat unitFactor() const; |
204 |
|
|
205 |
|
/** |
206 |
|
* This is the actual fundamental measuring unit base type of this unit, |
207 |
|
* which might be either Hertz, second or Bel. |
208 |
|
* |
209 |
|
* @returns standard unit type identifier or VM_NO_UNIT if no unit used |
210 |
|
*/ |
211 |
|
virtual StdUnit_t unitType() const = 0; |
212 |
|
|
213 |
|
/** |
214 |
|
* Returns the actual mathematical factor represented by the passed |
215 |
|
* @a prefix argument. |
216 |
|
*/ |
217 |
|
static vmfloat unitFactor(MetricPrefix_t prefix); |
218 |
|
|
219 |
|
/** |
220 |
|
* Returns the actual mathematical factor represented by the passed |
221 |
|
* two @a prefix1 and @a prefix2 arguments. |
222 |
|
*/ |
223 |
|
static vmfloat unitFactor(MetricPrefix_t prefix1, MetricPrefix_t prefix2); |
224 |
|
}; |
225 |
|
|
226 |
/** @brief Virtual machine expression |
/** @brief Virtual machine expression |
227 |
* |
* |
228 |
* This is the abstract base class for all expressions of scripts. |
* This is the abstract base class for all expressions of scripts. |
336 |
* abstract method evalInt() to return the actual integer result value of |
* abstract method evalInt() to return the actual integer result value of |
337 |
* the expression. |
* the expression. |
338 |
*/ |
*/ |
339 |
class VMIntExpr : virtual public VMExpr { |
class VMIntExpr : virtual public VMExpr, virtual public VMUnit { |
340 |
public: |
public: |
341 |
/** |
/** |
342 |
* Returns the result of this expression as integer (scalar) value. |
* Returns the result of this expression as integer (scalar) value. |
345 |
virtual vmint evalInt() = 0; |
virtual vmint evalInt() = 0; |
346 |
|
|
347 |
/** |
/** |
348 |
|
* Returns the result of this expression as integer (scalar) value and |
349 |
|
* thus behaves similar to the previous method, however this overridden |
350 |
|
* method automatically takes unit prefixes into account and returns a |
351 |
|
* value corresponding to the expected given unit @a prefix. |
352 |
|
* |
353 |
|
* @param prefix - default measurement unit prefix expected by caller |
354 |
|
*/ |
355 |
|
vmint evalInt(MetricPrefix_t prefix); |
356 |
|
|
357 |
|
/** |
358 |
|
* This method behaves like the previous method, just that it takes |
359 |
|
* a default measurement prefix with two elements (i.e. "milli cents" |
360 |
|
* for tuning). |
361 |
|
*/ |
362 |
|
vmint evalInt(MetricPrefix_t prefix1, MetricPrefix_t prefix2); |
363 |
|
|
364 |
|
/** |
365 |
* Returns always INT_EXPR for instances of this class. |
* Returns always INT_EXPR for instances of this class. |
366 |
*/ |
*/ |
367 |
ExprType_t exprType() const OVERRIDE { return INT_EXPR; } |
ExprType_t exprType() const OVERRIDE { return INT_EXPR; } |
368 |
|
|
369 |
|
/** |
370 |
|
* Returns @c true if the value of this expression should be applied |
371 |
|
* as final value to the respective destination synthesis chain |
372 |
|
* parameter. |
373 |
|
* |
374 |
|
* This property is somewhat special and dedicated for the purpose of |
375 |
|
* this expression's integer value to be applied as parameter to the |
376 |
|
* synthesis chain of the sampler (i.e. for altering a filter cutoff |
377 |
|
* frequency). Now historically and by default all values of scripts are |
378 |
|
* applied relatively to the sampler's synthesis chain, that is the |
379 |
|
* synthesis parameter value of a script is multiplied against other |
380 |
|
* sources for the same synthesis parameter (i.e. an LFO or a dedicated |
381 |
|
* MIDI controller either hard wired in the engine or defined by the |
382 |
|
* instrument patch). So by default the resulting actual final synthesis |
383 |
|
* parameter is a combination of all these sources. This has the |
384 |
|
* advantage that it creates a very living and dynamic overall sound. |
385 |
|
* |
386 |
|
* However sometimes there are requirements by script authors where this |
387 |
|
* is not what you want. Therefore the NKSP script engine added a |
388 |
|
* language extension by prefixing a value in scripts with a @c ! |
389 |
|
* character the value will be defined as being the "final" value of the |
390 |
|
* destination synthesis parameter, so that causes this value to be |
391 |
|
* applied exclusively, and the values of all other sources are thus |
392 |
|
* entirely ignored by the sampler's synthesis core as long as this |
393 |
|
* value is assigned by the script engine as "final" value for the |
394 |
|
* requested synthesis parameter. |
395 |
|
*/ |
396 |
|
virtual bool isFinal() const = 0; |
397 |
}; |
}; |
398 |
|
|
399 |
/** @brief Virtual machine string expression |
/** @brief Virtual machine string expression |
597 |
virtual bool acceptsArgType(vmint iArg, ExprType_t type) const = 0; |
virtual bool acceptsArgType(vmint iArg, ExprType_t type) const = 0; |
598 |
|
|
599 |
/** |
/** |
600 |
|
* This method is called by the parser to check whether arguments |
601 |
|
* passed in scripts to this function are accepted by this function. If |
602 |
|
* a script calls this function with an argument's measuremnt unit type |
603 |
|
* not accepted by this function, the parser will throw a parser error. |
604 |
|
* |
605 |
|
* This default implementation of this method does not accept any |
606 |
|
* measurement unit. Deriving subclasses would override this method |
607 |
|
* implementation in case they do accept any measurement unit for its |
608 |
|
* function arguments. |
609 |
|
* |
610 |
|
* @param iArg - index of the function argument in question |
611 |
|
* (must be between 0 .. maxAllowedArgs() - 1) |
612 |
|
* @param type - standard measurement unit data type used for this |
613 |
|
* function argument by currently parsed script |
614 |
|
* @return true if the given standard measurement unit type would be |
615 |
|
* accepted for the respective function argument by the function |
616 |
|
*/ |
617 |
|
virtual bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const; |
618 |
|
|
619 |
|
/** |
620 |
|
* This method is called by the parser to check whether arguments |
621 |
|
* passed in scripts to this function are accepted by this function. If |
622 |
|
* a script calls this function with a metric unit prefix and metric |
623 |
|
* prefixes are not accepted for that argument by this function, then |
624 |
|
* the parser will throw a parser error. |
625 |
|
* |
626 |
|
* This default implementation of this method does not accept any |
627 |
|
* metric prefix. Deriving subclasses would override this method |
628 |
|
* implementation in case they do accept any metric prefix for its |
629 |
|
* function arguments. |
630 |
|
* |
631 |
|
* @param iArg - index of the function argument in question |
632 |
|
* (must be between 0 .. maxAllowedArgs() - 1) |
633 |
|
* |
634 |
|
* @return true if a metric prefix would be accepted for the respective |
635 |
|
* function argument by this function |
636 |
|
* |
637 |
|
* @see MetricPrefix_t |
638 |
|
*/ |
639 |
|
virtual bool acceptsArgUnitPrefix(vmint iArg) const; |
640 |
|
|
641 |
|
/** |
642 |
|
* This method is called by the parser to check whether arguments |
643 |
|
* passed in scripts to this function are accepted by this function. If |
644 |
|
* a script calls this function with an argument that is declared to be |
645 |
|
* a "final" value and this is not accepted by this function, the parser |
646 |
|
* will throw a parser error. |
647 |
|
* |
648 |
|
* This default implementation of this method does not accept a "final" |
649 |
|
* value. Deriving subclasses would override this method implementation |
650 |
|
* in case they do accept a "final" value for its function arguments. |
651 |
|
* |
652 |
|
* @param iArg - index of the function argument in question |
653 |
|
* (must be between 0 .. maxAllowedArgs() - 1) |
654 |
|
* @return true if a "final" value would be accepted for the respective |
655 |
|
* function argument by the function |
656 |
|
* |
657 |
|
* @see VMIntExpr::isFinal() |
658 |
|
*/ |
659 |
|
virtual bool acceptsArgFinal(vmint iArg) const; |
660 |
|
|
661 |
|
/** |
662 |
* This method is called by the parser to check whether some arguments |
* This method is called by the parser to check whether some arguments |
663 |
* (and if yes which ones) passed to this script function will be |
* (and if yes which ones) passed to this script function will be |
664 |
* modified by this script function. Most script functions simply use |
* modified by this script function. Most script functions simply use |
1067 |
*/ |
*/ |
1068 |
class VMDynIntVar : virtual public VMDynVar, virtual public VMIntExpr { |
class VMDynIntVar : virtual public VMDynVar, virtual public VMIntExpr { |
1069 |
public: |
public: |
1070 |
|
MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } |
1071 |
|
StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } |
1072 |
|
bool isFinal() const OVERRIDE { return false; } |
1073 |
}; |
}; |
1074 |
|
|
1075 |
/** @brief Dynamically executed variable (of string data type). |
/** @brief Dynamically executed variable (of string data type). |
1354 |
} |
} |
1355 |
return "invalid"; |
return "invalid"; |
1356 |
} |
} |
1357 |
|
|
1358 |
|
/** |
1359 |
|
* Convenience function used for converting an StdUnit_t constant to a |
1360 |
|
* string, i.e. for generating error message by the parser. |
1361 |
|
*/ |
1362 |
|
inline String unitTypeStr(const StdUnit_t& type) { |
1363 |
|
switch (type) { |
1364 |
|
case VM_NO_UNIT: return "none"; |
1365 |
|
case VM_SECOND: return "seconds"; |
1366 |
|
case VM_HERTZ: return "Hz"; |
1367 |
|
case VM_BEL: return "Bel"; |
1368 |
|
} |
1369 |
|
return "invalid"; |
1370 |
|
} |
1371 |
|
|
1372 |
/** @brief Virtual machine representation of a script. |
/** @brief Virtual machine representation of a script. |
1373 |
* |
* |