New - multiple animations inside void draw()

edited May 2016 in Library Questions

Hello processing community.

My name is jules, design student, and I'm working on a code to translate live video from the webcam into sounds.

I'm taking out one pixel every 24 pixels that is then displayed bigger (and round) and is picked to be translated into a sine wave. I want this one selected pixel to appear bigger(let's say twice the scale), and then decrease its size slowly until it gets the same size as all the other squares. I'm doing this in order to display clearly where the sound is coming from/ highlight this part of the image for the moment it's played. The problem I face here is that the animation of the change of scale would take place while the normal loop of the draw is still running. And I don't know how to deal with that.

Thanks for reading

import processing.video.*;
import ddf.minim.*;
import ddf.minim.ugens.*;

Minim minim;
AudioOutput out;

Oscil      wave;

Capture cam;
int pointillize = 30;
int Lx[] = {1, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300};
int Ly[] = {1, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220};
int i  = 0;


void setup() {
  size(1200, 1200);

  cam = new Capture(this, 320, 240, 30);
  cam.start();
  background(0);
  rectMode(CENTER);
  smooth();

   // initialize the minim and out objects
  minim = new Minim(this);
  out   = minim.getLineOut();

  wave = new Oscil( 440, 0.6f, Waves.SINE );

  wave.patch( out );
}

void draw() {

    cam.read();

   int x = Lx[ (int) random(Lx.length) ];
  int y = Ly[ (int) random(Ly.length) ];
  int loc = x + y*cam.width;

  // Look up the RGB color in the source image
  loadPixels();
  float r = red(cam.pixels[loc]);
  float g = green(cam.pixels[loc]);
  float b = blue(cam.pixels[loc]);
  noStroke();

  // Draw an ellipse at that location with that color
   i = i + 1;
   fill(r,g,b,255);

  if (i == 24){

        ellipse(((x+150)*2),((y+150)*2),pointillize+20,pointillize+20);
        i = 0;

      //getting the wavelengh = lwave
      color c = color(r,g,b);
      float lwave = ((hue(c))*400/360)+380;

      //getting the related frequency= swave
      //octave 350_718Hz
      float swave = 300000000/lwave*1000000000/1099511627776L;


      //play sound of it
      wave.setFrequency( swave );


  } else {

      rect(((x+150)*2),((y+150)*2),pointillize,pointillize);
  }


  // bpm
  delay(5);
} 

Also, another question : The code runs quite slow, I putted the delay at (1) but still, I would like to have it faster. Does anyone knows why ?

Answers

  • It probably runs slow because you're using high res in a device not capable of such high res. I changed the size and voila, the sketch runs quite fast.

  • don't use delay

  • edited May 2016

    Anyways, coming to the main question -
    That's what PGraphics is for.
    Draw your rectangles to a PGraphics instance, and the ellipses to the PApplet.
    Just ask if you got confused or want the modified, working code.

  • @Chrisir Why would a 1ms delay affect performance by much? Did you miss the last line of the question that states:

    The code runs quite slow, I putted the delay at (1) but still, I would like to have it faster.

  • delay is general not advisable

  • I would love to see the code :)

    For the speed I found it. Delay has been removed and the framerate had to go higher, until 1000 . And it's great .

  • great!

  • edited May 2016 Answer ✓

    @Chrisir I didn't know that. Thanks!
    @jules512 framerate of 1000?? How??
    Anyways, the code(Note that it uses ArrayList ):

    import processing.video.*;
    import ddf.minim.*;
    import ddf.minim.ugens.*;
    
    static final int xoffset = 30;//adjust to suit you needs
    static final int yoffset = 30;//adjust to suit you needs
    
    Minim minim;
    AudioOutput out;
    
    Oscil      wave;
    
    Capture cam;
    
    ArrayList<Circle> cirs;//An ArrayList to keep track of circles
    PGraphics pg;//to draw rectangles
    int pointillize = 30;
    int Lx[] = {0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300};
    int Ly[] = {0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220};
    
    
    void setup() {
      size(720, 600);
      frameRate(30);//not exactly required, but could come of use
    
      //initialize
      pg = createGraphics(width, height);
      cirs = new ArrayList<Circle>();
      pg.beginDraw();
      pg.background(0);
      pg.rectMode(CENTER);
      pg.endDraw();
    
      cam = new Capture(this, 320, 240, 30);
      cam.start();
      background(0);
      smooth(4);
       // initialize the minim and out objects
      minim = new Minim(this);
      out   = minim.getLineOut();
    
      wave = new Oscil( 440, 0.6f, Waves.SINE );
    
      wave.patch( out );
    }
    
    void draw() {
    
      cam.read();
    
      int x = Lx[ (int) random(Lx.length) ];
      int y = Ly[ (int) random(Ly.length) ];
      int loc = x + y*cam.width;
    
      // Look up the RGB color in the source image
      cam.loadPixels();
      float r = red(cam.pixels[loc]);
      float g = green(cam.pixels[loc]);
      float b = blue(cam.pixels[loc]);
      noStroke();
    
      if (frameCount%24 == 0){
    
          cirs.add(new Circle(((x+xoffset)*2),((y+yoffset)*2),pointillize+20, color(r,g,b, 200)));//two choices here - either use the colour of the pixel, or use a single bright colour, but that is not my concern
    
          //getting the wavelengh = lwave
          color c = color(r,g,b);
          float lwave = ((hue(c))*400/360)+380;
    
          //getting the related frequency= swave
          //octave 350_718Hz
          float swave = 300000000/lwave*1000000000/1099511627776L;
    
    
          //play sound of it
          wave.setFrequency( swave );
    
    
      } else {
        pg.beginDraw();
        pg.fill(r,g,b);
        pg.rect(((x+xoffset)*2),((y+yoffset)*2),pointillize,pointillize);
        pg.endDraw();
      }
      image(pg, 0, 0);
    
      for(int i = cirs.size() - 1; i >= 0; i--){
        Circle cir = cirs.get(i);
        cir.draw();
        if(cir.isDead())cirs.remove(i);
      }
      // bpm
      delay(5);
    } 
    

    Code for class Circle:

    class Circle{
      int framesLeft = 60;
      float posX, posY, size;
      int colour;
    
      Circle(float posX_, float posY_, float size_, int colour_){
        posX = posX_;
        posY = posY_;
        size = size_;
        colour = colour_;
      }
    
      void draw(){
        pushStyle();
        fill(colour);
        ellipse(posX, posY, size * norm(framesLeft, 0, 60), size * norm(framesLeft, 0, 60));
        framesLeft--;
        popStyle();
      }
    
      boolean isDead(){
        return (framesLeft <= 0);
      }
    }
    

    I admit it is probably a bit of an overkill, but tell me if that is what you wanted.

Sign In or Register to comment.