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?

2 Likes

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.

1 Like

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:

2 Likes

Thank you very much!

1 Like

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

1 Like