How to play a minim track at a specific time using millis()

edited February 2018 in Library Questions

I am attempting to write a code which sets of a beep at controlled but random intervals using millis and minim. I can't understand why the beeps are not playing using the code below. Can anyone help?

I am very new to processing!

Thank you,

Amy

<

pre lang="javascript">

 import ddf.minim.*;
    import ddf.minim.AudioPlayer;

    import oscP5.*;
    import netP5.*;

    OscP5 oscP5;
    NetAddress otherSketch;

    Minim minim;
    AudioPlayer beep;

    PFont f;
    int [] beeps = new int [5];
    int ms;
    int start;
    int totalBeeps;
    boolean pressEnter;

    void setup(){
      size (512,200,P3D);
      f= createFont ("Georgia",16);

      boolean pressEnter = false;
      totalBeeps = 0;
      oscP5 = new OscP5(this,8001); /* start oscP5, listening for incoming messages at port 12000 */
      otherSketch = new NetAddress("127.0.0.1",8000);

    beeps [0] = int(random(10,60))*1000;//these numbers aren't right but give an earlier beep!
    beeps [1] = int(random(1260,1739))*1000;
    beeps [2] = int(random(1860,2339))*1000;
    beeps [3] = int(random(2460,2939))*1000;
    beeps [4] = int(random(3060,3539))*1000;

    printArray (beeps);

    minim = new Minim(this);
    beep = minim.loadFile ("ping.wav");

    }

    void keyPressed() { //boolean controlling the start screen.
      if (keyCode == ENTER) { 
        start = millis();
        pressEnter = true;
      }
    }

    void draw (){

    background (255);
    textFont (f,16);
    fill (0);

    int ms = millis()-start;

    println(ms);

      if (pressEnter)//this boolean controls the start screen and initiates the timer -resetting millis to 0 when ENTER is pressed.
      {
        text("The experiment has begun and these are the random beep times:",10,40);
        text(beeps[0],10,70);
        text("milliseconds",80,70);
        text(beeps[1],10,90);
        text("milliseconds",80,90);
        text(beeps[2],10,110);
        text("milliseconds",80,110);
        text(beeps[3],10,130);
        text("milliseconds",80,130);
        text(beeps[4],10,150);
        text("milliseconds",80,150);

        OscMessage myMessage = new OscMessage("/time in milliseconds");//this isn't the correct place but a test
        myMessage.add(ms); 
        oscP5.send(myMessage, otherSketch); 
      }else {
        text("Press Enter to begin",10,100);
      }

    for (int i=0;i<beeps.length;i++){ //this for loop should initiate the beeps in the array to sound if their value matches int ms (which is millis - millis when ENTER pressed) 
    if (beeps[i] == ms) 
         {
      beep.play();
      totalBeeps =totalBeeps+1;
        }
      else if ( beep.position() == beep.length() )
      {
        beep.rewind();
       }
      }
    }

Answers

  • Answer ✓

    Check the following code. You need to check when to generate the trigger and make sure it only happens once. With your current design, it requires to coordinate between the current time and the current active beep item.

    Kf

    import ddf.minim.*;
    import ddf.minim.AudioPlayer;
    
    
    Minim minim;
    AudioPlayer beep;
    
    PFont f;
    int [] beeps = new int [5];
    int ms;
    int start;
    int totalBeeps;
    boolean pressEnter;
    int current=-1;
    
    void setup() {
      size (512, 200, P3D);
      f= createFont ("Georgia", 16);
    
      boolean pressEnter = false;
      totalBeeps = 0;
    
    
      int fac=2000;
      beeps [0] = int(random(10, 60))*fac;//these numbers aren't right but give an earlier beep!
      beeps [1] = int(random(1260, 1739))*fac;
      beeps [2] = int(random(1860, 2339))*fac;
      beeps [3] = int(random(2460, 2939))*fac;
      beeps [4] = int(random(3060, 3539))*fac;
    
    
      for (int i=0; i<5; i++)
        beeps[i]=fac*(i+1);
    
      printArray (beeps);
    
      minim = new Minim(this);
      beep = minim.loadFile ("button-3.mp3");
    }
    
    void keyPressed() { //boolean controlling the start screen.
      if (keyCode == ENTER) { 
        start = millis();
        pressEnter = true;
      }
    }
    
    void draw () {
    
      background (255);
      textFont (f, 16);
      fill (0);
    
      int ms = millis()-start;
    
      println(ms);
    
      if (pressEnter)//this boolean controls the start screen and initiates the timer -resetting millis to 0 when ENTER is pressed.
      {
        text("The experiment has begun and these are the random beep times:", 10, 40);
        text(beeps[0], 10, 70);
        text("milliseconds", 80, 70);
        text(beeps[1], 10, 90);
        text("milliseconds", 80, 90);
        text(beeps[2], 10, 110);
        text("milliseconds", 80, 110);
        text(beeps[3], 10, 130);
        text("milliseconds", 80, 130);
        text(beeps[4], 10, 150);
        text("milliseconds", 80, 150);
      } else {
        text("Press Enter to begin", 10, 100);
      }
    
      if (!pressEnter)
        return;
    
      for (int i=0; i<beeps.length; i++) { //this for loop should initiate the beeps in the array to sound if their value matches int ms (which is millis - millis when ENTER pressed) 
    
    
        if (ms > beeps[i] && i>current) {
          current=i;
          beep.rewind();
          beep.play();
          totalBeeps =totalBeeps+1;
          return;
        }
      }
    }
    
  • edited February 2018

    Hey,

    This works perfectly!

    Can I just check the function of this for loop:

     for (int i=0;i<5; i++)
     beeps[i]=fac*(i+1);
    

    Is it simply a method to check all is working without waiting such a long time?

    Thanks!

    Amy

  • Answer ✓

    Yes, testing testing testing should try to make things simpler... you are designing the trigger algorithm, not checking the performance of the random() function :-B ;)

    Kf

  • Absolutely -thanks so much!!!!!

Sign In or Register to comment.