Timed sound effect happening twice via Handler - android

My activity plays a specific sound effect once every second.
The following code works, however there is a bug: occasionally the sound is played TWICE every second. This only happens every once in a while (once every 10-20 attempts). When it happens, the double sound occurs for the entire run of the activity, start to finish. So, if I see the activity started without the bug, it stays that way for the entire run of the activity.
Here's the relevant code - what's the problem with it? Thank you!
private Handler mHandler = new Handler();
#Override
protected void onResume() {
super.onResume();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.post(mUpdateTimeTask);
}
#Override
protected void onPause() {
// Another activity is taking focus (this activity is about to be "paused").
mHandler.removeCallbacks(mUpdateTimeTask);
super.onPause();
}
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
PlayTick();
mHandler.removeCallbacks(this);
mHandler.postDelayed(this, 1000);
}
};
public void PlayTick() {
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;
soundPool.play(soundID, volume, volume, 1, 0, 1f);
}

Found a solution - seems it's a known SoundPool bug, it sometimes plays the effect twice. I used a .wav file; converting the file to .ogg seems to resolve the issue.

Related

Set the volume of youtubeplayer api over time android

I have been integrating the YoutubePlayer API for with my Android project. The videos from the playlist are working well. What I am trying to do is have the audio start low and fade in over 30seconds.
What I have done so far, for some reason is doing somthing really weird. It set it to max volume and if you try to turn it down it turns it back up again really straight away.
The way I thought I could do it was to set the audio manager to a 0 volume and then on an ontick timer raise that by 1 until it got to the max volume.
The code below was my attempt, but like I said it is doing weird things.
Thanks for your help
youTubePlayer.loadPlaylist(playListTitle);
final AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
// Add listeners to YouTubePlayer instance
youTubePlayer.setPlayerStateChangeListener(new YouTubePlayer.PlayerStateChangeListener() {
#Override
public void onLoaded(String arg0) {
youTubePlayer.play();
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
Integer volumeRaisingTime = 30000;
new CountDownTimer(volumeRaisingTime, 1000) {
Integer deviceMaxVolume = 20;
Integer devicevolume = 0;
public void onTick(long millisUntilFinished) {
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 20, 0);
if (devicevolume > deviceMaxVolume){
devicevolume++;
Log.d("Device Volume:", ""+devicevolume);
}
}
public void onFinish() {
}
}.start();
}

Android sounds not playing after successive button clicks

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.

Lags while playing 2 sounds on the same time in timer

I have a small app that basically sets up a timer and plays sets of 2 sounds one after another.
I've tried 2 timers, because I wanted both sounds to start exactly at the same time each time. I gave the app 500ms for setting both timers before they start
Calendar cal = Calendar.getInstance();
Date start = new Date(cal.getTime().getTime() + 500);
timerTask1 = new TimerTask() { //1st timer
#Override
public void run() {
soundManager.playSound(1);
}
};
timer1 = new Timer();
timer1.schedule(timerTask1, start, 550);
timerTask2 = new TimerTask() { //2nd timer
#Override
public void run() {
soundManager.playSound(2);
}
};
timer2 = new Timer();
timer2.schedule(timerTask2, start, 550);
}
soundManager is a SoundManager object which is based on this tutorial. Thew only change I've made was decreasing number of avalible streams from 20 to 2 since I play only 2 sounds at the same time.
Now the problem. It's not playing at the equal rate neither on my Motorola RAZR or the emulator. The app slows sometimes, making a longer brake than desired. I can't let that happen. What could be wrong here?
I'm using very short sounds in OGG format
EDIT:
I've made some research. Used 2 aproaches. I was measuring milisecond distances between sound was fired. Refresh rate was 500 ms.
1st aproach was TimerTask - it is a big fail. It started at 300ms, then was constantly growing, and after some time (2 mins) stabilized at 497ms which would be just fine if it started as that.
2nd aproach was while loop on AsyncTask - it was giving me outputs from 475 to 500ms which is better than TimerTask but still inaccurate
At the end none of aproach was playing smoothly. There were always lags
I know it may be a little too much, but you could try a different implementation of SoundPool:
public class Sound {
SoundPool soundPool;
int soundID;
public Sound(SoundPool soundPool, int soundID) {
this.soundPool = soundPool;
this.soundID = soundID;
}
public void play(float volume) {
soundPool.play(soundID, volume, volume, 0, 0, 1);
}
public void dispose() {
soundPool.unload(soundID);
}
}
To use it you can do something like this:
SoundPool soundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
AssetFileDescriptor assetFileDescriptor = activity.getAssets().openFd(fileName);
int soundID = soundPool.load(assetFileDescriptor, 0);
Sound sound = new Sound(soundPool, soundID);
And then play:
sound.play(volume);
P.S. If the problem persists even with this code, post a comment and I'll get back to you.
Are you using SoundPool? It is quicker than MediaPlayer. The best chance of getting the two sounds together is when playing them on the same thread.

