Really great sound reactivity in bedroom lights!

This is my favorite project so far. Setting up the lights in a really organic way makes the environment feel really nice.

I was wondering if there was interest in the code. I need to clean it a little bit first and add comments if y’all would like it.

The pixelblaze’s sound processing is so fast! Thanks wizard

2 Likes

Of course! You can paste it here and surround it with 3 backtick characters to format it as code (you can always edit it afterwards)

Eg

```
Code
```

And you can upload to the pattern site when you are ready!

I like the the layout too!

1 Like

Awesome, thank you. Here is the sound reactive code. I have a few other patterns I’d like to share to the patterns page, but I think the upload may not be working. Is there another way to get them there? Emailing them to you?

// @kylarleds
// sound - Starburst
// https://www.youtube.com/watch?v=cFQ6EF1kr9M

export var frequencyData
export var energyAverage

var pixels_val = array(pixelCount)
var pixels_sat = array(pixelCount)
var pixels_age = array(pixelCount)


export var average  = 0 // Short average
export var average2 = 0 // Long average
var lowthresh = 6       // Splits the frequencyData into lows and highs at this index

export var howmany = 6  // How many lines are going back and forth - slider controlled
export function sliderHowManyLeaders(v)
{
  howmany = floor(v*11)+1
}


var rainbow = 0
export function sliderRainbow(v){
  rainbow = v > 0.5
}

// Custom timers based on delta rather than time()
var fastTimer = 0 
var slowTimer = 0

// Control over the color changing less when the bass/energy is high
var bassPause = 9
var bassPauseHue = 0
var bassPauseHigh = 4000  // At 4000 there is a medium speed hue shift
var bassPauseLow = 200    // At 200 the LEDs rainbow flicker (hue changing very fast)

var samples = 12          // How many samples to average over. Lower will react to small things more

export function beforeRender(delta) {
  // This timer controls how fast they move
  posTimer = time(.1)
  posTimerReverse = 1-posTimer
  
  fastTimer = (fastTimer+delta/bassPauseLow)%1
  slowTimer = (slowTimer+delta/bassPauseHigh)%1
  
  // Count up the lows and highs in case you want to use them separately
  lows = 0
  highs = 0
  for(var i = 0; i < 32; i++){
    if(i < lowthresh){
      lows  += frequencyData[i]
    }else if(i > lowthresh){
      highs += frequencyData[i]
    }
  }
  
  sum = highs+lows
  average = (average*(samples-1) + sum)/samples         // Moving average. Incorporate new data
  average2 = (average2*(samples*2-1) + sum)/(samples*2) // Moving average2, twice as long
  
  val = (average > average2)*energyAverage*80
  sat = 0.3  // Controls the whiteness of the leading pixel
  for(var leader = 0; leader < howmany; leader++){
    
    // We do 2 index calculations, one for a leader moving left, and the reflection of it moving right
    index = floor(((posTimer+leader/howmany)%1)*pixelCount)        
    pixels_sat[index] = sat
    pixels_val[index] = val
    pixels_age[index] = 0
    
    index = floor(((posTimerReverse+leader/howmany)%1)*pixelCount)
    pixels_sat[index] = sat
    pixels_val[index] = val
    pixels_age[index] = 0
  }
  
  // Age each of the pixels.
  for(var i = 0; i < pixelCount; i++){
    pixels_age[i] += delta/200
  }
  
  // bassPauseHue is a way to maintain a slow changing hue when the bass hits (or other intensity is maintained)
  // Otherwise, the fastTimer timer will take over and do a flickering rainbow
  bassPauseHue = average > average2 ? slowTimer : fastTimer     
  
}

export function render(index) {
  h = 0
  
  if(pixels_age[index] < 1){
    //Young pixel. Young pixels have the luxury of not rainbow flickering out, they are based on slowTimer only
     h = ((slowTimer) + ( (16*index)/pixelCount )*rainbow )
  }else{
    //Old pixel. This will rainbow out if bassPauseHue is on fastTimer ( average < average2 )
     h = ((bassPauseHue) + ( (16*index)/pixelCount )*rainbow )
  }
  
  pixels_sat[index] = min(pixels_sat[index]*1.3,1)  // Limit the saturation so it doesn't loop. Modify 1.3 to change the rate the white disappears
  
  pixels_val[index] = pixels_val[index]*( average > average2 ? 0.96 : 0.88) // When loud, fade less (0.96). Fade fast when not loud (0.88)
  
  s = pixels_sat[index]
  v = pixels_val[index]
  
  hsv(h, s, v) // :) thanks for reading some code
}
3 Likes

What happens when you try to upload? It should be working as far as I know. You’ll need an .epe file exported from your pattern list. If this was an edit of an existing pattern (instead of a clone) then there might be an ID conflict, but thats pretty easy to fix. You can send it to me and I’ll post it if you still can’t upload it for some reason.

Thank yo for the contribution!

1 Like

been playing with your code. I am an absolute novice, but really like some of the diversity you can get when playing with the sliders. is there any way you could code the how many leaders and rainbow out put to be changing randomly using Math.random under the howmany.

it assigns a random number but only the once, what i’m trying to achieve the amount of headers changing on significant frequency data peaks but have no idea how to go about doing that

1 Like

also have you considered using palettes from the utility palette pattern. I’m full of ideas just sorely lacking in the knowledge to execute them.

hugely grateful for another decent sound reactive pattern though so massive thumbs up from me

1 Like

Thanks! I got them uploaded :slight_smile: - I was copy pasting the code into a text file and trying to upload that way (even giving it a .epe extension). However I see now the .epe file includes the pattern, exporting directly from PB worked.

1 Like

Awesome, yes I can try to help you execute any idea you have.

export function beforeRender(delta) {
  howmanyTimer = time(0.05)
  howmany = howmanyTimer*10+2
  //howmany = (average > average2*1.05 ? 12 : 6) // (condition ? if_true : if_false)
  //howmany = random(10)+2
...

This code will do the howmany changes you mentioned. Uncomment the one you want. The problem with changing howmany when the significant frequency peaks is that we only create them when the beat hits - so it would always be the same. I tried to adjust this by making it change when average is 5% greater than average2.

I’ll get back to you with the rainbow in a little.

I haven’t really done much with the color palette :o

1 Like

awesome ill give it a test now as I’m in the mood for loud music,

Here’s my current setup
Rave room

Still needs a lot of work with diffusion and tidying up.

1 Like

Awesome room! Great LED cube and you have a great placement for the strip :smiley: :D.

I’m trying to assemble something like you have.

export function beforeRender(delta) {
  rainbow = average > (average2*1.05);// rainbow turns on when beat hits 5% extra hard
...

I don’t think this works very well with the rainbow fizzling out that happens. It makes it go rainbow -> solid -> rainbow fade , rather than just solid -> rainbow fade

Let me know what ideas you have! I’m trying to make more sound reactive patterns (and patterns in general!)

2 Likes