arrays + midi msj

edited November 2017 in Library Questions

Hi! i cant resolve a problem here. Im trying to do a music visualizer. The idea is very simple; when i press a Key in my midiController add a new Particle, and when i release, delete that Particle. but when i release a key, all particles are delete. What i was looking for is that only delete the Particle what was correspond that key that i was release. here the code:

import themidibus.*;
MidiBus myBus;

int pitchs;
float cc [] =new float [256];
boolean note;
ArrayList<Particle>part;

void setup () {

  fullScreen();
  background(0);
  note = true;
  myBus= new MidiBus(this, "visuals", "visuals");
  part = new ArrayList <Particle>();
}

void draw() {

  background(0);

  for (int i = part.size()-1; i>= 0; i--) {
    Particle p = part.get(i);
    p.update();
    p.display();

    if(p.isDead()){
    part.remove(i);
    }
  }
}

void noteOff(int channel, int pitch, int velocity) {

  println();
  println("Note Off:");
  println("--------");
  println("Channel:"+channel);
  println("Pitch:"+pitch);
  println("Velocity:"+velocity);
  note=false;
  pitchs = pitch;
}

void noteOn(int channel, int pitch, int velocity) {

  println();
  println("Note On:");
  println("--------");
  println("Channel:"+channel);
  println("Pitch:"+pitch);
  println("Velocity:"+velocity);
  pitchs= pitch;
  note = true;
  part.add(new Particle(random(width), random(height), pitchs, note));
}



void controllerChange(int channel, int number, int value) {
  // Receive a controllerChange
  println();
  println("Controller Change:");
  println("--------");
  println("Channel:"+channel);
  println("Number:"+number);
  println("Value:"+value);

  cc[number]=map(value, 0, 127, 0, 1);
}

class Particle {

  PVector pos, vel, acel;
  float pitch;
  float life;
  boolean notes;

  Particle (float x, float y, float pitchs) {
    pos = new PVector(x, y);
    vel = new PVector(random(-1, 1), random(-1, 1));
    acel = new PVector(0, 0);
    pitch = pitchs;
    life = 255;

  }

  void update() {
    pos.add(vel);
    vel.add(acel);
    vel.limit(1);
    life-=1;
  }

  void display() {
    float r = map(pitchs, 0, 127, 0, 200);
    fill(255);
    noStroke();
    ellipse(pos.x, pos.y, r, r);
  }

  boolean isDead() {

    if (note==false || life < 0) {
      return true;
    } else {
      return false;
    }
  }
}

Answers

  • you're using a global flag, note, in isDead(). so all notes will be marked as dead as soon as line 41 is called.

  • (and please don't post duplicates)

  • koogs. thanks, but someone move the post into library question topic, and i think that is programming question topic, so i post again and i couldnt delete the previous one. yes, i can see that. but i dont how to do. any suggestions? thanks a lot

  • It's no real surprise it got moved to library section if the subject is "midi bus"... You could've, I think, just move it back (and rename it)

    Maybe the solution to the code problem is to remember the new particle and remove only that.

    Thinking about it some more, which I would recommend, the newest particle is always at the end of the list. So just remove the end of the list. But that suggests that they'll only ever be one or zero things on the list. Is that right?

  • I need to remove the specific particle, the particle that correspond to the note i play. Some kind of trigger, who add a new particle and delete That particle, no all of the array.

  • i realize that a global boolean is not very useful. but i dont know how put that messege into the class

  • something related to pitchs maybe? i really need help here

  •   boolean isDead() {
    
        if (note==false || life < 0) {
          return true;
        } else {
          return false;
        }
      }
    

    Point number 1: note is different to notes. In general, and for your case, if global variables are the problem, I would start by removing them.

    Not sure how your device works. Would the midi key be represented by the channel parameter in your noteOn and noteOff functions? Is this field constrained in the range of 0 to 255? If so, then I suggest to create 256 particles in setup(), all in dead state. When noteOn is called, you change the state of that particle to "true" meaning that is alive. When noteOff is called, you set the state of the particle to dead. A final edit in your code would be to display the particle only if it is in alive state.

    Kf

  • Answer ✓

    Resolved, thank you very much:

    import themidibus.*;
    MidiBus myBus;
    
    int pitchs;
    float cc [] =new float [256];
    boolean note;
    ArrayList<Particle>part;
    
    void setup () {
    
      fullScreen();
      background(0);
      note = true;
      myBus= new MidiBus(this, "visuals", "visuals");
      part = new ArrayList <Particle>();
    }
    
    void draw() {
    
      background(0);
    
      for (int i = part.size()-1; i>= 0; i--) {
        Particle p = part.get(i);
        p.update();
        p.display(); 
        if(p.isDead()){
          part.remove(i);
        }
      }
    }
    
    void noteOff(int channel, int pitch, int velocity) {
    
      println();
      println("Note Off:");
      println("--------");
      println("Channel:"+channel);
      println("Pitch:"+pitch);
      println("Velocity:"+velocity);
      note=false;
      pitchs = pitch;
      for (Particle p : part) {
          if(p.pitch == pitchs){
            p.Notesoff();
          }
      }
    }
    
    void noteOn(int channel, int pitch, int velocity) {
    
      println();
      println("Note On:");
      println("--------");
      println("Channel:"+channel);
      println("Pitch:"+pitch);
      println("Velocity:"+velocity);
      pitchs= pitch;
      note = true;
      part.add(new Particle(random(width), random(height), pitchs, note));
    }
    
    class Particle {
    
      PVector pos, vel, acel;
      float pitch;
      float life;
      boolean notes;
    
      Particle (float x, float y, float pitchs, boolean b) {
        notes=b;
        pos = new PVector(x, y);
        vel = new PVector(random(-1, 1), random(-1, 1));
        acel = new PVector(0, 0);
        pitch = pitchs;
        life = 255;
    
      }
    
      void update() {
        pos.add(vel);
        vel.add(acel);
        vel.limit(1);
        life-=1;
      }
    
      void display() {
        float r = map(pitch, 0, 127, 0, 200);
        fill(255);
        noStroke();
        ellipse(pos.x, pos.y, r, r);
      }
    
      void Notesoff(){
        notes=false;
      }
      boolean isDead() {
    
        if (notes==false || life < 0) {
          return true;
        } else {
          return false;
        }
      }
    }
    
  • Great to hear and thank you for sharing your solution.

    Kf

Sign In or Register to comment.