22 May 2007

project sound examples

For now this project will rest a few months (exams). We made a few sound examples to let you hear some effects, and a few concrete things one can do with an intelligent effect patch as explained in the final written project report.
In the folder effects one finds several examples of DAFx.
In the folder iDAFx one finds the five basic tracks used to mix a song and then a showcase called song.

16 May 2007

tap

tap

This block outputs a bpm value when triggered by a bang that can come from a MIDI message (eg a drum pad). When it loses track because the trigger is not periodic enough, it restarts and for a moment (2 taps) holds the previous tempo.

version

v1.0: built 14/05/2007 with Pd v0.40-2 [pd][pdf]
based on http://www.parasitaere-kapazitaeten.net/Pd/pdpatches

interface

Input 1: the inlet that receives triggers, anything counts: a bang, a value,...
Input 2: a reset knob: resets the counting when tempo is lost. Also happens automatically.

Output 1: the tempo in beats per minute (bpm)
Output 2: a bang when tempo is lost. It's not necessary to connect this with the reset input. It's taken care of inside

implementation


To calculate the tempo, this algorithm uses three steps: it calculates the interval between the previous click and the current click, it calculates the mean inter-click interval time and it computes the bpm value of this. Then as an extra step the last value before losing the tempo and dropping to 0bpm is remembered by only updating the outlet if it's not 0 (0 can never be a tempo of a song, therefor it's allowed)
The time between the current and previous tap, beat or click is calculated by a timer object, which does just that. A simple counter is used to start this process only after two taps, each time the reset restarts the counter.

Then the mean is calculated by adding the new value to the sum of the previous values (this last sum is made by multiplying the last mean value by the last counter index, so a small backward recalculation is done). This is each time divided by the current counter value (indicating the number of terms of the sum).

Another step decides if the tempo is between the right values, that it doesn't deviate too much. If it does, the whole thing is reset.

15 May 2007

round

round

This block extends the integer calculations of Pure Data by allowing to use a rounding value of a float.

version

v1.0: built 10/05/2007 with Pd v0.40-2 [pd][pdf]

interface

Input 1: a float control signal input

Output 1: an integer control signal output signal

implementation

A floor operation is performed on the value. This floored value is subtracted from the original version, which gives a value between 0 and 1. If this value is greater than or equal to 0.5, then the int block which holds the floored value + 1 is banged, otherwise the int block with the floored value is banged. The last int block is just to collect signals, it's not necessary for the correct functioning of this algorithm.

dynamics

dynamics

This block is a versatile dynamics processing block that, depending on the parameters on its inlets is a limiter, compressor, expander or noise gate. It can compress, suppress and expand at the same time. Four regions can be chosen, each with their own behaviour. One has to use an argument when using multiple instances of this block in the same patch.

version

v1.0: built 14/05/2007 with Pd v0.40-2 [pd][pdf]

interface

Input 1: the (mono) audio signal input
Input 2, 3, 4: The different thresholds expressed in a dB scale ranging from 0dB to 100dB. (this means that a threshold of -20dB equals 80dB in this scaling)
Input 5, 6, 7, 8: The different ratios R that indicate the behaviour of what happens if the signal level reaches that part.
limiter
R = infinity
compressor
1 < R < infinity
linear
R = 1
expander
0 < R < 1
noise gate
R = 0

Output1: the output audio signal

Display:
In the abstraction itself one can see the input signal level compared to the output signal level and compared to the unity level 100dB (or 0dB). Also g(k) is displayed against unity.

implementation


We use a scheme based on DAFx (p37). The level of the signal is measured to obtain the instantaneous RMS in dB with the env~ block. We take an RMS over 2048 samples. Some moses blocks route X(dB) the right way. Then the following calculation is done:
g(k) = [th + ( X(dB)-th )/R] / X(dB)
The float object f does nothing else but collecting the four routes.
The delay on the original signal is meant to align the samples but is now set on 0, because we haven't made a method yet to discover how long the delay in the other leg is. There is a certain drift anyway, because the gain factor g(k) is often greater than 1 even when all ratios R are 1. TODO

09 May 2007

pitchShifter~

pitchShifter~

This block shifts the pitch over some halftones, up or down according to the sign of the first inlet. There is a variable delay between the minimum delay,
corresponding to the third inlet and the the minimum delay + the size of the window, corresponding to the second inlet.

version

v1.0: built 8/05/2007 with Pd v0.40-2 [pd][pdf]

interface

Input1: incoming mono audio signal
Input2: number of halftones up or down depending on sign of the input
Input3: the size of the window in ms
Input4: the minimum delay in ms

Output 1: original signal shifted over a number of halftones specified by input2

implementation

