Minim Library Error - Unexpected Token

I'm implementing a music class for my tetris clone game. As far as I know, it follows the standard conventions of classes and minim.

However, I'm having an annoying unexpected token: minim error in my music code. I'm not sure what or where the typo is. Can someone point me in the right direction?

// Music Class for Blicks
// SDD Major Work
// By ----------
// Last Modified: 12/9/14

public class Music {
  //declare music files and create Audio Players - MenuMusic is for the menu
  Minim minim;
  AudioPlayer player1, player2, player3, menuPlayer;
  minim = new Minim(this);
  //Constants for score
  int low = 1000;
  int high = 5000;
  //Loading MenuPlayer outside out of the Class Constructor so that it doesn't need to be declared every time in each if statement below
  MenuPlayer = minim.loadFile("MainMenuMusic.mp3");

  //GameTypes are as ints. 1 Is normal, 2 is Survival, 3 is Frenzy, 4 and other numbers are the menus
  Music(int gameType, int score) {
    if (gameType.equals ("1")) {
      //Normal music
      player1 = minim.loadFile("BH-Lightest.mp3");
      player2 = minim.loadFile("BH-Light.mp3");
      player3 = minim.loadFile("BH.mp3");
      //Stop menu music
      MenuPlayer.stop();
      //Normal Music choice
      if (score <= low) {
        player1.loop();
      } else if (score > low && score <= high) {
        player1.stop();
        player2.loop();
      } else if (score > high) {
        player2.stop();
        player3.loop(); 
      } else {}
      //For contingency purposes

    } else if (gameType.equals ("2")) {
      //Survival Music
      player1 = minim.loadFile("RY-Lightest.mp3");
      player2 = minim.loadFile("RY-Light.mp3");
      player3 = minim.loadFile("RY.mp3");
      //Stop menu music
      MenuPlayer.stop();
      //Survival Music choice
      if (score <= low) {
        player1.loop();
      } else if (score > low && score <= high) {
        player1.stop();
        player2.loop();
      } else if (score > high) {
        player2.stop();
        player3.loop(); 
      } else {}
      //For contingency purposes
    } else if (gameType.equals ("3")) {
      //Frenzy Music
      player1 = minim.loadFile("DY-Lightest.mp3")
      player2 = minim.loadFile("DY-Light.mp3")
      player3 = minim.loadFile("DY.mp3")
      //SurvivalMusic choice
      //Stop menu music
      MenuPlayer.stop();
      if (score <= low) {
        player1.loop();
      } else if (score > low && score <= high) {
        player1.stop();
        player2.loop();
      } else if (score > high) {
        player2.stop();
        player3.loop(); 
      } else {}
      //For contingency purposes
    } else {
      //Menu Music
      player1 = minim.loadFile(null)
      player2 = minim.loadFile(null)
      player3 = minim.loadFile(null)
      //Play Menu Music)
      MenuPlayer.loop();
    }
  }
}

