I recently added simple looping background music to my Android game. It uses Canvas to draw to the screen, so I am very careful about optimizing performance. I added music using the standard MediaPlayer which seems to be the most common and easiest way to handing looping music. Unfortunately, I'm having trouble with the music skipping occasionally and, far worse, sometimes causing significant lag in the game play.
My only phone to test on is a Droid Eris, which is a fairly old phone, so I suspect this would not be an issue on newer Android phones, but I would like my game to be playable on all Android devices. What can I do to add music while maintaining reasonable performance?
This is the code I added:
// in setup() method of game thread
mediaPlayer = MediaPlayer.create(context, R.raw.rl_theme);
mediaPlayer.setLooping(true);
mediaPlayer.start();
// in method called when the player looses
mediaPlayer.stop();
mediaPlayer.release();
I have not ever had this issue, so I am not positive, but I think SoundPool is what you're looking for.
http://developer.android.com/reference/android/media/SoundPool.html
It looks like there isn't much you can do. Yes, adding music does slow Android apps down some, but it doesn't seem to be a major issue on newer phones. I did change the format of the audio files from OGG to MP4 to fix what appears to be a bug in the Android MediaPlayer (still looking into it, but the media server was crashing on OGG and works perfectly with MP4) and the performance seems to have gotten better. I'm not sure if that's related, though.
Related
I am making a game for android which needs to play a small beep whenever a user touches a certain object.
To do this I have this simple code to create the media player. beep is a small .ogg file of ~1.5 sec length.
MediaPlayer mp = MediaPlayer.create(getContext(), R.raw.beep);
mp.setVolume(0.5f, 0.5f);
and use it like this
mp.start();
The problem I am having is that my game uses the android canvas, and the thread which draws to the canvas also calls mp.start(). I have discovered that playing the sound is taking quite a lot of time, and it is very varied in how long it takes. Sometimes 1ms, sometimes 15ms. This appears to be causing my game to noticeably lag a little bit, as the android canvas is pretty slow anyway.
I've had a look at the logs and I don't appear to having garbage collection causing the delay. I'm wondering if anyone can give me some advice to reduce this delay
EDIT - I've just discovered that MediaPlayer is designed for longer sound files, and SoundPool is better for shorter audio files. However, I load the file into the mediaPlayer only once, so I don't see how it should make any difference. I will test it out though
sorry for my english
Use SoundPool instead of MediaPlayer cause MediaPlayer need releasing memory after each call or call method mp.release() after each call of player
SoundPool tutorial here
I'm currently implementing a sound effect mixing on Android via OpenSL. I have an initial implementation going, but I've encountered some issues.
My implementation is as follows:
1) For each sound effect I create several AudioPlayer objects (one for each simultaneous sound) that uses an SLDataLocator_AndroidFD data source that in turn refers to an OGG file. For example, if I have a gun firing sound (lets call it gun.ogg) that is played in rapid succession, I use around 5 AudioPlayer objects that refer to the same gun.ogg audio source and also the same outputmix object.
2) When I need to play that sound effect, I search through all the AudioPlayer objects I created and find one that isn't currently in the SL_PLAYSTATE_PLAYING state and use it to play the effect.
3) Before playing a clip, I seek to the start of it using SLPlayItf::SetPosition.
This is working out alright so far, but there is some crackling noise that occurs when playing sounds in rapid succession. I read on the Android NDK newsgroup that OpenSL on Android has problems with switching data sources. Has anyone come across this issue?
I'm also wondering if anyone else seen or come up with a sound mixing approach for OpenSL on Android. If so, does your approach differ from mine? Any advice on the crackling noise?
I've scoured the internet for OpenSL documentation and example code, but there isn't much out there with regards to mixing (only loading which I've figured out already). Any help would be greatly appreciated.
This is probably not the best approach (creating many instances of audio players). Unfortunately the Android version (2.3) of OpenSL ES doesn't support SLDynamicSourceItf. Which would be similar to OpenAL's source binding interface. One approach would be to create multiple stream players. You would then search for a stream player that isn't currently playing and start streaming your sound effect to it from memory. It's not ideal but it's doable.
You should probably not use the ogg format for sound effects either. You're better off with WAV (PCM) as it won't need to be decoded.
Ogg is fine for streaming background music.
I am develping a media player for my learning purpose and I want to have crossfading feature in media player app. But I don't have clue where to start from. i tried searching on inernet but no luck. I am using Android MediaPlayer class for all media player related operation. Anyone know any workaround to achieve the same.
thanks for your support
Try to use the AudioTrack instead of MediaPlayer. Generally, I'd suggest the following plan:
Learn some sources for an app that uses AudioTrack. A good player can be found here
This is an aac audio player that uses JNI for aac-audio decoding.
Find a MP3 decoding library. The library should be a Java one (look at this for example, or it is possible there are another libraries (I did not use such java libraries)) or a C/C++ library (in this case you also will use it through JNI).
When you will get simple working MP3 player, add manual crossfading (this should be easy, if you aware of basics of digital audio).
Try to use two objects of MediaPlayer one after another with crossfade, like in this class https://github.com/psaravan/JamsMusicPlayer/blob/f165057dd664727ed06b9fac2c27557e5fb7e7ee/jamsMusicPlayer/src/main/java/com/jams/music/player/Services/AudioPlaybackService.java
When second mediaPlayer stars first pauses for while (On some devices mostly on samsung )so transition is not smooth. MediaPlayer has this issue and its been reported to google since long ago but still not resolved(https://issuetracker.google.com/issues/36931073) so we can do nothing about it. So I used Exoplayer for playing audio and it works very smoothly without any pause.
I released my first Android app two weeks ago (an MMO called Agent Syndicate) and everything has been working well, except for sounds and music!
Using standard MP3 files created in Sony's Sound Forge Pro 10 at 128kps, I immediately received reports from many users complaining about Force Close issues on a wide variety of handsets, mostly running Android 2.1 and 2.2. I released a new version which has all sounds turned off, and the complaints ceased. I'd really like to have sounds however, so this is far from ideal.
I don't have access to the resources to test the game on anything other than my personal phone and the emulator (where everything works flawlessly), but it's obvious there is a major issue for many players!
Should I not be using MP3s? Is there a universal method that works best for all handsets for just playing simple sound files?
This is what I'm using to start my sound effects:
final MediaPlayer player = MediaPlayer.create(GlobalState.Instance, resId);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
{
public void onCompletion(MediaPlayer mp)
{
mp.release();
}
});
player.setVolume(0.5f, 0.5f);
player.start();
I originally was calling player.prepare() before player.start(), but kept getting IllegalStateExceptions on some of the sound files. Some of the information out there is very confusing on when exactly to call these methods, and what the exception means. Removing player.prepare() made it work 100% of the time for me on the emulator and my local dev device.
There should be no problem using the MediaPlayer for music but for sound effect I would use the SoundPool class instead. My guess is you get the IllegalStateExceptions because you are starting the MediaPlayer before the player preperation is completed. Correct way would be to introduce a onPreparedListener for the MediaPlayer and start is from there. Are you making MediaPlayer operation on the main UI thread?
This is a tough one :/
I'm making a music-based Android game a la Audiosurf. It works all nice except a few seconds before end of a song (that is being played with a normal MediaPlayer) the music stops aprubtly and the whole game (including UI) freezes for several seconds.
Each time that happens I see an "AudioHardware pcm playback is going to standby"-error in logcat.
Googling has led me to the conclusion that
this could be a HTC Hero specific issue (cannot be reproduced on emulator or other devices)
this message is normally logged when a http stream isn't fast enough for MediaPlayer
Audio in Android sucks in general
As I am decoding the mp3 with the NDK + libmpg123 for audio analysis already I might aswell just play the audio myself (using a very ugly interface between NDK C code and an AudioTrack in Java).
Is there a fix/workaround for this bug or should I really go that way? (I only have limited time left to complete this project)
I appreciate every hint!
You might be stopping the music when you've buffered it all in your C code. Since the AudioTrack has a delay in it, you may need to wait longer for it to finish.
I'd need more detail about your code to help, though.