I have done an android project on NFC and I want to add a warning tone after receiving NFC date succeed ,how can I do it?
Use SoundPool class. Place your audio files in /res/raw/ and first init loading them (for example in OnCreate Method) and then request to play selected audio file. here is code example:
private SoundPool soundPool;
private boolean tiltSoundsLoaded = false;
private int tiltSoundID;
private int tiltFailureSoundID;
public void initTiltSounds(Context context) {
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
tiltSoundsLoaded = true;
}
});
tiltSoundID = soundPool.load(context, R.raw.swosh_sound_effect, 1);
tiltFailureSoundID = soundPool.load(context, R.raw.fail_metallic, 1);
}
public void playTiltSound(AudioManager audioManager, boolean success) {
try{
int soundToPlay;
if(success)
soundToPlay = tiltSoundID;
else
soundToPlay = tiltFailureSoundID;
float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
if (tiltSoundsLoaded)
soundPool.play(soundToPlay, actualVolume, actualVolume, 1, 0, 1f);
else
Log.e(LOG_TAG, "Tilt Sound not loaded");
}catch(Exception e){
Log.e(LOG_TAG, "Could not play tilt sound");
}
}
Related
I have a piano app working with this method:
public void play(String note) {
score++;
score();
try {
mp = MediaPlayer.create(this, getResources().getIdentifier(note, "raw", getPackageName()));
mp.start();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer media) {
media.release();
}
});
} catch (Exception e) {
Log.e("Error", "error playing file : " + note + "\n" + e);
}
}
The issue is that if I press the keys too fast and several times i get errors like this:
E/MediaPlayer: error (1, -19)
These errors occur as I go on playing. But when I uninstall the app, something seems to reset, and I get less errors...Why is this happening and is there a solution for it?
As your code implies you are playing notes and not long MP3s, I suggest you use SoundPool instead of MediaPlayer. It is better suited for this kind of application as it pre-loads all the resources in advance.
An example of this kind of implementation:
private SoundPool soundPool;
private HashMap<String, Integer> soundNameToSoundIdMap;
private void initSoundMap() {
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
soundNameToSoundIdMap = new HashMap<String, Integer>();
soundNameToSoundIdMap.put("note_a", loadSound(getContext(), R.raw.note_a));
soundNameToSoundIdMap.put("note_b", loadSound(getContext(), R.raw.note_b));
}
private int loadSound(Context context, int resId) {
return soundPool.load(context, resId, 1);
}
public void play(String note) {
score++;
score();
Integer soundId = soundNameToSoundIdMap.get(note);
if (soundId != null){
soundPool.play(soundId.intValue(), 100, 100, 1, 0, 0);
}
}
I am trying to play a sound in my activity using SoundPool but I am unable to hear the sound.
private void beginGame(){
setContentView(R.layout.activity_splash1);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){
AudioAttributes aa = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_GAME)
.build();
sp = new SoundPool.Builder()
.setMaxStreams(10)
.setAudioAttributes(aa)
.build();
}else{
sp = new SoundPool(10, AudioManager.STREAM_MUSIC,1);
}
sid = sp.load(Splash1.this,R.raw.bubble,1);
sp.play(sid,1,1,1,0,0.99f);
Thread loading = new Thread() {
public void run() {
try {
sleep(2000);
// TODO NEXT ACTIVITY
}
catch (Exception e) {
e.printStackTrace();
}
finally {
finish();
}
}
};
loading.start();
}
Initially, in a project i worked on, i had a class like [AnswerSound] the one below, so i always get instance of it and call any method as i need. I hope you can look at at and kick of from it.
public class AnswerSound {
private final float volume;
private Context context;
private SoundPool correctAnswerSoundPool;
private int correctAnswerSoundID;
boolean correctLoaded = false;
private SoundPool wrongAnswerSoundPool;
private int wrongAnswerSoundID;
boolean wrongLoaded = false;
public AnswerSound(Context context)
{
this.context = context;
correctAnswerSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 10);
correctAnswerSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener(){
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
correctLoaded = true;
}
}
);
wrongAnswerSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 10);
wrongAnswerSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener()
{
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
wrongLoaded = true;
}
}
);
//assign the sound IDS
correctAnswerSoundID = correctAnswerSoundPool.load(context, R.raw.correct_answer, 1);
wrongAnswerSoundID = wrongAnswerSoundPool.load(context, R.raw.wrong_answer_sound_effect, 2);
//getting the user sound settings
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
volume = actualVolume / maxVolume;
//then you can play the sound by checking if the sound is loaded
}
public void playCorrectAnswerSound()
{
if (correctLoaded) {
correctAnswerSoundPool.play(correctAnswerSoundID, volume, volume, 1, 0, 1f);
}
}
public void playWrongAnswerSound() {
if (wrongLoaded) {
wrongAnswerSoundPool.play(wrongAnswerSoundID, volume, volume, 1, 0, 1f);
}
}
}
I'm newbie in programming and I'm try to do a audio app that plays audio samples, but i want to sync all of them. Like a verification loop that counts 0, 1, 2, 3. And when the user click "play/stop", the audio only start/stop if the loop is in "0".
This is one of my classes, where i set play and stop methods.
public class Sample {
private static final int SAMPLE_RATE = 44100;
private String name;
private AudioTrack audioTrack;
private int loopPoint;
int soundId;
private Uri uri;
private Context context;
private MediaPlayer currentPlayer;
private boolean isImported;
private boolean isLooping = false;
public Sample(String name, byte[] soundBytes) {
this.name = name;
loopPoint = soundBytes.length / 2;
isImported = false;
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
soundBytes.length, AudioTrack.MODE_STATIC);
audioTrack.write(soundBytes, 0, soundBytes.length);
}
public Sample(String name, File file, Context context) {
this.name = name;
this.context = context;
isImported = true;
uri = Uri.parse(file.getAbsolutePath());
}
public String getName() {
return name;
}
public void updateSample(byte[] soundBytes) {
if (!isImported) {
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, soundBytes.length,
AudioTrack.MODE_STATIC);
audioTrack.write(soundBytes, 0, soundBytes.length);
}
}
public void play(boolean isLooped) {
isLooping = isLooped;
audioTrack.setPlaybackRate(88200);
if (isImported) {
if (currentPlayer != null) {
currentPlayer.seekTo(0);
} else {
currentPlayer = MediaPlayer.create(context, uri);
}
currentPlayer.setLooping(isLooped);
currentPlayer.start();
} else {
audioTrack.stop();
audioTrack.reloadStaticData();
if (isLooped) {
audioTrack.setLoopPoints(0, loopPoint, -1);
} else {
audioTrack.setLoopPoints(0, 0, 0);
}
audioTrack.play();
}
}
public void stop() {
try {
if (isImported && currentPlayer != null) {
currentPlayer.stop();
currentPlayer.release();
currentPlayer = null;
} else if (!isImported && audioTrack != null) {
audioTrack.stop();
}
} catch (Exception e) {
e.printStackTrace();
}
isLooping = false;
}
public boolean isImported() {
return isImported;
}
public boolean isLooping() {
return isLooping;
}
}
You can use currentPlayer.getCurrentPosition() to get the current position of playback of the sample in milliseconds.
Say your tempo was 120 bpm. That's half a second per beat.
Now say we are in 4/4 timing, then we have 4 beats in a bar, so each bar is a total of 2 seconds long.
So to stop the playback only at the start of a bar, you would need to stop playback when the CurrentPosition is a multiple of 2000 milliseconds.
You could make the MediaPlayer stop at the right time with something like the logic below:
onUserPressedStop() {
// Check if the remainder is 0 when you divide by bar length
if ((currentPlayer.getCurrentPosition() % barLengthMillis) == 0) {
// We are at the start of a bar so stop and release the MediaPlayer
stopMyMediaPlayer();}
// Else were not at the start of a bar, so find out how much longer we need to wait
else {
int waitTime = currentPlayer.getCurrentPosition() % barLengthMillis;
// Stop and release the MediaPlayer once the necessary time has elapsed
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
stopMyMediaPlayer();
}
}, waitTime);
}
}
I am using Media player to play a sound file. It is working well on 2.2 and 2.3 but not working for ICS 4.0.3, I have checked that mobile is not on silent mode. my code is:
private MediaPlayer mediaPlayer;
private void playSound(int soundType) {
try {
mediaPlayer = MediaPlayer.create(this, R.raw.beep);
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
}
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
});
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
Sound in ICS is played like this :
(i copied it from a previous post, so if theres any weird stuff in there i apologize)
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
int mSoundID = mSoundPool.load(this, R.raw.sound1, 1);
float lActualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
float lMaxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float lVolume = lActualVolume / lMaxVolume;
// Is the sound loaded already?
if (mSoundIsLoaded) {
mSoundPool.play(mSoundID, lVolume, lVolume, 1, 0, 1f);
}
You will have to put the sound file in your assets/raw directory.
edit: I forgot to mention where the mSoundIsLoaded parameter came from. I set it when my sound has been loaded. I do this in my onCreate method. when the sound is loaded I set the boolean field called mSoundIsLoaded. I do this to prevent NullPointerExceptions when playing the sound the loading of the sound looks like this:
mSoundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
mSoundIsLoaded = true;
}
});
mSoundID = mSoundPool.load(this, R.raw.sound1, 1);
This is the code i use in my app.. It is working fine in ICS
public void playWelcomeAudio() {
Thread t = new Thread()
{
#Override
public void run() {
AssetFileDescriptor afd = getApplicationContext().getResources().openRawResourceFd(R.raw.welcome);
try {
if(afd!=null)
{
UtilLog.d(TAG, "INIT MEDIA PLAYER");
welcomeAudio = new MediaPlayer();
welcomeAudio.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
welcomeAudio.prepare();
welcomeAudio.start();
}
} catch (Exception e) {
UtilLog.e(TAG, "Audio error", e);
}
}
};
t.start();
}
You can remove the thread. It is not necessory.
How to play audio file one after the other without using OncompletionListener();
here is my code:
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
i = i + 1;
System.out.println("" + audio.length);
if(i < audio.length){
img.setImageResource(image[i]);
try {
descriptor = getAssets().openFd(audio[i]);
mp.reset();
mp.setDataSource( descriptor.getFileDescriptor(), descriptor.getStartOffset(),descriptor.getLength());
descriptor.close();
mp.prepare();
mp.start();
xml();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
here the method xml() contains images and audio files that i am picking from assets folder
and also i need to play those files dynamically
please help
This service load an audio file from your raw , You have to call startService() in your activity to start this service , Do not forget to add this service to your android manifest.
EDITED
public class Backgroundmusic extends Service {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
// Random number generator
private final Random mGenerator = new Random();
private SoundPool soundPool;
private HashMap<Integer, Integer> soundsMap;
int SOUND1=1;
int SOUND2=2;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
soundsMap = new HashMap<Integer, Integer>();
soundsMap.put(SOUND1, soundPool.load(this, R.raw.baby_laugh, 1));
soundsMap.put(SOUND2, soundPool.load(this, R.raw.touchdown, 1));
}
public void playSound(int sound, float fSpeed) {
AudioManager mgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = streamVolumeCurrent / streamVolumeMax;
soundPool.play(soundsMap.get(sound), volume, volume, 1, 0, fSpeed);
}
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/** method for clients */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
public void soundPlay(int index){
playSound(index, 1.0f);
Log.d("SOUND1","hi1");
} }