We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi, If it is possible, I would use Minim in another class, and not in setup(). Is it possible? Because this code say "NullPointerException" at line 29
Music m;
void setup(){
size(100,100);
m = new Music();
m.start();
}
void draw(){
}
//============================
//another file where I use Minim
import ddf.minim.spi.*;
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.ugens.*;
import ddf.minim.effects.*;
class Music{
Minim minim;
AudioPlayer song;
Music(){
minim = new Minim(this);
song = minim.loadFile("asaf.mp3");
}
void start(){
song.play();
}
void stop(){
song.close();
minim.stop();
// super.stop();
}
}
Answers
That could work but Minim needs a PApplet as argument for its constructor, not a Music.
this
inside a class is contextual in Java.this
means some instance of type Music.A much better sane option is simply pass an already loaded AudioPlayer to Music's constructor. :-\"
(bad idea)
It is usual to have a single Minim object. So declare
minim
globally, create it with new inside setup and pass it to the Music constructor with the music file name.The Music class should keep the AudioPlayer field and this would be created in the constructor. This makes sense so that you can control the playback through the Music object.
It does not make sense to create a loaded AudioPlayer outside the class and pass it to the constructor because you would have to do his for every Music object.
@colouredmirrorball thanks! It works now! =D> :)
new Music(this);
.new Music(minim.loadFile("asaf.mp3"));
.Obviously it depends on what the sketch creator wants but to me ...
It does not make sense to share AudioPlayer objects between instances of Music because you cannot control individual Music objects. If you stop one and it stops all Music objects that share the AudioPlayer.
It does not make sense for the Minin instance being a local variable of setup. You might want the user to select the music file at runtime so you would need the
minim
object to be available outside the setup method.I generally avoid keeping tracking of things that won't be accessed later.
That's why we use local variables for after all!
If the need arises later on, it's just as simple as turning the local variable a field. :-\"
Perhaps in his particular sketch there won't be any need to share resources among those Music instances. However it's still good practice to do so nonetheless! L-)
Let's say we got a sketch w/ some Button instances shown in the canvas.
And there are some AudioPlayer to be assigned for diff. types of Button.
Some Button objects needs to play a "confirmation" sound, while others an "error" sound.
It makes total sense for them to share a particular AudioPlayer sound resource rather than each 1 load the very same file over & over! [-(
Of course that assumes there is not already a field with the same name :-\"
Well, of course I've meant that the declaration should go from local scope to global scope! :-@
But I still need to witness some case where the Minim instance was really needed after setup()! :P
Can't make the local declaration global if there is already a field with the same name.
Re-read it: "If the need arises later on, it's just as simple as turning the local variable a field."
Turning some local variable a field automatically implies removing the local declaration and placing that to the "global" scope! Only its assignment stays "local"! ~O)
Perhaps you misunderstood my statement so let me explain in more detail.
If this code is part of a larger sketch
You can't simply promote
int s
to a field because the identifier has already been used. Would have to change the local variable identifier throughout the setup method before promoting it.Although it is good practice to keep variable scope as small as possible it should be done in the context of the program design design.
I have re-read this entire discussion and I stand by my original post. Everything else that follows is waffle.
It makes sense to have a single instance of Minim because it is accessing the sound hardware resources so we must be certain to release them correctly. Multiple instances of Minim make it difficult to ensure all resources are released. The best way of making
minim
generally available is to make it a field.It makes sense that each Music object has its own AudioPlayer object so that each Music object can be started independently. The example you give showing the AudioPlayer object being shared is a disaster waiting to happen
means that
musics [0].stop()
also stopsmusics[2]
in fact you would get exactly the same thing if you replaced the last line withmusics[2] = musics [0];
A good reason for not sharing AudioPlayer objects.
From your post I assume you have two tabs (files) so here is my solution to your problem.
Although it is possible to shorten the code a little there is no need to. Clarity is more important than reducing the code base.
Main tab:
Music.java tab
Thanks for answers @quark and @GoToLoop, It is for a project for university's exam and I do a little animation with music track, but this weeks I didn't have much time, sorry. Anyway thanks again ^:)^