Minim pause() does not work

edited May 2016 in Library Questions

Hi,

I am working on a tangible music player with Arduino and for this I am using the minim library. However, the player.pause() function does not work in my code. It only stops the song for a few milliseconds and then continues to play the song.

The code for the pause function is as the following:

    boolean state = false;
    
    if (keyPressed) {
        if (key == 'p' && !state) {
          state = true;
          player[currentSong].pause();
        }
        else if (key == 'p' && state) {
        state = false;
        player[currentSong].play();
      }

Is there something else that I have to add in order to let it pause until I press the P key again?

Answers

  • Pressing the key is working properly, because I have printed the boolean states. The state changes from true to false and vice versa. However, the song does not pauses, it just keeps playing.

  • edited May 2016

    Based on ddf.minim.AudioPlayer's pause() example:
    http://code.Compartmental.net/minim/audioplayer_method_pause.html

    /**
     * AudioPlayer Pause isPlaying (v1.0.2)
     * GoToLoop 2016-May-04
     * forum.Processing.org/two/discussion/16413/minim-pause-does-not-work
     */
    
    import ddf.minim.Minim;
    import ddf.minim.AudioPlayer;
    
    static final String NAME = "song", EXT = ".mp3";
    static final int SONGS = 3;
    
    final AudioPlayer[] songs = new AudioPlayer[SONGS];
    int idx;
    
    void setup() {
      final Minim m = new Minim(this);
    
      for (int i = 0; i < SONGS; ++i)
        songs[i] = m.loadFile(NAME + nf(i+1, 2) + EXT);
    
      songs[0].loop();
    }
    
    void draw() {
    }
    
    void keyPressed() {
      final ddf.minim.Playable song = songs[idx];
    
      switch (keyCode) {
      case ENTER:
      case RETURN:
      case ' ':
        song.pause();
        songs[idx = (idx + 1) % SONGS].loop();
        break;
    
      case 'P':
        if (song.isPlaying())  song.pause();
        else                   song.loop();
      }
    }
    
    @ Override void exit() {
      for (final ddf.minim.AudioSource s : songs)  s.close();
      super.exit();
    }
    
  • I assume that your code is inside the draw() method and if so that is the problem. Try this code and you will see that when you press a key it registers over several frames and each time flipping the state between true and false.

    boolean state = false;
    
    void setup() {
    }
    
    void draw() {
      if (keyPressed){
        state = !state;
        println(frameCount, state);
      }
    }
    

    Move your code into the keyPressed method like this,. After all you only need to to the test when a key is pressed not every frame.

    boolean state = false;
    
    void setup() {
    }
    
    void draw() {
      if (keyPressed) {
        state = !state;
        println(frameCount, state);
      }
    }
    
    void keyPressed() {
      if (key == 'p' && !state) {
        state = true;
        player[currentSong].pause();
      } else if (key == 'p' && state) {
        state = false;
        player[currentSong].play();
      }
    }
    

    Also I would change the name of the variable state to isStopped it makes it much clearer what is happening.

  • Thanks for helping. I have tried both of the codes but it still does not work. In the code of GoToLoop the song just keeps rewinding to the beginning, but does not pause. In the code of quark, the state does change according to the code, so it does change from false to true. Thus, in none of these situations the song does not pause...

    Whatever I do the song never stops, only if I use close(), but then the song never plays again.

  • edited May 2016

    I know that my code does what you want. Load the example called 'PlayAFile' that comes with minim and replace the code with this code and try it . It worked for me with PS3.0.2

    import ddf.minim.*;
    
    Minim minim;
    AudioPlayer[] player = new AudioPlayer[1];
    int currentSong = 0;
    boolean state = true;
    
    void setup() {
      size(512, 200, P3D);
      minim = new Minim(this);
      player[currentSong] = minim.loadFile("groove.mp3");
    }
    
    void draw() {
      background(0);
      stroke(255);
      for (int i = 0; i < player[currentSong].bufferSize() - 1; i++)
      {
        float x1 = map( i, 0, player[currentSong].bufferSize(), 0, width );
        float x2 = map( i+1, 0, player[currentSong].bufferSize(), 0, width );
        line( x1, 50 + player[currentSong].left.get(i)*50, x2, 50 + player[currentSong].left.get(i+1)*50 );
        line( x1, 150 + player[currentSong].right.get(i)*50, x2, 150 + player[currentSong].right.get(i+1)*50 );
      }
    
      float posx = map(player[currentSong].position(), 0, player[currentSong].length(), 0, width);
      stroke(0, 200, 0);
      line(posx, 0, posx, height);
    
      text("Press key 'p' to toggle playback", 10, 20 );
    }
    
    void keyPressed() {
      if (key == 'p' && !state) {
        state = true;
        player[currentSong].pause();
      } else if (key == 'p' && state) {
        state = false;
        if ( player[currentSong].position() == player[currentSong].length() )
          player[currentSong].rewind();
        player[currentSong].play();
      }
    }
    
  • edited May 2016

    @pet0103, my sketch example was intended as a template, not a complete program.
    I haven't tested it till now. The only thing I had to do was adding an empty draw():

    void draw() {
    }
    

    Changed SONGS to 3 and dragged 3 ".mp3" files onto the PDE.
    Hit CTRL+K, entered subfolder "data/" and renamed those as:
    "song01.mp3", "song02.mp3", "song03.mp3".
    And voilà, "song01.mp3" started playing. And I could hit 'P' key to pause/resume.
    Also spacebar or ENTER to jump to next ".mp3".

    Please test it correctly before stating it isn't working! [-(

    P.S.: In older Minim versions, it seemed to have some problems when closing the sketch w/ paused AudioPlayer and displayed some horrible red error messages.

    That's why I've @Override exit() in order to forcibly close() all AudioPlayer instances.
    However it seems it's not needed anymore. You can delete exit() method if you wish. :-\"

  • @quark, the code does work in another file indeed. However not in my code, so I guess there is something else happening in the 500 lines of code that I have. The parts that are related to pause are as the following:

    AudioPlayer[] player = new AudioPlayer[5]; 
    Minim minim; 
    int currentSong =0;
    boolean state = true;
    
    void setup() {
     minim = new Minim(this); 
      player[0] = minim.loadFile("Sia - Cheap Thrills.mp3"); 
      player[1] = minim.loadFile("Sia - Bird Set Free (Lyrics).mp3"); 
      player[2] = minim.loadFile("Twenty one pilots - Stressed out.mp3"); 
      player[3] = minim.loadFile("G-Eazy X Bebe Rexha - Me Myself & I.mp3"); 
      player[4] = minim.loadFile("Ed Sheeran - I See Fire (Kygo Remix).mp3"); 
    
    }
    
    void draw() {
    }
    
    void keyPressed() {
      if (key == 'p' && !state) {
        state = true;
        player[currentSong].pause();
      } else if (key == 'p' && state) {
        state = false;
        if ( player[currentSong].position() == player[currentSong].length() )
          player[currentSong].rewind();
        player[currentSong].play();
      }
    }
    
    

    When comparing this part of the code with yours it should work, but it does not pause it only stops the song for a few milliseconds..

  • @GoToLoop, my code is very long, so it could be that while testing your code I missed something. And the way you describe it, it should indeed work, but in my code something goes wrong.

  • I cannot see anything in your last post that would cause the problem. Are you using minim in any other part of your code?

  • edited May 2016 Answer ✓

    New "AudioPlayer Pause isPlaying II" w/ more features like rewind(), skip(), etc.: :-bd

    /**
     * AudioPlayer Pause isPlaying II (v1.0.3)
     * GoToLoop 2016-May-06
     * forum.Processing.org/two/discussion/16413/minim-pause-does-not-work
     */
    
    import ddf.minim.Minim;
    import ddf.minim.Playable;
    import java.io.FilenameFilter;
    
    static final FilenameFilter MP3_FILTER = new FilenameFilter() {
      boolean accept(final File f, final String name) {
        return name.toLowerCase().endsWith("mp3");
      }
    };
    
    static final int FPS = 1, SKIP = 5 * 1000;
    
    Playable[] songs;
    int idx;
    
    void setup() {
      size(400, 200);
      frameRate(FPS);
    
      final Minim m = new Minim(this);
      final String[] paths = dataFile("").list(MP3_FILTER);
      final int len = paths.length;
    
      songs = new Playable[len];
      for (int i = 0; i < len; songs[i] = m.loadFile(paths[i++]));
      songs[0].play();
    
      printArray(paths);
      println();
    }
    
    void draw() {
      background((color) random(#000000));
    
      final Playable song = songs[idx];
      final int pos = song.position()/1000, len = song.length()/1000;
      final boolean playing = song.isPlaying();
    
      if (pos >= len & !playing) {
        println("Finished #", nf(idx, 2));
        println(song.getMetaData().fileName(), ENTER);
    
        song.rewind();
        keyCode = DOWN;
        keyPressed();
      }
    
      getSurface().setTitle("Idx: " + nf(idx, 2) +
        "   Pos: " + nf(pos, 3) + "   Len: " + nf(len, 3) + 
        (playing? "" : "   PAUSED"));
    }
    
    void keyPressed() {
      final Playable song = songs[idx];
    
      switch (keyCode) {
      case ENTER:
      case RETURN:
      case DOWN:
        song.pause();
        songs[idx = (idx + 1) % songs.length].play();
        break;
    
      case UP:
        song.rewind();
        break;
    
      case LEFT:
        song.skip(-SKIP);
        break;
    
      case RIGHT:
        song.skip(SKIP);
        break;
    
      case 'P':
      case ' ':
        if (song.isPlaying())  song.pause();
        else                   song.play();
      }
    }
    

    Just place your ".mp3" files inside subfolder "data/". B-)

  • Okay guys, thank you for your help! I have been busy with the code a lot and have been able to achieve my goal. Thanks for your time!

Sign In or Register to comment.