06 May 2007

control curves

control curves

v1.0 [pdf]

As a last step for making iDAFx, when the effects and the feature extractions are already existing, counts the control curve. The best work already made on it is from the hand of Verfaille and Arfib.

The feature extraction stage ends with a curve of values that change. Before entering the parameter curve/values of the effect a few adaptations must be made:

  • combine
    One can choose (it's optional) to combine several features. These can be added as a linear combination, each with their specific weight. Also must the signal be normalized. A block is made for this: combine.
  • map
    Several mapping strategies have to be provided, depending on the features and the effect parameter one wants to control. A lot of experimenting may be done with all possibilities. Different blocks are made for this, they all have one input and one output, both normalized: mapLinear, mapSine, mapTrunc, mapTime,...

    Also other mappings can be used. mapping is nothing more than applying a function. More window-like functions can be used too: hamming, hann, gauss,... and also non-symmetrical windows come in handy. View the documentation in the document mapWindow. Some other techniques are also presented is this documentation (eg bpm2time )
  • scale
    In the last step the curve must be shifted and scaled to the appropriate range of the effect parameter: scale.
Sometimes it's better to couple the feature and the parameter directly (for example: bpm feature, bpm effect parameter). Sometimes it's nice to control waves (from eg the waves block) using features and let these waves control parameters of effects. View the document about waves. One must always pay special attention to interfaces.

Hereunder follows the documentation of the blocks used for the technique described in the above mentioned paper.


combine

This block makes a linear combination of the inlets. The factors can be chosen from the display. The inlets must be normalized before entering the block. The output is normalized too.

version

v1.0: built 29/04/2007 with Pd v0.40-2 [pd]

interface

Input 1, 2 and 3: control signals to combine. They have to be normalized before entering the block. One can also use only two inlets.

Output 1: a normalized control signal that is the linear combination as chosen from the display.

Controls:
number box 1, 2 and 3: The factors a, b and c in the equation y = ax1 + bx2 + cx3.

implementation

The equation used here is:
y = (ax1 + bx2 + cx3)/(a+b+c)
The bang blocks make sure that it doesn't matter which inlets are used or not used. Either way the sum will be updated, even though a cold inlet might be used (that normally would not update that sum). If the inlets are normalized (and this is assumed), the division by the sum of all coefficients will normalize the output too.


scale, scaleS

This block scales a normalized input to a range that is specified in the controls on a display or at the inlets.

version

v1.0: built 29/04/2007 with Pd v0.40-2 [scale.pd][scaleS.pd]

interface

Input 1: Input control signal ranging between 0 and 1
Input 2, number box m: lower boundary of the target range
Input 3, number box M: upper boundary of the target range

Output 1: a scaled version of the input signal

implementation

For both instances the following mathematical formula is performed:
y = (M-m)*x+m


mapLinear/mapLin

This block performs a linear mapping between a normalized input and a normalized output. That constraint is not even necessary, the only real constraint is that the curve starts at zero. But for mapping purposes the signal is mostly normalized. Include an argument number!

version

v1.0: built 29/04/2007 with Pd v0.40-2 [mapLinear][mapLin]

interface

mapLinear:
Input 1: control signal
Input 2, 3, 4: knee of the curve: x1, x2, x3. These knees correspond with thresholds in dynamics processing
Input 5, 6, 7, 8: slopes of each line: a1, a2, a3, a4. The slopes correspond eg with compression factors: 2:1 would give a slope of 1/2 or 0.5
Output 1: the normalized result of the linear curve

mapLin:
Input 1: control signal
Input 2: slope of the line a
Input 3: y-intercept of the line b

implementation

This patch does nothing more than performing the formulas you find in the graphs in the section interface. To check where x is situated, moses blocks are used.



mapSine

This block maps the normalized input according to a sinusoidal curve (as one can see in the figure in the preamble).

version

v1.0: built 29/04/2007 with Pd v0.40-2 [pd]

interface

Input 1: a normalized input control signal
Output 1: a mapped signal output according to the given curve. It ranges from 0 to 1.

implementation

The given formula is performed with Pure Data blocks. The sin~ block is a phase shifted version of the cos~ block. View the documentation of sin~ if needed. Because it outputs an audio signal, the bang object bangs a snapshot~ object that samples and holds the value of that moment. Because the bang block is connected with the output of the calculation, each change will result in a new sample at the output of the snapshot~ block.


mapTrunc/mapTruncS

This block maps a chosen part of the normalized input to the output (as one can see in the figure in the preamble). This mapping curve is a very basic limiter and noise gate. The threshold of the noise gate would be tm and the threshold of the limiter would be tM. Include an argument number!

version

v1.0: built 29/04/2007 with Pd v0.40-2 [mapTrunc][mapTruncS]

interface

Input 1: a normalized input control signal
Input 2, number box tm: lower boundary of truncation
Input 3, number box tM: upper boundary of truncation
Output 1: a mapped signal output according to the given curve. It ranges from 0 to 1.

implementation

In comparison with other implementations in this document, nothing new is done, only another formula. The formula performed here with Pure Data blocks is:
y = [tm (if x<tm) + tM (if x>tM) + x (if tm<x<tM)]/(tM-tm)


mapTime/mapTimeS

This block time stretches the original control signal. The time-stretched parameter alpha divides the original range into two parts: the lowest will be contracted to sm, the upper dilated to sM (as one can see in the figure in the preamble). Include an argument number!

version

v1.0: built 29/04/2007 with Pd v0.40-2 [mapTime.pd][mapTimeS.pd]

interface

Input 1: a normalized input control signal
Input 2, number box alpha: time-stretched parameter that realizes the boundary between contraction and dilatation.
Input 3, number box sm: contraction factor smaller than or equal to 1
Input 4, number box sM: dilatation factor greater than or equal to 1
Output 1: a mapped signal output according to the given curve. It ranges from 0 to 1.

implementation

As with the other blocks in this document a formula is calculated with PureData blocks. Care is taking to include dollar arguments to ensure multiple and correct use in the same patch. The formula calculated is:
y = sm^((alpha-x)/alpha) (if x < alpha) + sM^(x.alpha/(1-alpha)) (if x > alpha))


