Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

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