assign times to musical notes

edited October 2013 in Library Questions

Hi everyone,

I have a problem with my code, I almost finish a project but I have problems with assign times to musical notes, I tried different ways but nothing works, this code make something strange, for every frame or every [a] play all the array, also there should be a sincronization between the drawing and the music, someone who knows what happen?

Really thanks

  import arb.soundcipher.*;
  import arb.soundcipher.constants.*;
  import processing.serial.*; //llama a todas las intruccionnes con todas las extenciones

  SoundCipher part1 = new SoundCipher(this);
  SCScore score = new SCScore();

  float[] pitches = {69, 71, 73, 74, 76, 76, 76, 76, 78, 74, 81, 78, 76};
  float[] durations = {0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 2.0};
  float[] dynamics = new float[pitches.length];

  int n = 0;
  int a = 0;
  int b = 0;
   float xLoc = 0;
  float yLoc = -150;
  float lineDistY = 100;
 float posX = 0;
 float posX2 = 0;

  void setup(){
    for (int i=0; i<durations.length; i++) {
     dynamics[i] = random(40) + 70;
     }
   background(255);
   size(640, 480);
   stroke(0);
   frameRate(2); 
   double newPitches = pitches[a];
   double newDurations = durations[a];
   }

  void draw()
    { 
      if (a >= pitches.length-1) {
          a = 0;
           }
      if (xLoc >= width) {
          xLoc = 0;
          yLoc = yLoc + lineDistY;
           }

       line(0, 139.5, 640, 139.5);
        line(0, 128.5, 640, 128.5);
        line(0, 117.5, 640, 117.5);
        line(0, 107, 640, 107);
        line(0, 95.5, 640, 95.5);

       ellipse(xLoc+20, height-3*pitches[a]+yLoc, 8 , 8);
       fill(204,102,150); //rellena la ellipse con un color determinado
       a += 1;
       xLoc += 20.0;

       println(a);

      double newPitches = pitches[a];
      double newDurations = durations[a];

      for(int a = 0; a<pitches.length; a++){  
            score.addNote(0, 0, 34, pitches[a], 20, durations[a], 0.2, 64);
            a+=1;
            score.play(1);
             }
        //println(pitches[a]);
        //println(newPitches);
        println(pitches);
      }

