Skip to content
Hans Lindetorp edited this page Oct 24, 2023 · 10 revisions

The <var> element does not route or generate any audio signal. Instead, it is used as a container and mapper of an external controller variable. Let's say you have a HTML-slider generating a value ranging from 0 to 100 and you want the slider to control different audio parameters differently. Then the <var> element is the solution. Every <var>element must have the attributes "name", "default" and "value" (another value possibly set by Javascript or the HTML integration attribute syntax).

The following code shows how a slider sets the variable "slider_value" and how two BiquadFilterNodes respond differently to the value using two intermediate <var> elements with different mapping settings. See below for more possibilities.

The following example shows how to use a single slider to fade between extra bass and less treble (by moving the slider to the left) or extra treble and less bass (by moving the slider to the right).

HTML:

<input type="range" value="0" min="0" max="100" data-waxml-input-set="$slider_value=this.value" />

XML:

<?xml version="1.0" encoding="UTF-8"?>
<Audio version="1.0">

    <var name="eq_low" value="$slider_value" mapin="0,100" mapout="3,-12" convert="dB->power"></var>
    <var name="eq_high" value="$slider_value" mapin="0,100" mapout="-12,3" convert="dB->power"></var>

    <Chain>
        <OscillatorNode type="sawtooth" />
        <BiquadFilterNode type="lowshelf" frequency="300" gain="$eq_low" />
        <BiquadFilterNode type="highshelf" frequency="2000" gain="$eq_high" />
    </Chain>

</Audio>  

In order to transform the value from a controller (like the mouse, a sensor, statistical data or any other data source), in a more complex way, there are several attributes to use:

mapin

The "mapin" attribute typically contains two or more values (separated by comma, semicolon or space). The basic function is to specify one "min" value and one "max" value for the incoming variable. This is the foundation for the mapping process. Those two values are used to map the incoming variable to a "minOut" and "maxOut" value and to be interpolated for any value in between. If multiple values are used, it's possible to design a complex curve as the relationship between the incoming and outgoing value.

mapout

The mapout attribute typically contains the same number of values (separated by comma, semicolon or space) as the mapin attribute. In the simplest case there will be two mapin values and two mapout values. This maps the minIn to minOut and maxIn to maxOut and interpolates the values in between. If the mapout contains at least one string value (that is not referring to a numeric variable) the nearest mapout value will be used. This is useful for mapping an incoming numeric value to a string value that can be used for selecting waveforms, filter types etc.

curve

When the input value falls between two mapin values, the output value will be interpolated according to the relative distance to the nearest lower and nearest higher mapin value. The conversion is done linearly if not specified differently with the "curve" attribute. It can be specified with one or more (typically one less than the number of mapin values) to specify one curve for all interpolations or different curves for each interpolation.

Note:

Multiple values MUST be separated by semicolon.

The following preset curves are available:

  • linear (default)
  • step
  • easeInQuad (or just easeIn)
  • easeOutQuad (or just easeOut)
  • easeInOutQuad (or just easeInOut)
  • easeInCubic
  • easeOutCubic
  • easeInOutCubic
  • easeInQuart
  • easeOutQuart
  • easeInOutQuart
  • easeInQuint
  • easeOutQuint
  • easeInOutQuint
  • easeInSin
  • easeOutSin
  • easeInOutSin
  • easeInElastic
  • easeOutElastic
  • easeInOutElastic

See a graphical display of different easing functions: https://easings.net/

There is also a possibility to specify a custom javascript expression to define the curve. Please note that the incoming value shall be named "x" and can be a value between 0 and 1. The expression shall return a value between 0 and 1. The following example generates an exponential curve similar to the preset function "easeInQuad":

curve="Math.pow(x, 2)"

steps

After the mapping process has taken place (meaning the value is now between the minimum and maximum mapout values) the value can be snapped to list of values (separated by comma, semicolon or space). It was originally created to snap a linear value to a predefined MIDI note scale but can be used to snap any value to a defined pattern. This is done by specifying a scale with comma or space separated numbers. The scale is repeated as a pattern between the minimum and maximum mapout values. The last number defines the modulus value for the pattern (e.g. the "octave" for a normal musical scale).

ex.

  • major scale: steps="0 2 4 5 7 9 11 12"
  • minor scale: steps="0 2 3 5 7 8 10 12"
  • diminished scale: steps="0 2 3"

In this example incoming values between 0 and 100 will be mapped to a value between 60 and 84 (useful MIDI note values) and then snapped to one of the following: 60, 62, 64, 65, 67, 69, 71, 72, 74, 75, 77, 79, 80, 82, 84

<var name="noteNr" follow="relX" mapin="0 100" mapout="60 84" steps="0 2 4 5 7 9 11 12"></var>

It's possible to define different steps for different interpolation regions (e.g. one pattern between the first and second mapin values and another pattern between the second and third mapin values). For multiple step patterns you have to use a strict bracket and comma-based syntax like this:

ex. multiple step patterns:

steps="[ [0, 2, 4, 5, 7, 9, 11, 12], [0, 2, 3, 5, 7, 8, 10, 12] ]"

convert

After the value is mapped and (possibly) snapped to a value it might be converted to another value domain using the "convert" attribute. It is typically a preset conversion function like "MIDI->frequency", or "db->power" or it can be a custom javascript function where "x" is the mapped variable. This example is the equivalent to the preset "MIDI->frequency":

Note:

Multiple functions (for converting different input ranges differently) MUST be separated by semicolon (in order for the functions to be able to contain commas and spaces).

convert="440 * Math.pow(2, (x - 69) / 12)"

The output of the convert function is finally stored in the parameter or variable object that can be used for any numeric attribute of an element.

Clone this wiki locally