123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- #include <SPI.h>
- #include <GD.h>
- struct voice
- {
- float f;
- float a;
- } voices[16];
- void load()
- {
- byte v;
- unsigned int gg = 0;
- float sum = 0.0;
- for (v = 0; v < 16; v++) {
- sum += voices[v].a;
- }
- float scale = 255.0 / sum;
- for (v = 0; v < 16; v++) {
- byte a = int(voices[v].a * scale);
- GD.voice(v, 0, int(4 * voices[v].f), a, a);
- }
- }
- struct sprite
- {
- int x;
- int y;
- } sprites[64];
- static int sprnum;
- void note(byte voice, byte m, byte vel)
- {
- if (voice == 0 && vel) {
- sprites[sprnum].x = 384;
- sprites[sprnum].y = 284 - 8 * m;
- sprnum = (sprnum + 1) & 63;
- }
- float f0 = 440 * pow(2.0, (m - 69) / 12.0);
- float a0 = vel / 120.;
- if (voice == 0) {
- float choirA[] = { 3.5, 1.6, .7, 3.7, 1, 2 };
- byte v;
- for (v = 0; v < 6; v++) {
- voices[v].f = (v + 1) * f0;
- voices[v].a = a0 * choirA[v] / 3.7;
- }
- } else {
- voices[voice].f = f0;
- voices[voice].a = a0;
- }
- }
- static void pause(int n)
- {
- load();
- long started = millis();
- while (millis() < (started + n * 3 / 2)) {
- GD.waitvblank();
- byte i;
- for (i = 0; i < 64; i++) {
- if (sprites[i].x > -16) {
- GD.sprite(i, sprites[i].x, sprites[i].y, 0, 0, 0);
- sprites[i].x--;
- } else {
- GD.sprite(i, 400, 400, 0, 0, 0);
- }
- }
- }
- }
- #include "music.h"
- static void play()
- {
- prog_uchar *pc = widor_toccata;
- while (pc < (widor_toccata + sizeof(widor_toccata))) {
- byte a = pgm_read_byte_near(pc++);
- byte b = pgm_read_byte_near(pc++);
- if (a == 255) {
- pause(b);
- } else {
- byte c = pgm_read_byte_near(pc++);
- note(a, b, c);
- }
- }
- }
- void setup()
- {
- int i;
- GD.begin();
-
- GD.ascii();
- GD.wr16(RAM_SPRPAL + (0 * 2), 0x8000);
- GD.wr16(RAM_SPRPAL + (1 * 2), RGB(255, 255, 255));
- GD.fill(RAM_SPRIMG, 0, 256);
- GD.wr(RAM_SPRIMG + 0x78, 1);
- GD.wr(RAM_SPRIMG + 0x98, 1);
- GD.wr(RAM_SPRIMG + 0x87, 1);
- GD.wr(RAM_SPRIMG + 0x89, 1);
- GD.wr(RAM_SPRIMG + 0x88, 1);
- GD.putstr(0, 0,"Widor's Toccata");
- }
- void loop()
- {
- play();
- delay(2000);
- int i;
- for (i = 0; i < 256; i++)
- GD.sprite(i, 400, 400, 0, 0, 0);
- }
|