Playing two sounds in sequence with SoundPool - android

Actually, I want to play all the sounds in raw folder in sequence. When I click the button only the first one is played. I will be grateful for your help . This is my code:
public class MainActivity extends AppCompatActivity {
private SoundPool soundPool;
private int sound1, sound2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
soundPool = new SoundPool.Builder()
.setMaxStreams(2)
.setAudioAttributes(audioAttributes)
.build();
} else {
soundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
}
sound1 = soundPool.load(this, R.raw.a, 1);
sound2 = soundPool.load(this, R.raw.d, 1);
}
public void playSound(View v) {
soundPool.play(sound1, 1, 1, 0, 0, 1);
soundPool.play(sound2, 1, 1, 0, 0, 1);
}
#Override
protected void onDestroy() {
super.onDestroy();
soundPool.release();
soundPool = null;
}
}

I used Howard Liu's SoundPoolPlayer class, a wrapper around the SoundPool that calculates the duration of the audio file playing (using the MediaPlayer) and calls the custom OnCompletionListener event after the playback is finished using postDelayed.
In the handling of the OnCompletionListener event, you just need to start playing the next audio file.

Related

How to implement release function in soundpool?

hy,,im newbie for android,i have error
AudioFlinger could not create track, status: -12 when running my application. i read for use release() method for fix it, but i don't know how to implement on my code, please help me ?? this is my code,please fix it :)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.talempong);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
spool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundID = spool.load(this, R.raw.doo, 1);
ImageButton Button = (ImageButton)findViewById(R.id.imagebutton1);
Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Sound();
}
});
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
spool2 = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundID2 = spool2.load(this, R.raw.re, 1);
ImageButton Button2 = (ImageButton)findViewById(R.id.imagebutton2);
Button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Sound2();
}
});
Is your sound greater that 1MB? SoudPool doesn't plays sounds that are greater that that.
If it isn't you can use the release after playing the sound.
// your code:
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
spool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundID = spool.load(this, R.raw.doo, 1);
//after this you have to:
spool.setOnLoadCompleteListener(new OnLoadCompleteListener(){
#Override
public void onLoadComplete(SoundPool sound,int sampleId,int status){
spool.play(teste, 20,20, 1, 0, 1);
new Thread(new Runnable(){
#Override
public void run(){
try {
Thread.sleep(2000);
spool.release();
} catch (InterruptedException e) { e.printStackTrace(); }
}
}).start();
}
});
// in the Thread.sleep put the value in millisecs of the time of your music this is a sample os 2 seconds

Passing soundpool to multiple activities in Android

Basically, in a short explanation, I am making a sound board. Once I run the initial activity, it adds all sound clips to the soundpool. I then have two other activities that are to organize the sound clips, and I would like to use the previously loaded soundpool so that there isn't move load time when switching between activities. I am fairly new to this Android coding, so please make things in simple terms!
EDIT: Also, does anybody know how to stop the playback on a second button click? Not as in clicking a different button, I understand that, but if the same button is clicked, it will stop it?
My main activity:
private SoundManager mSoundManager;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
mSoundManager = new SoundManager();
mSoundManager.initSounds(getBaseContext());
mSoundManager.addSound(0, R.raw.stop_playing);
mSoundManager.addSound(1, R.raw.sound1);
mSoundManager.addSound(2, R.raw.sound2);
mSoundManager.addSound(3, R.raw.sound3);
Dealing with soundpool stuff:
public void initSounds(Context theContext) {
mContext = theContext;
mSoundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
mSoundPoolMap = new HashMap<Integer, Integer>();
mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
}
public void addSound(int Index,int SoundID)
{
mSoundPoolMap.put(Index, mSoundPool.load(mContext, SoundID, 1));
}
public void pauseSound(){
mSoundPool.autoPause();
}
public void stopSound(){
mSoundPool.stop(playingNumber);
}
public int playSound(int index) {
int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int soundId = mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f);
mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f);
playingNumber = index;
return playingNumber;
}
}
Alwade create Application class, and create static SoundManager instance in the your application class, and add needed sounds to SoundManager in the Initial activity. Then you can use current Soundmanager in other activities. Change SoundManager class to static class.
For example:
public class MyApplication extends Application {
public static SoundManager soundManager;
public static SoundManager getSoundManager() {
return soundManager;
}
public static void setSoundManager(SoundManager soundManagerIns) {
soundManager = soundManagerIns;
}
}
and in the initial activity create instance and set it to :
mSoundManager = new SoundManager();
mSoundManager.initSounds(getApplicationContext);
mSoundManager.addSound(0, R.raw.stop_playing);
mSoundManager.addSound(1, R.raw.choo_choo);
mSoundManager.addSound(2, R.raw.all);
mSoundManager.addSound(3, R.raw.hearts);
MyApplication.setSoundManager(mSoundManager);
Then you can get this SoundManager in the other activities:
SoundManager sManager = MyApplication.getSoundManager();
This is my example project: SoundPoolExample

