I have a sound clip play while I am displaying some numbers, then want it to stop. Then I want to repeat the process.
init stuff:
private SoundPool soundPool;
private int soundRoll;
boolean soundloaded = false;
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
soundloaded = true;
}
});
soundRoll = soundPool.load(this, R.raw.roll, 1);
Thread Call:
public void update() {
.......
new Thread(new Runnable() {
public void run() {
int streamID = 0;
streamID = soundPool.play(soundRoll, volume, volume, 1, -1, 1);
... loop to animate text....
soundPool.stop(streamID);
}
}).start();
}
This works fine every other time.
so the first time it plays and stops at the right time.
second time I hear nothing
but then it works the third time
If I take out the looping, then it works.
Any help would be appretiated
Seems that if I switch to an OGG file from an MP3, the bug goes away
Related
I want to play a short sound when a button is clicked using SoundPool. But when the button is clicked no sound appears despite the Log telling me it's loaded and "playing". The soundfile is an .ogg in case that's relevant. Here's my code, buttonSound() is called in onCreate().
void buttonSound(){
AudioAttributes attributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
soundPool = new SoundPool.Builder().setAudioAttributes(attributes).build();
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
Log.d("SOUNDPOOL", "COMPLETE "+button);
}
});
button = soundPool.load(this, R.raw.button, 1);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.button_back:
// Sound loaded
if(button != 0) {
soundPool.play(button, 1f, 1f, 1, 0, 1f);
Log.d("PLAYING", "PLAYING");
}
break;
So apparently AudioAttributes.USAGE_ASSISTANCE_SONIFICATION was the issue, it works fine with AudioAttributes.USAGE_GAME and AudioAttributes.USAGE_MEDIA. I have no idea why, though.
I am trying to play a sound in an app. However, using SoundPool I am unable to do so. The code is really simple and I don't see where it can fail.
A similar code but using MediaPlayer does work, but I am interested in using SoundPool.
SoundPool code:
private void playSound2(){
SoundPool sp = new SoundPool.Builder().build();
int soundID = sp.load(MainActivity.this, R.raw.sound, 1);
sp.play(soundID, 1, 1, 1, 0, 1);
}
Context:
public void goButtonClick(View view){
Button goButton = findViewById(id.button2);
if (onGoing){
goButton.setText("GO!");
} else {
goButton.setText("STOP");
//playSound(); // MediaPlayer
playSound2(); // SoundPool
}
onGoing = !onGoing;
}
MediaPlayer version (works):
private void playSound(){
MediaPlayer mediaPlayer;
mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.sound);
mediaPlayer.start();
}
Solved!
I was missing to wait for the loading of the sound file into soundPool. The correct code is:
private void playSound2() {
SoundPool sp = new SoundPool.Builder().build();
int soundID = sp.load(MainActivity.this, raw.sound, 1);
sp.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool sp, int soundID, int i1) {
sp.play(soundID, 1, 1, 1, 0, 1);
}
});
}
Recently I've been working on an android game, but have hit a problem when adding music and other sounds. I read that Mediaplayers are optimal for background music, which works well, and I read that Soundpool is optimal for short music clips like sound effects. However, I can't get the Soundpool to work, it appears that the Soundpool isn't even loading.
I did more research and found a lot of nightmare stories about Soundpool's lack of support, so should I just use a mediaplayer for all audio? Is this efficient?
//My Code
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int mySoundId, int status) {
loaded = true;
}
});
if(loaded==true){
soundId = soundPool.load(this, R.raw.sound1, 1);
soundPool.play(soundId, 1, 1, 1, 0, 1f);}
else{
System.exit(0);
}
//Forces the program to exit everytime
SoundPool#load method is asynchronous, you should play sound after onLoadComplete had been invoked
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int mySoundId, int status) {
soundPool.play(mySoundId, 1, 1, 1, 0, 1f);
}
});
soundPool.load(this, R.raw.sound1, 1);
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int mySoundId, int status) {
loaded = true;
soundId = soundPool.load(this, R.raw.sound1, 1);
soundPool.play(soundId, 1, 1, 1, 0, 1f);
}
});
because your loaded variable will be always false, you should do the things within the onLoadComplete.
I have one SoundPool in my Android app, but I don't know how to write code for 2 or more SoundPool instances. Is there a way to rework this code for multiple SoundPools?
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = findViewById(R.id.button1);
view.setOnTouchListener(this);
// Set the hardware buttons to control the music
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// 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);
}
public boolean onTouch( View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// 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);
Log.e("Test", "Played sound");
}
}
return false;
}
Try:
// 8 soundpools
SoundPool[] soundPool = new SoundPool[8];
int[] soundID = new int[8];
// You can have more that one set per sound if need, just make more raw sound
// arrays with different sounds.
// 8 sounds per soundpool
int[] rawSounds = new int[]{ R.id.sound1, R.id.sound2, R.id.sound3,
R.id.sound4, R.id.sound5, R.id.sound6,
R.id.sound7, R.id.sound8 };
boolean[] loaded = new boolean[8];
// Go through each soundpool
for(int i = 0; i < 8; i++)
{
soundPool[i] = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
// 8 sounds in one soundpool
for(int h = 0; h < 8; h++)
{
soundID[i] = soundPool.load(this, rawSounds[i], 1);
}
soundPool[i].setOnLoadCompleteListener(new OnLoadCompleteListener()
{
Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status)
{
// One boolean per soundpool
loaded[i] = true;
}
});
}
Then use a for loop to see what is being press for which sound and use soundID[i].play to play sounds.
Hope this helps even though a little late!)
In my activity there is a timer which send a message to a handler every second which changes a picture.
Every time user clicks the image a sound is played in onClickListner function of activity using this code:
MediaPlayer.create(this, R.raw.voice).start();
On a xperia arc (Android 4.0.4) the sound is not completely played and as soon as the timer triggers it stops. If I disable the timer there is no problem.
On a HTC Legend (Android 2.2) there is no problem. The sound is played completely.
I can't figure out the problem.
public class ActivityTest extends Activity implements View.OnClickListener, ViewSwitcher.ViewFactory
{
ImageSwitcher switcher;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test_listen);
switcher = (ImageSwitcher) findViewById(R.id.imageSwitcher);
switcher.setFactory(this);
switcher.setOnClickListener(this);
final Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
switcher.setImageDrawable(getResources().getDrawable(R.drawable.image));
// if this line is commented it works fine
}
};
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run()
{
handler.sendEmptyMessage(0);
}
}, 0, 1000);
}
#Override
public void onClick(View view)
{
MediaPlayer.create(this, R.raw.voice).start();
}
#Override
public View makeView()
{
ImageView image = new ImageView(this);
image.setScaleType(ImageView.ScaleType.FIT_CENTER);
image.setLayoutParams(new ImageSwitcher.LayoutParams(ImageSwitcher.LayoutParams.FILL_PARENT, ImageSwitcher.LayoutParams.FILL_PARENT));
return image;
}
}
Solution -------------------------------------
I moved the declaration of MediaPlayer to class and it fixed the problem.
MediaPlayer mp;
#Override
public void onClick(View view)
{
mp =MediaPlayer.create(this, R.raw.voice);
mp.start();
}
I don't know why the previous code works on 2.2 but not 4. anyway it worked.
since its a short sound your playing i'd recommend a soundpool. Soundpool clips are kept in memory for quick access since there small. Im assuming your playing a very short sound. in onCreate do this to preload it:
// Load the sound
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundID= soundPool.load(this, R.raw.voice, 1);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
}
});
then in the onclick method (when user clicks the image) do this:
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;
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
}
where soundPool is declared as a instance variable private SoundPool soundPool or something similar. Try that and let me know what happens.