instruments2.ino 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include <SPI.h>
  2. #include <GD.h>
  3. #include "instruments.h"
  4. // midi frequency table
  5. static const PROGMEM uint16_t midifreq[128] = {
  6. 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
  7. };
  8. class player {
  9. public:
  10. byte voices, duration;
  11. flash_uint8_t *amps;
  12. byte fv;
  13. player() {
  14. duration = 0;
  15. }
  16. void begin(flash_uint8_t *instr, byte note, byte firstvoice) {
  17. voices = pgm_read_byte(instr++);
  18. duration = pgm_read_byte(instr++);
  19. uint16_t midi = pgm_read_word(midifreq + note);
  20. fv = firstvoice;
  21. for (byte i = 0; i < voices; i++) {
  22. uint16_t w = pgm_read_word(instr);
  23. GD.voice(fv + i, 0, (long(w) * midi) >> 10, 0, 0);
  24. instr += 2;
  25. }
  26. amps = instr;
  27. }
  28. void update() {
  29. for (byte j = 0; j < voices; j++) {
  30. byte v = pgm_read_byte(amps++) >> 2;
  31. GD.wr(VOICES + 4 * (fv + j) + 2, v);
  32. GD.wr(VOICES + 4 * (fv + j) + 3, v);
  33. }
  34. duration--;
  35. }
  36. byte available() {
  37. return duration != 0;
  38. }
  39. };
  40. static struct {
  41. byte t, note;
  42. } pacman[] = {
  43. { 0, 71 },
  44. { 2, 83 },
  45. { 4, 78 },
  46. { 6, 75 },
  47. { 8, 83 },
  48. { 9, 78 },
  49. { 12, 75 },
  50. { 16, 72 },
  51. { 18, 84 },
  52. { 20, 79 },
  53. { 22, 76 },
  54. { 24, 84 },
  55. { 25, 79 },
  56. { 28, 76 },
  57. { 32, 71 },
  58. { 34, 83 },
  59. { 36, 78 },
  60. { 38, 75 },
  61. { 40, 83 },
  62. { 41, 78 },
  63. { 44, 75 },
  64. { 48, 75 },
  65. { 49, 76 },
  66. { 50, 77 },
  67. { 52, 77 },
  68. { 53, 78 },
  69. { 54, 79 },
  70. { 56, 79 },
  71. { 57, 80 },
  72. { 58, 81 },
  73. { 60, 83 }
  74. };
  75. static void pickinstrument(flash_uint8_t* &instdata, byte &pitchdrop, byte n)
  76. {
  77. char* name = "";
  78. switch (n) {
  79. case 0: name = "chimebar"; instdata = chimebar; pitchdrop = 0; break;
  80. case 1: name = "piano"; instdata = piano; pitchdrop = 4; break;
  81. case 2: name = "flute"; instdata = flute; pitchdrop = 0; break;
  82. case 3: name = "harp"; instdata = harp; pitchdrop = 1; break;
  83. case 4: name = "glock"; instdata = glock; pitchdrop = 5; break;
  84. case 5: name = "nylon"; instdata = nylon; pitchdrop = 2; break;
  85. case 6: name = "bass"; instdata = bass; pitchdrop = 4; break;
  86. case 7: name = "clarinet"; instdata = clarinet; pitchdrop = 1; break;
  87. case 8: name = "recorder"; instdata = recorder; pitchdrop = 1; break;
  88. case 9: name = "musicbox"; instdata = musicbox; pitchdrop = 0; break;
  89. case 10: name = "guitar"; instdata = guitar; pitchdrop = 3; break;
  90. case 11: name = "oboe"; instdata = oboe; pitchdrop = 2; break;
  91. case 12: name = "organ"; instdata = organ; pitchdrop = 2; break;
  92. }
  93. GD.fill(64, ' ', 128);
  94. GD.putstr(0, 2, name);
  95. }
  96. #include "showvoices.h"
  97. #include "sphere.h"
  98. void setup()
  99. {
  100. GD.begin();
  101. GD.ascii();
  102. GD.copy(RAM_SPRIMG, sphere_img, sizeof(sphere_img));
  103. GD.copy(RAM_SPRPAL, sphere_pal, sizeof(sphere_pal));
  104. for (byte i = 0; i < 64; i++)
  105. GD.sprite(i, 100, 284 * i / 64, 0, 0);
  106. GD.microcode(showvoices_code, sizeof(showvoices_code));
  107. GD.putstr(0, 0, "Synthesized instruments");
  108. // Serial.begin(1000000); // JCB
  109. }
  110. static int ss; // JCB
  111. void loop()
  112. {
  113. player p[4];
  114. byte nextv = 0;
  115. byte v;
  116. for (byte inst = 0; inst < 13; inst++) {
  117. flash_uint8_t* instdata;
  118. byte pitchdrop;
  119. pickinstrument(instdata, pitchdrop, inst);
  120. byte t = 0;
  121. byte i = 0;
  122. while (i < sizeof(pacman) / sizeof(pacman[0])) {
  123. if (t == pacman[i].t) {
  124. p[nextv].begin(instdata, pacman[i].note - 12 * pitchdrop, 16 * nextv);
  125. nextv = (nextv + 1) & 3;
  126. i++;
  127. }
  128. for (int d = 4; d; d--) {
  129. for (v = 0; v < 4; v++)
  130. if (p[v].available())
  131. p[v].update();
  132. GD.waitvblank();
  133. // GD.screenshot(ss++); // JCB
  134. }
  135. t++;
  136. }
  137. byte anyplaying;
  138. do {
  139. anyplaying = 0;
  140. for (v = 0; v < 4; v++) {
  141. byte playing = p[v].available();
  142. anyplaying |= playing;
  143. if (playing)
  144. p[v].update();
  145. }
  146. GD.waitvblank();
  147. // GD.screenshot(ss++); // JCB
  148. } while (anyplaying);
  149. }
  150. }