4 // Distorsion modes 0-15 data
7 // No sound, used to output 4-bit samples by changing the volume very fast
8 [ [1], // Source Samples data
10 [1] ], // Clock mode (pixelclock = 3 * cpuclock)
11 // Distorsion 1 / Buzzy Tones
12 [ [0,0,1,0,1,0,0,0,0,1,1,1,0,1,1],
15 // Distorsion 2 / Carries distorsion 1 downward into a rumble
16 [ [0,0,1,0,1,0,0,0,0,1,1,1,0,1,1],
17 [0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0],
19 // Distorsion 3 / Flangy wavering tones, like a UFO
20 [ [0,0,1,0,1,0,0,0,0,1,1,1,0,1,1],
21 [0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1],
23 // Distorsion 4 / Pure tone
27 // Distorsion 5 : same as 4
31 // Distorsion 6 / Between pure tone and buzzy tone
32 [ [1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
35 // Distorsion 7 / Reedy tones, much brighter
36 [ [0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1],
39 // Distorsion 8 : 511 bits of white noise
40 // White noise / explosions / lightning, jet / spacecraft engine
41 [ [1,1,0,0,0,0,1,1,0,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,1,0,0,0,1,0,0,0,1,1,1,0,0,1,0,
42 0,1,1,0,0,0,1,0,0,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1,1,1,0,1,0,1,0,0,1,1,0,1,1,1,0,1,
43 1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,1,0,1,1,0,0,1,0,1,1,1,0,1,1,1,
44 1,0,1,1,0,0,0,0,1,0,1,0,1,1,0,1,0,0,0,1,0,1,0,0,0,0,1,0,1,0,1,0,0,0,0,1,1,1,1,0,
45 1,1,1,1,1,0,1,1,1,0,1,0,1,0,1,0,0,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,0,1,0,0,1,0,0,1,
46 1,0,0,0,0,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,1,1,0,1,0,1,1,0,0,0,0,0,1,1,1,
47 0,0,1,0,1,1,0,0,1,0,1,0,1,0,1,0,0,0,1,1,0,1,1,1,0,1,1,0,0,0,1,0,1,0,1,1,0,0,1,0,
48 1,0,1,0,1,1,1,0,0,0,1,0,1,0,0,0,1,1,1,0,1,1,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,0,1,1,
49 1,0,0,0,0,1,0,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,1,1,1,
50 1,0,1,0,0,0,1,1,0,1,1,0,0,0,1,0,0,1,0,1,1,1,0,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,0,0,
51 0,1,0,0,0,1,1,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,0,1,1,1,0,1,0,1,0,0,1,0,0,
52 0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,1,1,0,1,0,1,0,1,1,0,1,1,1,0,0,0,0,0,0,0,1,
53 0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,1,0,1,0,0,0,1,0],
56 // Distorsion 9 : same as 7
57 [ [0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1],
60 // Distorsion 10 : same as 6
61 [ [1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
64 // Distorsion 11 : same as 0
68 // Distorsion 12 / Pure tone, goes much lower in pitch than 4 & 5
72 // Distorsion 13 : same as 12
76 // Distorsion 14 / Electronic tones, mostly lows, extends to rumble
77 [ [1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
80 // Distorsion 15 / Electronic tones, mostly lows, extends to rumble
81 [ [0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1],
84 ] @=> int DMData[][][];
86 //Step s => Envelope e;
91 int pitch; // 0-31 pitch value
92 int distorsion; // 0-15 distorsion mode (modifies source & modifier)
97 1.4134615384::samp => dur tbase; // 44100 / 31200 (TIA PAL samplerate based on pixelclock)
98 //1.4026717557::samp => dur tbase; // 44100 / 31440 (TIA NTSC samplerate based on pixelclock)
102 1 => int sourceLength;
103 1 => int modifierLength;
105 0 => int i; // source index (0 -> source length - 1)
106 0 => int j; // modifier index (0 -> modifier length - 1)
111 0 => float lastSampleValue;
117 public void gain( float g ) {
121 public void connect( UGen ugen ){
127 DMData[distorsion][0].size() => sourceLength;
128 DMData[distorsion][1].size() => modifierLength;
130 // switch between cpuclock and pixelclock (pixelclock = 3 * cpuclock)
131 if (DMData[distorsion][2][0] == 3) tbase + tbase + tbase => t;
137 (1.0 / 16) * volume => sampleVolume;
148 public void set(int _p, int _d, int _v) {
152 (1.0 / 16) * volume => sampleVolume;
153 DMData[distorsion][0].size() => sourceLength;
154 DMData[distorsion][1].size() => modifierLength;
156 // switch between cpuclock and pixelclock (pixelclock = 3 * cpuclock)
157 if (DMData[distorsion][2][0] == 3) tbase + tbase + tbase => t;
164 public void play(dur _durmax) {
166 0::samp => dur duree;
168 if (DMData[distorsion][1][j] == 1) {
169 DMData[distorsion][0][i] => sampleValue;
170 sampleValue => lastSampleValue;
171 } else lastSampleValue => sampleValue;
173 sampleValue * sampleVolume => sample;
176 if (timeIndex % (pitch + 1) == 0) i++;
177 i % sourceLength => i;
180 j % modifierLength => j;
184 if (duree > durmax) break;
200 /* ************************************************************** */
221 // open joystick 0, exit on fail
222 if( !hi.openJoystick( device ) ) me.exit();
224 <<< "joystick '" + hi.name() + "' ready", "" >>>;
226 spork~ atarinotejoy();
228 // infinite event loop
230 hi => now; // wait on HidIn as event
233 while( hi.recv( msg ) ) {
234 if( msg.isAxisMotion() ) {
235 //<<< "joystick axis", msg.which, ":", msg.axisPosition >>>;
236 if (msg.which == 0) msg.axisPosition => x;
237 if (msg.which == 1) msg.axisPosition => y;
238 if (msg.which == 2) msg.axisPosition => z;
239 } else if( msg.isButtonDown() ) {
240 // <<< "joystick button", msg.which, "down" >>>;
241 Std.rand2(5, 30)::ms => dur randur;
242 if (Std.rand2(0, 1) > 0.5) spork ~ atariup(msg.which, 8, randur, g);
243 else spork ~ ataridown(msg.which, 8, randur, g);
248 fun void atariup(int _dis, int _vol, dur _d, UGen ugen) {
253 for ( 0 => int i; i < 31; i++ ) {
254 aa.set(i, _dis, _vol);
259 fun void ataridown(int _dis, int _vol, dur _d, UGen ugen) {
264 for ( 31 => int i; i > 0; i-- ) {
265 aa.set(i, _dis, _vol);
270 fun void atarinotejoy() {
272 ((x + 1) * 15) $ int => int xx;
273 ((y + 1) * 7) $ int => int yy;
274 ((z + 1) * 7) $ int => int zz;
275 <<<"pitch " + xx + " disto " + yy + " vol " + zz>>>;
276 ajoy.set(xx, yy, zz);