We are about to switch to a new forum software. Until then we have removed the registration on this forum.
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
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! /:)
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 bemenuPlayer
.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?
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?
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!
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:
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! *-:)
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
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:
Music
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?
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.
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!
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)
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()! ;)
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: %%-
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);
This is the only thing in the log:
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:
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.
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:
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-|
@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.
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