MZPokey POKEY Chip Sound Simulator



Emulation of the sound generation hardware of the POKEY chip by Michael Borisov

this version calculates in 16bits, is bandlimited and generally better sounding.  see [Pokey] for another more rough 8bit version.


*ar(audf1, audc1, audf2, audc2, audf3, audc3, audf4, audc4, audctl)

audfX -

7-0 - frequency

audcX -

7 - poly5 or direct clock

6 - poly4 or poly17

5 - poly4/17 or pure tone

4 - volume output only

3-0 - volume

audctl -

7 - switches main clock base from 64KHz to 15KHz

6 - inserts high-pass filter into channel 2, clocked by channel 4

5 - inserts high-pass filter into channel 1, clocked by channel 3

4 - joins channel 4 to channel 3 (16bit resolution)

3 - joins channel 2 to channel 1 (16bit resolution)

2 - clocks channel 3 with 1.79MHz

1 - clocks channel 1 with 1.79MHz

0 - makes the 17bit poly-counter into a 9bit poly-counter


code adapted from the MZPOKEY sound chip emulation, v1.6, from the Atari800 emulator project, available here http://atari800.sourceforge.net/

more info on how to program this chip can be found here http://www.atariarchives.org/dere/chapt07.php and here http://www.retroclinic.com/leopardcats/bbpokey/pokey.pdf



s.boot;


{MZPokey.ar(Line.kr(0, 255, 5), 2r00001111)}.play

{MZPokey.ar(Line.kr(0, 255, 5), 2r00101111)}.play //one bit differs in the voice control register

{MZPokey.ar(Line.kr(0, 255, 5), 2r10101111)}.play //one bit differs in the voice control register

{MZPokey.ar(Line.kr(0, 255, 5), 2r10101111, audctl: 2r00000001)}.play //another clock

{MZPokey.ar(Line.kr(0, 255, 5), 2r10101111, audctl: 2r01000001)}.play //with highpass filter


//--two voices

{MZPokey.ar(MouseX.kr(0, 255), 2r10101010, MouseY.kr(0, 255), 2r10101010, audctl: 2r00000001)}.play


//--all four voices

({MZPokey.ar(

MouseX.kr(0, 255), 2r11000111,

MouseY.kr(0, 255), 2r11100111,

SinOsc.kr(0.4, 0, 127.5, 127.5), 2r11000111,

SinOsc.kr(0.5, 0, 127.5, 127.5), 2r01000111,

2r00000000 //general ctl

).dup}.play)




(

SynthDef(\mzpokey, {|out= 0, gate= 1, f1= 0, c1= 0, f2= 0, c2= 0, f3= 0, c3= 0, f4= 0, c4= 0, ctl= 0, amp= 1, pan= 0|

var e, z;

e= EnvGen.kr(Env.asr(0.01, amp, 0.05), gate, doneAction:2);

z= MZPokey.ar(f1, c1, f2, c2, f3, c3, f4, c4, ctl);

Out.ar(out, Pan2.ar(z*e, pan));

}).add;

)


(

Pbind(

\instrument, \mzpokey,

\dur, Pseq([Pn(0.1, 10), Pn(0.05, 12)], inf),

\amp, 0.8,

\ctl, 2r10000000,

\f1, Pseq([Pseries(0, 10, 20), Pgeom(200, 0.94, 20)], inf),

\c1, 2r10101111

).play

)


(

Pbind(

\instrument, \mzpokey,

\dur, Pseq([0.1, 0.08], inf),

\amp, 0.8,

\ctl, Pseq([Pn(2r10000000, 48), Pn(2r01010001, 24)], inf),

\f1, Pbrown(30, 40, 8)+Pseq([0, 22], inf),

\c1, Pseq([2r10101100, 2r11000100, 2r00000000, 2r11100111], inf)

).play

)


(

Pbind(

\instrument, \mzpokey,

\dur, 0.125,

\amp, 0.8,

\ctl, Pseq([2r10000001, 2r01000001, 2r00100000], inf),

\f1, Pseq([Pn(88, 8), Pseq([120, 130, 140, 50], 4)], inf)+Pseq([Pn(0, 72), Pn(-10, 36)], inf),

\c1, 2r10101111,

\f2, Pseq([0, 255, 255, 0, 25, 255, 0, 25, Pn(13, 11)], inf),

\c2, Pseq([2r10101111, 2r00100111], inf)

).play

)


(

Pbind(

\instrument, \mzpokey,

\dur, 0.1,

\amp, 0.8,

\ctl, Pseq([2r00000110, (2r00000110).setBit(0), (2r00000110).setBit(3)], inf),

\f1, Pseq([30, 80, 70, 30, 80, 70, 30], inf),

\c1, Pseq([2r11101111], inf),

\f2, Pseq([8, 9, 10, 8], inf)*Pseq([Pn(1, 64), Pn(3, 32)], inf),

\c2, 2r11101111,

\f3, Pseq([Pn(255, 10), Pn(55, 6)], inf),

\c3, Pseq([Pn(2r10101111, 7), 0], inf)

).play

)


(

Pbind(

\instrument, \mzpokey,

\dur, 0.1,

\amp, 0.8,

\legato, 1.25,

\ctl, 2r10000000,

\f1, Pseq([5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 140, 6, 5, 6], inf),

\c1, Pseq([2r10000000], inf)|Pseq([15, 15, 0, 0, 15, 0, 15, 0, 8, 8, 0, 0, 8, 0, 0, 15+64], inf),

\f2, Pseq([Pn(0, 32), Pn(255, 64), Pseq([0, 255, 255, 0, 25, 255, 0, 25, Pseries(8, -1, 8)], inf)]),

\c2, Pseq([Pseq([2r10101111, 2r10101000], inf)], inf),

\f3, Pseq([Pn(32, 15), Prand([33, 35])], inf),

\c3, Pseq([Pn(0, 64), Pn(2r01101000, 32), Pn(2r11101100, 32)], inf),

\f4, Pseq([0, 0, 100, 155], inf),

\c4, Pseq([Pn(0, 128), Pseq([Pn(2r11001100, 7), 0], 128)], inf)

).play

)


(

Ptpar([

0, Pbind(\instrument, \mzpokey, \dur, 0.16, \amp, 0.2, \f1, 100, \c1, 2r01101111),

0.16*16, Pbind(\instrument, \mzpokey, \dur, 0.181, \amp, 0.2, \f2, 10, \c2, 2r10101111),

0.16*48, Pbind(\instrument, \mzpokey, \dur, 1.1, \amp, 0.2, \legato, 4, \f2, 20, \c2, 2r11101111),

0.16*112, Pbind(\instrument, \mzpokey, \dur, 0.322, \amp, 0.2, \legato, 1.8, \f2, 200, \c2, 2r11101111),

0.16*200, Pbind(\instrument, \mzpokey, \dur, 2, \amp, 0.2, \legato, 1.8, \f2, 10, \c2, 2r11101111)

]).play

)