How do you return audio focus to previously playing apps?

I'm new to android app development and have what I think is probably a pretty simple question, but I'm having trouble sussing out how to do what I want...
I have a simple application that plays a sound when a button is pressed. After the sound is played I'd like for the application to return the audio to whatever was playing before the application started (for example, if the music app is playing, the sound should interrupt music while it plays, and then return control and resume music playing. I tried using the setOnCompletionListener method, but with no joy.
Here's the code:
public class MainActivity extends Activity implements OnClickListener{
public MediaPlayer mp = null;
public ImageButton playm = null;
public AudioManager audioManager = null;
/** called when activity first created */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
//Sigh Button
playm = (ImageButton) findViewById(R.id.sighButton);
playm.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v==playm){
OnAudioFocus onAudioFocus=new OnAudioFocus(this);
audioManager.requestAudioFocus(onAudioFocus, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
playSighSound();
}
}
public void playSighSound(){
mp = MediaPlayer.create(this, R.raw.ohboy);
try {
mp.start();
mp.setOnCompletionListener(new OnCompletionListener(){
#Override
public void onCompletion(MediaPlayer mp){
mp.release();
}
});
} catch (IllegalArgumentException e){
e.printStackTrace();
} catch (IllegalStateException e){
e.printStackTrace();
}
}
}
class OnAudioFocus implements AudioManager.OnAudioFocusChangeListener{
MainActivity onAudioFocus;
public OnAudioFocus(MainActivity onAudioFocus){
this.onAudioFocus = onAudioFocus;
}
public void onAudioFocusChange(int focusChange) {
switch(focusChange){
case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
onAudioFocus.playSighSound();
break;
}
}
}
I know Im little late, but here is implementation on how to get audio focus when needed and release it when you are done with playing your audio.
The background apps, that are playing audio, will stop when you gain audio focus requestAudioFocus() for your application, and will continue where they have stopped, after you release the audio focus releaseAudioFocus().
Also, have implementation for API 26 and above.
public class AudioFocusManager {
Context context;
private AudioFocusRequest audioFocusRequest;
public AudioFocusManager(Context context) {
this.context = context;
}
public void requestAudioFocus() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
audioFocusRequest =
new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
.build();
getAudioManager().requestAudioFocus(audioFocusRequest);
} else {
getAudioManager().requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
}
}
public void releaseAudioFocus() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (audioFocusRequest != null) {
getAudioManager().abandonAudioFocusRequest(audioFocusRequest);
audioFocusRequest = null;
}
} else {
getAudioManager().abandonAudioFocus(null);
}
}
private AudioManager getAudioManager() {
return ((AudioManager) context.getSystemService(Context.AUDIO_SERVICE));
}
}

Soundpool different streamid

I have soundpool that will load file from sd-card and I used mstreamID to stop it and I use mstreamID in OnLoadCompleteListener so the files can load. I use 2 buttons to play soundpool diffrent sounds. But when I click first button and while it plays 1 sound I click second button and it stops the sound from first button.
Here is my code:
public class MainActivity extends Settings {
SoundPool mSoundPool;
int mSoundId;
int mStreamId = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
mSoundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
mSoundPool
.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
public void onLoadComplete(SoundPool soundPool,
int sampleId, int status) {
mStreamId = soundPool.play(sampleId, 1, 1, 1, 0, 1f);
}
});
}
//OnClick
public void button1(View view) {
if (mStreamId != 0) {
mSoundPool.stop(mStreamId);
}
// et1 is extended from Settings.java
String path = getFullFilePath(getApplicationContext(), et1.getText()
.toString());
mSoundId = mSoundPool.load(path, 1);
}
public void button2(View view) {
if (mStreamId != 0) {
mSoundPool.stop(mStreamId);
}
String path = getFullFilePath(getApplicationContext(), et2.getText()
.toString());
mSoundId = mSoundPool.load(path, 1);
}
Read doc please, and what is the thing you want to say?
do not load same file more than one time if you not unload it.
load all sound at start when use SoundPool.
streamId is increasing all the time, you never get same streamId.

