/[svn]/linuxsampler/trunk/src/scriptvm/common.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/scriptvm/common.h

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

revision 3573 by schoenebeck, Tue Aug 27 21:36:53 2019 UTC revision 3582 by schoenebeck, Fri Aug 30 12:23:40 2019 UTC
# Line 19  Line 19 
19  #include <vector>  #include <vector>
20  #include <map>  #include <map>
21  #include <stddef.h> // offsetof()  #include <stddef.h> // offsetof()
22    #include <functional> // std::function<>
23    
24  namespace LinuxSampler {  namespace LinuxSampler {
25    
# Line 137  namespace LinuxSampler { Line 138  namespace LinuxSampler {
138      };      };
139    
140      /**      /**
141         * This constant is used for comparison with Unit::unitFactor() to check
142         * whether a number does have any metric unit prefix at all.
143         *
144         * @see Unit::unitFactor()
145         */
146        static const vmfloat VM_NO_FACTOR = vmfloat(1);
147    
148        /**
149       * All measurement unit types supported by this script engine.       * All measurement unit types supported by this script engine.
150       *       *
151       * @e Note: there is no standard unit "cents" here (for pitch/tuning), use       * @e Note: there is no standard unit "cents" here (for pitch/tuning), use
# Line 153  namespace LinuxSampler { Line 162  namespace LinuxSampler {
162          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).          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).
163      };      };
164    
165        //TODO: see Unit::hasUnitFactorEver()
166        enum EverTriState_t {
167            VM_NEVER = 0,
168            VM_MAYBE,
169            VM_ALWAYS,
170        };
171    
172      // just symbol prototyping      // just symbol prototyping
173      class VMIntExpr;      class VMIntExpr;
174      class VMRealExpr;      class VMRealExpr;
175      class VMStringExpr;      class VMStringExpr;
176      class VMScalarNumberExpr;      class VMNumberExpr;
177        class VMArrayExpr;
178      class VMIntArrayExpr;      class VMIntArrayExpr;
179      class VMRealArrayExpr;      class VMRealArrayExpr;
180      class VMStringArrayExpr;      class VMStringArrayExpr;
181      class VMParserContext;      class VMParserContext;
182    
183      /** @brief Virtual machine measuring unit.      /** @brief Virtual machine standard measuring unit.
184       *       *
185       * Abstract base class representing standard measurement units throughout       * Abstract base class representing standard measurement units throughout
186       * the script engine. These might be i.e. "dB" (deci Bel) for loudness,       * the script engine. These might be e.g. "dB" (deci Bel) for loudness,
187       * "Hz" (Hertz) for frequencies or "s" for "seconds".       * "Hz" (Hertz) for frequencies or "s" for "seconds". These unit types can
188         * combined with metric prefixes, for instance "kHz" (kilo Hertz),
189         * "us" (micro second), etc.
190       *       *
191       * Originally the script engine only supported abstract integer values for       * Originally the script engine only supported abstract integer values for
192       * controlling any synthesis parameter or built-in function argument or       * controlling any synthesis parameter or built-in function argument or
193       * variable. Under certain situations it makes sense though for an       * variable. Under certain situations it makes sense though for an
194       * instrument script author to provide values in real, standard measurement       * instrument script author to provide values in real, standard measurement
195       * units, for example setting the frequency of some LFO directly to "20Hz".       * units to provide a more natural and intuitive approach for writing
196       * Hence support for standard units in scripts was added as an extension to       * instrument scripts, for example by setting the frequency of some LFO
197       * the NKSP script engine.       * directly to "20Hz" or reducing loudness by "-4.2dB". Hence support for
198         * standard units in scripts was added as an extension to the NKSP script
199         * engine.
200         *
201         * So a unit consists of 1) a sequence of metric prefixes as scale factor
202         * (e.g. "k" for kilo) and 2) the actual unit type (e.g. "Hz" for Hertz).
203         * The unit type is a constant feature of number literals and variables, so
204         * once a variable was declared with a unit type (or no unit type at all)
205         * then that unit type of that variable cannot be changed for the entire
206         * life time of the script. This is different from the unit's metric
207         * prefix(es) of variables which may freely be changed at runtime.
208       */       */
209      class VMUnit {      class VMUnit {
210      public:      public:
211          /**          /**
212           * Returns the metric prefix of this unit. A metric prefix essentially           * Returns the metric prefix(es) of this unit as unit factor. A metric
213           * is just a mathematical scale factor that should be applied to the           * prefix essentially is just a mathematical scale factor that should be
214           * number associated with the measurement unit. Usually a unit either           * applied to the number associated with the measurement unit. Consider
215           * has exactly none or one prefix, but note that there might also be           * a string literal in an NKSP script like '3kHz' where 'k' (kilo) is
216           * units with more than one prefix, for example mdB (mili deci bel)           * the metric prefix, which essentically is a scale factor of 1000.
217           * is used sometimes which has two prefixes. This is an exception though           *
218           * and more than two prefixes is currently not supported by the script           * Usually a unit either has exactly none or one metric prefix, but note
219           * engine.           * that there might also be units with more than one prefix, for example
220             * @c mdB (milli deci Bel) is used sometimes which has two prefixes. The
221             * latter is an exception though and more than two prefixes is currently
222             * not supported by the script engine.
223           *           *
224           * Start iterating over the prefixes of this unit by passing @c 0 as           * The factor returned by this method is the final mathematical factor
225           * argument to this method. The prefixes are terminated with return           * that should be multiplied against the number associated with this
226           * value VM_NO_PREFIX being always the last element.           * unit. This factor results from the sequence of metric prefixes of
227             * this unit.
228           *           *
229           * @param i - index of prefix           * @see MetricPrefix_t, hasUnitFactorNow(), hasUnitFactorEver(),
230           * @returns prefix of requested index or VM_NO_PREFIX otherwise           *      VM_NO_FACTOR
231           * @see unitFactor()           * @returns current metric unit factor
232           */           */
233          virtual MetricPrefix_t unitPrefix(vmuint i) const = 0;          virtual vmfloat unitFactor() const = 0;
234    
235            //TODO: this still needs to be implemented in tree.h/.pp, built-in functions and as 2nd pass of parser appropriately
236            /*virtual*/ EverTriState_t hasUnitFactorEver() const { return VM_NEVER; }
237    
238          /**          /**
239           * Conveniently returns the final mathematical factor that should be           * Whether this unit currently does have any metric unit prefix.
240           * multiplied against the number associated with this unit. This factor           *
241           * results from the sequence of metric prefixes of this unit.           * This is actually just a convenience method which returns @c true if
242             * unitFactor() is not @c 1.0.
243           *           *
244           * @see unitPrefix()           * @see MetricPrefix_t, unitFactor(), hasUnitFactorEver(), VM_NO_FACTOR
245             * @returns @c true if this unit currently has any metric prefix
246           */           */
247          vmfloat unitFactor() const;          bool hasUnitFactorNow() const;
248    
249          /**          /**
250           * This is the actual fundamental measuring unit base type of this unit,           * This is the actual fundamental measuring unit base type of this unit,
251           * which might be either Hertz, second or Bel.           * which might be either Hertz, second or Bel.
252           *           *
253           * @returns standard unit type identifier or VM_NO_UNIT if no unit used           * Note that a number without a unit type may still have metric
254             * prefixes.
255             *
256             * @returns standard unit type identifier or VM_NO_UNIT if no unit type
257             *          is used for this object
258           */           */
259          virtual StdUnit_t unitType() const = 0;          virtual StdUnit_t unitType() const = 0;
260    
# Line 225  namespace LinuxSampler { Line 267  namespace LinuxSampler {
267          /**          /**
268           * Returns the actual mathematical factor represented by the passed           * Returns the actual mathematical factor represented by the passed
269           * two @a prefix1 and @a prefix2 arguments.           * two @a prefix1 and @a prefix2 arguments.
270             *
271             * @returns scale factor of given metric unit prefixes
272           */           */
273          static vmfloat unitFactor(MetricPrefix_t prefix1, MetricPrefix_t prefix2);          static vmfloat unitFactor(MetricPrefix_t prefix1, MetricPrefix_t prefix2);
274    
275            /**
276             * Returns the actual mathematical factor represented by the passed
277             * @a prefixes array. The passed array should always be terminated by a
278             * VM_NO_PREFIX value as last element.
279             *
280             * @param prefixes - sequence of metric prefixes
281             * @param size - max. amount of elements of array @a prefixes
282             * @returns scale factor of given metric unit prefixes
283             */
284            static vmfloat unitFactor(const MetricPrefix_t* prefixes, vmuint size = 2);
285      };      };
286    
287      /** @brief Virtual machine expression      /** @brief Virtual machine expression
# Line 263  namespace LinuxSampler { Line 318  namespace LinuxSampler {
318           * return NULL! Same applies if this expression is actually a real           * return NULL! Same applies if this expression is actually a real
319           * number expression: asInt() would return NULL in that case as well.           * number expression: asInt() would return NULL in that case as well.
320           *           *
321           * @see exprType(), asReal(), asScalarNumberExpr()           * @see exprType(), asReal(), asNumber()
322           */           */
323          VMIntExpr* asInt() const;          VMIntExpr* asInt() const;
324    
# Line 279  namespace LinuxSampler { Line 334  namespace LinuxSampler {
334           * simply return NULL! Same applies if this expression is actually an           * simply return NULL! Same applies if this expression is actually an
335           * integer expression: asReal() would return NULL in that case as well.           * integer expression: asReal() would return NULL in that case as well.
336           *           *
337           * @see exprType(), asInt(), asScalarNumberExpr()           * @see exprType(), asInt(), asNumber()
338           */           */
339          VMRealExpr* asReal() const;          VMRealExpr* asReal() const;
340    
# Line 287  namespace LinuxSampler { Line 342  namespace LinuxSampler {
342           * In case this expression is a scalar number expression, that is either           * In case this expression is a scalar number expression, that is either
343           * an integer (scalar) expression or a real number (floating point           * an integer (scalar) expression or a real number (floating point
344           * scalar) expression, then this method returns a casted pointer to that           * scalar) expression, then this method returns a casted pointer to that
345           * VMScalarNumberExpr base class object. It returns NULL if this           * VMNumberExpr base class object. It returns NULL if this
346           * expression is neither an integer (scalar), nor a real number (scalar)           * expression is neither an integer (scalar), nor a real number (scalar)
347           * expression.           * expression.
348           *           *
# Line 301  namespace LinuxSampler { Line 356  namespace LinuxSampler {
356           *           *
357           * @see exprType(), asInt(), asReal()           * @see exprType(), asInt(), asReal()
358           */           */
359          VMScalarNumberExpr* asScalarNumberExpr() const;          VMNumberExpr* asNumber() const;
360    
361          /**          /**
362           * In case this expression is a string expression, then this method           * In case this expression is a string expression, then this method
# Line 366  namespace LinuxSampler { Line 421  namespace LinuxSampler {
421          virtual VMRealArrayExpr* asRealArray() const;          virtual VMRealArrayExpr* asRealArray() const;
422    
423          /**          /**
424             * This is an alternative to calling either asIntArray() or
425             * asRealArray(). This method here might be used if the fundamental
426             * scalar data type (real or integer) of the array is not relevant,
427             * i.e. for just getting the size of the array. Since all as*() methods
428             * here are very strict regarding type casting, this asArray() method
429             * sometimes can reduce code complexity.
430             *
431             * Likewise calling this method only returns a valid pointer if the
432             * expression is some array type (currently either integer array or real
433             * number array). For any other expression type this method will return
434             * NULL instead.
435             *
436             * @see exprType()
437             */
438            VMArrayExpr* asArray() const;
439    
440            /**
441           * Returns true in case this expression can be considered to be a           * Returns true in case this expression can be considered to be a
442           * constant expression. A constant expression will retain the same           * constant expression. A constant expression will retain the same
443           * value throughout the entire life time of a script and the           * value throughout the entire life time of a script and the
# Line 401  namespace LinuxSampler { Line 473  namespace LinuxSampler {
473       * This is the abstract base class for integer (scalar) expressions and       * This is the abstract base class for integer (scalar) expressions and
474       * real number (floating point scalar) expressions of scripts.       * real number (floating point scalar) expressions of scripts.
475       */       */
476      class VMScalarNumberExpr : virtual public VMExpr, virtual public VMUnit {      class VMNumberExpr : virtual public VMExpr, virtual public VMUnit {
477      public:      public:
478          /**          /**
479           * Returns @c true if the value of this expression should be applied           * Returns @c true if the value of this expression should be applied
# Line 432  namespace LinuxSampler { Line 504  namespace LinuxSampler {
504           * requested synthesis parameter.           * requested synthesis parameter.
505           */           */
506          virtual bool isFinal() const = 0;          virtual bool isFinal() const = 0;
507    
508            /**
509             * Calling this method evaluates the expression and returns the value
510             * of the expression as integer. If this scalar number expression is a
511             * real number expression then this method automatically casts the value
512             * from real number to integer.
513             */
514            vmint evalCastInt();
515    
516            /**
517             * Calling this method evaluates the expression and returns the value
518             * of the expression as real number. If this scalar number expression is
519             * an integer expression then this method automatically casts the value
520             * from integer to real number.
521             */
522            vmfloat evalCastReal();
523      };      };
524    
525      /** @brief Virtual machine integer expression      /** @brief Virtual machine integer expression
# Line 441  namespace LinuxSampler { Line 529  namespace LinuxSampler {
529       * abstract method evalInt() to return the actual integer result value of       * abstract method evalInt() to return the actual integer result value of
530       * the expression.       * the expression.
531       */       */
532      class VMIntExpr : virtual public VMScalarNumberExpr {      class VMIntExpr : virtual public VMNumberExpr {
533      public:      public:
534          /**          /**
535           * Returns the result of this expression as integer (scalar) value.           * Returns the result of this expression as integer (scalar) value.
# Line 479  namespace LinuxSampler { Line 567  namespace LinuxSampler {
567       * implement the abstract method evalReal() to return the actual floating       * implement the abstract method evalReal() to return the actual floating
568       * point result value of the expression.       * point result value of the expression.
569       */       */
570      class VMRealExpr : virtual public VMScalarNumberExpr {      class VMRealExpr : virtual public VMNumberExpr {
571      public:      public:
572          /**          /**
573           * Returns the result of this expression as real number (floating point           * Returns the result of this expression as real number (floating point
# Line 549  namespace LinuxSampler { Line 637  namespace LinuxSampler {
637          virtual vmint arraySize() const = 0;          virtual vmint arraySize() const = 0;
638      };      };
639    
640        /** @brief Virtual Machine Number Array Expression
641         *
642         * This is the abstract base class for all expressions which either evaluate
643         * to an integer array or real number array.
644         */
645        class VMNumberArrayExpr : virtual public VMArrayExpr {
646        public:
647            /**
648             * Returns the metric unit factor of the requested array element.
649             *
650             * @param i - array element index (must be between 0 .. arraySize() - 1)
651             * @see VMUnit::unitFactor() for details about metric unit factors
652             */
653            virtual vmfloat unitFactorOfElement(vmuint i) const = 0;
654    
655            /**
656             * Changes the current unit factor of the array element given by element
657             * index @a i.
658             *
659             * @param i - array element index (must be between 0 .. arraySize() - 1)
660             * @param factor - new unit factor to be assigned
661             * @see VMUnit::unitFactor() for details about metric unit factors
662             */
663            virtual void assignElementUnitFactor(vmuint i, vmfloat factor) = 0;
664        };
665    
666      /** @brief Virtual Machine Integer Array Expression      /** @brief Virtual Machine Integer Array Expression
667       *       *
668       * This is the abstract base class for all expressions inside scripts which       * This is the abstract base class for all expressions inside scripts which
# Line 556  namespace LinuxSampler { Line 670  namespace LinuxSampler {
670       * abstract methods arraySize(), evalIntElement() and assignIntElement() to       * abstract methods arraySize(), evalIntElement() and assignIntElement() to
671       * access the individual integer array values.       * access the individual integer array values.
672       */       */
673      class VMIntArrayExpr : virtual public VMArrayExpr {      class VMIntArrayExpr : virtual public VMNumberArrayExpr {
674      public:      public:
675          /**          /**
676           * Returns the (scalar) integer value of the array element given by           * Returns the (scalar) integer value of the array element given by
# Line 588  namespace LinuxSampler { Line 702  namespace LinuxSampler {
702       * classes implement the abstract methods arraySize(), evalRealElement() and       * classes implement the abstract methods arraySize(), evalRealElement() and
703       * assignRealElement() to access the array's individual real numbers.       * assignRealElement() to access the array's individual real numbers.
704       */       */
705      class VMRealArrayExpr : virtual public VMArrayExpr {      class VMRealArrayExpr : virtual public VMNumberArrayExpr {
706      public:      public:
707          /**          /**
708           * Returns the (scalar) real mumber (floating point value) of the array           * Returns the (scalar) real mumber (floating point value) of the array
# Line 693  namespace LinuxSampler { Line 807  namespace LinuxSampler {
807          /**          /**
808           * Script data type of the function's return value. If the function does           * Script data type of the function's return value. If the function does
809           * not return any value (void), then it returns EMPTY_EXPR here.           * not return any value (void), then it returns EMPTY_EXPR here.
810             *
811             * Some functions may have a different return type depending on the
812             * arguments to be passed to this function. That's what the @a args
813             * parameter is for, so that the method implementation can look ahead
814             * of what kind of parameters are going to be passed to the built-in
815             * function later on in order to decide which return value type would
816             * be used and returned by the function accordingly in that case.
817             *
818             * @param args - function arguments going to be passed for executing
819             *               this built-in function later on
820           */           */
821          virtual ExprType_t returnType() = 0;          virtual ExprType_t returnType(VMFnArgs* args) = 0;
822    
823            /**
824             * Standard measuring unit type of the function's result value
825             * (e.g. second, Hertz).
826             *
827             * Some functions may have a different standard measuring unit type for
828             * their return value depending on the arguments to be passed to this
829             * function. That's what the @a args parameter is for, so that the
830             * method implementation can look ahead of what kind of parameters are
831             * going to be passed to the built-in function later on in order to
832             * decide which return value type would be used and returned by the
833             * function accordingly in that case.
834             *
835             * @param args - function arguments going to be passed for executing
836             *               this built-in function later on
837             * @see Unit for details about standard measuring units
838             */
839            virtual StdUnit_t returnUnitType(VMFnArgs* args) = 0;
840    
841            /**
842             * Whether the result value returned by this built-in function is
843             * considered to be a 'final' value.
844             *
845             * Some functions may have a different 'final' feature for their return
846             * value depending on the arguments to be passed to this function.
847             * That's what the @a args parameter is for, so that the method
848             * implementation can look ahead of what kind of parameters are going to
849             * be passed to the built-in function later on in order to decide which
850             * return value type would be used and returned by the function
851             * accordingly in that case.
852             *
853             * @param args - function arguments going to be passed for executing
854             *               this built-in function later on
855             * @see VMNumberExpr::isFinal() for details about 'final' values
856             */
857            virtual bool returnsFinal(VMFnArgs* args) = 0;
858    
859          /**          /**
860           * Minimum amount of function arguments this function accepts. If a           * Minimum amount of function arguments this function accepts. If a
# Line 804  namespace LinuxSampler { Line 964  namespace LinuxSampler {
964           * @return true if a "final" value would be accepted for the respective           * @return true if a "final" value would be accepted for the respective
965           *         function argument by the function           *         function argument by the function
966           *           *
967           * @see VMIntExpr::isFinal()           * @see VMNumberExpr::isFinal(), returnsFinal()
968           */           */
969          virtual bool acceptsArgFinal(vmint iArg) const;          virtual bool acceptsArgFinal(vmint iArg) const;
970    
# Line 824  namespace LinuxSampler { Line 984  namespace LinuxSampler {
984          virtual bool modifiesArg(vmint iArg) const = 0;          virtual bool modifiesArg(vmint iArg) const = 0;
985    
986          /**          /**
987             * This method is called by the parser to let the built-in function
988             * perform its own, individual parse time checks on the arguments to be
989             * passed to the built-in function. So this method is the place for
990             * implementing custom checks which are very specific to the individual
991             * built-in function's purpose and its individual requirements.
992             *
993             * For instance the built-in 'in_range()' function uses this method to
994             * check whether the last 2 of their 3 arguments are of same data type
995             * and if not it triggers a parser error. 'in_range()' also checks
996             * whether all of its 3 arguments do have the same standard measuring
997             * unit type and likewise raises a parser error if not.
998             *
999             * For less critical issues built-in functions may also raise parser
1000             * warnings instead.
1001             *
1002             * It is recommended that classes implementing (that is overriding) this
1003             * method should always call their super class's implementation of this
1004             * method to ensure their potential parse time checks are always
1005             * performed as well.
1006             *
1007             * @param args - function arguments going to be passed for executing
1008             *               this built-in function later on
1009             * @param err - the parser's error handler to be called by this method
1010             *              implementation to trigger a parser error with the
1011             *              respective error message text
1012             * @param wrn - the parser's warning handler to be called by this method
1013             *              implementation to trigger a parser warning with the
1014             *              respective warning message text
1015             */
1016            virtual void checkArgs(VMFnArgs* args,
1017                                   std::function<void(String)> err,
1018                                   std::function<void(String)> wrn);
1019    
1020            /**
1021           * Implements the actual function execution. This exec() method is           * Implements the actual function execution. This exec() method is
1022           * called by the VM whenever this function implementation shall be           * called by the VM whenever this function implementation shall be
1023           * executed at script runtime. This method blocks until the function           * executed at script runtime. This method blocks until the function
# Line 1219  namespace LinuxSampler { Line 1413  namespace LinuxSampler {
1413       */       */
1414      class VMDynIntVar : virtual public VMDynVar, virtual public VMIntExpr {      class VMDynIntVar : virtual public VMDynVar, virtual public VMIntExpr {
1415      public:      public:
1416          MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; }          vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
1417          StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; }          StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; }
1418          bool isFinal() const OVERRIDE { return false; }          bool isFinal() const OVERRIDE { return false; }
1419      };      };
# Line 1542  namespace LinuxSampler { Line 1736  namespace LinuxSampler {
1736       * Returns @c true in case the passed data type is some scalar number type       * Returns @c true in case the passed data type is some scalar number type
1737       * (i.e. not an array and not a string).       * (i.e. not an array and not a string).
1738       */       */
1739      inline bool isScalarNumber(const ExprType_t& type) {      inline bool isNumber(const ExprType_t& type) {
1740          return type == INT_EXPR || type == REAL_EXPR;          return type == INT_EXPR || type == REAL_EXPR;
1741      }      }
1742    

Legend:
Removed from v.3573  
changed lines
  Added in v.3582

  ViewVC Help
Powered by ViewVC