You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 line
7.0KB

  1. // Implement a 16 note polyphonic midi player :-)
  2. //
  3. // Music data is read from memory. The "Miditones" program is used to
  4. // convert from a MIDI file to this compact format.
  5. //
  6. // This example code is in the public domain.
  7. #include <Audio.h>
  8. #include <Wire.h>
  9. #include <SD.h>
  10. #include <SPI.h>
  11. #include <SerialFlash.h>
  12. #include "PlaySynthMusic.h"
  13. unsigned char *sp = score;
  14. #define AMPLITUDE (0.2)
  15. // Create 16 waveforms, one for each MIDI channel
  16. AudioSynthWaveform sine0, sine1, sine2, sine3;
  17. AudioSynthWaveform sine4, sine5, sine6, sine7;
  18. AudioSynthWaveform sine8, sine9, sine10, sine11;
  19. AudioSynthWaveform sine12, sine13, sine14, sine15;
  20. AudioSynthWaveform *waves[16] = {
  21. &sine0, &sine1, &sine2, &sine3,
  22. &sine4, &sine5, &sine6, &sine7,
  23. &sine8, &sine9, &sine10, &sine11,
  24. &sine12, &sine13, &sine14, &sine15
  25. };
  26. // allocate a wave type to each channel.
  27. // The types used and their order is purely arbitrary.
  28. short wave_type[16] = {
  29. WAVEFORM_SINE,
  30. WAVEFORM_SQUARE,
  31. WAVEFORM_SAWTOOTH,
  32. WAVEFORM_TRIANGLE,
  33. WAVEFORM_SINE,
  34. WAVEFORM_SQUARE,
  35. WAVEFORM_SAWTOOTH,
  36. WAVEFORM_TRIANGLE,
  37. WAVEFORM_SINE,
  38. WAVEFORM_SQUARE,
  39. WAVEFORM_SAWTOOTH,
  40. WAVEFORM_TRIANGLE,
  41. WAVEFORM_SINE,
  42. WAVEFORM_SQUARE,
  43. WAVEFORM_SAWTOOTH,
  44. WAVEFORM_TRIANGLE
  45. };
  46. // Each waveform will be shaped by an envelope
  47. AudioEffectEnvelope env0, env1, env2, env3;
  48. AudioEffectEnvelope env4, env5, env6, env7;
  49. AudioEffectEnvelope env8, env9, env10, env11;
  50. AudioEffectEnvelope env12, env13, env14, env15;
  51. AudioEffectEnvelope *envs[16] = {
  52. &env0, &env1, &env2, &env3,
  53. &env4, &env5, &env6, &env7,
  54. &env8, &env9, &env10, &env11,
  55. &env12, &env13, &env14, &env15
  56. };
  57. // Route each waveform through its own envelope effect
  58. AudioConnection patchCord01(sine0, env0);
  59. AudioConnection patchCord02(sine1, env1);
  60. AudioConnection patchCord03(sine2, env2);
  61. AudioConnection patchCord04(sine3, env3);
  62. AudioConnection patchCord05(sine4, env4);
  63. AudioConnection patchCord06(sine5, env5);
  64. AudioConnection patchCord07(sine6, env6);
  65. AudioConnection patchCord08(sine7, env7);
  66. AudioConnection patchCord09(sine8, env8);
  67. AudioConnection patchCord10(sine9, env9);
  68. AudioConnection patchCord11(sine10, env10);
  69. AudioConnection patchCord12(sine11, env11);
  70. AudioConnection patchCord13(sine12, env12);
  71. AudioConnection patchCord14(sine13, env13);
  72. AudioConnection patchCord15(sine14, env14);
  73. AudioConnection patchCord16(sine15, env15);
  74. // Four mixers are needed to handle 16 channels of music
  75. AudioMixer4 mixer1;
  76. AudioMixer4 mixer2;
  77. AudioMixer4 mixer3;
  78. AudioMixer4 mixer4;
  79. // Mix the 16 channels down to 4 audio streams
  80. AudioConnection patchCord17(env0, 0, mixer1, 0);
  81. AudioConnection patchCord18(env1, 0, mixer1, 1);
  82. AudioConnection patchCord19(env2, 0, mixer1, 2);
  83. AudioConnection patchCord20(env3, 0, mixer1, 3);
  84. AudioConnection patchCord21(env4, 0, mixer2, 0);
  85. AudioConnection patchCord22(env5, 0, mixer2, 1);
  86. AudioConnection patchCord23(env6, 0, mixer2, 2);
  87. AudioConnection patchCord24(env7, 0, mixer2, 3);
  88. AudioConnection patchCord25(env8, 0, mixer3, 0);
  89. AudioConnection patchCord26(env9, 0, mixer3, 1);
  90. AudioConnection patchCord27(env10, 0, mixer3, 2);
  91. AudioConnection patchCord28(env11, 0, mixer3, 3);
  92. AudioConnection patchCord29(env12, 0, mixer4, 0);
  93. AudioConnection patchCord30(env13, 0, mixer4, 1);
  94. AudioConnection patchCord31(env14, 0, mixer4, 2);
  95. AudioConnection patchCord32(env15, 0, mixer4, 3);
  96. // Now create 2 mixers for the main output
  97. AudioMixer4 mixerLeft;
  98. AudioMixer4 mixerRight;
  99. AudioOutputI2S audioOut;
  100. // Mix all channels to both the outputs
  101. AudioConnection patchCord33(mixer1, 0, mixerLeft, 0);
  102. AudioConnection patchCord34(mixer2, 0, mixerLeft, 1);
  103. AudioConnection patchCord35(mixer3, 0, mixerLeft, 2);
  104. AudioConnection patchCord36(mixer4, 0, mixerLeft, 3);
  105. AudioConnection patchCord37(mixer1, 0, mixerRight, 0);
  106. AudioConnection patchCord38(mixer2, 0, mixerRight, 1);
  107. AudioConnection patchCord39(mixer3, 0, mixerRight, 2);
  108. AudioConnection patchCord40(mixer4, 0, mixerRight, 3);
  109. AudioConnection patchCord41(mixerLeft, 0, audioOut, 0);
  110. AudioConnection patchCord42(mixerRight, 0, audioOut, 1);
  111. AudioControlSGTL5000 codec;
  112. // Initial value of the volume control
  113. int volume = 50;
  114. void setup()
  115. {
  116. Serial.begin(115200);
  117. //while (!Serial) ; // wait for Arduino Serial Monitor
  118. delay(200);
  119. // http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
  120. Serial.print("Begin ");
  121. Serial.println(__FILE__);
  122. // Proc = 12 (13), Mem = 2 (8)
  123. // Audio connections require memory to work.
  124. // The memory usage code indicates that 10 is the maximum
  125. // so give it 12 just to be sure.
  126. AudioMemory(18);
  127. codec.enable();
  128. codec.volume(0.45);
  129. // reduce the gain on some channels, so half of the channels
  130. // are "positioned" to the left, half to the right, but all
  131. // are heard at least partially on both ears
  132. mixerLeft.gain(1, 0.36);
  133. mixerLeft.gain(3, 0.36);
  134. mixerRight.gain(0, 0.36);
  135. mixerRight.gain(2, 0.36);
  136. // set envelope parameters, for pleasing sound :-)
  137. for (int i=0; i<16; i++) {
  138. envs[i]->attack(9.2);
  139. envs[i]->hold(2.1);
  140. envs[i]->decay(31.4);
  141. envs[i]->sustain(0.6);
  142. envs[i]->release(84.5);
  143. // uncomment these to hear without envelope effects
  144. //envs[i]->attack(0.0);
  145. //envs[i]->hold(0.0);
  146. //envs[i]->decay(0.0);
  147. //envs[i]->release(0.0);
  148. }
  149. Serial.println("setup done");
  150. // Initialize processor and memory measurements
  151. AudioProcessorUsageMaxReset();
  152. AudioMemoryUsageMaxReset();
  153. }
  154. unsigned long last_time = millis();
  155. void loop()
  156. {
  157. unsigned char c,opcode,chan;
  158. unsigned long d_time;
  159. // Change this to if(1) for measurement output every 5 seconds
  160. if(1) {
  161. if(millis() - last_time >= 5000) {
  162. Serial.print("Proc = ");
  163. Serial.print(AudioProcessorUsage());
  164. Serial.print(" (");
  165. Serial.print(AudioProcessorUsageMax());
  166. Serial.print("), Mem = ");
  167. Serial.print(AudioMemoryUsage());
  168. Serial.print(" (");
  169. Serial.print(AudioMemoryUsageMax());
  170. Serial.println(")");
  171. last_time = millis();
  172. }
  173. }
  174. // Volume control
  175. // uncomment if you have a volume pot soldered to your audio shield
  176. /*
  177. int n = analogRead(15);
  178. if (n != volume) {
  179. volume = n;
  180. codec.volume((float)n / 1023);
  181. }
  182. */
  183. // read the next note from the table
  184. c = *sp++;
  185. opcode = c & 0xF0;
  186. chan = c & 0x0F;
  187. if(c < 0x80) {
  188. // Delay
  189. d_time = (c << 8) | *sp++;
  190. delay(d_time);
  191. return;
  192. }
  193. if(*sp == CMD_STOP) {
  194. for (chan=0; chan<10; chan++) {
  195. envs[chan]->noteOff();
  196. waves[chan]->amplitude(0);
  197. }
  198. Serial.println("DONE");
  199. while(1);
  200. }
  201. // It is a command
  202. // Stop the note on 'chan'
  203. if(opcode == CMD_STOPNOTE) {
  204. envs[chan]->noteOff();
  205. return;
  206. }
  207. // Play the note on 'chan'
  208. if(opcode == CMD_PLAYNOTE) {
  209. unsigned char note = *sp++;
  210. unsigned char velocity = *sp++;
  211. AudioNoInterrupts();
  212. waves[chan]->begin(AMPLITUDE * velocity2amplitude[velocity-1],
  213. tune_frequencies2_PGM[note],
  214. wave_type[chan]);
  215. envs[chan]->noteOn();
  216. AudioInterrupts();
  217. return;
  218. }
  219. // replay the tune
  220. if(opcode == CMD_RESTART) {
  221. sp = score;
  222. return;
  223. }
  224. }