I'm trying to make a short arcade-like beep sound whenever the user clicks a movement button for a game. for this, I tried to use the code I always use to make audio:
in the MainActivity class I declared
MediaPlayer bpress;
in the OnCreate function
bpress = MediaPlayer.create(getApplicationContext(), R.raw.blop);
and in the OnClick
if (view == left) {
bpress.start();
}
and it does work, but the volume of the sound isn't consistent - it often plays on half the volume or becomes barely audible.
I tried switching to a different, longer audio file to see if the problem comes from the short length of the beep sound, but the problem remains.
Therefore, I'm almost certain that the problem is related to the fact that said buttons are pressed quickly, and many times. but I don't know why it happens or how to fix it
Here is the solutions to the problem.
Put this chunk of code inside your onClick listener
Solution 1:
mpBlob.stop();
try {
mpBlob.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mpBlob.start();
Solution 2:
if(mpBlob.isPlaying()) {
mpBlob.stop();
mpBlob.release();
mpBlob = MediaPlayer.create(getApplicationContext(), R.raw.blob);
}
mpBlob.start();
Related
When I press back button on android, it exits the game although I ask it to go to other screen instead. It goes to the other screen for one or two seconds then it exits.:
if((Gdx.input.isKeyPressed(Input.Keys.BACK)))
game.setScreen(new GameOverScreen(game,4));
if(controller.isresumePressed())
{
controller.table2visible(false);
controller.table1visible(true);
pausestate = false;
}
You also need to tell LibGDX to catch the back key from Android. This only needs to be done once so you can do this in the onCreate() method of your main class.
Gdx.input.setCatchBackKey(true);
I was wondering if releasing my media player before I play a random sound is bad practice:
So I don't usually deal with media output too much, but I am making a simple app that plays a random sound every time a button is clicked (sounds [] is an array filled with raw media files)
public void onClick(View v){
if(mediaplayer != null){
mediaplayer.release();
}
mediaplayer = MediaPlayer.create(this, sounds[randomNum])
mediaplayer.start();
}
So my question is, would releasing my media player every time before creation be considered good/bad practice? Would there be any better way to do this, as releasing and re-initializing the MediaPlayer object seems like it would consume resources...
Thanks,
Ruchir
You typically use release() when you no longer want to use a MediaPlayer any more. Once you call that, it can never be used again. It effectively destroys the native components that back its functionality.
If you do release, you will have to prepare the media all over again the next time you want to play it. This can be a time consuming process. If you want a sound to play responsively to a button press, you probably don't want to have to prepare it each time.
When two audio's are played at the same time...the sound is canceling out. How do I fix this weird phenomenon?
I have some code where there is audio on button click and audio in ten second intervals (in a background service). I have the following code to stop the button audio when the ten second interval plays, and it works fine:
public static void myPop(Context context){
AudioManager manager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
if(!manager.isMusicActive()) { //Only if there isn't any other audio playing
MediaPlayer pop = MediaPlayer.create(context, R.raw.pop);
pop.start();
}
else{
Log.v(TAG, "Audio is already playing");
}
}
This works fine, and it stops one audio from playing (pop) to let the other audio play(The one from the background service). Now, I am getting the issue when they both play at the same time. For example, when I tap the button at the exact same time as when the audio from the background service is about to start. when they are both played at the same time, the audio just gets cut off
Is there any way to give a preference to the background service audio? Somehow say that: If two audio pieces start at the exact same time, I want to let the background service audio to play.
To think of this visually:
(https://upload.wikimedia.org/wikipedia/en/4/49/Preference_example.jpg)
I want to say that if I have the choice between apples and oranges, pick apples. AKA If I have two audioplayers playing at the same time, pick one (the apple).
Thanks for your help,
Ruchir
You may have a race condition. In these three lines
1 if(!manager.isMusicActive()) {
2 MediaPlayer pop = MediaPlayer.create(context, R.raw.pop);
3 pop.start();
Between line 1 and line 3, there is opportunity for another player to get the media player and start playing, especially if line 2 is slow.
I would suggest making one media player that both players access (i.e. create the "MediaPlayer pop" elsewhere and share it), or find another way to synchronize the different players. Perhaps issuing a stop right before a play, rather than checking for play state.
You can use code for play or pause audio when other player start or pause.
AudioManager.OnAudioFocusChangeListener afChangeListener =
new AudioManager.OnAudioFocusChangeListener() {
public void onAudioFocusChange(int focusChange) {
if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT) {
// Pause playback
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
// Resume playback
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
am.abandonAudioFocus(afChangeListener);
// Stop playback
}
}
};
For more referernce
http://developer.android.com/training/managing-audio/audio-focus.html
I am looking for a simple way to implement a mute button.
Obviously I could have a toggle button, mute_button and in every instance where a sound is played I could check:
if(mute_button.isChecked()){
//dont play
}else{
//play the sound
}
But I have a lot of instances that I would need to sort through and add this in. Is there a simpler way of something along the lines of:
mute_button.setOnClickListener() ...
onClick
if(isChecked){
//set entire application to mute mode
}else{
//keep default application sound settings
}
So, really I am looking for a "higher level" or application wide mute, rather than checking if a button is checked every single time a sound may play.
You can try by setting the media volume to zero
MediaPlayer media = MediaPlayer.create(this, R.raw.backgroundSound);
//media.setVolume(leftVolume , rightVolume);
media.setVolume(0 , 0);
For soundpool you can try like this:
soundpool.setVolume(streamID, 0f, 0f);
My app plays a coin sound every time a button is pressed.
coin_sound.start();
You can easily press faster than the coin sound. When this happens I want the coin sound to start from the beginning ever time the button is pressed.
if(coin_sound.isPlaying()){
coin_sound.reset();
coin_sound = MediaPlayer.create(getContext(), R.raw.coin02);
}
coin_sound.start();
The problem with this is that loading a media file tiny as it may be is still a relatively slow process. When you start to click the button really fast the app lags hard.
Are there any solutions to my problem? The only idea I have is to do something with an array of coin_sounds, but this method seems like it will be messy and gross...
The other answer posted here is somewhat correct. You should not call create over and over.
The code in that answer has a problem, though. The reset method sends the MediaPlayer into the idle state, where it is illegal to call most other methods. If you were to go that route, you have to call methods in the following order:
coin_sound.reset();
coin_sound.setDataSource(...);
coin_sound.prepare();
coin_sound.start();
The difference between calling create and the previous sequence of method calls is simply the creation of a new instance. That, however, is not the quickest way to do what should be done.
You should simply call coin_sound.seekTo(0); when you want the current playing sound to restart. So do something like:
if (coin_sound.isPlaying()) coin_sound.seekTo(0);
else coin_sound.start();
That assumes you have left the MediaPlayer in the prepared state so start can be called. You can accomplish that by calling reset, setDataSource, and prepare in the onCompletion listener. Also, make sure to call release when the sound is no longer needed.
It is because you are initiating coin_sound in the button click event, try this
initiate this variable in your oncreate method
coin_sound = MediaPlayer.create(getContext(), R.raw.coin02);
then make this your code for your button
if(coin_sound.isPlaying()){
coin_sound.reset();
}
coin_sound.start();
the problem is you are recreating a new media player each time the button is clicked so the new media player doesnt think there is a sound
and do you need to start it again with coin_sound.start();? doesnt restart stop then start the sound for you?