How to play an audio file sequentially.

edited October 2015 in Library Questions

Hey, I'm working on a new piece where a random number generator is connected to sound files of a lady I know screaming the numbers. So when the generator hits 1 it plays her screaming 1 and so on. I'm having trouble because I want the code to be in "void draw", however the audio files play over each other when I place it into that section.

I imagine that I need a piece of code to tell the next audio file to wait until the end of the last before it plays but I am an absolute beginner at coding, so I have no idea how to write it.

I have attached what I have done so far for reference, there is only one audio file in so far as I felt it was best to start simply and then add more audio files as I go.

        import ddf.minim.*;
    
        Minim house;
        AudioPlayer player1;
    
        int christine;
    
        void setup(){
          size(100,100);
        }
    
        void draw(){
      
           house = new Minim(this);
      
          player1 = house.loadFile("u.wav");
      
      
          christine = (int)random(10);
      
          println("christine is "  + christine);
        player1.play();
        player1.isPlaying();
        for (int =
        }
    

Answers

  • .isPlaying() tells you when its's over

    your goal is to wait that long and then make the new random number and start a new song

    you can fill an array in setup() and use it in draw()

  • edited October 2015

    it's better to post code here as text (and not as an image)

    there is a sticky post here that explain how it's done

  • Hey @Chrisir,

    Thanks for that, I tried my best to edit the code so that it was posted properly, I don't think I got it quite right though.

    As for the .isPlaying(), where should it tell me that it is over? I thought that it should return with a true or a false. So my idea was to use a conditional, if(), to say that if it was playing then it should pause the random number. However, as soon found out the if() only responds to integers. Sorry for being so dense but do you reckon you could help a little more?

  • edited October 2015 Answer ✓
    • Avoid loading any resources past setup(). That's why setup() exists for! [-X
    • For multiple files, prefer using a container rather than multiple variables:
      AudioPlayer[] players = new AudioPlayer[2];
    • Declare a variable to track the index of the current active AudioPlayer: int idx;
    • Fill up the AudioPlayer[] array w/ your audio files in setup():
      Minim m = new Minim(this); players[0] = m.loadFile("u.wav"); players[1] = m.loadFile("v.wav");
    • Still in setup(), ignite the 1st 1: players[0].play();
    • Now in draw(), check for isPlaying() for current active idx and increment it and play() next 1:
      if (!players[idx].isPlaying()) players[idx = (idx + 1) % players.length].play();
  • edited October 2015

    ... as soon found out the if () only responds to integers.

    That's incorrect! if () expects 1 boolean as the result of the check expression: :-B

    1. https://Processing.org/reference/boolean.html
    2. https://Processing.org/reference/if.html

    And we use the logical NOT operator ! in order to negate the evaluated expression: ~O)
    https://Processing.org/reference/logicalNOT.html

  • Ok thanks, I think that should set me on my way! Just one last question, if I want the program to loop then should I place a loop() into the draw? Will it then run and restart once it has played all the files?

  • OK, I have tried what you said but it comes up with the error, "players cannot be resolved to a variable". Any ideas? Have attached the code.

    import ddf.minim.*;
    
    Minim house;
    
    int christine;
    
    void setup(){
      size(100,100);
      {AudioPlayer[] players = new AudioPlayer[2];
      int idx;
      house = new Minim(this);
      players[0] = house.loadFile("u.wav");
      players[1] = house.loadFile("Blue.wav");
      players[0].play();
      }
    }
    void draw(){
      if (!players[idx].isPlaying())  players[idx = (idx + 1) % players.length].play();
    }
    
  • no.........

    draw() runs on and on anyway......

    with gotoloops solution he is starting of with the first song again when the last song is over....

    this is because he used % here:

     if (!players[idx].isPlaying())  players[idx = (idx + 1) % players.length].play();
    

    this is the same as

     if (players[idx].isPlaying() == false) {
         idx = idx + 1;
         if (idx>=players.length)
               idx=0;
         players[idx].play();
    }
    
  • import ddf.minim.*;
    
    Minim house;
    AudioPlayer[] players ;
      int idx;
    
    int christine;
    
    
    void setup() {
    
      size(100,100);
    
      house = new Minim(this);
    
      players = new AudioPlayer[2];
    
    
      players[0] = house.loadFile("u.wav");
      players[1] = house.loadFile("Blue.wav");
    
      players[0].play();
    
    }
    
    void draw(){
      if (!players[idx].isPlaying())  
              players[idx = (idx + 1) % players.length].play();
    }
    
  • edited October 2015

    Variable players needs to be "global". So both setup() & draw() can "see" it.

    // forum.processing.org/two/discussion/12966/
    // how-to-play-an-audio-file-sequentially
    
    // 2015-Oct-13
    
    import ddf.minim.Minim;
    import ddf.minim.AudioPlayer;
    
    static final int PLAYERS = 2;
    final AudioPlayer[] players = new AudioPlayer[PLAYERS];
    int idx;
    
    void setup() {
      Minim m = new Minim(this);
      (players[0] = m.loadFile("u.wav")).play();
      players[1]  = m.loadFile("Blue.wav");
    }
    
    void draw() {
      if (!players[idx].isPlaying())  players[idx = (idx + 1) % PLAYERS].play();
    }
    
  • OK thank you. Now when I play the code, the sound files play after one another, but are not connected to a random number generator and do not loop. I need it so that they are both connected to the random number generator (as they were in my first attached code), play sequentially and will loop. How would this be achieved? I tried to add an if() to say that if the random number generator hit 1 then it should play players[1] but that did not work.

  • Problem is I don't understand what the values from the random() mean.
    For example, what should happen if we got a 5? What's the value range?
    Also how many times another value is picked? Or is it once only within setup()?

  • Should a 5 return then the soundfile of her screaming 'five' would play. Would you mind explaining what you mean by value range? The values should be picked continuously from playing the code, which makes me feel like it should be in draw().

  • Would you mind explaining what you mean by value range?

    The sequence of values available to pick up. For example from 0 to 9 we got 10 diff. values.

    Should a 5 return then the sound file of her screaming "five" would play.

    By that I suppose there are more than 2 sound files for your sketch, right?

    The values should be picked continuously from playing the code, ...

    That's what I'm having problem to understand:

    1. Is your sketch supposed to play a sequence of files 1 after the other once previous finish?
    2. Or is it a shuffled sequence? Like some other sound are chosen after 1 finishes?
    3. Or once a keyPressed(), pick another random() to play()?
Sign In or Register to comment.