Answers

  • Answer ✓

    Hi! Looking at the code it looks like you have a for loop that adds all notes to the score each time draw() is called. That's a lot of playing! :)

    Shouldn't you play the score just once in the setup(), instead inside the draw() loop?

  • Answer ✓

    here....

    you forget in the command addNote that the 1st entry is the startBeat, set this to a instead of 0

    import arb.soundcipher.*;
    import arb.soundcipher.constants.*;
    //import processing.serial.*; //llama a todas las intruccionnes con todas las extenciones
    
    SoundCipher part1 = new SoundCipher(this);
    SCScore score = new SCScore();
    
    float[] pitches = {
      69, 71, 73, 74, 76, 76, 76, 76, 78, 74, 81, 78, 76
    };
    float[] durations = {
      0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 2.0
    };
    float[] dynamics = new float[pitches.length];
    
    int n = 0;
    int a = 0;
    int b = 0;
    float xLoc = 0;
    float yLoc = -150;
    float lineDistY = 100;
    float posX = 0;
    float posX2 = 0;
    
    void setup() {
      size(640, 480);
    
      for (int i=0; i<durations.length; i++) {
        dynamics[i] = random(40) + 70;
      }
      background(255);
    
      stroke(0);
      frameRate(2);
      //  double newPitches   = pitches[a];
      //  double newDurations = durations[a];
    
      for (int a = 0; a<pitches.length; a++) { 
        score.addNote( a, 0, 34, pitches[a], 20, durations[a]*10, 0.2, 64);
        // a+=1;
        // score.play(1);
      }
      a=0;
      score.play();
    
      //  noLoop();
    }
    
    void draw()
    {
      if (score.isPlaying() && a < pitches.length) { 
        // 
        //    if (a >= pitches.length-1) {
        //      a = 0;
        //    }
        if (xLoc >= width) {
          xLoc = 0;
          yLoc = yLoc + lineDistY;
        }
    
        line(0, 139.5, 640, 139.5);
        line(0, 128.5, 640, 128.5);
        line(0, 117.5, 640, 117.5);
        line(0, 107, 640, 107);
        line(0, 95.5, 640, 95.5);
    
        ellipse(xLoc+20, height-3*pitches[a]+yLoc, 8, 8);
        fill(204, 102, 150); //rellena la ellipse con un color determinado
        // a += 1;
        xLoc += 20.0;
    
        println(a);
    
        double newPitches = pitches[a];
        double newDurations = durations[a];
    
        //for (int a = 0; a<pitches.length; a++) { 
        //  score.addNote(0, 0, 34, pitches[a], 20, durations[a], 0.2, 64);
    
    
        // }
        //println(pitches[a]);
        //println(newPitches);
    
        a+=1;
        // println(pitches);
      }
    }
    //
    
  • With this suggestion you can hear one note per time but you can not change the duration of the note, you only can hear something like two note in one time (that supposedly is a note of two times) , also the drawing is not synchronized with the music, any other idea?

  • edited October 2013

    hello,

    sorry for being late, the forum didn't notify me that you answered (wth, I thought that would be the purpose of switching to a new forum!?)

    anyway, you are right, in my bad approach we put all notes in the score (in setup()) and play the whole thing in draw which causes the problems you correctly describe.

    Alternatively you could just put one note in the score (in draw()) and play it immediately and then clear the score and put in the next note and play it immediately. This is what you had in your first sketch except for some small changes. The main change would be to get rid of the for-loop in draw() and just use the fact that draw() in itself loops automatically.

    you need the lines

    if ( ! score.isPlaying()) { 
        a++; 
        score.empty();
        if ( a < pitches.length ) { 
             score.addNote( 0, 0, 34, pitches[a], 20, durations[a]*10, 0.2, 64);
        }
    }
    

    or so. Saying when the note is over (not playing anymore), turn to the next one.

    If you want me to I can give it a try tonight.

    Greetings, Chrisir

    P.S. this text has been edited

    ! denotes a "not"

    see also http://explodingart.com/soundcipher/reference.html

    http://explodingart.com/soundcipher/doc/arb/soundcipher/SCScore.html

  • Sorry, I tried my own approach - it doesn't seem to work.

    Also, I never have worked with soundcipher. Is there a way to just play a note without using score?

  • edited October 2013

    like this

    this plays but not good

    import arb.soundcipher.*;
    import arb.soundcipher.constants.*;
    //import processing.serial.*; //llama a todas las intruccionnes con todas las extenciones
    
    SoundCipher part1 = new SoundCipher(this);
    SCScore score = new SCScore();
    
    float[] pitches = {
      69, 71, 73, 74, 76, 76, 76, 76, 78, 74, 81, 78, 76
    };
    float[] durations = {
      0.5, 2.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 2.0
    };
    float[] dynamics = new float[pitches.length];
    
    int n = 0;
    int a = 0;
    int b = 0;
    float xLoc = 20;
    float yLoc = -150;
    float lineDistY = 100;
    float posX = 0;
    float posX2 = 0;
    boolean stopPlaying = false; 
    
    // -------------------------------------------------------
    
    void setup() {
      for (int i=0; i<durations.length; i++) {
        dynamics[i] = random(40) + 70;
      }
      background(255);
      size(640, 480);
      stroke(0);
      //  frameRate(2); 
      //  double newPitches = pitches[a];
      //  double newDurations = durations[a];
    
      // init 
      score.addNote(0, 0, 34, pitches[a], 20, durations[a], 0.2, 64);
      score.play();
      println(a);
    }
    
    void draw()
    { 
      background(255);
      if (a >= pitches.length-1) {
        //a = 0;
        //
        // stopPlaying=true;
        // exit();
      }
      if (xLoc >= width) {
        xLoc = 0;
        yLoc = yLoc + lineDistY;
      }
    
      line(0, 139.5, 640, 139.5);
      line(0, 128.5, 640, 128.5);
      line(0, 117.5, 640, 117.5);
      line(0, 107, 640, 107);
      line(0, 95.5, 640, 95.5);
    
    
      if (!stopPlaying) 
        ellipse(xLoc+20, height-3*pitches[a]+yLoc, 8, 8);
      fill(204, 102, 150); //rellena la ellipse con un color determinado
      //
      // if it is not playing anymore
      if ( ! score.isPlaying()) {
        if (!stopPlaying) { 
          a++;
          println(a);
          xLoc += 20.0;
          score.empty();
        } // if 
        // 
        // still to go? 
        if ( a < pitches.length ) {
          score.addNote( 0, 0, 34, pitches[a], 20, durations[a], 0.2, 64);
          score.update();
          score.play();
        }
        else {
          // stop
          stopPlaying=true;
        } // else
      } // if
    } // func 
    //
    
  • yes, there are a function call playNote and other call playPhrase also I tried with playNote but I had the same problem with the durations of the notes

  • another approach would be to start a note and then set a timer and after .75 seconds or so (depending on the duration) stop the playing. Thus you would have pretty good control.

  • edited October 2013 Answer ✓

    here, this version is with timer and using playNote

    Unfortunately, playNote doesn't know a isPlaying, so we don't know if the note has ended... but with the timer it's ok. It also comes with colors denoting the duration.

    it's not using score anymore but only playNote see http://explodingart.com/soundcipher/doc/arb/soundcipher/SoundCipher.html#playNote(double, double, double)

    import arb.soundcipher.*;
    import arb.soundcipher.constants.*;
    //import processing.serial.*; //llama a todas las intruccionnes con todas las extenciones
    
    SoundCipher part1 = new SoundCipher(this);
    //SCScore score = new SCScore();
    //
    final int factor = 14 ; // for duration (multiply) for playNote
    final int factorMillis = 1000;  //  for duration (multiply) for timer 
    final int factorColor = 100;   //  for duration (multiply) for color
    //
    float[] pitches = {
      69, 71, 73, 74, 76, 76, 76, 76, 78, 74, 81, 78, 76
    };
    float[] durations = {
      0.5, 2.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 2.0
    };
    float[] dynamics = new float[pitches.length];
    
    int n = 0;
    int a = 0;
    int b = 0;
    float xLoc = 20;
    float yLoc = -150;
    float lineDistY = 100;
    float posX = 0;
    float posX2 = 0;
    boolean stopPlaying = false; 
    int i;  // timer 
    
    // -------------------------------------------------------
    
    void setup() {
      for (int i=0; i<durations.length; i++) {
        dynamics[i] = random(40) + 70;
      }
      background(255);
      size(640, 480);
      stroke(0);
      println(a);
      part1.playNote ( pitches[a], 20, durations[a]*factor );
      i=millis();
    }
    
    void draw()
    { 
      //  background(255);
      if (xLoc >= width) {
        xLoc = 0;
        yLoc = yLoc + lineDistY;
      }
    
      line(0, 139.5, 640, 139.5);
      line(0, 128.5, 640, 128.5);
      line(0, 117.5, 640, 117.5);
      line(0, 107, 640, 107);
      line(0, 95.5, 640, 95.5);
    
    
      if (!stopPlaying) {
        fill(204, 102, durations[a]*factorColor); //rellena la ellipse con un color determinado
        noStroke();
        ellipse(xLoc+20, height-3*pitches[a]+yLoc, 8, 8);
      }
    
      //
      if (!stopPlaying) { 
        // if timer is over
        if ( i + durations[a]*factorMillis  < millis() ) {
          part1.stop();
          i=millis(); // set new timer 
          if (!stopPlaying) { 
            a++;
            println(a);
            xLoc += 20.0;
            part1.stop();
          } // if 
          // 
          // still to go? 
          if ( a < pitches.length ) {
            // next note 
            part1.playNote ( pitches[a], 20, durations[a]*factor );
          }
          else {
            // stop
            stopPlaying=true;
          } // else
        } // if
      } // if
    } // func 
    //
    
  • edited October 2013

    ....

  • sorry for the delay, yes, with playNote sound and work better, I've been tried to put this code into an other code with screens to simulate a videogame but I have some problems with the sincronization between the music part and the drawing, in your sketch this work fine, but let me see if I doing something wrong when I pass this into the other sketch.

    thanks a lot :D

Sign In or Register to comment.