The desired pitch shift in halftones(num) is converted into a transposition factor t= 2^(num/12)= e^(num*log(2)/12) = e^(0.05776*num).
In the tape head rotation speed part f is calculated with f = [(t-1)*Fs]/s (Fs= samplerate and s= size window). This f is used to calculate
the saw tooth signals and corresponding envelopes.
The minimum delay (input3) is added to both sawtooth signals to make the delay input for the vd~ blocks.
The fact that two copies are made (one is shifted in phase with respect to the other one --> 0.5 correspondig to 180 degrees)
is to avoid discontinuities due to sampling.
Finally both vd~ block outputs are then multiplied by the corresponding envelopes and summed.

multitapdelay~ / reversedelay~

multitapdelay~ / reversedelay~

These blocks are derivatives of the very general stereomultitapdelay~ block. They represent specific cases that are nice to use in practice. The multitapdelay~ has 10 delay taps that each are DLY (delay time) delayed and the next tap is always FBK (feedback level) attenuated. One can choose which taps are played back. The new settings herefore work only when the FBK is touched again. An argument must be specified when one wants to use multiple delays in one patch. The reversedelay~ does exactly the same but each tap will incremently play louder.
For both effects one can choose to give a pingpong effect by adjusting the panning of all taps. The uneven taps evenly go left, the even taps evenly right for positive PAN values.

version

v1.0 [pdf]

pan~ v1.1 [pd]

v1.0: built 9/05/2007 with Pd v0.40-2 [multitapdelay~.pd] [reversedelay~.pd]

interface

Input 1: the signal you want to delay.
Input 2: the delay time parameter DLY. It specifies how long it takes in milliseconds before you hear the following repetition. It ranges from 0msec tot 3000msec (3 seconds). This is the length of the delay line used in the implementation and is thus an absolute maximum.
Input 3: the feedback parameter FBK. The first tap is attenuated (amplified) with this value divided by 100 (1000) for the multitapdelay~ (reversedelay~). In other words, you can vary the level from 0 (no delay audible) to 0.999 (maximum amplitude of the delayed signals, keeps on repeating as if it never ends) with steps of hundreds/thousands. The system can't get instable because there are no feedback loops involved. But when the FBK value is 100 (internally 0.1) for the reversedelay~, the last tap is at its maximum, being as loud as the original signal.
Input 4: the panorama parameter PAN. The value ranges between -127 and 127. They are applied evenly to each tap, but the uneven ones with a reversed value.

Output 1, 2, 3, 4, 5, 6, 7, 8, 9, 10: the delayed, wet taps
Output 11, 12: the delayed, wet stereo signal.

implementation


