PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

145 lines
4.3KB

  1. // LED Audio Spectrum Analyzer Display
  2. //
  3. // Creates an impressive LED light show to music input
  4. // using Teensy 3.1 with the OctoWS2811 adaptor board
  5. // http://www.pjrc.com/store/teensy31.html
  6. // http://www.pjrc.com/store/octo28_adaptor.html
  7. //
  8. // Line Level Audio Input connects to analog pin A3
  9. // Recommended input circuit:
  10. // http://www.pjrc.com/teensy/gui/?info=AudioInputAnalog
  11. //
  12. // This example code is in the public domain.
  13. #include <OctoWS2811.h>
  14. #include <Audio.h>
  15. #include <Wire.h>
  16. #include <SD.h>
  17. #include <SPI.h>
  18. // The display size and color to use
  19. const unsigned int matrix_width = 60;
  20. const unsigned int matrix_height = 32;
  21. const unsigned int myColor = 0x400020;
  22. // These parameters adjust the vertical thresholds
  23. const float maxLevel = 0.5; // 1.0 = max, lower is more "sensitive"
  24. const float dynamicRange = 40.0; // total range to display, in decibels
  25. const float linearBlend = 0.3; // useful range is 0 to 0.7
  26. // OctoWS2811 objects
  27. const int ledsPerPin = matrix_width * matrix_height / 8;
  28. DMAMEM int displayMemory[ledsPerPin*6];
  29. int drawingMemory[ledsPerPin*6];
  30. const int config = WS2811_GRB | WS2811_800kHz;
  31. OctoWS2811 leds(ledsPerPin, displayMemory, drawingMemory, config);
  32. // Audio library objects
  33. AudioInputAnalog adc1(A3); //xy=99,55
  34. AudioAnalyzeFFT1024 fft; //xy=265,75
  35. AudioConnection patchCord1(adc1, fft);
  36. // This array holds the volume level (0 to 1.0) for each
  37. // vertical pixel to turn on. Computed in setup() using
  38. // the 3 parameters above.
  39. float thresholdVertical[matrix_height];
  40. // This array specifies how many of the FFT frequency bin
  41. // to use for each horizontal pixel. Because humans hear
  42. // in octaves and FFT bins are linear, the low frequencies
  43. // use a small number of bins, higher frequencies use more.
  44. int frequencyBinsHorizontal[matrix_width] = {
  45. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  46. 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
  47. 3, 3, 3, 3, 4, 4, 4, 4, 4, 5,
  48. 5, 5, 6, 6, 6, 7, 7, 7, 8, 8,
  49. 9, 9, 10, 10, 11, 12, 12, 13, 14, 15,
  50. 15, 16, 17, 18, 19, 20, 22, 23, 24, 25
  51. };
  52. // Run setup once
  53. void setup() {
  54. // the audio library needs to be given memory to start working
  55. AudioMemory(12);
  56. // compute the vertical thresholds before starting
  57. computeVerticalLevels();
  58. // turn on the display
  59. leds.begin();
  60. leds.show();
  61. }
  62. // A simple xy() function to turn display matrix coordinates
  63. // into the index numbers OctoWS2811 requires. If your LEDs
  64. // are arranged differently, edit this code...
  65. unsigned int xy(unsigned int x, unsigned int y) {
  66. if ((y & 1) == 0) {
  67. // even numbered rows (0, 2, 4...) are left to right
  68. return y * matrix_width + x;
  69. } else {
  70. // odd numbered rows (1, 3, 5...) are right to left
  71. return y * matrix_width + matrix_width - 1 - x;
  72. }
  73. }
  74. // Run repetitively
  75. void loop() {
  76. unsigned int x, y, freqBin;
  77. float level;
  78. if (fft.available()) {
  79. // freqBin counts which FFT frequency data has been used,
  80. // starting at low frequency
  81. freqBin = 0;
  82. for (x=0; x < matrix_width; x++) {
  83. // get the volume for each horizontal pixel position
  84. level = fft.read(freqBin, freqBin + frequencyBinsHorizontal[x] - 1);
  85. // uncomment to see the spectrum in Arduino's Serial Monitor
  86. // Serial.print(level);
  87. // Serial.print(" ");
  88. for (y=0; y < matrix_height; y++) {
  89. // for each vertical pixel, check if above the threshold
  90. // and turn the LED on or off
  91. if (level >= thresholdVertical[y]) {
  92. leds.setPixel(xy(x, y), myColor);
  93. } else {
  94. leds.setPixel(xy(x, y), 0x000000);
  95. }
  96. }
  97. // increment the frequency bin count, so we display
  98. // low to higher frequency from left to right
  99. freqBin = freqBin + frequencyBinsHorizontal[x];
  100. }
  101. // after all pixels set, show them all at the same instant
  102. leds.show();
  103. // Serial.println();
  104. }
  105. }
  106. // Run once from setup, the compute the vertical levels
  107. void computeVerticalLevels() {
  108. unsigned int y;
  109. float n, logLevel, linearLevel;
  110. for (y=0; y < matrix_height; y++) {
  111. n = (float)y / (float)(matrix_height - 1);
  112. logLevel = pow10f(n * -1.0 * (dynamicRange / 20.0));
  113. linearLevel = 1.0 - n;
  114. linearLevel = linearLevel * linearBlend;
  115. logLevel = logLevel * (1.0 - linearBlend);
  116. thresholdVertical[y] = (logLevel + linearLevel) * maxLevel;
  117. }
  118. }