269 lines
6.1 KiB
Racket
269 lines
6.1 KiB
Racket
#lang scribble/manual
|
|
@(require (for-label racket))
|
|
|
|
@title{Gendy3}
|
|
Dynamic stochastic synthesis generator.@section{related}
|
|
Classes/Gendy1, Classes/Gendy2
|
|
@section{categories}
|
|
UGens>Generators>Stochastic
|
|
|
|
|
|
@section{description}
|
|
|
|
|
|
See link::Classes/Gendy1:: help file for background. This variant of
|
|
GENDYN normalises the durations in each period to force oscillation at
|
|
the desired pitch. The breakpoints still get perturbed as in
|
|
link::Classes/Gendy1:: .
|
|
|
|
There is some glitching in the oscillator caused by the stochastic
|
|
effects - control points as they vary cause big local jumps of amplitude.
|
|
Put
|
|
@racketblock[ampscale:: and ]
|
|
|
|
@racketblock[durscale::
|
|
low to minimise the rate of this.
|
|
|
|
SuperCollider implementation by Nick Collins
|
|
|
|
]
|
|
@section{classmethods}
|
|
|
|
|
|
@section{method}
|
|
ar, kr
|
|
|
|
@section{argument}
|
|
ampdist
|
|
|
|
Choice of probability distribution for the next perturbation of
|
|
the amplitude of a control point.
|
|
|
|
The distributions are (adapted from the GENDYN program in Formalized Music):
|
|
|
|
@section{table}
|
|
|
|
## 0: || LINEAR.
|
|
## 1: || CAUCHY.
|
|
## 2: || LOGIST.
|
|
## 3: || HYPERBCOS.
|
|
## 4: || ARCSINE.
|
|
## 5: || EXPON.
|
|
## 6: || SINUS.
|
|
::
|
|
|
|
Where the sinus (Xenakis' name) is in this implementation taken
|
|
as sampling from a third party oscillator. See example below.
|
|
|
|
|
|
@section{argument}
|
|
durdist
|
|
|
|
Choice of distribution for the perturbation of the current inter
|
|
control point duration.
|
|
|
|
|
|
@section{argument}
|
|
adparam
|
|
|
|
A parameter for the shape of the amplitude probability
|
|
distribution, requires values in the range 0.0001 to 1 (there are
|
|
safety checks in the code so don't worry too much if you want to
|
|
modulate!).
|
|
|
|
|
|
@section{argument}
|
|
ddparam
|
|
|
|
A parameter for the shape of the duration probability
|
|
distribution, requires values in the range 0.0001 to 1.
|
|
|
|
|
|
@section{argument}
|
|
freq
|
|
|
|
Oscillation frequency.
|
|
|
|
|
|
@section{argument}
|
|
ampscale
|
|
|
|
Normally 0.0 to 1.0, multiplier for the distribution's delta
|
|
value for amplitude. An ampscale of 1.0 allows the full range
|
|
of -1 to 1 for a change of amplitude.
|
|
|
|
|
|
@section{argument}
|
|
durscale
|
|
|
|
Normally 0.0 to 1.0, multiplier for the distribution's delta
|
|
value for duration. An ampscale of 1.0 allows the full range of
|
|
-1 to 1 for a change of duration.
|
|
|
|
|
|
@section{argument}
|
|
initCPs
|
|
|
|
Initialise the number of control points in the memory.
|
|
Xenakis specifies 12. There would be this number of control
|
|
points per cycle of the oscillator, though the oscillator's
|
|
period will constantly change due to the duration distribution.
|
|
|
|
|
|
@section{argument}
|
|
knum
|
|
|
|
Current number of utilised control points, allows modulation.
|
|
|
|
@section{argument}
|
|
mul
|
|
|
|
@section{argument}
|
|
add
|
|
|
|
@section{discussion}
|
|
|
|
All parameters can be modulated at control rate except for
|
|
@racketblock[initCPs:: which is used only at initialisation.
|
|
|
|
|
|
]
|
|
@section{Examples}
|
|
|
|
|
|
|
|
@racketblock[
|
|
|
|
//LOUD! defaults like a rougher Gendy1
|
|
{Pan2.ar(Gendy3.ar(mul:0.5))}.play
|
|
|
|
{Pan2.ar(Gendy3.ar(freq:MouseX.kr(220,880,'exponential'), durscale:0.01, ampscale:0.02, mul:0.2))}.play
|
|
|
|
//stochastic waveform distortion- also play me at the same time as the previous example...
|
|
{Pan2.ar(Gendy3.ar(1,2,0.3,-0.7,MouseX.kr(55,110,'exponential'),0.03,0.1))}.play
|
|
|
|
|
|
(
|
|
{Pan2.ar(
|
|
Normalizer.ar(
|
|
RLPF.ar(
|
|
RLPF.ar(Mix.new(Gendy3.ar(freq:[230, 419, 546, 789])),
|
|
MouseX.kr(10,10000,'exponential'),0.05),
|
|
MouseY.kr(10,10000,'exponential'),0.05)
|
|
,0.9)
|
|
,Lag.kr(LFNoise0.kr(1),0.5))}.play
|
|
)
|
|
|
|
|
|
//concrete pH?
|
|
(
|
|
{Pan2.ar(
|
|
Mix.new(Gendy3.ar(freq:([1,1.2,1.3,1.76,2.3]*MouseX.kr(3,17,'exponential')),mul:0.2)))}.play
|
|
)
|
|
|
|
//glitch low, mountain high
|
|
(
|
|
{Pan2.ar(
|
|
Mix.new(Gendy3.ar(3,5,1.0,1.0,(Array.fill(5,{LFNoise0.kr(1.3.rand,1,2)})*MouseX.kr(100,378,'exponential')),MouseX.kr(0.01,0.05),MouseY.kr(0.001,0.016),5,mul:0.1)))}.play
|
|
)
|
|
|
|
//play me
|
|
{Pan2.ar(RLPF.ar(Gendy3.ar(1,3,freq:MouseX.kr(100,1000), durscale:0.0, ampscale:MouseY.kr(0.0,0.1), initCPs:7, knum: MouseY.kr(7,2)), 500,0.3, 0.2), 0.0)}.play
|
|
|
|
|
|
|
|
//used as an LFO
|
|
(
|
|
{Pan2.ar(SinOsc.ar(Gendy3.kr(2,5,SinOsc.kr(0.1,0,0.49,0.51),SinOsc.kr(0.13,0,0.49,0.51), 0.34, SinOsc.kr(0.17,0,0.49,0.51), SinOsc.kr(0.19,0,0.49,0.51),10,10,mul:50, add:350), 0, 0.3), 0.0)}.play
|
|
)
|
|
|
|
//buzzpipes
|
|
{Pan2.ar(Mix.new(Gendy3.ar(0, 0, SinOsc.kr(0.1, 0, 0.1, 0.9),1.0, [100,205,410], 0.011,0.005, 12, 12, 0.12)), 0.0)}.play
|
|
|
|
|
|
//modulate distributions
|
|
//change of pitch as distributions change the duration structure and spectrum
|
|
{Pan2.ar(Gendy3.ar(MouseX.kr(0,7),MouseY.kr(0,7),mul:0.2), 0.0)}.play
|
|
|
|
|
|
//modulate num of CPs
|
|
{Pan2.ar(Gendy3.ar(knum:MouseX.kr(2,13),mul:0.2), 0.0)}.play
|
|
|
|
|
|
//Gendy1 into Gendy2 into Gendy3...with cartoon side effects
|
|
(
|
|
{Pan2.ar(Gendy3.ar(1,2,freq:Gendy2.ar(maxfreq:Gendy1.kr(5,4,0.3, 0.7, 0.1, MouseY.kr(0.1,10), 1.0, 1.0, 5,5, 25,26),minfreq:24, knum:MouseX.kr(1,13),mul:150, add:200), durscale:0.01, ampscale:0.01, mul:0.1), 0.0)}.play
|
|
)
|
|
|
|
//use SINUS to track any oscillator and take CP positions from it, use adparam and ddparam as the inputs to sample
|
|
{Pan2.ar(Gendy3.ar(6,6,LFPulse.kr(LFNoise0.kr(19.0,0.5,0.6), 0, 0.4, 0.5), Gendy1.kr(durscale:0.01,ampscale:0.01), MouseX.kr(10,100),mul:0.2), 0.0)}.play
|
|
|
|
|
|
|
|
//wolf tones
|
|
(
|
|
{
|
|
Mix.fill(10,{
|
|
var freq;
|
|
|
|
freq= exprand(130,1160.3);
|
|
Pan2.ar(SinOsc.ar(Gendy3.ar(6.rand,6.rand,SinOsc.kr(0.1,0,0.49,0.51),SinOsc.kr(0.13,0,0.49,0.51),freq, SinOsc.kr(0.17,0,0.0049,0.0051), SinOsc.kr(0.19,0,0.0049,0.0051), 12, 12, 200, 400), 0, 0.1), 1.0.rand2)
|
|
});
|
|
}.play
|
|
)
|
|
|
|
//CAREFUL! mouse to far right causes explosion of sound-
|
|
//notice how high frequency and num of CPs affects CPU cost
|
|
(
|
|
{Pan2.ar(
|
|
CombN.ar(
|
|
Resonz.ar(
|
|
Gendy3.ar(2,3,freq:MouseX.kr(10,700), initCPs:100),
|
|
MouseY.kr(50,1000), 0.1)
|
|
,0.1,0.1,5, 0.16
|
|
)
|
|
, 0.0)}.play
|
|
)
|
|
|
|
|
|
//storm
|
|
(
|
|
{
|
|
var n;
|
|
n=15;
|
|
|
|
0.5*Mix.fill(n,{
|
|
var freq, numcps;
|
|
|
|
freq= rrand(130,160.3);
|
|
numcps= rrand(2,20);
|
|
Pan2.ar(Gendy3.ar(6.rand,6.rand,10.0.rand,10.0.rand,freq*exprand(1.0,2.0), 10.0.rand, 10.0.rand, numcps, SinOsc.kr(exprand(0.02,0.2), 0, numcps/2, numcps/2), 0.5/(n.sqrt)), 1.0.rand2)
|
|
});
|
|
}.play
|
|
)
|
|
|
|
|
|
|
|
//another glitchy moment
|
|
(
|
|
{
|
|
var n;
|
|
n=10;
|
|
|
|
Resonz.ar(
|
|
Mix.fill(n,{
|
|
var freq, numcps;
|
|
|
|
freq= rrand(50,560.3);
|
|
numcps= rrand(2,20);
|
|
Pan2.ar(Gendy3.ar(6.rand,6.rand,1.0.rand,1.0.rand,freq, 1.0.rand, 1.0.rand, numcps, SinOsc.kr(exprand(0.02,0.2), 0, numcps/2, numcps/2), 0.5/(n.sqrt)), 1.0.rand2)
|
|
})
|
|
,MouseX.kr(100,2000), MouseY.kr(0.01,1.0), 0.3)
|
|
;
|
|
}.play
|
|
)
|
|
::
|
|
|
|
]
|
|
|
|
|