bpm2time

This block calculates the period between two beats or any division of it. It can be used to calculate a certain delay time parameter.

version

v1.0: built 29/04/2007 with Pd v0.40-2 [pd]

interface

Input 1: a bpm value. Best somewhere between 40bpm and 250bpm, but it works for every value given.
Input 2: the division (DIV) parameter specifies how to divide the period between two beats. Here's a list with values that can be used on instruments like the Korg Microkorg and Roland SH32. The ones with an asterisk are whole divisions of a period. The others need several periods to synchronise again with the first count of a measure. A block is made for this purpose: measure. It has buttons for every possibility.
1/1 DIV=1 *
3/4 DIV=0.75
2/3 DIV=0.66666
1/2 DIV=0.5 *
3/8 DIV=0.375
1/3 DIV=0.333333 *
1/4 DIV=0.25 *
3/16 DIV=0.1875
1/6 DIV=0.16666 *
1/8 DIV=0.125 *
3/32 DIV=0.09375
1/12 DIV=0.08333 *
1/16 DIV=0.0625 *
3/64 DIV=0.04687
1/24 DIV=0.04166 *
1/32 DIV=0.03125 *

Output 1: a time parameter in msec. 60bpm=1000msec

implementation


This is the measure block implementation. All in the red box is part of the display (by a graph-on-parent).
The mathematical formula for this calculation is:
DLY = DIV*60000/BPM
This formula come from 60sec/minute and 1000msec/second. The bang block is provided to make sure that the output is also updated when only the DIV inlet is changed, although it is attached to the cold inlet of the multiplication block.



No comments: