Fixing laggy code (Minim, gradientline)

Hello,
I wanted to ask for help regarding my painfully inefficent code. I am currently working on a project were I create an audio reactive circle, that has a gradient. The intention is to create a circle that expands to the beat like in [Trapnations Videos](http://Trapnations Videos) and also does the wavy thing.

In my code I create a bunch of lines in a circle (a is the amount of lines, fac the size of the lines).
With the help of a forum post were onum asked how to create a gradient line I replicated the code from the last answer to create the gradient. But since the code segments my lines and puts a bunch of circles ontop of them I kinda have x amount of ellipses per line - making my code incredibly laggy.

/*
 Author:    edarcie
 Created:   22.12.2019
 
 Resources Used:
 http://code.compartmental.net/minim/index.html
 https://processing.org/reference/
 https://forum.processing.org/two/discussion/12226/#Comment_49588
 https://forum.processing.org/two/discussion/5620/how-to-draw-a-gradient-colored-line
 
 */

/* 
 #Version 1 - made reactive line, added music, commented everything
 #Version 2 - made it circle shaped, lines stopped being reactive though
 #Version 3 - lines reactive again!
 #Version 4 - added own function for a gradient line - it lag's >:
 */


import ddf.minim.*; //Java audio library

Minim minim; //Minim Object
AudioPlayer player; //recuired Audioplayer so that Minim Object works
int a= 100;        //amount of lines
int fac = 200;      //line length
color purple = color(255, 0, 255);
color blue = color(0, 255, 255);

void setup() {
  size(1920, 1080);
  minim = new Minim(this);  //so that Minim can load files from data directory
  player = minim.loadFile("abc.mp3");  //Pass File, absolute Path or URL
}

void draw() {
  background(0);
  stroke(255);
  // Text Displayed
  if ( player.isPlaying() )
  {
    text("Press any key to pause playback.", 10, 20 );
  } else
  {
    text("Press any key to start playback.", 10, 20 );
  }

  translate(width/2, height/2); //centers circle
  for (int i = 0; i < a; i++) { //creates lines and arranges them in a circle
    rotate(radians(360.0/a)); //rotates the lines so they are facing the proper way
    gradient(50, 0, 200 + player.left.get(i)*fac, player.left.get(i)*fac, purple, blue);
    //line(50, 0, 200 + player.left.get(i)*fac, player.left.get(i)*fac); //x outside points of lines that are supposed to move
  }
}

void gradient(float x1, float y1, float x2, float y2, color a, color b) {
  float distX = x2 - x1;
  float distY = y2 - y1;
  float step = 1.0/dist(x1, y1, x2, y2);    //amount of Steps
  for (float p = 0.0; p < 1.0; p +=step) {  //p = % of colored line
    fill(lerpColor(a, b, p));              //fill and not stroke, because stroke seems to need more RAM
    ellipse(x1+p*distX, y1+p*distY, 3, 3);  
    /*we took an ellipse because it retained the shape of a line the best;
     x1 as start point + the percentage of how much we already colored * dist so we can move down the line
     3,3 because the ellipse needs to be fairly small, to look like a line  
     */
  }
}

void keyPressed()
{
  if ( player.isPlaying() )
  {
    player.pause();
  }
  // rewind if at end of song
  else if ( player.position() == player.length() )
  {
    player.rewind();
    player.play();
  } else
  {
    player.play();
  }
}

Can you help me to just make that hot mess a bit more efficent? And possibly more circular?

just some small ideas:

/*
 Author:    edarcie
 Created:   22.12.2019
 
 Resources Used:
 http://code.compartmental.net/minim/index.html
 https://processing.org/reference/
 https://forum.processing.org/two/discussion/12226/#Comment_49588
 https://forum.processing.org/two/discussion/5620/how-to-draw-a-gradient-colored-line
 
 */

/* 
 #Version 1 - made reactive line, added music, commented everything
 #Version 2 - made it circle shaped, lines stopped being reactive though
 #Version 3 - lines reactive again!
 #Version 4 - added own function for a gradient line - it lag's >:
 */
// Version 5 - kll play

import ddf.minim.*; //Java audio library

Minim minim; //Minim Object
AudioPlayer player; //recuired Audioplayer so that Minim Object works
int a= 50;//100;        //amount of lines
int fac = 200;      //line length
color purple = color(255, 0, 255);
color blue = color(0, 255, 255);

void setup() {
  //  size(1920, 1080);
  size(500, 500);
  minim = new Minim(this);  //so that Minim can load files from data directory
  //  player = minim.loadFile("abc.mp3");  //Pass File, absolute Path or URL
  player = minim.loadFile("data/groove.mp3");
}

void draw() {
  background(0);
  //stroke(255);
  noStroke();
  if ( player.isPlaying() ) text("Press any key to pause playback.", 10, 20 );
  else                      text("Press any key to start playback.", 10, 20 );
  translate(width/2, height/2); //centers circle
  fill(purple);
  circle(0, 0, 100);
  for (int i = 0; i < a; i++) { //creates lines and arranges them in a circle
    rotate(radians(360.0/a)); //rotates the lines so they are facing the proper way
//    gradient(50, 0, 200 + player.left.get(i)*fac, player.left.get(i)*fac, purple, blue);
    gradient(50, 0, 200 + player.left.get(i)*fac,0, purple, blue);
  }
}

void gradient(float x1, float y1, float x2, float y2, color a, color b) {
  float distX = x2 - x1;
//  float distY = y2 - y1;
//  float step = 1.0/dist(x1, y1, x2, y2);    //amount of Steps
  float step = 0.05;
  for (float p = 0.0; p < 1.0; p +=step) {  //p = % of colored line
    fill(lerpColor(a, b, p));               //fill and not stroke, because stroke seems to need more RAM
//    circle(x1+p*distX, y1+p*distY, 15+30*p);  //we took an ellipse because it retained the shape of a line the best;
    circle(x1+p*distX, 0, 10+30*p);  //we took an ellipse because it retained the shape of a line the best;
  }
}

void keyPressed() {
  if ( player.isPlaying() )      player.pause();
  else if ( player.position() == player.length() ) {  // rewind if at end of song
    player.rewind();
    player.play();
  } else                         player.play();
}

//Can you help me to just make that hot mess a bit more efficent? And possibly more circular?

Ah I see. Instead of both doing lines and smacking ellipses on them you just left the lines out right? Thanks a bunch for that. Would it be alright with you if I took that code and developed it further to my needs? :smiley:

yes, but also go back to the minim examples,
there are some more ideas from that side to smooth data for this kind of animation.

Hello,

Here is one approach using shapes (just the shape code):

int steps = 50; //steps
float r;        //radius 
float s;        //arc length  s = r*theta; theta = TAU/a

void setup()
  {
  size(600, 600, P2D);
  frameRate(1);        //Only for testing! 
  background(0);  
  }

void draw() 
  {
  background(0);
  surface.setTitle("frameRate: " + frameRate);   
  
  translate(width/2, height/2);
  
  float step = TAU/steps;
  
  noStroke();
  for (int i = 0; i <= steps; i++) 
    {
    push();
    rotate(i*step);
    
    r = random(100, 200);
    s = r*step;        
    
    beginShape();
    fill(255, 255, 0); vertex(0,  0);
    fill(0, 0, 255); vertex( r, +s);
    fill(0, 0, 255); vertex( r, 0);
    endShape();
   
    pop();  
    }
  }

Note:

  • frameRate(1) is just for testing to slow things down
  • You can throw a lot more variables in there to change the visual effects.
  • See title bar for frame rate; I was able to maintain 60 fps for 1000+ steps!

I did integrate it with your code for some cool effects:


:slight_smile:

Thank you very much!

Oh that’s a super interesting way to go about it! Thank you very much!