123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- #include <SPI.h>
- #include <GD.h>
- #include "instruments.h"
- // midi frequency table
- static PROGMEM prog_uint16_t midifreq[128] = {
- 32,34,36,38,41,43,46,48,51,55,58,61,65,69,73,77,82,87,92,97,103,110,116,123,130,138,146,155,164,174,184,195,207,220,233,246,261,277,293,311,329,349,369,391,415,440,466,493,523,554,587,622,659,698,739,783,830,880,932,987,1046,1108,1174,1244,1318,1396,1479,1567,1661,1760,1864,1975,2093,2217,2349,2489,2637,2793,2959,3135,3322,3520,3729,3951,4186,4434,4698,4978,5274,5587,5919,6271,6644,7040,7458,7902,8372,8869,9397,9956,10548,11175,11839,12543,13289,14080,14917,15804,16744,17739,18794,19912,21096,22350,23679,25087,26579,28160,29834,31608,33488,35479,37589,39824,42192,44701,47359,50175
- };
- class player {
- public:
- byte voices, duration;
- prog_uchar *amps;
- byte fv;
- player() {
- duration = 0;
- }
- void begin(PROGMEM prog_uchar *instr, byte note, byte firstvoice) {
- voices = pgm_read_byte(instr++);
- duration = pgm_read_byte(instr++);
- uint16_t midi = pgm_read_word(midifreq + note);
- fv = firstvoice;
- for (byte i = 0; i < voices; i++) {
- uint16_t w = pgm_read_word(instr);
- GD.voice(fv + i, 0, (long(w) * midi) >> 10, 0, 0);
- instr += 2;
- }
- amps = instr;
- }
- void update() {
- for (byte j = 0; j < voices; j++) {
- byte v = pgm_read_byte(amps++) >> 2;
- GD.wr(VOICES + 4 * (fv + j) + 2, v);
- GD.wr(VOICES + 4 * (fv + j) + 3, v);
- }
- duration--;
- }
- byte available() {
- return duration != 0;
- }
- };
- static struct {
- byte t, note;
- } pacman[] = {
- { 0, 71 },
- { 2, 83 },
- { 4, 78 },
- { 6, 75 },
- { 8, 83 },
- { 9, 78 },
- { 12, 75 },
- { 16, 72 },
- { 18, 84 },
- { 20, 79 },
- { 22, 76 },
- { 24, 84 },
- { 25, 79 },
- { 28, 76 },
- { 32, 71 },
- { 34, 83 },
- { 36, 78 },
- { 38, 75 },
- { 40, 83 },
- { 41, 78 },
- { 44, 75 },
- { 48, 75 },
- { 49, 76 },
- { 50, 77 },
- { 52, 77 },
- { 53, 78 },
- { 54, 79 },
- { 56, 79 },
- { 57, 80 },
- { 58, 81 },
- { 60, 83 }
- };
- static void pickinstrument(prog_uchar* &instdata, byte &pitchdrop, byte n)
- {
- char* name = "";
- switch (n) {
- case 0: name = "chimebar"; instdata = chimebar; pitchdrop = 0; break;
- case 1: name = "piano"; instdata = piano; pitchdrop = 4; break;
- case 2: name = "flute"; instdata = flute; pitchdrop = 0; break;
- case 3: name = "harp"; instdata = harp; pitchdrop = 1; break;
- case 4: name = "glock"; instdata = glock; pitchdrop = 5; break;
- case 5: name = "nylon"; instdata = nylon; pitchdrop = 2; break;
- case 6: name = "bass"; instdata = bass; pitchdrop = 4; break;
- case 7: name = "clarinet"; instdata = clarinet; pitchdrop = 1; break;
- case 8: name = "recorder"; instdata = recorder; pitchdrop = 1; break;
- case 9: name = "musicbox"; instdata = musicbox; pitchdrop = 0; break;
- case 10: name = "guitar"; instdata = guitar; pitchdrop = 3; break;
- case 11: name = "oboe"; instdata = oboe; pitchdrop = 2; break;
- case 12: name = "organ"; instdata = organ; pitchdrop = 2; break;
- }
- GD.fill(64, ' ', 128);
- GD.putstr(0, 2, name);
- }
- #include "showvoices.h"
- #include "sphere.h"
- void setup()
- {
- GD.begin();
- GD.ascii();
- GD.copy(RAM_SPRIMG, sphere_img, sizeof(sphere_img));
- GD.copy(RAM_SPRPAL, sphere_pal, sizeof(sphere_pal));
- for (byte i = 0; i < 64; i++)
- GD.sprite(i, 100, 284 * i / 64, 0, 0);
- GD.microcode(showvoices_code, sizeof(showvoices_code));
- GD.putstr(0, 0, "Synthesized instruments");
- // Serial.begin(1000000); // JCB
- }
- static int ss; // JCB
- void loop()
- {
- player p[4];
- byte nextv = 0;
- byte v;
- for (byte inst = 0; inst < 13; inst++) {
- prog_uchar* instdata;
- byte pitchdrop;
- pickinstrument(instdata, pitchdrop, inst);
- byte t = 0;
- byte i = 0;
- while (i < sizeof(pacman) / sizeof(pacman[0])) {
- if (t == pacman[i].t) {
- p[nextv].begin(instdata, pacman[i].note - 12 * pitchdrop, 16 * nextv);
- nextv = (nextv + 1) & 3;
- i++;
- }
- for (int d = 4; d; d--) {
- for (v = 0; v < 4; v++)
- if (p[v].available())
- p[v].update();
- GD.waitvblank();
- // GD.screenshot(ss++); // JCB
- }
- t++;
- }
- byte anyplaying;
- do {
- anyplaying = 0;
- for (v = 0; v < 4; v++) {
- byte playing = p[v].available();
- anyplaying |= playing;
- if (playing)
- p[v].update();
- }
- GD.waitvblank();
- // GD.screenshot(ss++); // JCB
- } while (anyplaying);
- }
- }
|