I'm working on a little game that is uses soundpool to play small sound-files.
However, it now seems that I have too many sound files that I want to add to the soundpool since I get an error saying that the heap has an overflow.
So then I tried to load the sound files when they are needed instead of loading them when the class instance is initialized, but the result of that turned out very bad.
Are there any other ways I can make it work using soundpool or do I have to use media player instead? I already have media player class that is used to play long sound clips like music files and so on. So the backup plan is to make two instances of the media player class that runs on two separate threads where one of them handles the small sound files.
Any help and ideas is highly appreciated.
Greetings!
Try dividing the SoundPool object you are using into multiple instances. Ex. SoundPool sp1, sp2, sp3; Do not use multiple MediaPlayer objects as this will be very slow and inefficient.
Related
I'm building an app that plays multiple short sound effects in one activity.
There are over 80 buttons with each buttons that plays a specific sound effect.
I've searched about SoundPool and MediaPlayer and found out SoundPool is more efficient for short sound files.
Here's my question, if I should load over 80 sound effects in one activity, would SoundPool still be the better option? I ask because SoundPool loads the sound at once and reuses it, I think it's a bit heavy to load 80 sounds in one activity (Maybe I'm wrong.) Would like to hear the experts here for a better way or any advice!
Thanks in advance
It does not depend by the number of sounds, but from their size in terms of bytes. Every sound is loaded into memory and if they are too big, you could not have enough memory to load them all.
I would consider using AudioTrack. You instantiate it and when you have to play a sound you can read it from file system or assets or resources and add it to the play queue. It works only with PCM.
How can I play background audio, in Android, without interrupting the MediaPlayer playback, by either using MediaPlayer (preferred) or OpenSL ES?
I know SoundPool is able to play sound effects without interrupting any MediaPlayer playback, but the size is limited to 1M per effect, which is way to less. Not requesting audio focus, via AudioManager doesn't seem to work either, audio doesn't play at all in this case.
And in the case of OpenSL ES, all audio generally stops when I start to play a longer asset file. It's similar to the behaviour of SoundPool described above.
Edit from the comments:
I don't want to interrupt other music players, it's the background
audio of a game, which shall play without interrupting the, for
example, music of a player. Games like Subway Surfer, Clash Royale and
such seem to have this achieved somehow, but I could not achieve it
via OpenSL ES, or MediaPlayer.
In order to play sound in background you can use SoundPool, AudioTracks and OpenSlES.
Soundpool: Use small files and make a sequence. In my last project i use 148 sound files (all small) in different scenarios and played using soundpool. Make a list and play one by one or in parallel. Also in games usually you have a small set of sound for particular scenario and it loops. Best is soundpool for that. You can also perform some effects like rate change. Also ogg files are way small, so use them.
AudioTrack: You can use RAW PCM data in audio track. If you want you can extract pcm data using MediaExtractor from almost all formats and use it. But it will be a little work for you in your case, but it is really good (supports huge data, even live streaming).
OpenSLES: Apparently android uses opensles in background for all its purpose. So using it will help you a lot. But it's not easy to get everything done on it. You need to learn more for lesser work.
I have been deeply working on OpenSlES for about 20 days and still i will say for small purpose use soundpool, medium to high level implementation use AudioTracks and for kickass implementation use OpenSLES.
PS: It will be bad effect on your user if you play game sound in background while they are playing their music or their call. Personal experience.
When using a SoundPool audio class, it definitely has some advantages over a MediaPlayer when just playing short audio clips. The two I've noticed is SoundPool is a lot faster. MediaPlayer can lag a bit on startup and it's much easier to go from one sound clip to the next, where I don't have to stop,reset,prepare each time.
However, is it possible to use the visualizer to get real time fft data from audio data playing in the SoundPool like it is for MediaPlayer? I couldn't come across any topics that cover that, but by the off chance I thought I would ask because it seems like it should be possible. The documentation says, "The SoundPool library uses the MediaPlayer service to decode the audio into a raw 16-bit PCM mono or stereo stream." So if I could reference the MediaPlayer that SoundPool is using then I think I could just use getAudioSessionId() perhaps?
I already tried setting session ID to 0 to just get the output mix. It didn't work but it's not really the ideal effect that I am looking for anyway. Also one of the first things I did was try using the loaded SoundPool SoundID in place of the visualizers session ID, but that also didn't work.
I've been trying to make multiple sounds work simultaneously but I kept getting errors like Sample not ready and Error creating AudioTrack. Though I've taken care of the first error, the other error persists.
I'm using two mp3 files, that are away above 5 mb(>4 minutes) and thus was wondering if SoundPool is the right way to go about it? I can use Media Manager but it doesn't let me play multiple files simultaneously.
SoundPool is recommended for <1MB sound clips, so I'd use MediaPlayer in your case. You can call the following for each sound and they will play simultaneously:
MediaPlayer.create(YourActivity.this, R.raw.your_sound).start();
Or you can create multiple MediaPlayer objects and play a sound on each, then release() them.
I'm trying to play 20 ogg files at the same time using MediaPlayer.
This is because I want to make a mixing effect.
While one music is playing, other files also have to be played.
Actually, I already made an application with this function by iOS, and it didn't have any problems to play and mix.
And now, I should convert this app into android app.
so I sentenced 20 mediaplayer variables
MediaPlayer player1;
MediaPlayer player2;
MediaPlayer player3;
.....
play1 = (Button)findViewById(R.id.btn1);
play2 = (Button)findViewById(R.id.btn2);
play3 = (Button)findViewById(R.id.btn3);
......
play1.setOnClickListener(this);
play2.setOnClickListener(this);
play3.setOnClickListener(this);
......
and whenever I click each button, it play each sound and mix.
player1 = MediaPlayer.create(TestActivity.this, R.raw.md_cricket2);
player1.setLooping(true);
player1.start();
......
However, I have some problems at this point.
Two sounds mixing is ok, but when I tried to play more than 3 sounds,
some noises like "tick, tick" are added. It sounds like white noise..
I don't know why...
I thought it is really simple to make this mixing application in android, because
I already did it in iOS, but I don't know what the problem is...
Is there anybody who can advise me?
I think soundpool is not an answer. It is only for short sounds.
MediaPlayer is not proper to play multiple sounds at the same time?
Then, How can I make this function?
Playing sounds simultaneously with multiple media players is not recommend (crashes may occur).
You'd better use soundpool. Unfortunately, I don't have any experience with it myself so I can't help you there, but perhaps this post will help