PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
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.

137 lines
4.2KB

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