Skip to content

9.1 Math

Davide Magni edited this page Feb 2, 2018 · 15 revisions

One of Kontakt 5.6's most important feature is real numbers and arrays. The Developer is now able to handle real numbers, logarithms, powers and perform advanced calculations which were not possible before.

math.curve

This function allows to transform a linear input value into a value which stands on a curve. A UI Control should be associated with this function in order to set the curve's depth dynamically. The curve can be enclosed within boundaries, so you can use this function for any kind of purpose, from controlling the velocity curve to crete an automation system for your UI Controls. This function is not compatible with versions older than Kontakt 5.6. This is NOT an inline function, therefore it has to be loaded into a variable before it can be used in boolean statements (if, loops etc.).

math.curve(<curve_ctrl>,<lin_value>,<curve_steps>,<min>,<max>)

  • curve_ctrl Depth of the curve. Negative values make the curve convex, positive values make the curve concave. The suggested range is -50 to +50, but you can experiment with other values too. You can declare a Slider ranging from -50 to +50, for instance, to adjust the curve dynamically.
  • lin_value Linear reference value to process. This value is needed in order to turn a linear function into a curve. This value has to be within the range 0 to curve_steps. Typically, this value is a counter or any kind of pseudo-automated value in order to get the whole curve.
  • curve_steps Resolution of the curve. The higher this value, the more precise is the curve. Please keep in mind that this value also interacts with the others, so you might want to fine-tune curve_ctrl to get a proper curve range.
  • min Minimum output value of the curve.
  • max Maximum output value of the curve.

Here's a typical usage of math.curve(). The value of the curve is stored inside a table and displayed on screen. The curve depth ranges from -50 to 50. The curve has 128 steps and can process a maximum value of 60.

on init
	//...
	create_slider(curve_depth, FAM, 100, 50, 0, 0, -50, 50, 0, NOT_PERSISTENT, 0, '')
	create_table(tbl, FAM, 200, 50, 600, 300, 128, 60, NOT_PERSISTENT)
end on
on ui_control (curve_depth)
	for i := 0 to 127
		tbl[i] := math.curve(curve_depth, i, 128, 0, 60)
	end for
end on

math.curve_alt

This function is similar to math.curve. It was designed by Nabeel Ansari. It has a slightly different shape than math.curve and it IS an inline function, so there is less code overhead when using this function. Both the functions are still available to ensure backwards compatibility. This function returns a real value, therefore it is not compatible with versions older than Kontakt 5.6.

math.curve_alt(<ex>, <x>, <min>, <max>)

  • ex Depth of the curve. Negative values make the curve convex, positive values make the curve concave. The range of this parameter is -100 to 100 (int value).
  • x Linear reference value to process. This value is needed in order to turn a linear function into a curve. The range of this parameter is 0 to 1000 (int value) in order to ensure high resolution, apparently without using real numbers.
  • min Minimum output value of the curve.
  • max Maximum output value of the curve.

math.sign

This function is based on the majestic work of BigBob and his Math library for Kontakt. This function returns the sign of a given value. To help you with your scripts, two different return modes are available. If return_mode is set to 0, the function returns 0 when the input value is negative and 1 when it is positive; if return_mode is set to 1, the function returns -1 when the input value is negative and 1 when it is positive. This is an inline function, therefore it can be used in boolean statements (if, loops etc.).

math.sign(<value>,<return_mode>)

  • value Input value to be processed.
  • return_mode Format of the output of the function.

math.log10, math.log2 and math.log_b

These functions return the result of the n-base logarythm. math.log_b() allows to set a custom integer base, while math.log10() and math.log2() will obviously return the logarythm with base 10 and 2 of the input value. This function is not compatible with versions older than Kontakt 5.6. This is an inline function, therefore it can be used in boolean statements (if, loops etc.).

math.log10(<value>) math.log2(<value>) math.log_b(<base>,<value>)

  • value Input value to be processed.
  • base Base of the logarythm. Must be an integer value.

math.pow2 and math.pow3

These functions are snippets for the Kontakt function pow(). These functions are not compatible with versions older than Kontakt 5.6. These are inline functions, therefore they can be used in boolean statements (if, loops etc.).

math.pow2(<value>) math.pow3(<value>)

  • value Input value to be processed.