Answers

  • edited July 2014 Answer ✓

    Either declare & initialize a field variable in the same statement like this:
    final Minim minim = new Minim(this);

    Or simply declare it and postpone the initialization part to some enclosing curly braces block later!

    Moreover, I believe that Minim's constructor demands a PApplet reference as its argument!
    Your class Music isn't exactly that! /:)

  • edited July 2014 Answer ✓

    As said, the line 10 is not legal in the declaration section of a class, it must go in the constructor, for example.

    Same for the line 15, you have to defer the initialization until minim is initialized.

    And the remark about this is correct, see the Technical FAQ, article Why I can't create an instance of a library from my own classes? for details and a solution...

    PS.: the lines 76 to 78 are strange! I doubt you can load a null file, can you?
    And the calls on MenuPlayer will give you trouble, it must be menuPlayer.

  • I have implemented these fixed, thank you.

    However, for some reason I'm getting an 'Expecting SEMI, got BeginSound' when I try to initialize it in the main file.

    I've looked all over and I can't find a semicolon missing.

    What am I doing wrong?

    //Import all Minim Controls and G4P controls
    import ddf.minim.spi.*;
    import ddf.minim.signals.*;
    import ddf.minim.*;
    import ddf.minim.analysis.*;
    import ddf.minim.ugens.*;
    import ddf.minim.effects.*;
    import g4p_controls.*;
    
    
    // Blicks main program
    // SDD Major Work
    // By ----------
    // Last Modified: 15/7/14
    
    class Blicks {
     void Blicks() {
    
      }
    }
    
     void setup() {
      size(800, 550);
      //initialize all the main menus
      mainMenu = new Menu("MainMenu", this);
      selectMenu = new Menu("GameSelect", this);
      helpMenu = new Menu("HelpScreen", this);
      creditsMenu = new Menu("CreditsScreen", this);
      quitMenu = new Menu("Quit", this);
     //show the main menu
      mainMenu.show();
      currentMenu = mainMenu;
      Music BeginSound = new Music(PApplet papp, 4, 0);
    }
    
    void draw() {
     if (currentMenu.menuBackground == null) {
        background(158, 207, 207);
     } else {
        image(currentMenu.menuBackground, 0, 0);
      fill(0);
      text(currentMenu.name, 20, 40);
      }
    }
    

    Also, on another point, I had an error in the Music file that said 'the function stop() does not exist.) It was referring to whenever I told a music file to stop playing and start playing another one. I fixed it by changing 'stop' to 'close', but what else could be causing the error?

  • edited July 2014

    Dunno exactly what is wrong, but line #33 is clearly wrong!
    We only declare a parameter type when defining a method, not when calling 1!
    Plus, I dunno where variable papp comes from either!

    ... that said 'the function stop() does not exist'.

    It means a library demands a callback method called stop() be present!
    You simply should define 1 for yourself -> void stop() {}

  • The Blicks class is wrong, too, the constructor doesn't have a type (void here).

    About line 33, try: Music beginSound = new Music(this, 4, 0); (but you don't use this local variable, anyway.

  • I have fixed this, but I am receiving an error when loading the main menu music file as it says that I am having a nullpointerexception, even though it's in the files' /data folder.

    I've even used datapath("mainMusic.mp3") and it doesn't work.

    Here is the offending code:

    public Music(PApplet papp, int gameType, int score) {
        pa = papp;   
        menuPlayer = minim.loadFile(dataPath("mainMusic.mp3"));
    
  • edited July 2014

    I am of the opinion that resources like images, audio, video, etc. should be loaded inside setup()!
    Then if need be, the reference to the already loaded resource passed to an object's constructor later! *-:)

  • edited July 2014

    Yes, but doing so means that I won't be able to call the player 'menuPlayer' outside of Game (which is where the only setup file is.)

    Is there another way of doing this? Or am I missing something?

  • As mentioned: Just pass the already-loaded resources' reference to the constructor! 8-X

  • edited July 2014

    Unfortunately, passing the reference into the constructor caused the code to break (syntax didn't let me.)

    I had to get rid of it from the constructor. This unfortunately meant that I had to move the menuPlayer thing back into the music file.

    Now, instead of a nullpointerexception error, I'm getting an 'unexpected token: menuPlayer' error in the code.

    What could be causing this error?

    EDIT: Just in case you need both codes in order to explain to me why I am really dumb or something:

    Game:

    //Import all Minim Controls and G4P controls
    import ddf.minim.spi.*;
    import ddf.minim.signals.*;
    import ddf.minim.*;
    import ddf.minim.analysis.*;
    import ddf.minim.ugens.*;
    import ddf.minim.effects.*;
    import g4p_controls.*;
    import processing.core.*;
    public int score = 0;
    
    // Blicks main program
    // SDD Major Work
    // By ---------
    // Last Modified: 16/7/14
    
    class Blicks {
      void Blicks() {
      }
    }
    Minim minim;
    void setup() {
      size(800, 550);
      //initialize all the main menus and Minim AND the Menu Music
      mainMenu = new Menu("MainMenu", this);
      selectMenu = new Menu("GameSelect", this);
      helpMenu = new Menu("HelpScreen", this);
      creditsMenu = new Menu("CreditsScreen", this);
      quitMenu = new Menu("Quit", this);
      final Minim minim = new Minim(this);
      //show the main menu
      mainMenu.show();
      currentMenu = mainMenu;
      Music beginSound = new Music(this, 4, 0);  <-------This is where the class is called
    }
    
    void draw() {
      if (currentMenu.menuBackground == null) {
        background(158, 207, 207);
      } else {
        image(currentMenu.menuBackground, 0, 0);
        fill(0);
      }
    }
    

    Music

    // Music Class for Blicks
    // SDD Major Work
    // By  --------
    // Last Modified: 16/7/14
    
    
    public class Music {
      //declare music files and create Audio Players - MenuMusic is for the menu
      AudioPlayer player1, player2, player3, menuPlayer;
      menuPlayer = minim.loadFile(dataPath("mainMusic.mp3"));
      //Constants for score
      int low = 1000;
      int high = 5000;
      //Loading PApplet to skip 'undefined' error
      private PApplet pa;
    
      //GameTypes are as ints. 1 Is normal, 2 is Survival, 3 is Frenzy, 4 and other numbers are the menus
      public Music(PApplet papp, int gameType, int score) {
        pa = papp;   
        if (gameType == 1) {
          //Normal music
          player1 = minim.loadFile("BH-Lightest.mp3");
          player2 = minim.loadFile("BH-Light.mp3");
          player3 = minim.loadFile("BH.mp3");
          //Stop menu music
          menuPlayer.close();
          //Normal Music choice
          if (score <= low) {
            player1.loop();
          } else if (score > low && score <= high) {
            player1.close();
            player2.loop();
          } else if (score > high) {
            player2.close();
            player3.loop();
          } else {
          }
          //For contingency purposes
        } else if (gameType == 2) {
          //Survival Music
          player1 = minim.loadFile("RY-Lightest.mp3");
          player2 = minim.loadFile("RY-Light.mp3");
          player3 = minim.loadFile("RY.mp3");
          //Stop menu music
          menuPlayer.close();
          //Survival Music choice
          if (score <= low) {
            player1.loop();
          } else if (score > low && score <= high) {
            player1.close();
            player2.loop();
          } else if (score > high) {
            player2.close();
            player3.loop();
          } else {
          }
          //For contingency purposes
        } else if (gameType == 3) {
          //Frenzy Music
          player1 = minim.loadFile("DY-Lightest.mp3");
          player2 = minim.loadFile("DY-Light.mp3");
          player3 = minim.loadFile("DY.mp3");
          //SurvivalMusic choice
          //Stop menu music
          menuPlayer.close();
          if (score <= low) {
            player1.loop();
          } else if (score > low && score <= high) {
            player1.close();
            player2.loop();
          } else if (score > high) {
            player2.close();
            player3.loop();
          } else {
          }
          //For contingency purposes
        } else {
          //Menu Music
          player1 = minim.loadFile("null.mp3");
          player2 = minim.loadFile("null.mp3");
          player3 = minim.loadFile("null.mp3");
          //Play Menu Music)
          menuPlayer.loop();
        }
      }
    }
    
  • Move line 10 of Music to the constructor, you cannot have instructions (non-declarations) outside of a function / method.

  • Since I have moved the line back into the constructor, I am receiving the 'nullpointerexception' error again.

    As you can see, I'm still pretty new at processing - can you point out how I can import the music from the main menu into the constructor and avoid the syntax error?

  • edited July 2014

    By chance, Is your Music class in a ".pde" or ".java" suffixed tab? :-/
    A ".java" tab is for an independent top-class and can't directly access the regular ".pde" tabs!

    You can also take a look at this thread:
    http://forum.processing.org/two/discussion/5616/program-tabs

  • The music class is in a .pde file.

  • edited July 2014

    So you don't need to get a PApplet for your Music nested class!
    I see that you use a variable called minim a lot inside Music. However minim was defined at the top sketch!
    Funnily, you use that only to loadFile() for some fields called player1/2/3 & menuPlayer.

    I advise you to load those resources inside setup() and pass those references to your Music's constructor.
    This way your class focus on using the resources rather than worry about getting them.
    Also, resources shouldn't be loaded more than once, since it's a fairly slow operation!

  • edited July 2014

    The Music class isn't a problem, there is only one instance of it. And even a nested class can need a reference to the parent PApplet. Although this class doesn't use this field!

    The issue I overlooked previously is the line 30. There, you re-declare Minim, shadowing the global one (used in the class) which then remains null.

    See the second article of the Technical FAQ.

  • So would you suggest I have multiple player1, player2 and player 3s in setup, then call them as necessary? (e.g player1a, player1b, player1c)

  • edited July 2014

    I mean load them in setup(), but pass them to your class.
    The fields themselves stay in the class. And the passed parameters are assigned to them in the constructor!

    P.S.: Don't invoke close() on your AudioPlayer objects. Lest you'd have to reload them over again!
    Rather, use pause() &/or rewind()! ;)

  • edited July 2014

    Well, i did 2 static classes: 1 for loading the audio called MusicLoader and the other to play them called Music.
    Dunno whether it's working or not since apparently Minim doesn't work w/ my 64-bit OpenJDK 7 in Linux! :o3
    So you've gotta check it out for yourself. Good luck: %%-

    /**
     * Music Loader (v2.11)
     * by  FlandersNed (2014/Jul)
     * mod GoToLoop
     *
     * forum.processing.org/two/discussion/6328/minim-library-error-unexpected-token
     */
    
    import ddf.minim.Minim;
    import ddf.minim.AudioPlayer;
    
    void setup() {
      size(800, 550, JAVA2D);
      smooth(4);
      frameRate(60);
    
      MusicLoader.initialize(new Minim(this));
      Music.startMenuPlay();
      println(Music.displayCurrentPlay());
    }
    
    static final class MusicLoader {
      static final String EXT = ".mp3";
      static final String MENU_FILE = "mainMenu" + EXT;
    
      static final String[] STYLE_NAMES = {
        "BH", "RY", "DY"
      };
    
      static final String[] BEAT_NAMES = {
        "-Lightest", "-Light", ""
      };
    
      static void initialize(Minim minim) {
        AudioPlayer[][] tracks = new AudioPlayer[Music.STYLES][Music.BEATS];
    
        for (int i = 0; i != Music.STYLES;) {
          AudioPlayer[] beats = tracks[i];
          String style = STYLE_NAMES[i++];
    
          for (int j = 0; j != Music.BEATS; beats[j] =
            minim.loadFile(style + BEAT_NAMES[j++] + EXT));
        }
    
        Music.initialize(minim.loadFile(MENU_FILE), tracks);
      }
    }
    
    static final class Music {
      static final int STYLES = 3, BEATS = 3;
      static final int LOW = 1000, HIGH = 5000;
    
      protected static int currentStyle, currentBeat;
      protected static AudioPlayer menuPlayer, players[][];
    
      static void initialize(AudioPlayer menu, AudioPlayer[][] sounds) {
        menuPlayer = menu;
        players = sounds;
      }
    
      static void startMenuPlay() {
        stopCurrentPlay();
        menuPlayer.loop();
      }
    
      static boolean stopMenuPlay() {
        if (!menuPlayer.isPlaying())  return false;
    
        menuPlayer.pause();
        menuPlayer.rewind();
    
        return true;
      }
    
      static void startCurrentPlay() {
        players[currentStyle][currentBeat].loop();
      }
    
      static boolean stopCurrentPlay() {
        AudioPlayer ap = players[currentStyle][currentBeat];
        if (!ap.isPlaying())  return false;
    
        ap.pause();
        ap.rewind();
    
        return true;
      }
    
      static boolean changeCurrentStyle(int style) {
        if (style == currentStyle)  return false;
    
        stopCurrentPlay();
        currentStyle = constrain(style, 0, STYLES-1);
        startCurrentPlay();
    
        return true;
      }
    
      static boolean changeCurrentBeat(int beat) {
        if (beat == currentBeat)  return false;
    
        stopCurrentPlay();
        currentBeat = constrain(beat, 0, BEATS-1);
        startCurrentPlay();
    
        return true;
      }
    
      static boolean chooseCurrentBeat(int score) {
        return changeCurrentBeat(score < LOW? 0 : score < HIGH? 1 : 2);
      }
    
      static String displayCurrentPlay() {
        AudioPlayer ap = players[currentStyle][currentBeat];
    
        return ap.getMetaData().fileName() + " - " + ap.position()/1000
          + "/" + ap.length()/1000;
      }
    }
    
  • Thank you for the help.

    To get this to work, do I move the stuff from your setup() and draw() to my setup() and draw()?

  • 1st of all, have you been able to run it the way it is now above?
    It's supposed to load all your 10 ".mp3" files and start playing the "mainMenu.mp3" 1.
    And display an info about it too.
    Only then a transfer of it to your original code can take place!

    As you can see, I just worried about implementing load and play selection for the ".mp3" files. Nothing more!

  • Oh, ok then.

    I'll export the music files from the creator and try it; I'll get back to you.

  • Alright, I've created the music so that it can loop, but when I run the file, it doesn't play anything.

  • Does it say anything about not able to load some file, like "mainMenu.mp3" @ line #45?
    Music.initialize(minim.loadFile(MENU_FILE), tracks);

  • edited July 2014

    This is the only thing in the log:

    ==== JavaSound Minim Error ====
    ==== Don't know the ID3 code APIC
    
    BH-Lightest.mp3 - 0/8
    

    On another note, do you think that the frame rate will change the speed of the music?

    As in, the game may need to be slowed down to 10fps in order for it to play nice.

  • Is that from my example? I try to play "mainMenu.mp3". Not "BH-Lightest.mp3"! /:)
    I believe Minim plays audio using a separate thread. So it doesn't interfere w/ Processing's main "Animation Thread"!

  • I also got this:

    ==== JavaSound Minim Error ====
    ==== Error invoking createInput on the file loader object: null
    

    I believe Minim, which is a wrapper for JavaSound, doesn't work w/ OpenJDK.
    I guess I'd need to install Oracle's original Java! :-q

  • It was from your example. The only thing I did was put my music files into the data folder of that example.

  • edited July 2014

    Picked some ".mp3" file and renamed it to "mainMenu.mp3".
    Got this IllegalStateException: Line must be open()ed before it can be start()ed.

    Whole error dump:

    ==== JavaSound Minim Error ====
    ==== Couldn't open the line: null
    
    ==== JavaSound Minim Error ====
    ==== Unable to return a SourceDataLine: unsupported format - 
         PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
    
    ==== JavaSound Minim Error ====
    ==== Don't know the ID3 code USLT
    
    ==== JavaSound Minim Error ====
    ==== Don't know the ID3 code Mmo�
    
    ==== JavaSound Minim Error ====
    ==== Error parsing ID3v2: -633347870
    
    ==== JavaSound Minim Error ====
    ==== Couldn't open the line: null
    
    ==== JavaSound Minim Error ====
    ==== Unable to return a SourceDataLine: unsupported format - 
         PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
    
    java.lang.NullPointerException
        at processing.mode.java.runner.Runner.findException(Runner.java:947)
        at processing.mode.java.runner.Runner.reportException(Runner.java:892)
        at processing.mode.java.runner.Runner.exceptionEvent(Runner.java:818)
        at processing.mode.java.runner.Runner$2.run(Runner.java:707)
    
  • I'm sorry; I'm not really that good at processing. What exactly does this mean?

  • It means Minim doesn't work for me! Just reporting the error messages I've got! 8-|

  • edited July 2014

    @FlandersNed: If you have problems with a MP3, try your program with the MP3s coming with Processing: if it still doesn't work, the issue is with your code. If it works, you have to change the encoding of your MP3, perhaps.

  • edited July 2014

    Nope. Not even the Minim's examples w/ ".mp3"s themselves work for me! :-&
    That's why I need some1, whose Minim works alright, to test my program!
    Gonna need 10 ".mp3" files though w/ the right names! :P

Sign In or Register to comment.