I have a problem with playing more than 2 sound files in a game I'm developing now in j2me MIDP2 in eclipse.
Please advice me the best way for playing multiple "wav" sound files.
I created the following method that is called once when the program starts
public void setSound()
{
System.out.println("Sound on");
try {
p1=Manager.createPlayer(is1, "audio/X-wav");
p2=Manager.createPlayer(is2, "audio/X-wav");
p3=Manager.createPlayer(is3, "audio/X-wav");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MediaException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
and every time I need to play one of the sounds I stop the two other players (to insure that no one of them is running p2.stop(); p3.stop();) and start the third one (p1.start();) and every time I have two players stopped (being in PREFETCHED State) the third one is not running and exceptions are thrown.
The Java ME spec is not specific about this, but on actual devices you can usually have only one allocated player at a time, so just stopping a player is not enough. See also this forum post. I found it is a challenge even to deallocate a player properly before playing a new one, so in my own code I resorted to waiting for one sound to end before trying to play a new one.
in j2me there is only one player.More than 1 players are not supported.How execute the sound one sound after another or any other.If u want playing multiple sounds means then u follow the below coding
public class AudioPlayer implements javax.microedition.media.PlayerListener{
Player player;
int count=0;
public void playMedia(){
try{
player = Manager.createPlayer(getClass().getResourceAsStream(audioFiles[count]),"audio/x-amr");
player.addPlayerListener(this);
player.start();
}
catch (Exception e) {
return ;
}
}
public void playerUpdate(Player p,String event,Object eventData)
{
//Playing next audio file after completion of current audio.
}
}
Related
Ok I'm currently doing a Trivial Pursuit game project with javafx and my group wants me to add audio the problem is I have a method
public static void playSoundEffect(Sound sfx) {
Media media=null;
try {
media = new Media(GameAudio.class.getClassLoader().getResource(sfx.getSound()).toURI().toString());
mediaPlayer = new MediaPlayer(media);
mediaPlayer.play();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
But it has its issues because if I want to mute all the audio, only the last played sound will be muted and not the whole project's audio.
I was thinking of making 2 List of MediaPlayer(SFX and Music) that contains each audio files but I'm not sure how to set this up properly... My current try was using Enum for the const strings containing the path. Then in some class i use the method above to play the sound at a certain point. But since i always call a new instance of mediaPlayer I don't have any control on it anymore and that's why I'm so lost.
As #James_D supposed for the mute I will use a BooleanProperty muted and call a method mediaPlayer.muteProperty().bind(muted) on each mediaplayer created.
I am looking for a way to display images on my ListField from a background thread. First in my drawListRow i try this
path = (String) imagePaths.elementAt(index);
bit = connectServerForImage(path);
g.drawBitmap(xText, y + yText, 80, 200, bit, 0, 0);
but can't scroll smoothly throughout the list, and they say do not do networking or other blocking operations on the UI. But i also try this
private class imgConnection extends Thread
{
public imgConnection() {
super();
}
public void run() {
try {
for (int i = 0; i < imagePaths.size(); i++)
{
final int index = i;
String path = imagePaths.elementAt(index).toString();
bit = connectServerForImage(path);
image.addElement(bit);
}
}
catch (Exception e)
{
System.out.println(e.toString());
}
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_list.setSize(image.size());
subManager.add(_list);
screen.invalidate();
}
});
}
}
public void drawListRow(ListField list, Graphics g, int index, int y, int w) {
bit = (Bitmap) image.elementAt(index);
g.drawBitmap(xText, y + yText, 80, 200, bit, 0, 0);
}
but nothing happens. Any idea, comments.
You are right, i just started java development 2 weeks ago particularly BB development and i try this link. I want to add a background thread to download image after i got the path url from json return.
first thread:
_connectionthread = new Connection();
_connectionthread.start();
private class Connection extends Thread
{
public Connection()
{
super();
}
public void run() {
try {}
catch (Exception e) {}
}
}
second thread:
_imgConnectionThread = new ImgConnection();
_imgConnectionThread.start();
private class ImgConnection extends Thread
{
public ImgConnection() {
super();
}
public void run() {
try {
}
catch (Exception e)
{
}
}
}
how to update images on ListField?
Answer is based on code from - pastebin.com/90UKTHzP
Terrible code! It's really hard to read and undersand! It looks like you copy pasted several examples from different locations. Also you overriding default behavior with same behavior. Also MainScreen already has VerticalManagerField. Also you're adding list every iteration to manager which will cause IAE. And main one thread is depended on result of second one. They start at the same time, but getting json from server and it's processing could take longer time, so image thread most probably will finish his run without any result.
So main recommendation to fix it - read clean code book! Read more about java development - conventions, multithreading. Read about BB development - UI api, networking.
And finally - start only one thread to get and parse json. After you get it finished - start another thread to get images.
There some minor things that could save you more battery and processor time also - start loading images on demand - when it painted or going to be painted (user scrolls list).
By convention, Java class names start with a capital letter, so imgConnection should really be ImgConnection.
In your sample code, I don't see imgConnection being instantiated anywhere, and I don't see any call to Thread.start(), which is the way a thread i started. Without Thread.start() it is not surprising nothing is happening - the thread is never starting.
I have problem restart sound in J2ME. I want to create player in constructor, then call playExplosion() to play it, but it only plays once. I'm using Wireless Toolkit.
Sound class
public class Sound () {
private Player playerExplosion;
public Sound() throws IOException, MediaException {
// Explosion
InputStream is = getClass().getResourceAsStream("/explosion.mid");
playerExplosion = Manager.createPlayer(is, "audio/midi");
playerExplosion.realize();
playerExplosion.setLoopCount(1);
}
public void playExplosion() {
try {
System.out.println(playerExplosion.getState());
playerExplosion.start();
} catch (MediaException ex) {
ex.printStackTrace();
}
}
}
MyMIDlet class
public class MyMIDlet extends MIDlet() {
public Sound sound;
public MyMIDlet() {
// Init sound object
try {
sound = new Sound(this);
} catch (Exception ex) {
ex.printStackTrace();
}
// Test
System.out.println("Start");
for (int i = 0; i < 5; i++) {
sound.playExplosion();
// My sound is less than 1 second.
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("End");
}
}
Output
Start
200
300
300
300
300
End
For the 1st time, playerExplosion state before start() is 200 (REALIZED).
For the 2nd, 3rd, 4th, 5th times, playerExplosion state before start() is 300 (PREFETCH).
At the moment, I have to create playerExplosion again in playExplosion() method, but it's too slow in a real device.
Try after removing
playerExplosion.setLoopCount(1);
Realizing a Player can be a resource and time consuming process havint to create playerExplosion would mean calling playerExplosion.realize(); again that is why the process takes so much time
When your player is in PREFETCHED State what you need to do is just call playerExplosion.start(); but its not paying again because there is a general limitation on the number of times its should pay
Remove
playerExplosion.setLoopCount(1);
And you would be able to pay your file several times
Thanks
:)
I am developing a Java-ME Based Mobile Application. Now My Requirements are like whenever I am updating one of my RMS, I want my application to be stay in a Freeze kind of mode; which means no other action like clicking button or anything else should happen. My Method is already "Synchronized".
Kindly guide me regarding this question.
Thanks.
The best way to handle this is to "serialize" your tasks. You can do this with a message queue - a class that maintains a Vector of message objects (tasks) and runs code based on each message. The queue runs on a thread that processes each task (message) in series. You create a simple message class for the different tasks - read RMS etc. A message can be an Integer if you like that wraps a number. The operation of adding and retrieving messages is synchronized but the code than does the tasks is not and runs on a simple switch block. The benefit of serializing your tasks is you don't have to worry about concurrency. Here is some of the essential code from a class I use to do this.
class MessageQueue implements Runnable{
Vector messages;
Thread myThread;
volatile boolean stop;
public void start() {
stop=false;
myThread=new Thread(this);
myThread.start();
}
// add message to queue - this is public
public synchronized void addMessage(Message m) {
messages.addElement(m);
if(stop) {
start();
} else {
// wake the thread
notify();
}
}
// get next message from queue - used by this thread
private synchronized Message nextMessage() {
if(stop) return null;
if(messages.isEmpty()) {
return null;
} else {
Message m=(Message)messages.firstElement();
messages.removeElementAt(0);
return m;
}
}
public void run() {
while (!stop) {
// make thread wait for messages
if (messages.size() == 0) {
synchronized (this) {
try {
wait();
} catch (Exception e) {
}
}
}
if (stop) {
// catch a call to quit
return;
}
processMessage();
}
}
}
// all the tasks are in here
private void processMessage() {
Message m = nextMessage();
switch (m.getType()) {
case Message.TASK1:
// do stuff
break;
case Message.TASK2:
// do other stuff
break;
case Message.TASK3:
// do other other stuff
break;
default: //handle bad message
}
}
}
What you are asking is very code depended. Usually when you want to make some synchronic actions you just write them one after the other. in java it's more complected, since sometimes you "ask" the system to do something (like repaint() method). But since the RMS read/write operations are very quick (few millisecond) i don't see any need in freesing.
Could you please provide some more information about the need (time for RMS to respond)? does your code runs on system thread (main thread) or your own thread?
I want my application to be stay in a Freeze kind of mode; which means no other action like clicking button or anything else should happen.
First of all I would strongly advise against real freezing of UI - this could make a suicidal user experience for your application.
If you ever happened to sit in front of computer frozen because of some programming bug, you may understand why approach like this is strongly discouraged. As they describe it in MIDP threading tutorial, "user interface freezes, the device appears to be dead, and the user becomes frustrated..."
This tutorial by the way also suggests possibly the simplest solution for problems like you describe: displaying a wait screen. If you don't really have reasons to avoid this solution, just do as tutorial suggests.
To be on a safe side, consider serializing tasks as suggested in another answer. This will ensure that when RMS update starts, there are no other tasks pending.
I want to play a audio file from the internal speaker (that from which comes the voice during a call) it's possibile ?
Use the setSpeakerphoneOn method of the AudioManager. This requires the MODIFY_AUDIO_SETTINGS permission.
audioManager = (AudioManager)Context.getSystemService(Context.AUDIO_SERVICE);
audioManager.setSpeakerphoneOn(false);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
Question is a bit old. Anyhow, this method may help others:
public void play(MediaPlayer player, String filePath){
try {
player.setDataSource(filePath);
player.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
player.prepare();
player.start();
} catch (IOException e) {
e.printStackTrace();
}
}