/[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 3580 by schoenebeck, Wed Aug 28 15:23:23 2019 UTC revision 3581 by schoenebeck, Fri Aug 30 11:40:25 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 VMScalarNumberExpr;
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.
          * is used sometimes which has two prefixes. This is an exception though  
          * and more than two prefixes is currently not supported by the script  
          * engine.  
217           *           *
218           * Start iterating over the prefixes of this unit by passing @c 0 as           * Usually a unit either has exactly none or one metric prefix, but note
219           * argument to this method. The prefixes are terminated with return           * that there might also be units with more than one prefix, for example
220           * value VM_NO_PREFIX being always the last element.           * @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           * @param i - index of prefix           * The factor returned by this method is the final mathematical factor
225           * @returns prefix of requested index or VM_NO_PREFIX otherwise           * that should be multiplied against the number associated with this
226           * @see unitFactor()           * unit. This factor results from the sequence of metric prefixes of
227             * this unit.
228             *
229             * @see MetricPrefix_t, hasUnitFactorNow(), hasUnitFactorEver(),
230             *      VM_NO_FACTOR
231             * @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.
          * multiplied against the number associated with this unit. This factor  
          * results from the sequence of metric prefixes of this unit.  
240           *           *
241           * @see unitPrefix()           * This is actually just a convenience method which returns @c true if
242             * unitFactor() is not @c 1.0.
243             *
244             * @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 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 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 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 707  namespace LinuxSampler { Line 821  namespace LinuxSampler {
821          virtual ExprType_t returnType(VMFnArgs* args) = 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 VMScalarNumberExpr::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
861           * script is calling this function with less arguments, the script           * script is calling this function with less arguments, the script
862           * parser will throw a parser error.           * parser will throw a parser error.
# Line 814  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 VMScalarNumberExpr::isFinal(), returnsFinal()
968           */           */
969          virtual bool acceptsArgFinal(vmint iArg) const;          virtual bool acceptsArgFinal(vmint iArg) const;
970    
# Line 834  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 1229  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      };      };

Legend:
Removed from v.3580  
changed lines
  Added in v.3581

  ViewVC Help
Powered by ViewVC