| 39 | 39 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,100 @@ |
| 1 |
+( dev/audio ) |
|
| 2 |
+ |
|
| 3 |
+%MOD { DUP2 DIV MUL SUB }
|
|
| 4 |
+ |
|
| 5 |
+( |
|
| 6 |
+ position in track, |
|
| 7 |
+ frame: counter for current frame, |
|
| 8 |
+ only playing every few frames |
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+@timer $1 |
|
| 12 |
+@song [ ¬e $1 ] |
|
| 13 |
+ |
|
| 14 |
+( devices ) |
|
| 15 |
+ |
|
| 16 |
+|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ] |
|
| 17 |
+|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ] |
|
| 18 |
+|30 @Audio [ &wave $2 &env $2 &pad $4 &vol $1 &pitch $1 &play $1 &value $2 &delay $2 &finish $1 ] |
|
| 19 |
+ |
|
| 20 |
+|0100 ( -> ) |
|
| 21 |
+ |
|
| 22 |
+ ( set color pallete ) |
|
| 23 |
+ #0fff DUP2 DUP2 |
|
| 24 |
+ .System/r DEO2 |
|
| 25 |
+ .System/g DEO2 |
|
| 26 |
+ .System/b DEO2 |
|
| 27 |
+ |
|
| 28 |
+ ;on-frame .Screen/vector DEO2 ( run on-frame every 1/60th of a second ) |
|
| 29 |
+ #ff .Audio/vol DEO ( set volume to max ) |
|
| 30 |
+ ;saw .Audio/wave DEO2 ( set waveform to saw for audio engine ) |
|
| 31 |
+ ;env .Audio/env DEO2 ( set envelope for audio engine ) |
|
| 32 |
+ |
|
| 33 |
+BRK |
|
| 34 |
+ |
|
| 35 |
+@on-frame ( -> ) |
|
| 36 |
+ |
|
| 37 |
+ ( incr ) .timer PEK #01 ADD .timer POK |
|
| 38 |
+ ( skip ) .timer PEK #10 NEQ ;silence JNZ2 |
|
| 39 |
+ |
|
| 40 |
+ ( get note ) |
|
| 41 |
+ ;melody #00 .song/note PEK ADD2 GET ( -- note ) |
|
| 42 |
+ |
|
| 43 |
+ ( play note ) |
|
| 44 |
+ DUP #80 ORA .Audio/pitch DEO ( -- note ) ( OR note with #80 and set the audio pitch to it. ) |
|
| 45 |
+ #01 .Audio/play DEO ( play the note ) |
|
| 46 |
+ |
|
| 47 |
+ ( erase last note ) |
|
| 48 |
+ #20 .Screen/color DEO ( draw a dot ) |
|
| 49 |
+ |
|
| 50 |
+ ( draw note ) |
|
| 51 |
+ #00 SWP #0004 MUL2 #0100 SUB2 .Screen/y DEO2 ( calculate the y position of a dot. TODO make this not upside down ) |
|
| 52 |
+ #00 .song/note PEK #0008 MUL2 .Screen/x DEO2 ( calculate the x position of a dot ) |
|
| 53 |
+ ;dot .Screen/addr DEO2 ( set the sprite for a dot ) |
|
| 54 |
+ #21 .Screen/color DEO ( draw a dot ) |
|
| 55 |
+ |
|
| 56 |
+ ( incr ) .song/note PEK #01 ADD #20 MOD .song/note POK |
|
| 57 |
+ |
|
| 58 |
+ #00 .timer POK |
|
| 59 |
+ |
|
| 60 |
+BRK |
|
| 61 |
+ |
|
| 62 |
+@silence ( -> ) |
|
| 63 |
+ |
|
| 64 |
+BRK |
|
| 65 |
+ |
|
| 66 |
+( defines a sawtooth wave. ) |
|
| 67 |
+ |
|
| 68 |
+@saw ( -> ) |
|
| 69 |
+ |
|
| 70 |
+ #6000 .Audio/value DEO2 |
|
| 71 |
+ #0000 .Audio/delay DEO2 ( move to volume #600 after 0 delay ) |
|
| 72 |
+ #0000 .Audio/value DEO2 |
|
| 73 |
+ #ffff .Audio/delay DEO2 ( reach volume 0 after the whole note. Interpolated linearly ) |
|
| 74 |
+ |
|
| 75 |
+BRK |
|
| 76 |
+ |
|
| 77 |
+( defines an envelope ) |
|
| 78 |
+ |
|
| 79 |
+@env ( -> ) |
|
| 80 |
+ |
|
| 81 |
+ #ffff .Audio/value DEO2 |
|
| 82 |
+ #1000 .Audio/delay DEO2 ( move pretty quickly to volume #ffff (maximum) ) |
|
| 83 |
+ #0000 .Audio/value DEO2 |
|
| 84 |
+ #4000 .Audio/delay DEO2 ( interpolating linearly, move to #0000 after a delay of #4000 where #8000 is half a second ) |
|
| 85 |
+ #00 .Audio/finish DEO ( end the envelope ) |
|
| 86 |
+ |
|
| 87 |
+BRK |
|
| 88 |
+ |
|
| 89 |
+( song data. note ff is used for a rest. ) |
|
| 90 |
+ |
|
| 91 |
+@melody [ |
|
| 92 |
+ 54 52 54 4f 4b 4f 48 ff |
|
| 93 |
+ 54 52 54 4f 4b 4f 48 ff |
|
| 94 |
+ 54 56 57 56 57 54 56 54 |
|
| 95 |
+ 56 52 54 52 54 50 54 ff |
|
| 96 |
+] |
|
| 97 |
+ |
|
| 98 |
+( dot sprite for on-screen ) |
|
| 99 |
+ |
|
| 100 |
+@dot [ 003c 7eff 7e3c 0000 ] |