Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

188 lines
4.2KB

  1. // Implement the midi player inside the Audio library.
  2. // This uses the new version of the waveform generator code
  3. // See PlayMidiTones for code which uses the old version
  4. #include <Audio.h>
  5. #include <Wire.h>
  6. //#include <WM8731.h>
  7. #include <SD.h>
  8. #include <SPI.h>
  9. #include "arm_math.h"
  10. #include "PlaySynthMusic.h"
  11. unsigned char *sp = score;
  12. #define AMPLITUDE (0.4)
  13. // The midi file has more than 8 channels
  14. // Those above 7 will be mapped to 0, 1 etc.
  15. AudioSynthWaveform sine0;
  16. AudioSynthWaveform sine1;
  17. AudioSynthWaveform sine2;
  18. AudioSynthWaveform sine3;
  19. AudioSynthWaveform sine4;
  20. AudioSynthWaveform sine5;
  21. AudioSynthWaveform sine6;
  22. AudioSynthWaveform sine7;
  23. AudioSynthWaveform *waves[8] = {
  24. &sine0,
  25. &sine1,
  26. &sine2,
  27. &sine3,
  28. &sine4,
  29. &sine5,
  30. &sine6,
  31. &sine7,
  32. };
  33. // allocate a wave type to each channel.
  34. // The types used and their order is purely arbitrary.
  35. short wave_type[8] = {
  36. TONE_TYPE_SINE,
  37. TONE_TYPE_SQUARE,
  38. TONE_TYPE_SAWTOOTH,
  39. TONE_TYPE_TRIANGLE,
  40. TONE_TYPE_SINE,
  41. TONE_TYPE_SQUARE,
  42. TONE_TYPE_SAWTOOTH,
  43. TONE_TYPE_TRIANGLE,
  44. };
  45. // Two mixers are needed to handle the 8 channels of music
  46. AudioMixer4 mixer1;
  47. AudioMixer4 mixer2;
  48. AudioOutputI2S audioOut;
  49. // Mix the first four channels into mixer1
  50. AudioConnection c0(sine0, 0, mixer1, 0);
  51. AudioConnection c1(sine1, 0, mixer1, 1);
  52. AudioConnection c2(sine2, 0, mixer1, 2);
  53. AudioConnection c3(sine3, 0, mixer1, 3);
  54. // and the last 4 channels into mixer2
  55. AudioConnection c4(sine4, 0, mixer2, 0);
  56. AudioConnection c5(sine5, 0, mixer2, 1);
  57. AudioConnection c6(sine6, 0, mixer2, 2);
  58. AudioConnection c7(sine7, 0, mixer2, 3);
  59. // Output mixre1 to the left channel and mixer2 to the right
  60. AudioConnection c11(mixer1, 0, audioOut, 0);
  61. AudioConnection c12(mixer2, 0, audioOut, 1);
  62. //AudioControl_WM8731 codec;
  63. AudioControlSGTL5000 codec;
  64. // Initial value of the volume control
  65. int volume = 50;
  66. void setup()
  67. {
  68. Serial.begin(115200);
  69. while (!Serial) ;
  70. delay(2000);
  71. // http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
  72. Serial.print("Begin ");
  73. Serial.println(__FILE__);
  74. // Proc = 12 (13), Mem = 2 (8)
  75. // Audio connections require memory to work.
  76. // The memory usage code indicates that 8 is the maximum
  77. // so give it 10 just to be sure.
  78. AudioMemory(10);
  79. codec.enable();
  80. codec.volume(0.5);
  81. // I want output on the line out too
  82. // Comment this if you don't it
  83. codec.unmuteLineout();
  84. // Set the ramp time for each wave object
  85. for(int i = 0; i < 8;i++) {
  86. waves[i]->set_ramp_length(88);
  87. }
  88. Serial.println("setup done");
  89. // Initialize processor and memory measurements
  90. AudioProcessorUsageMaxReset();
  91. AudioMemoryUsageMaxReset();
  92. }
  93. unsigned long last_time = millis();
  94. void loop()
  95. {
  96. unsigned char c,opcode,chan;
  97. unsigned long d_time;
  98. // Change this to if(1) for measurement output every 5 seconds
  99. if(1) {
  100. /*
  101. For PlaySynthMusic this produces:
  102. Proc = 20 (21), Mem = 2 (8)
  103. */
  104. if(millis() - last_time >= 5000) {
  105. Serial.print("Proc = ");
  106. Serial.print(AudioProcessorUsage());
  107. Serial.print(" (");
  108. Serial.print(AudioProcessorUsageMax());
  109. Serial.print("), Mem = ");
  110. Serial.print(AudioMemoryUsage());
  111. Serial.print(" (");
  112. Serial.print(AudioMemoryUsageMax());
  113. Serial.println(")");
  114. last_time = millis();
  115. }
  116. }
  117. // Volume control
  118. int n = analogRead(15);
  119. if (n != volume) {
  120. volume = n;
  121. codec.volume((float)n / 1023);
  122. }
  123. // read the next note from the table
  124. c = *sp++;
  125. opcode = c & 0xf0;
  126. // was 0x0f but I'm only handling 8 channels
  127. // This will map Ch 8->Ch 0, Ch 9->Ch 1, etc.
  128. chan = c & 0x07;
  129. if(c < 0x80) {
  130. // Delay
  131. d_time = (c << 8) | *sp++;
  132. delay(d_time);
  133. return;
  134. }
  135. if(*sp == CMD_STOP) {
  136. Serial.println("DONE");
  137. while(1);
  138. }
  139. // It is a command
  140. // Stop the note on 'chan'
  141. if(opcode == CMD_STOPNOTE) {
  142. waves[chan]->amplitude(0);
  143. return;
  144. }
  145. // Play the note on 'chan' - divide the frequency by two because the
  146. // table of frequencies has been doubled.
  147. if(opcode == CMD_PLAYNOTE) {
  148. waves[chan]->begin(AMPLITUDE,tune_frequencies2_PGM[*sp++],
  149. wave_type[chan]);
  150. return;
  151. }
  152. // replay the tune
  153. if(opcode == CMD_RESTART) {
  154. sp = score;
  155. return;
  156. }
  157. }