I am trying to play a sound in an app. However, using SoundPool I am unable to do so. The code is really simple and I don't see where it can fail.
A similar code but using MediaPlayer does work, but I am interested in using SoundPool.
SoundPool code:
private void playSound2(){
SoundPool sp = new SoundPool.Builder().build();
int soundID = sp.load(MainActivity.this, R.raw.sound, 1);
sp.play(soundID, 1, 1, 1, 0, 1);
}
Context:
public void goButtonClick(View view){
Button goButton = findViewById(id.button2);
if (onGoing){
goButton.setText("GO!");
} else {
goButton.setText("STOP");
//playSound(); // MediaPlayer
playSound2(); // SoundPool
}
onGoing = !onGoing;
}
MediaPlayer version (works):
private void playSound(){
MediaPlayer mediaPlayer;
mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.sound);
mediaPlayer.start();
}
Solved!
I was missing to wait for the loading of the sound file into soundPool. The correct code is:
private void playSound2() {
SoundPool sp = new SoundPool.Builder().build();
int soundID = sp.load(MainActivity.this, raw.sound, 1);
sp.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool sp, int soundID, int i1) {
sp.play(soundID, 1, 1, 1, 0, 1);
}
});
}
Related
Recently I've been working on an android game, but have hit a problem when adding music and other sounds. I read that Mediaplayers are optimal for background music, which works well, and I read that Soundpool is optimal for short music clips like sound effects. However, I can't get the Soundpool to work, it appears that the Soundpool isn't even loading.
I did more research and found a lot of nightmare stories about Soundpool's lack of support, so should I just use a mediaplayer for all audio? Is this efficient?
//My Code
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int mySoundId, int status) {
loaded = true;
}
});
if(loaded==true){
soundId = soundPool.load(this, R.raw.sound1, 1);
soundPool.play(soundId, 1, 1, 1, 0, 1f);}
else{
System.exit(0);
}
//Forces the program to exit everytime
SoundPool#load method is asynchronous, you should play sound after onLoadComplete had been invoked
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int mySoundId, int status) {
soundPool.play(mySoundId, 1, 1, 1, 0, 1f);
}
});
soundPool.load(this, R.raw.sound1, 1);
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int mySoundId, int status) {
loaded = true;
soundId = soundPool.load(this, R.raw.sound1, 1);
soundPool.play(soundId, 1, 1, 1, 0, 1f);
}
});
because your loaded variable will be always false, you should do the things within the onLoadComplete.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = findViewById(R.id.textView1);
view.setOnTouchListener(this);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
}
});
soundID = soundPool.load(this, R.raw.dog_bark, 1);
}
;
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float actualVolume = (float) audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
}
}
return false;
}
}
I tried this way, but the sound is being played on touch event. I want the sound to be played automatically when my activity starts. But it should stop after a loop is completed and start again on touch event. Please help.
Use this in the activity where you wanna hear the music
mMediaPlayer = new MediaPlayer();
mMediaPlayer = MediaPlayer.create(this, R.raw.sound1);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setLooping(true);
mMediaPlayer.start();
public class CommonMethod {
public static MediaPlayer player;
public static void SoundPlayer(Context ctx,int raw_id){
player = MediaPlayer.create(ctx, raw_id);
player.setLooping(false); // Set looping
player.setVolume(100, 100);
//player.release();
player.start();
}
}
//you can use this method for stopping the player.
CommonMethod.player.stop();
If it because you are just loading the sound on onCreate() and play it on touch!
Try soundPlay.play() in onCreate instead!
you can play the sound in a runnable and post it in onCreate method.
View view = findViewById(R.id.textView1);
view.post(new Runnable() {
#Override
public void run() {
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
}
}
});
Put your onTouch() method's code into OnStart() method of your Activity, so that when activity is started, then Your sound plays.
If your activity name is MainActivity
MediaPlayer play= MediaPlayer.create(MainActivity.this,R.raw.sound);
play.start();
Place this in the onCreate method
In my activity there is a timer which send a message to a handler every second which changes a picture.
Every time user clicks the image a sound is played in onClickListner function of activity using this code:
MediaPlayer.create(this, R.raw.voice).start();
On a xperia arc (Android 4.0.4) the sound is not completely played and as soon as the timer triggers it stops. If I disable the timer there is no problem.
On a HTC Legend (Android 2.2) there is no problem. The sound is played completely.
I can't figure out the problem.
public class ActivityTest extends Activity implements View.OnClickListener, ViewSwitcher.ViewFactory
{
ImageSwitcher switcher;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test_listen);
switcher = (ImageSwitcher) findViewById(R.id.imageSwitcher);
switcher.setFactory(this);
switcher.setOnClickListener(this);
final Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
switcher.setImageDrawable(getResources().getDrawable(R.drawable.image));
// if this line is commented it works fine
}
};
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run()
{
handler.sendEmptyMessage(0);
}
}, 0, 1000);
}
#Override
public void onClick(View view)
{
MediaPlayer.create(this, R.raw.voice).start();
}
#Override
public View makeView()
{
ImageView image = new ImageView(this);
image.setScaleType(ImageView.ScaleType.FIT_CENTER);
image.setLayoutParams(new ImageSwitcher.LayoutParams(ImageSwitcher.LayoutParams.FILL_PARENT, ImageSwitcher.LayoutParams.FILL_PARENT));
return image;
}
}
Solution -------------------------------------
I moved the declaration of MediaPlayer to class and it fixed the problem.
MediaPlayer mp;
#Override
public void onClick(View view)
{
mp =MediaPlayer.create(this, R.raw.voice);
mp.start();
}
I don't know why the previous code works on 2.2 but not 4. anyway it worked.
since its a short sound your playing i'd recommend a soundpool. Soundpool clips are kept in memory for quick access since there small. Im assuming your playing a very short sound. in onCreate do this to preload it:
// Load the sound
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundID= soundPool.load(this, R.raw.voice, 1);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
}
});
then in the onclick method (when user clicks the image) do this:
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float actualVolume = (float) audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
}
where soundPool is declared as a instance variable private SoundPool soundPool or something similar. Try that and let me know what happens.
I have a sound clip play while I am displaying some numbers, then want it to stop. Then I want to repeat the process.
init stuff:
private SoundPool soundPool;
private int soundRoll;
boolean soundloaded = false;
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
soundloaded = true;
}
});
soundRoll = soundPool.load(this, R.raw.roll, 1);
Thread Call:
public void update() {
.......
new Thread(new Runnable() {
public void run() {
int streamID = 0;
streamID = soundPool.play(soundRoll, volume, volume, 1, -1, 1);
... loop to animate text....
soundPool.stop(streamID);
}
}).start();
}
This works fine every other time.
so the first time it plays and stops at the right time.
second time I hear nothing
but then it works the third time
If I take out the looping, then it works.
Any help would be appretiated
Seems that if I switch to an OGG file from an MP3, the bug goes away
I am developing a memory game, in which I want to play background music while starting the game.
I used sound pool class and successfully executed it, but I have problem in playing. I added .mp3 audio file of two minutes, but it's playing only for 15 seconds more.
Can anyone say what problem I have? This is my soundclass file:
public class Soundclass {
private SoundPool soundpool;
private HashMap<Integer, Integer> soundpoolmap;
private AudioManager audiomanager;
private Context context;
public void initSounds(Context thecontext) {
context = thecontext;
soundpool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
soundpoolmap = new HashMap<Integer, Integer>();
audiomanager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
}
public Soundclass() {
}
public void addSound(int Index, int soundID) {
soundpoolmap.put(Index, soundpool.load(context, soundID, 1));
}
public void playSound(int Index) {
float streamVolume = audiomanager
.getStreamVolume(AudioManager.STREAM_MUSIC);
streamVolume = streamVolume
/ audiomanager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
soundpool.play(soundpoolmap.get(Index), streamVolume, streamVolume, 1,
0, 1f);
}
public void playLoopedSound(int Index) {
float streamVolume = audiomanager
.getStreamVolume(AudioManager.STREAM_MUSIC);
streamVolume = streamVolume
/ audiomanager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
soundpool.play(soundpoolmap.get(Index), streamVolume, streamVolume, 1,
-1, 1f);
}
}
and i used this class for given activitycalss .in oncreate function
Button btn = (Button) findViewById(R.id.sound);
soundclass = new Soundclass();
soundclass.initSounds(getBaseContext());
soundclass.addSound(1, R.raw.jinglebells);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
soundclass.playSound(1);
}
});
Soundpool is not meant to be used for background music. It has many limitations such as file size loading and playing time. It's mainly used for sound effects.
Use the MediaPlayer class for background music.