At the left the delay part is shown. Each tap will receive it's final DLY parameter here. The multiplication with 1 is a leftover from the general stereomultitapdelay~ implementation which also provided feedback loops here. At the bottom of this image the two main outlets are shown.
Everything is labeled with dollar arguments to ensure unique working when using multiple instance of delays.
In the image above the inlet is shown and also the section that calculates all the DLY and FBK parameters. For the multitapdelay~ here it is:
DLYi = SUMi(DLY)
FBKi = 1(or 0)*(FBK/100)^i
That means the DLY parameter is linearly raised and the FBK parameter is exponentially attenuated.
The next image shows this part for the reversedelay~ (it's the only section that differs for both effects). The feedback is now linearly raised.
DLYi = SUMi(DLY)
FBKi = 1(or 0)*SUMi(FBK/1000)

The next image shows the section that controls the on/off position of each tap and shows the position of each taps' parameters. The loadbang block and set 1 message are there to initialize the patch to all taps on.

The next section shows how the panning is controlled and shows also the rest of the taps.
The uneven taps get a reversed value of the PAN parameter. Each tap is connected to an outlet before entering the panning logic. After the panning logic the both channels are routed to the main outlets. For information of the pan~ function one must look at the respective documentation.
TO DO: put the outlets of each tap in a specific logical order

ringmod~

ringmod~

A type of audio mixer combining two audio signals, and outputting their sum and difference. The frequencies found in the original signals are not passed through to the output. For example, if two sine waves (single frequency waveforms containing no overtones) are inputted, one with a frequency of 1000 Hz, and the second at 400 Hz, the ring modulator will output two frequencies: 600 Hz and 1400 Hz. With more complex waveforms (which contain many more overtone frequencies) ring modulators produce a clangorous, "metallic" result often used for special effects, in synth programming, and so on. One popular use has been to process vocals, which produces sci-fi sounding "robotic" voices. [sw]

version

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

interface

Input 1: the (mono) audio signal input
Input 2: the modulation frequency, it's got no real boundaries but typical values are presented in the image on top.
Input 3: a reset inlet. When this is banged, the modulating wave is reset to it's beginning. Look at the documentation of the waves block.

Output1: the ring-modulated output audio signal

Controls:
MIDI commands for choosing different oscillators for modulation. View the documentation of the waves block.

implementation

Digital ring modulation is nothing more than a multiplication of a signal with another signal. The modulating signals' frequency is very low when one wants to hear the modulating envelope. For ring modulation it's faster. The multiplication is an arbitrary scaling of the modulation frequency input and can be left away. The outlet is high pass filtered to forbid the lowest frequencies (inaudible 5Hz and less) to slip through.

08 May 2007

octaver~

octaver~

This block has two outputs, respectively the input signal one octave higher and the input signal one octave lower. The synthesised octave effect is obtained by doubling (octave-up) or halving (octave-down) the frequency of the original input signal. This is possible due to the simple two-to-one relationship between the frequencies of musical notes which are separated by an octave.

version

v1.0: built 8/05/2007 with Pd v0.40-2 [pd][pdf]

interface

Input1: incoming mono audio signal

Output 1: original signal one octave lower
Output 2: origininal signal one octave higher

implementation

For the left output (octave higher) the purpose is to take out the odd harmonics. The result is a signal with only the even ones left, which sounds an octave higher. The spectral envelope of the input will remain roughly unchanged. In this way we avoid the chipmunk effect resulting by using a speed change to obtain a pitch shift. To do so we use a variable comb filter without feedback (non recirculating) that combines two delayed copies of the incoming signal. One copy with a fixed delay (delread~) with a window size set to that one of the pitch following algorithm. The delay in ms is adjust to the output of fiddle~: 1000.2048/Fs with Fs= sample rate. (where mtof is used to translate MIDI pitch to frequency) The variable delay is the same, plus 1/2 of the measured period of the input signal, 1000/(2f) ms where f is the frequency in cycles per second. These two delay times are added and smoothed with line~ and then used as input in the variable delay line vd~. The resonant frequencies of the resulting comb filter are 2f,4f,6f,... because the difference between the two delays is 1/2f. The the response is zero for f,3f,5f.... Thus the odd harmonics have been filtered out. You can consider this operation in a different way. The incoming signal is output twice, a half cycle apart: odd harmonics are shifted 180 degrees and cancel eachother out. The even ones are in phase, so they don't.

For the right output (octave lower) we use ring modulation. The ring modulation itself happens in osc~ and with the multiplier block. Multiplying with 2 is done to get the original better balanced. Again we get the fundamental frequency from the fiddle~ block (after conversion from MIDI pitch). This is then of course multiplied with 1/2 to get one octave lower.
The moses is used to stick the most recent good guess, because when fiddle fails it outputs 0. Because fiddle~'s analyse is most closely aligned to the middle of the window(2048/2) a standard pd delay block of fixed 1024 samples of the original signal, can be used for synchronization. You can change this to get a different effect. It is also possible to change the factor 1/, by example a large integer (15) and you'll also get a completely different effect (introduction of formants).
In this implementation we use osc~ to get the ring modulation. You have to notice that osc~ only uses the sine wave to modulate the original signal.
We could use our own waves block to get more possibilities.


traditionaldelay~

traditionaldelay~

This block delays an incoming signal (two first inlets to allow for mono and stereo signals) and outputs the wet, delayed signal(s) on one channel. The original signal is not throughput. It works like the traditional delays, this means with a feedback loop. Users can vary them by using the two other inputs. In the display one can see the current position.

version

v1.0: built 8/05/2007 with Pd v0.40-2 [pd] [pdf]

interface

Input 1, 2: the signal you want to delay. If only input 1 (or 2) is connected, only output 1 (or 2) will give a result.
Input 2: the delay time parameter DLY. It specifies how long it takes in milliseconds before you hear the following repetition. It ranges from 0msec tot 3000msec (3 seconds). This is not only the maximum value of the slider, but also the length of the delay line used in the implementation.
Input 3: the feedback parameter FBK. The signal is attenuated with this value divided by 1000. In other words, you can vary the level from 0 (no delay audible) to 0.999 (maximum amplitude of the delayed signals, keeps on repeating as if it never ends) with steps of thousands.

Output 1, 2: the delayed, wet signal

implementation

The delay itself is pretty simple: the incoming signal is read by a delread~ objects that write the signal into delay lines called $1-delayLeft and $1-delayRight and with length 3000ms. Although there's no visible loop, this is how the loop is formed: after a delay time DLY the associated delread~ object reads what's in the delay line, outputs it and sends it back into the delwrite~ object. Before outputting the delayed signals they are attenuated every time by a factor FBK ranging between 0 and 0.999 (with 1 clipping is to easy), in steps of thousands. That's why the control parameter lies between 0.001 and 999.
The DLY parameter of each channel is offset by the addition with the two last inlets.
Just before entering the outlet the signals are high pass filtered for very low frequencies to not reach the outlets.
TO DO: It's possible to also implement an HF DAMP function which simulates a retro analog delay effect. It's nothing more than adding a lowpass filter with fairly high cutoff frequency (or even adjustable) in the delayline, as can be seen in the reverb blocks of this project.

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.