Nes2 APU Chip Sound Simulator
Emulation of the sound generation hardware of the NES APU chip by Matthew Conte.
this ugen has 5 oscillators: 2 squares, 1 triangle, 1 noise, 1 dmc. note that dmc is only partially implemented.
for simplified interfaces to this class see [Nes2Square], [Nes2Triangle], [Nes2Noise], [Nes2DMC]
*ar(trig, a0, a1, a2, a3, b0, b1, b2, b3, c0, c2, c3, d0, d2, d3, e0, e1, e2, e3, smask)
a0/b0 - (the 2 square waves)
7-6 - duty cycle
5 - loop envelope
4 - envelope decay disable
3-0 - volume / envelope decay rate
a1/b1 -
7 - sweep on
6-4 - sweep length
3 - sweep inc/dec
2-0 - sweep shifts
a2/b2 -
7-0 - frequency low bits
a3/b3 -
7-3 - vbl length counter
2-0 - frequency high bits
c0 - (the triangle wave)
7 - linear counter start
6-0 - linear counter
c2 -
7-0 - frequency low bits
c3 -
7-3 length counter
2-0 frequency high bits
d0 - (the noise)
5 - loop envelope
4 - envelope decay disable
3-0 - volume / envelope decay rate
d2 -
7 - short mode
3-0 playback sample rate
d3 -
7-3 length counter
e0 - (the delta modulation channel)
7 - irq generator (not in use)
6 - looping
3-0 - frequency control
e1 -
6-0 - delta count register or output dc level (not in use)
e2 -
7-0 - address load register (not in use)
e3 -
7-0 - length register (not in use)
smask -
4 - dmc channel enabled
3 - noise channel enabled
2 - triangle wave channel enabled
1 - square wave channel 2 enabled
0 - square wave channel 1 enabled
code adapted from v1.2 of Nofrendo, available here http://sourceforge.net/projects/nosefart/
and more detailed info about this chip can be found here...
http://www.slack.net/~ant/nes-emu/apu_ref.txt
http://web.textfiles.com/games/nessound.txt
http://nesdev.parodius.com/dmc.txt
s.boot;
//--rectangle
{Nes2.ar(Impulse.kr(3), a0:2r00010111, a2:2r10000000, smask:2r00000001)}.play
{Nes2.ar(Impulse.kr(3), a0:2r00010111, a2:MouseX.kr(0, 255), smask:2r00000001)}.play
{Nes2.ar(Impulse.kr(3), a0:2r00100000, a2:MouseX.kr(0, 255), smask:2r00000001)}.play
//--2 rectangles
{Nes2.ar(Impulse.kr(3), a0:2r00010111, a2:MouseX.kr(0, 255), b0:2r00010111, b2:MouseY.kr(0, 255), smask:2r00000011)}.play
//--triangle
{Nes2.ar(Impulse.kr(3), c0:2r10000100, c2:MouseX.kr(0, 255), smask:2r00000100)}.play
//--noise
{Nes2.ar(Impulse.kr(3), d0:2r00000100, d2:MouseX.kr(0, 15), smask:2r00001000)}.play
{Nes2.ar(Impulse.kr(3), d0:2r00100111, d2:Line.kr(0, 15, 3), smask:2r00001000)}.play
(
SynthDef(\nes2, {|out= 0, gate= 1, a0= 0, a1= 0, a2= 0, a3= 0, b0= 0, b1= 0, b2= 0, b3= 0, c0= 0, c2= 0, c3= 0, d0= 0, d2= 0, d3= 0, e0= 0, e1= 0, e2= 0, e3= 0, smask= 0, amp= 1, pan= 0|
var e, z;
e= EnvGen.kr(Env.asr(0.01, amp, 0.05), gate, doneAction:2);
z= Nes2.ar(gate, a0, a1, a2, a3, b0, b1, b2, b3, c0, c2, c3, d0, d2, d3, e0, e1, e2, e3, smask);
Out.ar(out, Pan2.ar(z*e, pan));
}).memStore;
)
(
Pbind(
\instrument, \nes2,
\dur, 1,
\amp, 0.8,
\a0, 2r10111100,
\a1, Pseq([2r11111100, 2r11111100, 2r11110100, 2r11110100], inf),
\a2, 2r10010000,
\a3, Pseq([2r11111010, 2r00101011], inf),
\smask, 2r00000001
).play
)
(
Pbind(
\instrument, \nes2,
\dur, 0.12,
\amp, 0.8,
\legato, 1.5,
\a0, Pseq([Pn(0, 12), Pn(2r00000100, 12), Pn(0, 12), Pn(2r11000111, 12)], inf),
\a1, Pseq([Pn(2r00000000, 32), Pn(2r11110100, 12)], inf),
\a2, 2r00000000,
\a3, Pseq([2r00001010, 2r00000011], inf),
\smask, 2r00000001
).play
)
(
Pbind(
\instrument, \nes2,
\dur, 0.125,
\amp, 0.8,
\a0, Pseq([Pn(0, 12), Pn(2r00000100, 12), Pn(0, 12), Pn(2r11000111, 12)], inf),
\a1, Pseq([Pn(2r00000000, 32), Pn(2r11110100, 12)], inf),
\a2, 2r00000000,
\a3, Pseq([2r00001010, 2r00000011], inf),
\b0, 2r11100000,
\b1, Pseq([Pn(2r00000000, 32), Pn(2r11110011, 12)], inf),
\b2, Pseq([Pseries(255, -10, 25)], inf),
\b3, Pseq([2r11111010, 2r11111001], inf),
\smask, 2r00000011
).play
)
(
Pbind(
\instrument, \nes2,
\dur, Pbrown(0.1, 0.15, 0.1),
\amp, 0.8,
\d0, 2r00011000,
\d2, Pseq([2r00001000, 2r00000111, Pseq([2r10000100, 2r10001010], 3)], inf),
\d3, Pseq([2r11000000, 2r11100000, Pseq([2r11010000, 2r11011000], 4)], inf),
\smask, 2r00001000
).play
)
(
Pbind( //not working really but does produce some nice artifacts
\instrument, \nes2,
\dur, Pseq([0.06, 0.04], inf),
\amp, 1,
\e0, Pseq([Pn(2r01000000, 64), Pwhite(0, 12, 15).round(4)+2r01000000], inf),
\e1, 2r00000000,
\e2, 2r00000000,
\e3, 2r00000000,
\smask, 2r00010000
).play
)