Is there a reliable way to prevent truncating of sounds in soundpool? I have had some success with the sleep() function between sounds, but they still sometimes miss the last bit of sound before starting another sound. My app plays short sounds in sequence.
Jerry
Although this is an old question, I thought I would post something here since I couldn't find a solution to this problem online but did come up with something of a solution...
I get the duration of each sound (using MediaPlayer) when my app starts up, and store the R.id.sound_name value and the duration together. I can then play the sounds using the SoundPool.
Code to get duration:
private long getSoundDuration(int rawId){
MediaPlayer player = MediaPlayer.create(context, rawId);
int duration = player.getDuration();
return duration;
}
In my sound class, I then play the sound as usual then sleep for the duration. Pretty simple stuff.
Seems to work well. Gives me the advantages of low-latency from SoundPool, plus ability to chain things.
A couple things to note:
Don't get the duration each time, as creating a MediaPlayer has overhead.
Durations are taken from file metadata -- ogg's work great for me, but I can't vouch for anything else.
Make sure you have enough Streams.
in the SoundPool constructor, the first argument is MaxStreams.
Set that to whatever you seem fit. 8 or so should be enough i guess... but you might need more, depending on your sounds.
Related
I get popping sounds when simultaneously playing multiple SuperpoweredAudioPlayers. When one SuperpoweredAudioPlayer is playing a moderately loud sound, a popping sound gets made when I call play() on a second SuperpoweredAudioPlayer, even if there is initial silence in the second player and the process() volume is set to 0. I can't have pops in the output since I'm making a music production app. The output also needs to be generated in real time. Am I doing something wrong or is there a workaround? Would it be fixed by having the players in separate threads?
Separate threads are definitely not the solution, as all your audio processing should happen on the same thread. Two audio players are very low with CPU, you don't have a processing problem.
Perhaps you forgot to handle the return value of the process() function. If it's false, then it means silence, and the buffer is not updated (zeroed) at all.
Since my last question hasnt been answered where I used simple medaiplayer (Sound sometimes remains silent when playing more sounds in a row, why?) and tried to create the whole thing using SoundPool. But guess what, almost same thing happens but with an error
AudioFlinger could not create track, status: -12
Error creating AudioTrack
I read about that at most 32 sound can be stored in the memory of soundpool then I will get the error. Thats right, after the 32th sound I cannot play any of the sounds since I always get the error. So how could I use more than 32 sounds with SoundPool? I tried to use 3 Soundpools with 20 sounds in each of them, and I always unload all the sound from the other pools with this:
mSoundPoolMapV1.clear(); //clearing HashMap
for(int i=1;i<15;i++){
mSoundPoolV1.unload(i);
}
But same error comes again. (I use 22k sounds instead of 44.1k, I read this could solve it but nothing happened)
Any suggestions appreciated. What the hell is that I cannot play about 50 sounds neither with mediaplayer and nor with soundpool? How is that possible??
With release() :
mSoundPoolMap.clear();
for(int i=1;i<50;i++){
mSoundPool.unload(i);
}
mSoundPool.release();
mSoundPoolMap.put(1, mSoundPool.load(Main.this, R.raw.sound1, 1));
...
mSoundPoolMap.put(50, mSoundPool.load(Main.this, R.raw.sound50, 1));
SO I clear the hashmp, then unload all the sounds, then I release the soundpool. Then I fill the hashmap again, but now It gives me no sound at all. I must miss something, could you tell me what?
There's a limitation in the AudioMixer that only allows 32 AudioTracks at the same time. The SoundPool will try to create an AudioTrack whenever it starts playback of one of the channels (I guess this corresponds to a sample) belonging to the pool. However, the track is not destroyed until you destroy the SoundPool, so the track name will remain allocated even if it has been stopped.
You could try calling release() on your SoundPool. That should cause the native SoundPool object to be destroyed, thereby destroying all AudioTracks it has created and deallocating their names in the AudioMixer.
Underlying audio hardware is not unlimited. You can only hold so many sounds in memory at a time. When I made a 3D audio library for desktops the limit was variable so I had to query the limit from the hardware before starting or it would lead to seemingly random failures. You should have a single SoundPool and just load and unload sounds into as you need them. Then you need to set up some kind of a priority for the sounds that should be playing so you can make sure that the sounds you really need don't get unloaded to play an optional background noise.
The SoundPool Documentation actually has a really nice description of a typical use-case.
I have a game in which a "ding" sound is made for each point scored in a game. Sometimes you can score points in very quick succession. In this case I do not allow overlapping sounds so I wait for the mediaplayer's isPlaying() function to go to false before playing the next sound.
On every phone I've tried so far (admittedly all 2.2 or 2.3) the result is a pleasing rapid-fire succession of sounds.
But just now I've tried Samsung galaxy S II with 4.0.3. On this machine each "ding" is separated by a long gap. The isPlaying() state seems to last twice as long as the sound itself. According to Audacity the sound should last about 0.1 seconds, but isPlaying() is remaining true for .28 seconds.
The sound is saved from Audacity into Ogg Vorbis format.
Any idea what's gone wrong?
It's better to use SoundPool for playing rapid-fire samples in games as they're uncompressed once and kept in memory. MediaPlayer may be decoding on the fly, causing a delay as it gets ready. Not sure why there's such a difference between devices, but I'd give SoundPool a try and see if it improves things.
Maybe anybody faced with this issue.
I use SoundPool for playing sounds in my app.
After playing the sound I need to do further action. But how can I determine that the sound has stoped?
All the sounds in the app have a different length, so I can not count the time. I need a different approach.
Thank you.
soundpool's purpose is to load and play simple small sounds without the need to monitor them.
what you probably need is MediaPlayer and setOnCompletionListener() :
http://developer.android.com/reference/android/media/MediaPlayer.html
http://developer.android.com/reference/android/media/MediaPlayer.html#setOnCompletionListener(android.media.MediaPlayer.OnCompletionListener)
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