Hello Chuck list
I have been on this list just shortly, and saw no questions coming around , but i read that the list is also for questions ,, so hope its ok..
I have been trying to realize a 'prototype' for experimenting with chaos, fractals etc. as sound in Chuck. My aim is to find a good working template which i can use to test higher dimensional and larger algorithms quickly. I have read through the 4 page pdf :: CHUGENS, CHUBGRAPHS, CHUGINS: 3 TIERS FOR EXTENDING CHUCK and understand that the most efficient will of course by to write a Chugin,, but anyway looking for fast solutions in Chuck for now.
My test is done with iterating 1-dimensional (1 variable) algorithm and using the output to move the phase of a complex signal.
I have realized many versions of the exact same algorithm using different possibilities in Chuck . I have pasted the code of 3 versions beneath , the different files are separated by
-----------------------------------------------------
Each has some problems which I have not been able to find solutions for in the doc, therefore this mail .. (well,, no real background CS, may be one reason)
My objectives with the template are foremost: a) to be able to let some variables continue their orbits undisturbed while other parameters receive new values. b) to be able to realize higher dimensional algorithms and output the values separately. Multiple outputs
1 . Chugen,, the control of the parameters works really well, but i cannot find a way to make more than 1 output.. I cannot get my eyes on how to assign several tick functions to specific outputs..
2. Class.. using 2 * Impulse for 2 different outputs, which works , but whoops I am stuck in the first loop
3. also worked a bunch with the event, but the events layering got very cpu intensive, besides I have some problems with having to reset certain variables for new event signal which i would prefer not to reset...
Hope someone feels like looking at it, if there would be more outputs to the Chugen then forget the rest. I can use that very well .
much greetings
Vilbjørg
// 1.... SINKX - very simple chaos generator ::: x(n+1) = sin ( k * x(n)) --- Chugen for ChucK
// missing the possiblity for 2 or more outputs
class SinKX extends Chugen
{
0.3 => float x; // starting value != 0 (sin(0) = 0 , its a static point)
3.09287 => float k; //takes you through the bifurcation diagram;
25 => int itp; // iteration period
25 => int inp; // ramp period
0.0 => float zphase => float zphaseprevious => float zphaseinterpolated => float zphaseincrement;
0.2 => float zmag; // determines amplitude of waveform
0 => int i;
fun float tick(float in)
{
if (i == 0)
{
zphase => zphaseprevious;
Math.sin(k*x) => x;
(x + zphase) % 2*pi - pi => zphase;
(zphase-zphaseprevious)/inp => zphaseincrement;
}
else
{
zphase => zphase;
zphaseincrement => zphaseincrement;
}
zphaseincrement + zphaseinterpolated => zphaseinterpolated;
%(zmag , zphaseinterpolated) => polar zpolar;
zpolar $ complex => complex z;
(i + 1) % itp => i;
return z.re;
}
}
SinKX skx => Gain g => dac;
0.3 => g.gain;
0 => int ii;
while(true)
{
if (ii == 0)
{
8.301345 => skx.k; 3000 => skx.itp; 30 => skx.inp;
<<< skx.x, skx.k, skx.itp, skx.inp, skx.zphase, skx.zphaseprevious, skx.zphaseincrement >>>;
}
if (ii == 6)
{
7.789123 => skx.k; 8 => skx.itp; 8 => skx.inp;
<<< skx.x, skx.k, skx.itp, skx.inp, skx.zphase, skx.zphaseprevious, skx.zphaseincrement >>>;
}
if (ii == 8)
{
6.08 => skx.k; 1200 => skx.itp; 12 => skx.inp;
<<< skx.x, skx.k, skx.itp, skx.inp, skx.zphase, skx.zphaseprevious, skx.zphaseincrement >>>;
}
if (ii == 12)
{
5.011345 => skx.k; 100 => skx.itp; 100 => skx.inp;
<<< skx.x, skx.k, skx.itp, skx.inp, skx.zphase, skx.zphaseprevious, skx.zphaseincrement >>>;
}
if (ii == 18)
{
7.789123 => skx.k; 500 => skx.itp; 50 => skx.inp;
<<< skx.x, skx.k, skx.itp, skx.inp, skx.zphase, skx.zphaseprevious, skx.zphaseincrement >>>;
}
if (ii == 24)
{
5.78916 => skx.k; 40 => skx.itp; 40 => skx.inp;
<<< skx.x, skx.k, skx.itp, skx.inp, skx.zphase, skx.zphaseprevious, skx.zphaseincrement >>>;
}
ii++;
Math.random2f(0.5, 2.0)::second=>now;
}
---------------------------------------------
// 2... first part with the sinkx class works ok but i do not manage to vary parameters,, see beneath,
Impulse i1 => dac.left;
Impulse i2 => dac.right;
0.3 => i1.gain => i2.gain;
class sinkx
{
0.3 => float x; // starting value not 0 (sin(0) = 0 , its a static point)
0.0 => float zphase => float zphaseprevious => float zphaseinterpolated => float zphaseincrement;
0.2 => float zmag; // determines amplitude of waveform
0 => int i; // sample counter
fun float f(float k, int itp, int inp)
{
while (true)
{
if (i == 0)
{
zphase => zphaseprevious;
Math.sin(k*x) => x;
x + zphase => zphase;
(zphase-zphaseprevious)/inp => zphaseincrement;
}
else
{
zphase => zphase;
zphaseincrement => zphaseincrement;
}
zphaseincrement + zphaseinterpolated => zphaseinterpolated;
%(zmag , zphaseinterpolated) => polar zpolar;
zpolar $ complex => complex z;
z.re => i1.next;
z.im => i2.next;
(i + 1) % itp => i;
1::samp => now;
}
}
}
0 => int iii;
sinkx skx;
skx.f(6.08, 3000, 30); // here trouble, probably my lack of computer science, code never moves past this function call
Math.random2f(5.0, 10.0)::second => now; // to the next, I guess because of the endless while loop in the function skx.f..
skx.f(6.78, 300, 30);// maybe i need a second layer of abstraction??? to move further in the code???
//////////////// ...... any hints?????
-----------------------------------------------------------------------------
// 3. event-- SINKX - very simple chaos generator ::: x(n+1) = sin ( k * x(n))
// the events layering get very cpu expensive
//did not mange to leave the 'phase' untouched for new event..
Impulse i1 => dac.left;
Impulse i2 => dac.right;
0.3 => i1.gain => i2.gain;
Event e;
0.3 => float x; // starting value != 0 (sin(0) = 0 , its a static point)
// //for some reason it is not possible to move the declararion of the phase out here, side-effects not quite understood.
// //consequently the phase is reset for each new k / event;
//0.0 => float zphase => float zphaseprevious => float zphaseinterpolated => float zphaseincrement;
//0.2 => float zmag; // determines amplitude of waveform
//0 => int i; // sample counter
fun int sinkx( Event e, float k, int iterationperiod, int interpolationperiod)
{
0.0 => float zphase => float zphaseprevious => float zphaseinterpolated => float zphaseincrement;
0.2 => float zmag; // determines amplitude of waveform
0 => int i;
while( true )
{
e => now;
<<< x, k, iterationperiod, interpolationperiod, zphase, zphaseprevious, zphaseincrement, i >>>;
while (true)
{
if (i == 0)
{
zphase => zphaseprevious;
Math.sin(k*x) => x;
(x + zphase) % 2*pi - pi => zphase;
(zphase-zphaseprevious)/interpolationperiod => zphaseincrement;
}
else
{
zphase => zphase;
zphaseincrement => zphaseincrement;
}
zphaseincrement + zphaseinterpolated => zphaseinterpolated;
%(zmag , zphaseinterpolated) => polar zpolar;
zpolar $ complex => complex z;
z.re => i1.next;
z.im => i2.next;
(i + 1) % iterationperiod => i;
1::samp => now;
}
}
}
spork ~ sinkx( e, 8.301345, 3000, 30 ); // (e, k, iterationperiod, interpolationperiod)
spork ~ sinkx( e, 8.335123, 8, 8 );
spork ~ sinkx( e, 8.301345, 1500, 15 ); // k takes you through the bifurcation diagram;
spork ~ sinkx( e, 7.97865, 500, 50);
spork ~ sinkx( e, 8.301345, 3000, 30 ); // for linear interpolation/ ramp:: iteration period >= interpolation period
spork ~ sinkx( e, 5.78916, 25, 25); // and
spork ~ sinkx( e, 5.78916, 5000, 20 ); //iterationperiod modulo interpolationperiod = 0;
me.yield();
while( true )
{
e.signal();
Math.random2f(5.0, 10.0)::second => now;
// 5::second => now
}
// the random timing makes x take a slithly different orbit for each k for each run,