I´m currently trying to play sounds in my android app with SoundPool API. Playing a sound is not the problem. Now I want to stop the sound and restart it later from beginning. But when i call the stop function and then play(), the sound is not played. Here is some code:
load the sound:
soundId = soundPool.load(context, fileId, 1);
play the sound:
streamId = soundPool.play(soundId, 1.0f, 1.0f, 1, -1, 1);
stop the sound:
soundPool.stop(streamId);
I also tried to load the sound again before playing it a second time, but that didn´t fixed it.
When I use pause/resume the sound is played from the position where it was stopped (but I want it always from beginning).
Any help would be appreciated
EDIT:
I just figured out something strange. When I use soundpool.stop(), it works every second time I call soundpool.play(). So the first call of play() plays the sound, the second not, the 3rd, 5th, 7th.. call plays the sound.
When I use soundpool.pause() and then play(), it works every third time. So the 1st, 4th, 7th... call of play() starts the sound.
Is it a bug? Or am I using it wrong?
i have created a simple project to do start and stop a sound and then play it again. here's the code
Button b1, b2;
private int streamId;
private int soundID;
private SoundPool sp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1 = (Button) findViewById(R.id.b1);
b2 = (Button) findViewById(R.id.b2);
sp = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
soundID = sp.load(this, R.raw.middle, 1);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.b1:
streamId = sp.play(soundID, 1, 1, 1, 0, 1f);
break;
case R.id.b2:
sp.stop(streamId);
break;
}
}
i worked properly in my case, if you are doing the same thing then problem may be somewhere else. If you could provide the some more detail then may be we can figure out what's the problem.
Play:
nowPlaying= soundPool.play(soundId, 1.0f, 1.0f, 1, -1, 1);
soundPool.stop(nowPlaying);
now reload it:
soundId = soundPool.load(this, R.raw.yoursound, 0);
Related
When i click button plays sound on my app, but keep clicking for a while doesn`t play anymore. Maybe it is memory issue? Could you solve me my issue? Here is implemented play sound via SoundPool: when i click button i called play method: and play method works background thread
private void play(int resId) {
soundPool = buildBeforeAPI21();//TODO: refactor with deprecated constructor
soundPool.load(activity, Integer.parseInt(resId), 1);
}
public SoundPool buildBeforeAPI21() {
if (soundPool == null) {
soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
if (status == 0) {
soundPool.play(sampleId, 1.0f, 1.0f, 1, 0, 1.0f);
}
}
});
}
return soundPool;
}
Don't create a new SoundPool with each click. That is extremely wasteful. Do this instead:
1) Create the SoundPool just once
2) Load it with all the sounds you want to play, just once
3) Wait for all the sounds to load
4) Just call soundPool.play() with each click.
Maybe this answer cames too late; but here we go. The problem is in the line
soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
That '2' number is the int maxStreams, following the documentation "the maximum number of simultaneous streams for this SoundPool object" (you can go deep on this here). Now change it and set it to 10, for example, and try again. And after that, you cand adjust it as your wishes. So:
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
Hope this helps (if it is still necessary).
I am attempting to create a simple Morse code application. When the user presses a button the Morse sound should start before ending when released.
The problem is the latency- the Morse sound does not start until roughly 400ms after the user presses the button. I am not sure why this is exactly but after researching the problem i think it is the way my code is structured. The file i am trying to play is in Mp3 format and is located in the raw folder.
I had this completed using the Media Player but i ran into the same problem in regard it not being responsive enough so i opted to try and use Sound pool. Does anyone have any advice/suggestions as to how i can speed up the operation? This is new territory to me in regards development.
public int S1 = R.raw.morse;
private SoundPool soundPool;
private boolean loaded;
static int x;
public void initSounds(Context context) {
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
final int y = soundPool.load(context, R.raw.morse, 1);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
playSound(y);
}
});
}
public void playSound(int soundID) {
if(loaded) {
x = soundPool.play(soundID, 0.5f, 0.5f, 1, 0, 1f);
}
}
//Calling code
pad.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
//State of a toggle button
if(audioOnOff==true) {
//Sound pool object is created and initialized as a global variabe
sp.initSounds(getApplicationContext());
}
}
It looks to me like what's happening here is that each time the button is pressed, you're loading the sound, waiting for it to finish loading, then playing it. What you actually want is to load the sound once, then just play it each time the button is pressed.
So instead of calling initSounds in your onTouchListener, call initSounds somewhere else before the button is pressed. Then in your onTouchListener you just call your playSound method.
Finally, make sure you remove the playSound method call from your onLoadCompleteListener so you don't get a mysterious noise when you initially load up the sound ;)
I am programming a board game in android and need a sound effect for every click.I am using sound pool. There will be a lot of clicks and so I wanted to know where I have to declare the SoundPool and load it? In the onCreate function , or have a function that creates and loads and plays the sound and is called at every click?
//make soundpool public
SoundPool soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
//load sound here and play wherever needed
int soundID=soundPool.load(this,R.raw.metalimpact,1);
}
//or put it all in a function
private void makeSound(){
SoundPool soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
final int soundID=soundPool.load(this,R.raw.metalimpact,1);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener(){
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
soundPool.play(soundID, 1, 1, 0, 0, 1f);
}});
}
What is the right way to impement the SoundPool?
Will there be performance issues in the ways I have implemented it?
When should I release the soundpool object?..In the OnDestroy or onPause()?
Also SoundPool has been deprecated, but my min api level supported is 11. So what should I do?
Please help!!
My app currently uses a SoundPool to manage all the different sounds. When the user taps the button, a sound should play. Since he might push that button quite quickly, the sounds should be able to play on top of each other.
The SoundPool is not able to listen for a sound finishing nor can it get the length of a sound file. Therefore I am thinking about using the MediaPlayer.
I have no experience with the MediaPlayer, but it seems that it is not as straight forward to set up that ability to quickly play a sound. Unfortunately I have to check when a sound finished playing, so I will have to rewrite using the MediaPlayer.
How would you make the MediaPlayer able to play many short sounds?
an instance of a media player plays one sound at a time. it's better to use soundpool..
try this with soundpool...
1) create an int, don't leave it null. somewhere before the onCreate method.
2) in the onCreate method attach a resource to it
3) lastly, apply logic to a button..
int db1, db2, db3, db4, db5 = 0;
db1 = sp.load(this, R.raw.snd1, 1);
db2 = sp.load(this, R.raw.snd2, 1);
db3 = sp.load(this, R.raw.snd3, 1);
db4 = sp.load(this, R.raw.snd4, 1);
db5 = sp.load(this, R.raw.snd5, 1);
samplebutton5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (db5 != 0)
sp.play(db5, 1, 1, 1, 0, 1);
}
});
To use soundpool if you like you can first get the sound length by using MediaPlayer by using the following method:
private long getSoundDuration(int rawId)
{
MediaPlayer player = MediaPlayer.create(activity, rawId);
int duration = player.getDuration();
player.release();
return duration;
}
And afterwards use an handler and write something like:
handler.postAtTime(this, SystemClock.uptimeMillis() + duration);
The handler will wait until sound is finished to do the next task whatever that may be.
I have a math game with multiple choice questions. I have a bell sound for a right answer and an oink sound for a wrong answer. There is a timed play mode which encourages the player to enter answers rapidly. The sounds play fine if answer buttons are pressed slowly. But if in quick succession, a sound fails to play.
The two sounds are each a fraction of a second long.
In the method that handles correct answers I have ting.start();, and in the method for wrong answers I have oink.start();
One thing I tried was to forcibly stop both sounds and then start only the one I want (see below) but then the sounds don't play at all! Any suggestions?
private void handleWrongAnswer(int chosenID)
{
// Toast.makeText(getApplicationContext(), "Oops, try again.", Toast.LENGTH_SHORT).show();
Button checked_button = (Button) findViewById(chosenID);
checked_button.setEnabled(false);
checked_button.setClickable(false);
checked_button.setBackgroundColor(Color.rgb(255,100,100));
score = score - 1.0/3.0;
score_field.setText(String.format("%.2f", score));
ting.stop();
oink.stop();
oink.start();
}
Well I suppose that you are using Mediaplayer to play that sounds. If you want to play small audio clips and repeat them in small place of time you should use soundPool.
You should implement it this way:
private SoundPool soundPool;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Load the sound
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.sound1, 1);
}
And then when you want to use it:
// Getting the user sound settings
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;
// Is the sound loaded already?
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
}
Anyway you have a nice tutorial about this here.