math.cbrt and math.nth_root

These functions return the n-root of the input value. math.cbrt() returns the cube root, while math.nth_root() allows to set custom integer index for the root. These functions are not compatible with versions older than Kontakt 5.6. This is an inline function, therefore it can be used in boolean statements (if, loops etc.).

math.cbrt(<value>) math.nth_root(<index>,<value>)

  • value Input value to be processed.
  • index Index of the root. Must be an integer value.

math.hypot

This function returns the hypothenuse of a triangle of given cathetuses.

math.hypot(<cath1>,<cath2>)

  • cath1 Cathetus of the triangle.
  • cath2 Cathetus of the triangle.

math.max and math.min

This function is based on the majestic work of BigBob and his Math library for Kontakt. These functions return the maximum or minimum value between a set of two given values. These functions are not compatible with versions older than Kontakt 5.6. These are inline functions, therefore they can be used in boolean statements (if, loops etc.).

math.max(<a>,<b>) math.min(<a>,<b>)

math.int_to_bin and math.int_to_hex

These functions convert an integer in binary or hexadecimal format and return a text string. The output value can only be displayed in labels and cannot be used as a numeric value.

math.int_to_bin(<int>,<bit_nr>) math.int_to_hex(<int>)

  • int Integer value to be processed.
  • bit_nr In math.int_to_bin(), this parameter sets the amount of bits to be displayed. Please be careful about the sign bit, which is the furthest to the left and might be left out the display. bit_nr cannot be greater than 32.

math.bit_rnd

This function returns a new pseudo-random value everytime it is called. The value is generated by randomizing each bit in a bit sequence, thus Kontakt's random() function is used to generate a bit sequence. You can choose either to randomize the sign bit (which, in Kontakt's bit representation, is the MSB) or to have an unsigned integer as output. This function can be useful to generate random pseudo-unique IDs with a maximum word length of 31 bits plus a bit sign.

math.bit_rnd(<unsigned>)

  • unsigned If this value is 0, the return value will be either a positive or a negative value. If this value is 1, the return value will be a positive value.

math.trim

This function reduces the amount of decimal numbers of a real value. This function is not compatible with versions older than Kontakt 5.6. This is an inline function, therefore it can be used in boolean statements (if, loops etc.).

math.trim(<in>, <decim>)

  • in Input real value.
  • decim Amount of decimals after the comma.

math.note_to_freq and freq_to_note

These functions convert a MIDI note number into a frequency value in Hz and vice-versa. These functions is not compatible with versions older than Kontakt 5.6. These are inline functions, therefore they can be used in boolean statements (if, loops etc.).

math.note_to_freq(<note>, <ref>)

  • note MIDI note number. Goes from 0 to 127.
  • ref Reference frequency. Usually this would be 440.0 Hz.

math.fmod

This function allows to apply the modulo operator on real values. The modulo operator is undefined in the real domain, but sometimes you need to use it: with a simple, yet clever workaround, this becomes possible. This function is not compatible with versions older than Kontakt 5.6. This is an inline function, therefore it can be used in boolean statements (if, loops etc.).

math.fmod(<a>, <b>)

  • a Input value. Stands on the left of the modulo operation.
  • ref Input value. Stands on the right of the modulo operation.

math.flip

This function flips the desired bit in a bit sequence. Useful when dealing with bitmasks, as it "points and toggles" the desired bit. Another very useful application is to inline-invert the state of a button or switch. To do so, simply use 0 as <bit_nr>. For those who are more into bitwise maths, this function applies the XOR operator to a specific bit.

math.flip(<value>, <bit_pos>)

  • value Input value. Shall be either 0 or 1 for obvious reasons. Usually, this would be a variable.
  • bit_pos Position of the bit to flip. Zero-based, so 0 would mean the Least Significant Bit (the further to the right one).

math.scale

This function works similarly to the 'scale' object in Max MSP. Its purpose is to scale an input value enclosed in a certain range into an output value. This function works both with real and integer values, but you have to be careful with the consistency of data (either all real values or all integer values).

math.scale(<v>, <a>, <b>, <c>, <d>)

  • v Input value
  • a Input value min.
  • b Input value max.
  • c Output value min.
  • d Output value max.

math.simple_tri

