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
Related
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.
I am searching for a long time on net, and many answers advised to use the setVolume in MediaPlayer.OnPreParedListener, it works when I use it before MediaPlayer.start().
But now there is a button, I want to control mute or unmute when the video is playing, so how to resolve it?
Use this code
private static int aux = 0;
private Button mMuteButton;
private static int aux = 0;
private AudioManager mAudioManager;
//set the Mute button on clickListener inside the class android cycle where needed
mMuteButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
if(aux % 2 == 0){
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 100, 0);
aux++;
} else {
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
aux++;
}
}
});
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.
I am facing a vague issue with sound manager. Only the first sound that I load, works. The 2nd sound does not.
Initialization, here WRONG_SOUND does not load.
Globals.mSoundManager = new SoundManager();
Globals.mSoundManager.initSounds(getBaseContext());
Globals.mSoundManager.addSound(Globals.CORRECT_SOUND, R.raw.correct);
Globals.mSoundManager.addSound(Globals.WRONG_SOUND, R.raw.wrong);
If I reverse the loading, CORRECT_SOUND does not load
Globals.mSoundManager = new SoundManager();
Globals.mSoundManager.initSounds(getBaseContext());
Globals.mSoundManager.addSound(Globals.WRONG_SOUND, R.raw.wrong);
Globals.mSoundManager.addSound(Globals.CORRECT_SOUND, R.raw.correct);
Constructor of SoundManager
public void initSounds(Context theContext) {
mContext = theContext;
mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
mSoundPool.setOnLoadCompleteListener(this);
mSoundPoolMap = new HashMap<Integer, Integer>();
mAudioManager = (AudioManager) mContext
.getSystemService(Context.AUDIO_SERVICE);
}
addSound method
public synchronized void addSound(int Index, int SoundID) {
mSoundPoolMap.put(Index, mSoundPool.load(mContext, SoundID, 1));
synchronized(this) {
try {
this.wait(1000) ;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
SoundManager implements OnLoadCompleteListener
#Override
public void onLoadComplete(SoundPool arg0, int arg1, int arg2) {
synchronized (this) {
this.notifyAll();
}
}
I thought it was a load issue, so I added a OnLoadCompleteListener, but still the 2nd sound loaded fails to work.
To fix this I had to change the mp3 file, and it worked. Magically the mp3 file works on media player of Android, also on the mac. But for some reason this crazy change to a new mp3 was the only way to fix it. Many SO questions have this solution too.
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;
}