Forever playing without pause in Android

I have a problem. When I try to play sound using Soundpool there is small pause between each playing.
For example, I have 2 sec-sound which I want to play when button is pressed.
I tried to start 2 threads with the same sound. Second started 0.5 sec after first. But there is no helpful.
AudioManager mAudioManager;
SoundPool mSoundPool;
Runnable thr1;
Runnable thr2;
public void playLoopedSound(int soundId) {
mSoundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)*2;
thr1 = new Runnable() {
public void run() {
mSoundPool.play(soundId, 0, streamVolume, 1, -1, 1f); //0 = no loop, -1 = loop forever
}
};
thr2 = new Runnable() {
public void run() {
mSoundPool.play(soundId, 0, streamVolume, 1, -1, 1f);
}
};
thr1.run();
try {
Thread.sleep(400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
thr2.run();
}
It's hard to know without debugging, but I've had similar issues due to the performance of soundpool when it's loading sounds. To get around this, I implemented SoundPool.onLoadCompleteListener to ensure that I didn't start trying to play sounds until the soundpool was fully loaded.
Be aware that this is only available on API8 or above. See this answer for a nice implementation:
Knowing if the loading of a sound with SoundPool has been successful on Android 1.6/2.0/2.1

A click noise is happening at the end of the Audio playing.

I am having a couple problems I could really use some help on both. The first is I am trying to get an audio file to play when the application is started and as soon as the shake occurs it stops. (It is not playing it at all on either screen it is supposed to). The other issue I am having is when I shake the phone an audio is supposed to play. It is doing just that, but the problem is that at the end of the audio playing it make a pop sound. That noise isn't on the audio files so I am not exactly sure where that sound is coming from. Any help would be appreciated. Thanks in advance.
public class Ask extends Activity{
private SensorManager mSensorManager;
private ShakeEventListener mSensorListener;
String[] answer;
int possibleAnswers, randomAnswer, talkRun=0;
long lastClick;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ask);
final Random generator = new Random();
//Sounds
final SoundPool sounds = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
final int sound0 = sounds.load(this, R.raw.coughing, 1);
final int sound25 = sounds.load(this, R.raw.askbud, 1);
sounds.play(sound25, 1f, 1f, 1, 0, 1f);
mSensorListener = new ShakeEventListener();
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
final TextView tv = (TextView)findViewById(R.id.answer);
mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() {
public void onShake() {
if (System.currentTimeMillis() - lastClick > 500) {
lastClick = System.currentTimeMillis();
sounds.stop(sound25);
sounds.stop(sound0);
randomAnswer = generator.nextInt(possibleAnswers);
if(randomAnswer==0){
sounds.play(sound0, 1f, 1f, 1, 0, 1f);
}
}
}
});
}
#Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
}
#Override
protected void onStop() {
mSensorManager.unregisterListener(mSensorListener);
super.onStop();
}
}
I also had this sound click problem (or pop as you call it) at the end of the sounds I was playing. My files were .wav files then, but he click sound disappeared after I converted the sound files to .ogg.
I was experiencing this on the Android emulator.
its not working in the on create because sounds are not loaded yet when you call play here
sounds.play(sound25, 1f, 1f, 1, 0, 1f);
please look at
public void setOnLoadCompleteListener (SoundPool.OnLoadCompleteListener listener)
http://developer.android.com/reference/android/media/SoundPool.html#setOnLoadCompleteListener(android.media.SoundPool.OnLoadCompleteListener)
I fixed it by switching from using sound pool to using media player. Also got to make sure to release() or it was causing other problems like the sound stopped playing.

Categories

Resources