I have the counter working (thanks for the help) and I have added sound using MediaPlayer, the problem is that there is a delay loading the counter because the sounds are loaded on the same class.
Is there a way to pre-load the sounds using the main class, so then, when the counter is called, the numbers are buffered and can be called from this class?
The application has a splash screen and the only purpose is to load anything needed by the other classes to avoid delays.
If sounds can't be loaded from another class, could they be loaded individually at play time?
This is what I have so far...
final boolean sound = timer_sound.getBoolean("timer_sound", true);
final MediaPlayer number01 = MediaPlayer.create(this, R.raw.number_1);
final MediaPlayer number02 = MediaPlayer.create(this, R.raw.number_2);
final MediaPlayer number03 = MediaPlayer.create(this, R.raw.number_3);
final MediaPlayer number04 = MediaPlayer.create(this, R.raw.number_4);
final MediaPlayer number05 = MediaPlayer.create(this, R.raw.number_5);
final MediaPlayer number06 = MediaPlayer.create(this, R.raw.number_6);
final MediaPlayer number07 = MediaPlayer.create(this, R.raw.number_7);
final MediaPlayer number08 = MediaPlayer.create(this, R.raw.number_8);
final MediaPlayer number09 = MediaPlayer.create(this, R.raw.number_9);
final MediaPlayer number10 = MediaPlayer.create(this, R.raw.number_10);
final MediaPlayer number15 = MediaPlayer.create(this, R.raw.number_15);
final MediaPlayer number20 = MediaPlayer.create(this, R.raw.number_20);
lastSeconds = (TextView) findViewById(R.id.lastminuteseconds);
lastMinute = new CountDownTimer(60 * 1000, 1000) {
public void onTick(long secondsToStart) {
int elapseTime = (int) (secondsToStart / 1000);
if (sound == true){
switch(elapseTime) {
case 1: number01.start();break;
case 2: number02.start();break;
case 3: number03.start();break;
case 4: number04.start();break;
case 5: number05.start();break;
case 6: number06.start();break;
case 7: number07.start();break;
case 8: number08.start();break;
case 9: number09.start();break;
case 10: number10.start();break;
case 15: number15.start();break;
case 20: number20.start();break;
}
}
this is working almost fine, the problem is that there is a 2 second delay loading the files, and I wanted to add few more (50, 40, 30).
Your approach seems very wasteful. You should load the first sound, and upon playing it trigger the load of the next sound, so at any time you are only caching two sounds (current and next) in RAM.
So you pre-load only first sound, then in ontick() you trigger load of next sound upon playing current sound via run() and swap the sound objects for next ontick().
I am learning slowly and I have figured this out.
I can't believe how simple it was to do this....
Not to put all the code, here are the changes done;
First, I stop loading the sound with the switch, but I used the switch call a class..
if (sound == true){
switch(elapseTime) {
case 1: number01();break;
case 2: number02();break;
Then, I load the sounds when the class is called;
public void number01(){
final MediaPlayer number01 = MediaPlayer.create(this, R.raw.number_1);
number01.start();
}
public void number02(){
final MediaPlayer number02 = MediaPlayer.create(this, R.raw.number_2);
number02.start();
}
Now when the switch is called and it loads the sound and plays it. This stops the delay when loading the application.
I hope this helps other beginners, that like me, are learning by making mistakes and correcting them.
Related
I'm having trouble with the following:
I have a spinner with different songs in it. In the spinner, users can preview the selected sound. I already developed that part. But my problem is: when I select one song from the list it will play. Then when we select another song from the list, Mediaplayer doesn't stop and plays the previous song also. But what I need is to stop the previous song when a user selects another song.
Here is my code...
//set onClickListner to the onItem SelectedListner
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
choose_ringtone = (int) id;
// Toast.makeText(setAlarm.this,"The selected choice is "+ id,Toast.LENGTH_SHORT).show();
String ringtSound = String.valueOf(parent.getItemAtPosition(position));
//set ringtone options
switch (ringtSound) {
case "alarm Sound 1":
mp = MediaPlayer.create(setAlarm.this, R.raw.wake_up);
break;
case "alarm Sound 2":
mp = MediaPlayer.create(setAlarm.this, R.raw.alarm);
break;
case "alarm Sound 3":
mp = MediaPlayer.create(setAlarm.this, R.raw.wake_up_tone);
break;
case "alarm Sound 4":
mp = MediaPlayer.create(setAlarm.this, R.raw.sweet_alarm);
break;
case "alarm Sound 5":
mp = MediaPlayer.create(setAlarm.this, R.raw.morning_alarm);
break;
default:
break;
}
if(mp!=null) {
mp.start();
}
Before the switch statement, you could do something like
if (mp != null && mp.isPlaying()) {
mp.stop();
}
I am not sure what the rest of your code looks like, but please make sure that it also follows the tips from Android Developers, specifically:
It is also recommended that once a MediaPlayer object is no longer being used, call release() immediately so that resources used by the internal player engine associated with the MediaPlayer object can be released immediately. Resource may include singleton resources such as hardware acceleration components and failure to call release() may cause subsequent instances of MediaPlayer objects to fallback to software implementations or fail altogether. Once the MediaPlayer object is in the End state, it can no longer be used and there is no way to bring it back to any other state.
Try this,,Before start Play call below function.
switch (ringtSound) {
case "alarm Sound 1":
stopPlaying()
mp = MediaPlayer.create(setAlarm.this, R.raw.wake_up);
mp.start();
break;
}
Call the function to stop sound.
private void stopPlaying() {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
}
Try mp.stop(); before start any sound...
I am having trouble with MediaPlayer. In the enclosed code, when a button is touched, a voice cue is activated when the option to do so is selected. However, the voice works for approximately 31 times and then the sound goes off. Using the .release() method (which I have commented out for now) causes the sound to not work at all.
How can I correct this function?
Thank You
....
import android.media.MediaPlayer;
....
MediaPlayer mp = null;
........
// Causes the name of the appropriate cell to be announced
public void sayCellName() {
if(voiceChoice == false) return;
else{
switch(cellName){
case 1:
mp = MediaPlayer.create(this, R.raw.poly);
break;
case 2:
mp = MediaPlayer.create(this, R.raw.lymph);
break;
case 3:
mp = MediaPlayer.create(this, R.raw.mono);
break;
case 4:
mp = MediaPlayer.create(this, R.raw.eo);
break;
case 5:
mp = MediaPlayer.create(this, R.raw.baso);
break;
case 6:
mp = MediaPlayer.create(this, R.raw.band);
break;
default:
break;
} // end switch statement
} // end else statement;
mp.start();
// mp.release();
} // end of sayCellName
} // end of main
The Android OS has a hard-coded limit of audio track resources that may play back sound simultaneously. As it so happens that limit is 32 tracks that have to be shared by all running applications. What you are doing is wasting these tracks by creating fresh MediaPlayers on each button click without releasing them.
For your scenario you should probably create and reuse a single MediaPlayer instance and release it when your Activity stops. It is possible to reset a MediaPlayer and set a different stream data source afterwards.
You have to release the player OnPause or OnDestroy method.
#Override
public void onPause() {
if (mp!= null) mp.release();
}
I have the following code snippet. Not sure why, when clicked on the exit button the media player doesn't stop, even though exiting the game should stop all activities in it.
Any help would be appreciated.I have tried stop(), release(), reset() and setting to null. Please let me know where am I going wrong.
public void onClick(View v){
// The background music of the game
MediaPlayer back_music = MediaPlayer.create(getBaseContext(), R.raw.sher_khan);
switch (v.getId()){
case R.id.new_game:
openNewGameDialog();
break;
case R.id.about_game :
Intent i = new Intent(this, About.class);
startActivity(i);
break;
case R.id.exit_game :
if(back_music.isPlaying()){
back_music.release();
back_music.reset();
back_music = null ;
//onDestroy();
}
finish();
break;
case R.id.sound :
// Looping the music
//back_music.setLooping(true);
// Identifying and kind of looping through the sound_selector items
if(v.isSelected()){
v.setSelected(false);
play = false;
//Music start for the media player
back_music.start();
}
else if (!v.isSelected()){
//speaker.setSelected(false);
back_music.stop();
back_music.release();
v.setSelected(true);
play = true;
back_music.release();
}
}
Please try the following :
create your media player on the on create and declare it as a member of your ACTIVITY :
MediaPlayer back_music;
public class MainACtivity(){
....
....
onCreate(){
back_music= MediaPlayer.create(getBaseContext(), R.raw.sher_khan);
.....
}
then delete the the row "MediaPlayer back_music = MediaPlayer.create(getBaseContext(), R.raw.sher_khan);"
and give it a another shot :)
hope it helps you .
extreme newbie here!
I have ten soundclips in the /res/raw directory. I am using a single MediaPlayer instance (mp2) to play the clips. I am currently using if statements to select the desired clip to play but I'm sure there is a more efficient way to do this. I want to change which of the ten clips is being played based on the value of the counter variable...so that if counter=1 clip "one" is played, if counter=2 clip "two" is played, etc.
Also a related question... if I have these ten clips in 4 different languages, how do I reference the correct clip based on user selection of the language within the app? (not system locale setting)
switch (me.getAction()) {
case MotionEvent.ACTION_DOWN:
touched = true;
counter = (counter + 1);
// get soundfile from resources
mp = MediaPlayer.create(getBaseContext(), R.raw.hammer_blow);
mp.start(); // Starts your sound
if (counter == 1) {
mp2 = MediaPlayer.create(getBaseContext(), R.raw.one);
mp2.start();
}// Starts your sound
if (counter == 2) {
mp2 = MediaPlayer.create(getBaseContext(), R.raw.two);
mp2.start();
}// Starts your sound
if (counter == 3) {
mp2 = MediaPlayer.create(getBaseContext(), R.raw.three);
mp2.start();
}// Starts your sound
I would refactor the code to just include a switch on the counter;
int sound;
switch (counter)
{
case 1:
sound = R.raw.one;
break;
case 2:
sound = R.raw.two;
break;
etc.
}
mp2 = MediaPlayer.create(getBaseContext(), sound);
mp2.start();
I don't know about the language stuff. Maybe it's possible to set the app language to a user selected value? Then the raw resources would be figured out correctly.
I have a program with a function copied below it plays a sound upon clicking a button. If you click the button 10 times 10 different media players play the same sound that is the way i want it but how can i assign a button to stop all 10 media players at a time like a "STOP ALL BUTTON"
public void onClick(View v){
int resId = 0;
int stopped = 0;
switch (v.getId()){
case R.id.Wail:
resId = R.raw.fedsigwail;
break;
case R.id.Yelp:
resId = R.raw.fedsigyelp;
break;
case R.id.HiLow:
resId = R.raw.hilow;
break;
case R.id.FederalQ:
resId = R.raw.federalq;
break;
case R.id.Horn:
resId = R.raw.fedsignhorn;
break;
case R.id.STOPALL:
mp.stop();
mp.release();
stopped = 1;
break;
}
if (stopped != 1){
mp = MediaPlayer.create(this, resId);
mp.start();
}
}
The code above only stops the last instance of mp.
Any Input would be appreciated
mp.stop(); only stops one instance of a media player, since mp can only be one mediaplayer instance.
If mp is one of your media players, where are the other ones? You mentioned you have
10 different media players
so I would expect something like mp1, mp2, mp3, ..., mp10. But right now it seems you actually only using one media player instance, or at least stopping it.
With each call of
mp = MediaPlayer.create(this, resId)
you lose the reference to the previous created media player, since you 'override' it with a newly created instance.
You need to keep a reference to all your created media players, i.e. via an ArrayList or HashMap or similar.