This function outputs a series of numbers that follows a simple triangular wave. The purpose of this function is to mirror a value when it reaches a certain limit. For this reason, the parameter <period> sets both the period of the wave and the limit value. The behaviour is similar to using the mod operator: when <phase> reaches <period>, the output values start to decrement until 0 is reached, then they start to increment again.

math.simple_tri(<phase>, <period>, <v_offs>)

  • phase Value on x-axis to be evaluated
  • period Sets both the period of the wave and the maximum output value of the wave.
  • v_offs Vertical offset of the output wave.

math.simple_saw

This function outputs a series of numbers that follows a simple sawtooth wave. You can choose whether to use a ramp wave (the value rises from 0 to the max and then it's reset to 0) or a real sawtooth wave (the value falls from the max to 0 and then it's reset to max). The output of this function is equal to <phase> mod <period> when you are using a ramp wave.

math.simple_saw(<mode>, <phase>, <period>, <v_offs>)

  • mode Set to 0 to have a ramp wave; set to 1 to have a sawtooth wave.
  • phase Value on x-axis to be evaluated
  • period Sets both the period of the wave and the maximum output value of the wave.
  • v_offs Vertical offset of the output wave.

math.simple_sqr

This function outputs a square wave. The minimum value is 0; the maximum value is <period>.

math.simple_sqr(<phase>, <period>, <v_offs>)

  • phase Value on x-axis to be evaluated
  • period Sets both the period of the wave and the maximum output value of the wave.
  • v_offs Vertical offset of the output wave.

math.decimals

This function outputs a text string. It can be used to convert an integer into a decimal value for display purposes only. Being this a funciton on text strings, its output must be loaded into a string variable/array. This is an inline function.

math.decimals(<value>, <div>, <dec_div>)

  • value Input integer value
  • div Divider for the input value. Must be a power of 10.
  • dec_div Must be a power of 10. The exponent of the power indicates the amount of decimal numbers.

Usage example:

@t := math.decimals(88532, 10, 10)
{@t is loaded with the text string '8853.2'}
@t := math.decimals(88532, 1000, 100)
{@t is loaded with the text string '88.53'}
@t := math.decimals(88532, 1000, 1000)
{@t is loaded with the text string '88.532'}

math.decimals_hr

This function outputs a text string. It can be used to convert an integer into a decimal value for display purposes only. Being this a funciton on text strings, its output must be loaded into a string variable/array. This is a Hi-Res variant of math.decimals() a bit more pleasant to see, but it's a bit more heavy on the CPU.

math.decimals_hr(<value>, <div>, <dec_div>)

  • value Input integer value
  • div Divider for the input value. Must be a power of 10.
  • dec_div Must be a power of 10. The exponent of the power indicates the amount of decimal numbers.

math.gcd

This function calculates the Greatest Common Divider between two given numbers. The algorithm is called Euclidean algorithm. It is NOT an inline function, therefore its output shall be loaded into a variable before being processed by if, while etc.

math.gcd(<a>, <b>)

  • a First value
  • b Second value

math.lcm

This function calculates the Least Common Multiplier between two given numbers. It is NOT an inline function, therefore its output shall be loaded into a variable before being processed by if, while etc.

math.lcm(<a>, <b>)

  • a First value
  • b Second value

math.lcmm

This function calculates the Least Common Multiplier of a series of given numbers. It only accepts one parameter, which must be an int array's name. It is NOT an inline function, therefore its output shall be loaded into a variable before being processed by if, while etc.

math.lcmm(<arr>)

  • arr Array that contains the values to be evaluated. Leave the size of the array out of the call to the function.

math.reduce

Just like Python's reduce function, this one iterates a function on a set of values and returns the result of the calculations.

math.reduce(<func>, <arr>)

  • func Name of the function that needs to be iterated. Needs to be a two-parameters function.
  • arr Array that contains the values to be evaluated. Leave the size of the array out of the call to the function.

Usage example:

{Multiply two values}
function multiply(a, b) -> return
	return := a * b
end function

on init
	declare int 
	declare int_arr[6] := (2,3,6,8,1,5)

	{Multiply all the values contained in int_arr and return the result}
	int := math.reduce(multiply, int_arr)
end on
Clone this wiki locally