Centered one-dimensional spectrum analyzer?

So my goal is to use a single LED strip as a low-end frequency spectrum analyzer to react to music from an aux input. I did see and modify the spectrum analyzer by ChrisNZ but I have a few issues with it.

  1. The first issue is the decay time; sometimes, like when the song suddenly interrupts or in a bass-heavy song, the lights will all simultaneously turn off instead of “falling” off.
  2. The second issue is the positioning; I cannot for the life of me figure out how to move the starting point to the middle of the strip and have the band extend out from both the left and right sides.
  3. My third issue is the number of LEDs being used; during my tests I have a small amount of a strip unrolled on my desk and set it to a length of 40, but only ~30 of them ever actually activate.

My end goal is to replicate this Arduino music visualizer which can be seen in the repo’s README.

EDIT:
So I never planned on giving up and so after a bit of trial and error I came up with a result that I am very happy with. Bear with me because I haven’t taken the time to polish it at all and I’ll definitely work on it some more but I’m open to all criticism/feedback/suggestions.

Here’s the preview while playing Money Trees by Kendrick Lamar.

export var frequencyData

halfCount = pixelCount / 2
middle = floor(halfCount)
even = pixelCount % 2 == 0
leftMiddle = even ? middle : middle - 1
rightMiddle = even ? middle - 1 : middle - 2
freq = 0

export function beforeRender(delta) {
  t1 = time(.05)
  powerLevel = max(frequencyData[0], max(frequencyData[1], max(frequencyData[2], frequencyData[3])))
  freq = floor(min(1, powerLevel) * halfCount)
}

export function render(index) {
  s = 1
  v = 1
  
  if (even) {
    if (index == leftMiddle || index == rightMiddle) {
      h = 0
      v = freq > 0
    } else if (index > leftMiddle) {
      h = 1 / (halfCount / index)
      v = freq > index - leftMiddle
    } else if (index < rightMiddle) {
      h = -1 / (halfCount / (index + 1))
      v = freq > rightMiddle - index
    }
  } else {
    if (index == middle) {
      h = 0
      v = freq > 0
    } else if (index > middle) {
      h = 1 / (halfCount / index)
      v = freq > index - middle
    } else if (index < middle) {
      h = -1 / (halfCount / (index + 1))
      v = freq > middle - index
    }
  }
  
  hsv(h - t1, s, v)
}
2 Likes

Nice! I was just stopping back to this post to point you in the direction of some patterns that would help you do various parts, and here I see you basically nailed it.

1 Like