example class

here is a very basic supercollider class i wrote as an example of why and how to write classes.

//save this as MySequencerTrack.sc in your extensions folder and recompile
MySequencerTrack {
        var <steps;
        var <>array;
        *new {|steps= 16|
                ^super.newCopyArgs(steps).init;
        }
        init {
                array= Array.fill(4, {Array.fill(steps, 0)});  //4 here because of the four params: amp, freq, mod, pan
        }

        //array get/set
        amps {^array[0]}
        amps_ {|arr| array[0]= arr}
        freqs {^array[1]}
        freqs_ {|arr| array[1]= arr}
        mods {^array[2]}
        mods_ {|arr| array[2]= arr}
        pans {^array[3]}
        pans_ {|arr| array[3]= arr}

        //single value get/set
        amp {|index| ^array[0][index]}
        amp_ {|index, val| array[0].put(index, val)}
        freq {|index| ^array[1][index]}
        freq_ {|index, val| array[1].put(index, val)}
        mod {|index| ^array[2][index]}
        mod_ {|index, val| array[2].put(index, val)}
        pan {|index| ^array[3][index]}
        pan_ {|index, val| array[3].put(index, val)}
}

and here is some test code for it...

a= MySequencerTrack.new;
a.freqs
a.steps
a.amps= {1.0.rand}!a.steps
a.amps
a.amp(10)  //first one
//and then the same for a.freqs etc

(
s.waitForBoot{
        a.amps= {[0.5, 0.25, 0, 0, 0].choose}!a.steps;
        a.freqs= {[60, 66, 70].choose.midicps}!a.steps;
        a.mods= {1.0.linrand}!a.steps;
        a.pans= {1.0.rand2}!a.steps;
        b= {|freq= 400, amp= 0, mod= 0, pan= 0| Pan2.ar(SinOsc.ar(freq, SinOsc.ar*mod, amp), pan)}.play;
        s.sync;
        r= Routine.run({
                inf.do{
                        a.steps.do{|i|
                                b.set(\freq, a.freq(i), \amp, a.amp(i), \mod, a.mod(i), \pan, a.pan(i));
                                0.125.wait;
                        };
                };
        });
};
)

//and while it is running...  replace freqs
a.freqs= {[52, 66, 70, 80].choose.midicps}!a.steps;
a.amp_(0, 1)  //set first amp to 1.0
a.amps
a.amps= a.amps.rotate(-1)  //rotate amps left
a.freqs= a.freqs.rotate(2) //rotate freqs right
a.freqs= a.freqs+10  //transpose up
a.freqs= a.freqs.scramble //reorder

r.stop
b.free

//now the important thing and why classes are good...
//here we make 10 tracks all 32 values in length...
~mysequencer= {MySequencerTrack(32)}!10;
~mysequencer[0].amps  //amplitudes for first track
~mysequencer[0].amps= {1.0.rand}!a.steps
~mysequencer[0].amps
~mysequencer[0].amp(0)  //first one

(
s.waitForBoot{
10.do{|i|
        var steps= ~mysequencer[i].steps;
        ~mysequencer[i].amps= {[0.5, 0.25, 0, 0, 0, 0, 0, 0].choose}!steps;
        ~mysequencer[i].freqs= {[60, 66, 70, 90].choose.midicps}!steps;
        ~mysequencer[i].mods= {1.0.linrand}!steps;
        ~mysequencer[i].pans= {1.0.rand2}!steps;
};
~synths= {
        {|freq= 400, amp= 0, mod= 0, pan= 0| Pan2.ar(SinOsc.ar(freq, SinOsc.ar*mod, amp/2), pan)}.play;
}!10;
        s.sync;
        r= ~mysequencer.collect{|trk, i|
                var syn= ~synths[i];
                Routine.run({
                        inf.do{|j|
                                var x= j%trk.steps;
                                syn.set(\freq, trk.freq(x), \amp, trk.amp(x), \mod, trk.mod(x), \pan, trk.pan(x));
                                0.125.wait;
                        };
                });
        };
};
)

//while the above is running
~mysequencer[0..7].do{|trk| trk.amps= 0!32}  //mute all tracks except 8&9
~mysequencer[8..9].do{|trk| trk.mods= {4.0.linrand}!32}  //more fmod on tracks 8&9
~mysequencer[0..1].do{|trk, i| trk.freqs= {i+1*150}!32; trk.mods= {0}!32; trk.amps= {|j| [0, 1].wrapAt(i+j)}!32} //renew and add tracks 0&1
~mysequencer[8..9].do{|trk| trk.amps= {0.75.linrand*[1, 0].choose}!32}  //new amps for track 8&9
~mysequencer[8..9].do{|trk| trk.freqs= {8.linrand+1*150}!32}  //new freqs for track 8&9
~mysequencer[6].amps= {0.4}!9++({0}!23); ~mysequencer[6].freqs= {|i| 2**i*50+50}!32; //add arpeggio on track 6

~mysequencer.do{|x| x.freqs= x.freqs*1.1} //transpose all frequencies
~mysequencer.do{|x| x.amps= x.amps.rotate(-3)} //rotate all amps

r.do{|x| x.stop}
~synths.do{|x| x.free}