Play Sequence of audio files with SoundPool class of Android

I have three sound files in raw folder. I want to play them one after another with no delay between them. I tried them playing with below code but all three files are playing together, not one after another. All three files are less then 50 kb. I also want to change their playback rate, that's why I am using SoundPool instead of MediaPlayer.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
mSoundPoolMap = new HashMap<Integer, Integer>();
mAudioManager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
final int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
mSoundPoolMap.put(1, mSoundPool.load(this, R.raw.nancy, 1));
mSoundPoolMap.put(2, mSoundPool.load(this, R.raw.cymbal, 1));
mSoundPoolMap.put(3, mSoundPool.load(this, R.raw.njs, 1));
Button SoundButton = (Button)findViewById(R.id.Button);
SoundButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mSoundPool.play(mSoundPoolMap.get(1), streamVolume, streamVolume, 1, 0, 1f);
mSoundPool.play(mSoundPoolMap.get(2), streamVolume, streamVolume, 1, 0, 1f);
mSoundPool.play(mSoundPoolMap.get(3), streamVolume, streamVolume, 1, 0, 1f);
}
});
In order to do what you're trying to do, you'll probably have to create your own custom AsyncTask that takes in an array of SoundPool objects (or perhaps a HashMap), the implementation along the lines of:
private class SoundPoolTask extends AsyncTask <Soundpool, String, String>
{
#Override
protected String doInBackground(SoundPool... params) {
try {
//For each SoundPool object
// int soundLength = however long the SoundPool object is
// Play the sound
// Thread.sleep(soundLength);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {}
#Override
protected void onPostExecute(String result) {
//Clean up your class objects
}
}
You'll probably have to do some sort of calculation with the original length of the sound and the playrate to determine how long each sound is. I hope this helps!
I got same problem, so I create my own logic. Her it is:-
I have three audio file in my raw folder. I want to run these three file in sequence. To do this I follow this flow:-
Step1:- On clicking Button a thread will be generated.
Step2:- Thread will start a timer of 20 milliseconds.
Step3:- In timer it will check if media player is not playing.
If media player is not playing it will call a function to start media player.
Step4:- In function which will start the media player have switch logic which will decide which audio
file will be ON ( with help of a variable v).
Here is my code:-
public class MainActivity extends Activity {
int v=0;
TimerTask time;
MediaPlayer mp ;
Button btn;
void playmp(int a)
{
switch (a)
{
case 0:
{
mp = MediaPlayer.create(this,R.raw.a);
mp.start();
v++;
break;
}
case 1:
{
mp = MediaPlayer.create(this,R.raw.b);
mp.start();
v++;
break;
}
case 2:
{
mp = MediaPlayer.create(this,R.raw.c);
mp.start();
v++;
break;
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn= (Button) findViewById(R.id.button1);
mp = MediaPlayer.create(this,R.raw.a);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//Creating Thread
Thread thread = new Thread()
{
#Override
public void run() {
try {
sleep(1);
// Body Of Timer
time = new TimerTask() {
#Override
public void run() {
//Perform background work here
if(!mp.isPlaying())
{
playmp(v);
}
}
};
//Starting Timer
Timer timer = new Timer();
timer.schedule(time, 10, 20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
});
}
where "a","b"and "c" are my audio file name . If you want repeat audio after completing all three , replace this:-
case 2:
{
mp = MediaPlayer.create(this,R.raw.c);
mp.start();
v++;
break;
}
by this
case 2:
{
mp = MediaPlayer.create(this,R.raw.c);
mp.start();
v=0;
break;
}

Categories

Resources