play sound file with a delay and adjust time in android - android

I am trying to program a sound app where on button click I would like to play 3-4 sound files one after the other. How can this be done? Also I would like to increase the time of play of the files. Is this where the loop variable in play function used??
Here is part of code I have done with SoundPool. However the files all play simultaneously :(
public void onClick(View v){
//check for scan button
if(v.getId()==R.id.playbutton){
queueSound(1000);
sound.changePitchfile3(R.raw.a0);
queueSound(5000);
sound.changePitchfile2(R.raw.a1);
queueSound(10000);
sound.changePitchfile3(R.raw.a3);
}
}
});
}
private void queueSound(final long delay) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
}}, delay);
public void changePitchfile1(int res1) {
int soundId = (Integer) mSounds.get(res1);
this.myPlayer.play(soundId, 1, 1, 0, 0,1.125f);
}

Related

My Quit Button is not playing the sound when i click it, except this all the button are playing sound. Can anyone solve this problem?

// This is my app exit button it destroys the activity and exits the user from an app. I want to //play a sound when I click this button but unfortunately, the sound is not playing and the activity //destroys. Please help me in solving this issue. Except for this button, all my button sound is working.
// This is my second activity, in this activity, I have used a button for quitting the app but I also //want the button to play a sound when the button is clicked by user. But it is not playing the sound and //quits the app which destroys activity. please tell me how to play the sound on my exit button during //the click
mExitApp = (Button)findViewById(R.id.exit_app);
final MediaPlayer mp = MediaPlayer.create(this, R.raw.sample2);
mExitApp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp.start();
ScoreActivity.this.finish();
System.exit(0);
}
});
A quick and dirty way would be to wait for the sound to end playing before finishing the activity/process.
public void onClick(View v) {
mp.start();
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
ScoreActivity.this.finish();
System.exit(0);
}
}, 300);
}
A more cleaner solution would probably involve a MediaPlayer.OnCompletionListener.
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
finish(); // finish current activity
}
});
Or you could play the sound in a foreground/background service. But then you shouldn't kill the entire process (System.exit(0)) like you do now ofc.

how to make two buttons play sound together

When I touch sound play sound but when I touch another it stop play this sound. I need to sound don't stop playing.
public void onClick(View v) {
mSoundManager.playSound(1);
}
});
Button SoundButton2 = (Button)findViewById(R.id.sound2);
SoundButton2.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mSoundManager.playSound(2);
}
});
Button SoundButton3 = (Button)findViewById(R.id.sound3);
SoundButton3.setOnClickListener(new OnClickListener() {`enter code here`
public void onClick(View v) {
mSoundManager.playSound(3);
Your code in my comment shows that you have initialized your sound pool with 1 as the value for maxStreams. If you set this value to the maximum amount of sounds you want to be able to play at the same time, it should work.
You have mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
If you change that to mSoundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
You will be able to play 5 sounds at once.
I'd need to take a look at your sound manager class to have a better idea of what is wrong with it. However, it is perfectly possible.
Take a look at this:
Playing sounds simultaneously Android

MediaPlayer how to stop multiple sounds from playback

i have a button that plays a sound.
When i push the button multiple times, it plays the sound multiple times.
This is oke, i want this.
But when i click the stop button it must stop all sounds currently playing.
I used:
while (mediaPlayer.isPlaying()){mediaPlayer.stop();}
but it is not working, the sounds keep on playing. Can someone help me?
Here is my full code:
public class HelloSoundboard extends Activity {
MediaPlayer mediaPlayer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button item1 = (Button)findViewById(R.id.item1);
item1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.atyourservice);
mediaPlayer.start();
}
});
Button stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
while (mediaPlayer.isPlaying()){mediaPlayer.stop();}
// mediaPlayer.stop();
}
});
}
}
SoundPool is a much better alternative for this purpose. I would caution strongly against instantiating multiple MediaPlayer instances as most systems do not have the resources to generate many parallel active instances. You wil find on many device that hitting the button upwards of 5 times will cause a memory based crash.
As far as stopping all active streams, there is not baked-in function for this, but it's easy to accomplish in a manner to similar to your existing code. As a side note, there is an autoPause() method, which halts all streams, but it doesn't truly end their playback (as the method name insinuates). Here is a simple example to manage your audio streams:
//SoundPool initialization somewhere
SoundPool pool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
//Load your sound effect into the pool
int soundId = pool.load(...); //There are several versions of this, pick which fits your sound
List<Integer> streams = new ArrayList<Integer>();
Button item1 = (Button)findViewById(R.id.item1);
item1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
int streamId = pool.play(soundId, 1.0f, 1.0f, 1, 0, 1.0f);
streams.add(streamId);
}
});
Button stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
for (Integer stream : streams) {
pool.stop(stream);
}
streams.clear();
}
});
It is much more memory efficient to manage a list of streamID values than MediaPlayer instances, and your users will thank you. Also, note that it is safe to call SoundPool.stop() even if the streamID is no longer valid, so you don't need to check for existing playback.
HTH
I'm not sure about this, but I think is better if you use a SoundPool.
"SoundPool is designed for short clips which can be kept in memory decompressed for quick access, this is best suited for sound effects in apps or games".
"MediaPlayer is designed for longer sound files or streams, this is best suited for music files or larger files".
You can use a list of MediaPlayers:
List<MediaPlayer> mps = new ArrayList<MediaPlayer>();
Button item1 = (Button)findViewById(R.id.item1);
item1.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.atyourservice);
mp.start();
mps.add(mp);
}
});
Button stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
for (int i = mps.size() - 1; i >= 0; --i) { //changed ++i to --i
if (mps.get(i).isPlaying()) {
mps.get(i).stop();
}
mps.remove(i);
}
}
});

