create counter
Gendy • Very Non Standard | jvkr •• blog

a l l • m u s i c

j v k r

Gendy • Very Non Standard

The gen~ object, which is an addition to Max6, makes possible the creation of interesting synthesis techniques that until now were out of reach. The area that particularly has my interest is that of non standard synthesis. Probably the most well known example of such synthesis techniques is gendy, described by Iannis Xenakis. When gen~ was released, I was excited about whether it was possible to implement this algorithm with it.

Rather quickly, sooner then I had hoped, I had something running. At some point, after an update of gen~, those patches stopped working and I put the project aside for a while. Over the course of the past weeks I returned to it with renewed attention. Here I will be sharing a few ideas and patches, that can be found at the downloads page.

Gendy is...
First of all, a definition of what gendy is can depend on which person you’re talking to. When taking the origins of Iannis Xenakis as a departure point, there is one source that is thorough and clear. Sergio Luque did a research to those origins and describes them in his Masters Thesis on Stochastic Synthesis. On page 23 it mentions the model of what I try to work out here. I must add that in my realisation I don’t remain entirely true to those original ideas for the sake of simplicity. However, the deviation is small and does not violate the underlying logic.

Step 1: progress
Many synthesis models can be understood in terms of a progression from beginning to end that, once it is finished, is repeated. A phasor, driving a process, describes just that. Since such a phasor will be inherent to many algorithms and therefor bound to occur often, let’s first take a look at this. A phasor in terms of non standard synthesis is capable of setting a different speed at the beginning of each new phase. And it was exactly such a thing that had been impossible until now—with regular signal objects, that is.

The accumulation loop of the normalised frequency forms the core of this phasor. Added to this principle is the sampling of a new frequency value when wrapping occurs.

step1 of the code

Step 2: rand~ randomised
The rand~ object moves from one random value to the next in a fixed amount of time that is determined by its frequency setting. With the phasor of the previous step, it is possible to create a generator that produces random values at random intervals and interpolates between them. Here the phasor, that is the result of the accumulation loop, drives the interpolation by linearly mixing from the previous to the current sampled random amplitude value.

step2  of the code

Step 3: reading values
On our route towards implementing gendy we arrive at a crucial step. Upon the completion of each cycle both the horizontal and vertical values are varied in relation to their current setting. This means that they need to be stored temporarily in an array for later use. However, arrays don’t exist in the gen~ environment. But buffers can be seen as arrays of floating point values. Inside gen~, a local buffer can refer to one created outside it, a global one, that is filled with random frequency values.

A counter is incremented upon each completion of a phase, and it wraps when reaching the value that represent the amount of points used in the gendy algorithm, which is a variable. The result of multiplying the frequency values from peek with the amount of points ensures that the total period for an entire sequence does not depend on that amount.

step3 of the code

Step 4: writing values
After values are read, they must be given a random offset and stored in place. The approach taken here is to have a separate process of which the counter lags behind by one step. The frequency to which a random value is added, is sampled by the same trigger that increases the counter.

step4 of the code

Step 5: amplitudes
The last step is to include what was introduced in the second step: the interpolation from one amplitude value to the next. These are stored in the second channel of the buffer.

step5 of the code

Further development
This model can be used as a starting point for further development. A few things can be added or improved.

1. Rounding to whole number of samples
Currently the period for each line piece is described in terms of a frequency value. It is proposed that this value be expressed in terms of whole number of samples. Especially at higher pitches this gives a noticeably different result.

2. Second order random walk
From period to period each breakpoint moves in both horizontal and vertical direction because of an addition of a random value. If the movement on one of both axis were plotted out, this would show the behaviour of a random walk. A second order random walk would be the accumulation of this random walk. In above mentioned thesis the different behaviour is described, and especially, what effect it has on the algorithm.

3. Different frequency mapping
Especially with greater ranges it is clear that a given frequency offset works different for lower and higher frequencies. The model has the tendency to stay in the higher frequencies. Although this deviates from the original model, it is possible to work with pitch values instead. What can be achieved is a switching between low and high frequencies that sounds very fascinating.

4. Other distributions
Part of the original model is to use different distributions than uniform (noise). Mentioned are Gaussian, exponential, Poisson, Cauchy, arcsin and logistic. Also it is possible to use signals that are not random.

5. Different interpolation models
Instead of using a linear interpolation from breakpoint to breakpoint, other interpolation could be used, such as cosine.

go to downloads for the patches

blog comments powered by Disqus