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

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.

Related

How to speed up SoundPool in Android?

I am attempting to create a simple Morse code application. When the user presses a button the Morse sound should start before ending when released.
The problem is the latency- the Morse sound does not start until roughly 400ms after the user presses the button. I am not sure why this is exactly but after researching the problem i think it is the way my code is structured. The file i am trying to play is in Mp3 format and is located in the raw folder.
I had this completed using the Media Player but i ran into the same problem in regard it not being responsive enough so i opted to try and use Sound pool. Does anyone have any advice/suggestions as to how i can speed up the operation? This is new territory to me in regards development.
public int S1 = R.raw.morse;
private SoundPool soundPool;
private boolean loaded;
static int x;
public void initSounds(Context context) {
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
final int y = soundPool.load(context, R.raw.morse, 1);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
playSound(y);
}
});
}
public void playSound(int soundID) {
if(loaded) {
x = soundPool.play(soundID, 0.5f, 0.5f, 1, 0, 1f);
}
}
//Calling code
pad.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
//State of a toggle button
if(audioOnOff==true) {
//Sound pool object is created and initialized as a global variabe
sp.initSounds(getApplicationContext());
}
}
It looks to me like what's happening here is that each time the button is pressed, you're loading the sound, waiting for it to finish loading, then playing it. What you actually want is to load the sound once, then just play it each time the button is pressed.
So instead of calling initSounds in your onTouchListener, call initSounds somewhere else before the button is pressed. Then in your onTouchListener you just call your playSound method.
Finally, make sure you remove the playSound method call from your onLoadCompleteListener so you don't get a mysterious noise when you initially load up the sound ;)

Android SoundPool: Play a stopped sound again

I´m currently trying to play sounds in my android app with SoundPool API. Playing a sound is not the problem. Now I want to stop the sound and restart it later from beginning. But when i call the stop function and then play(), the sound is not played. Here is some code:
load the sound:
soundId = soundPool.load(context, fileId, 1);
play the sound:
streamId = soundPool.play(soundId, 1.0f, 1.0f, 1, -1, 1);
stop the sound:
soundPool.stop(streamId);
I also tried to load the sound again before playing it a second time, but that didn´t fixed it.
When I use pause/resume the sound is played from the position where it was stopped (but I want it always from beginning).
Any help would be appreciated
EDIT:
I just figured out something strange. When I use soundpool.stop(), it works every second time I call soundpool.play(). So the first call of play() plays the sound, the second not, the 3rd, 5th, 7th.. call plays the sound.
When I use soundpool.pause() and then play(), it works every third time. So the 1st, 4th, 7th... call of play() starts the sound.
Is it a bug? Or am I using it wrong?
i have created a simple project to do start and stop a sound and then play it again. here's the code
Button b1, b2;
private int streamId;
private int soundID;
private SoundPool sp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1 = (Button) findViewById(R.id.b1);
b2 = (Button) findViewById(R.id.b2);
sp = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
soundID = sp.load(this, R.raw.middle, 1);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.b1:
streamId = sp.play(soundID, 1, 1, 1, 0, 1f);
break;
case R.id.b2:
sp.stop(streamId);
break;
}
}
i worked properly in my case, if you are doing the same thing then problem may be somewhere else. If you could provide the some more detail then may be we can figure out what's the problem.
Play:
nowPlaying= soundPool.play(soundId, 1.0f, 1.0f, 1, -1, 1);
soundPool.stop(nowPlaying);
now reload it:
soundId = soundPool.load(this, R.raw.yoursound, 0);

Timed sound effect happening twice via Handler

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.

SoundPool Not Loading in Android App