Playing large PNG frame animation in android with animationDrawable

I have an app with buttons that play various frame-by-frame animations when pressed. The animations are stored as sequences of .png files. Some of the animations fill a small area, and they seem to play fine using animationDrawable. However, some of the animations fill a large part of the screen (even though they are mostly transparent using an alpha channel), and I get an out of memory error when the app loads on my phone (but not the emulator). I can't play them as video files because they need to overlay the main screen.
My main question - is there a way to play large png sequence animations (Say 60 frames at 320x480) using animationDrawable?
So far in my research there doesn't seem to be any way around the memory limitations... so I have been looking into making my own method that creates an ImageView and populates it with a bitmap, and then successively replaces the bitmap with each frame after a delay. However, with this technique my animation seems to only play the first and last frames.
Here is the code of my stab at using animationDrawable - the "chimp" plays fine, but when I add the "bubbles" (the larger images), the app doesn't load at all - logCat shows: "ERROR/dalvikvm-heap(3248): 1008000-byte external allocation too large for this process... ERROR/AndroidRuntime(3248): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
"
public class Babymode_tst extends Activity implements OnClickListener{
/** Called when the activity is first created. */
AnimationDrawable chimpAnimation;
AnimationDrawable bubblesAnimation;
private MediaPlayer mp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
final ImageButton chimpButton = (ImageButton) findViewById(R.id.chimp_button);
chimpButton.setOnClickListener(this);
ImageView chimpImage = (ImageView) findViewById(R.id.chimp_imageview);
chimpImage.setBackgroundResource(R.drawable.chimp_anim);
chimpAnimation = (AnimationDrawable) chimpImage.getBackground();
final ImageButton bubblesButton = (ImageButton) findViewById(R.id.bubbles_button);
bubblesButton.setOnClickListener(this);
ImageView bubblesImage = (ImageView) findViewById(R.id.bubbles_imageview);
bubblesImage.setBackgroundResource(R.drawable.bubbles_anim);
bubblesAnimation = (AnimationDrawable) bubblesImage.getBackground();
}
public void onClick(View v) {
if (mp != null) {
mp.release();
}
Random generator = new Random();
int randomIndex;
switch(v.getId()){
case R.id.chimp_button:
randomIndex = (generator.nextInt( 2 ) + 1);
if (randomIndex == 1){
mp = MediaPlayer.create(this, R.raw.chimp_1);
}
if (randomIndex == 2){
mp = MediaPlayer.create(this, R.raw.chimp_2);
}
mp.start();
chimpAnimation.setVisible(true,true);
chimpAnimation.start();
break;
case R.id.bubbles_button:
randomIndex = (generator.nextInt( 3 ) + 1);
if (randomIndex == 1){
mp = MediaPlayer.create(this, R.raw.bubbles_1);
}
if (randomIndex == 2){
mp = MediaPlayer.create(this, R.raw.bubbles_2);
}
if (randomIndex == 3){
mp = MediaPlayer.create(this, R.raw.bubbles_3);
}
mp.start();
bubblesAnimation.setVisible(true,true);
bubblesAnimation.start();
break;
}
}
}
And here is my attempt at playing the frames one by one in an ImageView, but it only plays the first and last frames:
public void playAnimation(String name){
final ImageView bubblesImageView = (ImageView) findViewById(R.id.bubbles_imageview);
bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0003);
mHandler.postDelayed(new Runnable() {
public void run() {
bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0015);
}
}, 500);
mHandler.postDelayed(new Runnable() {
public void run() {
bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0025);
}
}, 500);
mHandler.postDelayed(new Runnable() {
public void run() {
bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0035);
}
}, 500);
}
Any help would be appreciated - thanks
your mHandler.postDelayed(new Runnable(){...}); are all triggering at the same time e.g. after 500 ms, you need them to trigger one after another by either
nHandler.postDelayed(new Runnable() {
public void run() {
bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0015);
}
}, 500);
mHandler.postDelayed(new Runnable() {
public void run() {
bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0025);
}
}, 1000);
mHandler.postDelayed(new Runnable() {
public void run() {
bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0035);
}
}, 1500);
or having each runnable queue up the next one after a 500 ms delay e.g.
mHandler.postDelayed(new Runnable() {
public void run() {
bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0015);
mHandler.postDelayed(new Runnable() {
public void run() {
bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0025);
}
}, 1000);
}
}, 500);
Or you could construct an array of ìnt with the R.drawable.xxx value and every 500 ms just display the next image.
This is an extremely difficult thing to do, but it is doable. The key is to recycle your bitmaps right after you use them. Check out this wrapper class someone wrote that will handle all that for you:
http://snippetrepo.com/snippets/android-animation-without-outofmemoryerror
In my company we got the same problem, we've tried to make a splash screen in this way(and it was total disaster). If you want so hard to got some kind of animation, generate video from the PNG frames (i think that FFMPEG can do it), and then play the video.

