toccata.ino 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <SPI.h>
  2. #include <GD.h>
  3. struct voice
  4. {
  5. float f;
  6. float a;
  7. } voices[16];
  8. void load()
  9. {
  10. byte v;
  11. unsigned int gg = 0;
  12. float sum = 0.0;
  13. for (v = 0; v < 16; v++) {
  14. sum += voices[v].a;
  15. }
  16. float scale = 255.0 / sum;
  17. for (v = 0; v < 16; v++) {
  18. byte a = int(voices[v].a * scale);
  19. GD.voice(v, 0, int(4 * voices[v].f), a, a);
  20. }
  21. }
  22. struct sprite
  23. {
  24. int x;
  25. int y;
  26. } sprites[64];
  27. static int sprnum;
  28. void note(byte voice, byte m, byte vel)
  29. {
  30. if (voice == 0 && vel) {
  31. sprites[sprnum].x = 384;
  32. sprites[sprnum].y = 284 - 8 * m;
  33. sprnum = (sprnum + 1) & 63;
  34. }
  35. float f0 = 440 * pow(2.0, (m - 69) / 12.0);
  36. float a0 = vel / 120.;
  37. if (voice == 0) {
  38. float choirA[] = { 3.5, 1.6, .7, 3.7, 1, 2 };
  39. byte v;
  40. for (v = 0; v < 6; v++) {
  41. voices[v].f = (v + 1) * f0;
  42. voices[v].a = a0 * choirA[v] / 3.7;
  43. }
  44. } else {
  45. voices[voice].f = f0;
  46. voices[voice].a = a0;
  47. }
  48. }
  49. static void pause(int n)
  50. {
  51. load();
  52. long started = millis();
  53. while (millis() < (started + n * 3 / 2)) {
  54. GD.waitvblank();
  55. byte i;
  56. for (i = 0; i < 64; i++) {
  57. if (sprites[i].x > -16) {
  58. GD.sprite(i, sprites[i].x, sprites[i].y, 0, 0, 0);
  59. sprites[i].x--;
  60. } else {
  61. GD.sprite(i, 400, 400, 0, 0, 0);
  62. }
  63. }
  64. }
  65. }
  66. #include "music.h"
  67. static void play()
  68. {
  69. prog_uchar *pc = widor_toccata;
  70. while (pc < (widor_toccata + sizeof(widor_toccata))) {
  71. byte a = pgm_read_byte_near(pc++);
  72. byte b = pgm_read_byte_near(pc++);
  73. if (a == 255) {
  74. pause(b);
  75. } else {
  76. byte c = pgm_read_byte_near(pc++);
  77. note(a, b, c);
  78. }
  79. }
  80. }
  81. void setup()
  82. {
  83. int i;
  84. GD.begin();
  85. GD.ascii();
  86. GD.wr16(RAM_SPRPAL + (0 * 2), 0x8000);
  87. GD.wr16(RAM_SPRPAL + (1 * 2), RGB(255, 255, 255));
  88. GD.fill(RAM_SPRIMG, 0, 256);
  89. GD.wr(RAM_SPRIMG + 0x78, 1);
  90. GD.wr(RAM_SPRIMG + 0x98, 1);
  91. GD.wr(RAM_SPRIMG + 0x87, 1);
  92. GD.wr(RAM_SPRIMG + 0x89, 1);
  93. GD.wr(RAM_SPRIMG + 0x88, 1);
  94. GD.putstr(0, 0,"Widor's Toccata");
  95. }
  96. void loop()
  97. {
  98. play();
  99. delay(2000);
  100. int i;
  101. for (i = 0; i < 256; i++)
  102. GD.sprite(i, 400, 400, 0, 0, 0);
  103. }