Soundreactive RGB Led strip (MSGEQ7)

Hello!

Yes i'm one of "those" people who needs help with his soundreactive Led strip.

First of all here is my code:

int analogPin = 0;        // MSGEQ7 OUT
int strobePin = 2;        // MSGEQ7 STROBE
int resetPin = 4;         // MSGEQ7 RESET
int spectrumValue[7];

int r = 0;                //random nr.
int pr = 0;               //previous random nr.

int maxval = 0;           //max. value in spectrum
int maxpos = 0;           //max. value position
 
// MSGEQ7 OUT pin produces values around 50-80
// when there is no input, so use this value to
// filter out a lot of the chaff.
int filterValue = 90;
 
// LED pins connected to the PWM pins on the Arduino
int ledPinG = 9;
int ledPinR = 10;
int ledPinB = 11;
 
void setup()
{
  Serial.begin(9600);
  
  // Switch detection pins
  pinMode(17, INPUT);
  pinMode(16, OUTPUT);
  digitalWrite(16, LOW);
  digitalWrite(17, HIGH);
  
  // Read from MSGEQ7 OUT
  pinMode(analogPin, INPUT);
  
  // Write to MSGEQ7 STROBE and RESET
  pinMode(strobePin, OUTPUT);
  pinMode(resetPin, OUTPUT);

  // Create an initial state for our pins
  digitalWrite (resetPin,  LOW);
  digitalWrite (strobePin, LOW);
  delay        (1);
 
  // Reset the MSGEQ7 as per the datasheet timing diagram
  digitalWrite (resetPin,  HIGH);
  delay        (1);
  digitalWrite (resetPin,  LOW);
  digitalWrite (strobePin, HIGH); 
  delay        (1);
 
  // Set analogPin's reference voltage
  analogReference(DEFAULT); // 5V
}
 
void loop()
{
  // Set reset pin low to enable strobe
  digitalWrite(resetPin, HIGH);
  digitalWrite(resetPin, LOW);
 
  // Get all 7 spectrum values from the MSGEQ7
  for (int i = 0; i < 7; i++)
  {
    digitalWrite(strobePin, LOW);
    delayMicroseconds(30); // Allow output to settle
 
    spectrumValue[i] = analogRead(analogPin);
 
    // Constrain any value above 1023 or below filterValue
    spectrumValue[i] = constrain(spectrumValue[i], filterValue, 1023);

    // Remap the value to a number between 0 and 255
    spectrumValue[i] = map(spectrumValue[i], filterValue, 1023, 0, 255);

    // Determine array position of max. value
    if (spectrumValue[i]>maxval)
    {
      maxval = spectrumValue[i];
      maxpos = i;
    }

    // Remove serial stuff after debugging
    Serial.print(spectrumValue[i]);
    Serial.print(" ");
    digitalWrite(strobePin, HIGH);
  }
  
  Serial.println(); //Serialplotter

  //Reset max. value for next loop
  maxval = 0;

  // Check switch position
  int swtch = digitalRead(17);

  // Normal spectrum visualisation
  if (swtch == HIGH)
  {
    switch (maxpos)
    {
      case 0:
      analogWrite(ledPinR, 255);
      analogWrite(ledPinG,   0); 
      analogWrite(ledPinB,   0);
      break;
      case 1:
      analogWrite(ledPinR, 255);
      analogWrite(ledPinG, 127); 
      analogWrite(ledPinB,   0);
      break;
      case 2:
      analogWrite(ledPinR, 255);
      analogWrite(ledPinG, 255); 
      analogWrite(ledPinB,   0);
      break;
      case 3:
      analogWrite(ledPinR,   0);
      analogWrite(ledPinG, 255); 
      analogWrite(ledPinB,   0);
      break;
      case 4:
      analogWrite(ledPinR,   0);
      analogWrite(ledPinG,   0); 
      analogWrite(ledPinB, 255);
      break;
      case 5:
      analogWrite(ledPinR,  75);
      analogWrite(ledPinG,   0); 
      analogWrite(ledPinB, 130);
      break;
      case 6:
      analogWrite(ledPinR, 148);
      analogWrite(ledPinG,   0); 
      analogWrite(ledPinB, 211);
      break;
      default:
      analogWrite(ledPinR,   0);
      analogWrite(ledPinG,   0); 
      analogWrite(ledPinB,   0);
      break;
    }
    
    // Write the PWM values to the LEDs
    /*
    analogWrite(ledPinR, spectrumValue[0]);
    analogWrite(ledPinR, spectrumValue[1]); 
    analogWrite(ledPinG, spectrumValue[2]);
    analogWrite(ledPinG, spectrumValue[3]); 
    analogWrite(ledPinG, spectrumValue[4]);
    analogWrite(ledPinB, spectrumValue[5]);
    analogWrite(ledPinB, spectrumValue[6]);
    */
  }

  // Beat/Bass visualisation
  else if (spectrumValue[1]>=35)
  {
     // Colour pool for random funct.
     byte colour[12][3] =
     {
       {255,0,0},    // red
       {255,128,0},  // orange
       {255,255,0},  // yellow
       {128,255,0},  // lime
       {0,255,0},    // green
       {0,255,128},  // lightgreen
       {0,255,255},  // turquoise
       {0,128,255},  // blue
       {0,0,255},    // darkblue
       {127,0,255},  // violet
       {255,0,255},  // pink
       {255,0,127},  // rose
     };

     randomSeed(analogRead(6));
     r = random(12);

     // Prevents consecutive colours
     while (r == pr)
     {
       r = random(12);
     }
      
     pr = r;
      
     analogWrite(ledPinR, colour[r][0]);
     analogWrite(ledPinG, colour[r][1]);
     analogWrite(ledPinB, colour[r][2]);
  }
}

What i want to do: As you can see in the code i have two visualisation modes. First one is supposed to visualize the low, mid and high frequ. bands.

The second one only visualizes the beats/bass or just the low frequ. band. This one works fine (more or less) since i only check one band against a set threshold and then let it pick a random colour value from my pool.

It's the first mode that i just can't get right. At first i tried to write the frequ. band values directly to the Led's but that turned out to be very "spastic" and not really pleasing to the eyes. My second try was to create another colour pool with the same amount of colours as bands.

I then made the colour light up that corresponded to the band with the highest value. I thought it was an awesome idea until i realised that it only showed me what frequency was the highest at the moment.

What i'm asking: how do i manage a smooth transition between those max. value colours? And is there a better way than mine for the beat/bass detection?