I'm making an app where I'm trying to load a single sound onto a SoundPool so I can manage the playback rate when I want, play it when I want, and release it when I want. However, my SoundPool is not loading. I've tried to change a lot of different things and nothing seems to work. I put a Log.d in the OnLoadComplete function to see if it loads, and the log doesn't appear when running... Maybe after looking at my code somebody else could help me. Thanks!
private int currentVoice = 0;
private SoundPool voices = null;
....
public void onCreate(Bundle savedInstanceState) {
....
voices = new SoundPool(1, 3, 0);
voices.setOnLoadCompleteListener(this);
....
}
private void giveSentence() throws IOException {
....
voices.release();
currentVoice = voices.load(this, sentences[index].voice, 1);
voices.play(currentVoice, 1, 1, 1, 0, 1f);
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
soundPool.play(sampleId, 1, 1, 1, 0, 1f);
boolean loaded = true;
Log.d("Game","Is it loaded? " + loaded);
}
You should initialize your sound pool somewhere in a onCreate method, I guess.
private SoundPool voices;
#Override
public void onCreate(Bundle savedInstanceState) {
voices = new SoundPool(1, 3, 0);
voices.setOnLoadCompleteListener(this);
}
Fixed myself, I was doing voices.release(); before anything was loaded. For some reason that just turned the SoundPool off. Took out that line and did voices.release() after I checked if it was already loaded. Now it works.

Playing multiple sounds using SoundManager

If I play a single sound, it runs fine.
Adding a second sound causes it to crash.
Anyone know what is causing the problem?
private SoundManager mSoundManager;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sos);
mSoundManager = new SoundManager();
mSoundManager.initSounds(getBaseContext());
mSoundManager.addSound(1,R.raw.dit);
mSoundManager.addSound(1,R.raw.dah);
Button SoundButton = (Button)findViewById(R.id.SoundButton);
SoundButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mSoundManager.playSound(1);
mSoundManager.playSound(2);
}
});
}
mSoundManager.addSound(1,R.raw.dit);
mSoundManager.addSound(1,R.raw.dah);
You need to change the second line to:
mSoundManager.addSound(2,R.raw.dah);
In order to play multiple sounds at once, first you need to let the SoundPool know that. In the declaration of SoundPool notice that I specified 20 streams. I have many guns and bad guys making noise in my game, and each has a very short sound loop, < 3000ms. Notice when I add a sound below I keep track of the specified index in a vector called, "mAvailibleSounds", this way my game can try and play sounds for items that dont exist and carry on without crashing. Each Index in this case corresponds to a sprite id. Just so you understand how I map particular sounds to specific sprites.
Next we queue up sounds, with playSound(). Each time this happens a soundId is dropped into a stack, which I then pop whenever my timeout occurs. This allows me to kill a stream after it has played, and reuse it again. I choose 20 streams because my game is very noisy. After that the sounds get washed out, so each application will require a magic number.
I found this source here, and added the runnable & kill queue myself.
private SoundPool mSoundPool;
private HashMap<Integer, Integer> mSoundPoolMap;
private AudioManager mAudioManager;
private Context mContext;
private Vector<Integer> mAvailibleSounds = new Vector<Integer>();
private Vector<Integer> mKillSoundQueue = new Vector<Integer>();
private Handler mHandler = new Handler();
public SoundManager(){}
public void initSounds(Context theContext) {
mContext = theContext;
mSoundPool = new SoundPool(20, AudioManager.STREAM_MUSIC, 0);
mSoundPoolMap = new HashMap<Integer, Integer>();
mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
}
public void addSound(int Index, int SoundID)
{
mAvailibleSounds.add(Index);
mSoundPoolMap.put(Index, mSoundPool.load(mContext, SoundID, 1));
}
public void playSound(int index) {
// dont have a sound for this obj, return.
if(mAvailibleSounds.contains(index)){
int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int soundId = mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f);
mKillSoundQueue.add(soundId);
// schedule the current sound to stop after set milliseconds
mHandler.postDelayed(new Runnable() {
public void run() {
if(!mKillSoundQueue.isEmpty()){
mSoundPool.stop(mKillSoundQueue.firstElement());
}
}
}, 3000);
}
}

Categories

Resources