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.

179 satır
3.7KB

  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. AudioMixer4 mixer1;
  34. AudioMixer4 mixer2;
  35. AudioOutputI2S audioOut;
  36. AudioConnection c0(sine0, 0, mixer1, 0);
  37. AudioConnection c1(sine1, 0, mixer1, 1);
  38. AudioConnection c2(sine2, 0, mixer1, 2);
  39. AudioConnection c3(sine3, 0, mixer1, 3);
  40. AudioConnection c4(sine4, 0, mixer2, 0);
  41. AudioConnection c5(sine5, 0, mixer2, 1);
  42. AudioConnection c6(sine6, 0, mixer2, 2);
  43. AudioConnection c7(sine7, 0, mixer2, 3);
  44. AudioConnection c11(mixer1, 0, audioOut, 0);
  45. AudioConnection c12(mixer2, 0, audioOut, 1);
  46. //AudioControl_WM8731 codec;
  47. AudioControlSGTL5000 codec;
  48. int volume = 50;
  49. // allocate a wave type to each channel.
  50. // The types used and their order is purely arbitrary.
  51. short wave_type[8] = {
  52. TONE_TYPE_SINE,
  53. TONE_TYPE_SQUARE,
  54. TONE_TYPE_SAWTOOTH,
  55. TONE_TYPE_TRIANGLE,
  56. TONE_TYPE_SINE,
  57. TONE_TYPE_SQUARE,
  58. TONE_TYPE_SAWTOOTH,
  59. TONE_TYPE_TRIANGLE,
  60. };
  61. void setup()
  62. {
  63. Serial.begin(115200);
  64. while (!Serial) ;
  65. delay(3000);
  66. // Audio connections require memory to work.
  67. // The memory usage code indicates that 8 is the maximum
  68. // so give it 10 just to be sure.
  69. AudioMemory(10);
  70. codec.enable();
  71. codec.volume(volume);
  72. // I want output on the line out too
  73. // Comment this if you don't it
  74. codec.unmuteLineout();
  75. // Set the ramp time for each wave object
  76. for(int i = 0; i < 8;i++) {
  77. waves[i]->set_ramp_length(88);
  78. }
  79. Serial.println("Begin PlayMidiTones");
  80. Serial.println("setup done");
  81. // Initialize processor and memory measurements
  82. AudioProcessorUsageMaxReset();
  83. AudioMemoryUsageMaxReset();
  84. }
  85. unsigned long last_time = millis();
  86. void loop()
  87. {
  88. unsigned char c,opcode,chan;
  89. unsigned long d_time;
  90. // Change this to if(1) for measurement output
  91. if(0) {
  92. /*
  93. For PlaySynthMusic this produces:
  94. Proc = 20 (21), Mem = 2 (8)
  95. */
  96. if(millis() - last_time >= 5000) {
  97. Serial.print("Proc = ");
  98. Serial.print(AudioProcessorUsage());
  99. Serial.print(" (");
  100. Serial.print(AudioProcessorUsageMax());
  101. Serial.print("), Mem = ");
  102. Serial.print(AudioMemoryUsage());
  103. Serial.print(" (");
  104. Serial.print(AudioMemoryUsageMax());
  105. Serial.println(")");
  106. last_time = millis();
  107. }
  108. }
  109. // Volume control
  110. int n = analogRead(15);
  111. if (n != volume) {
  112. volume = n;
  113. codec.volume((float)n / 10.23);
  114. }
  115. c = *sp++;
  116. opcode = c & 0xf0;
  117. // was 0x0f but I'm only handling 8 channels
  118. // This will map Ch 8->Ch 0, Ch 9->Ch 1, etc.
  119. chan = c & 0x07;
  120. if(c < 0x80) {
  121. // Delay
  122. d_time = (c << 8) | *sp++;
  123. delay(d_time);
  124. return;
  125. }
  126. if(*sp == CMD_STOP) {
  127. Serial.println("DONE");
  128. while(1);
  129. }
  130. // It is a command
  131. // Stop the note on 'chan'
  132. if(opcode == CMD_STOPNOTE) {
  133. waves[chan]->amplitude(0);
  134. return;
  135. }
  136. // Play the note on 'chan'
  137. if(opcode == CMD_PLAYNOTE) {
  138. waves[chan]->begin(AMPLITUDE,tune_frequencies2_PGM[*sp++],
  139. wave_type[chan]);
  140. return;
  141. }
  142. // replay the tune
  143. if(opcode == CMD_RESTART) {
  144. sp = score;
  145. return;
  146. }
  147. }