Android: Playing an audio clip onClick

How do I set up an audiofile to play when a user touches an image.
Where should I store the audio file and what code should I use to actually play the file?
I don't want to bring up the MediaPlayer interface or anything like that.
I was thinking of doing it like this:
foo = (ImageView)this.findViewById(R.id.foo);
foo.setOnClickListener(this);
public void onClick(View v) {
if (foo.isTouched()) {
playAudioFile();
}
}
Thanks
This won't create a bring up the MediaPlayer interface... it will just play the sound you want.
Button boton = (Button) findViewById(R.id.boton);
boton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MediaPlayer mp = MediaPlayer.create(TestSonido.this, R.raw.slayer);
mp.start();
}
});
In this case, R.raw.slayer represents an audio file called slayer.mp3 that is stored in the res/raw/ folder and once you click the button the droid will rock you...
You can also achieve the same using SoundPool.
MediaPlayer first loads the whole sound data in memory then play, so it produces some lag when we switch among sounds frequently.
SoundPool is a better option with small size sound file and produces better result with .ogg media file.
SoundPool pl = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
// 5 indicates the maximum number of simultaneous streams for this SoundPool object
pl.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
// The onLoadComplet method is called when a sound has completed loading.
soundPool.play(sampleId, 1f, 1f, 0, 0, 1);
// second and third parameters indicates left and right value (range = 0.0 to 1.0)
}
});
Button btn = findViewById(R.id.boton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int sound = pl.load(this, R.raw.sound_01, 0);
}
});
public void aud_play(View view) {
if (!mp.isPlaying()) { //If media player is not playing it.
mp = MediaPlayer.create(this, R.raw.audio_name);
mp.start();
} else {// Toast of Already playing ...
}
}

Categories

Resources