I have loaded sounds using Soundpool in Android.
I have used the play function to play the sound.
How do I know how long a file is and where I am currently in that file as it is playing?
Sound File Duration
MediaPlayer is probably your best bet, here:
MediaPlayer player = MediaPlayer.create(ctxt, R.raw.mysound);
int duration = player.getDuration();
player.release(); //(If not using this player later on)
Current Playback Position
SoundPool does not support this functionality. Your three main options:
Use MediaPlayer for playback. MediaPlayer supplies a getCurrentPosition() method.
Use AudioTrack -- manually sending uncompressed audio to the stream on a byte-by-byte basis. AudioTrack has some basic functionality for determining playback position (usually accurate to within a few tens of milliseconds, on most devices), and besides that you can know exactly how much audio's been added to the playback buffer.
Stick with SoundPool, but time the playback yourself. That is, take a time hack (SystemClock.UptimeMillis()) or set a CountDownTimer, and estimate your playback position by assuming that playback began as soon as play() returned. This approach is rife with problems and inaccuracies, but has the benefit of not involving AudioTrack's complexity.
Related
I'm trying to use Android's MediaPlayer to play a backing audio track to a music game which should stay in sync with other events.
However, I'm finding that on different devices the backing track seems out of sync.
After some frustration, I'm coming to the conclusion that the time it takes to start playing the audio is indeterminate.
Is there a way around this? Or some kind of callback from the MediaPlayer that represents "starting to play NOW"?
AFAICT I can't use the SoundPool for this backing track as the audio file is too long.
I am using Exoplayer2 to play an audio file in a loop. The audio file is 3600ms in length. However, different loops are played with slightly varied durations of 3811ms, 3611ms, 3589ms, 3605ms, 3602ms, 3595ms, etc. I want this to be precisely 3600ms. How do I achieve this?
I am recording the time durations in onPositionDiscontinuity with Player.DISCONTINUITY_REASON_PERIOD_TRANSITION.
I create Exoplayer MediaSource using SingleSampleMediaSource.Factory.
Could it be due to Exoplayer2's attempt to play gapless playback? If so, how do I turn gapless off.
When using a SoundPool audio class, it definitely has some advantages over a MediaPlayer when just playing short audio clips. The two I've noticed is SoundPool is a lot faster. MediaPlayer can lag a bit on startup and it's much easier to go from one sound clip to the next, where I don't have to stop,reset,prepare each time.
However, is it possible to use the visualizer to get real time fft data from audio data playing in the SoundPool like it is for MediaPlayer? I couldn't come across any topics that cover that, but by the off chance I thought I would ask because it seems like it should be possible. The documentation says, "The SoundPool library uses the MediaPlayer service to decode the audio into a raw 16-bit PCM mono or stereo stream." So if I could reference the MediaPlayer that SoundPool is using then I think I could just use getAudioSessionId() perhaps?
I already tried setting session ID to 0 to just get the output mix. It didn't work but it's not really the ideal effect that I am looking for anyway. Also one of the first things I did was try using the loaded SoundPool SoundID in place of the visualizers session ID, but that also didn't work.
My question is about the relative latency of playing, pausing/stopping, and setting volume of audio in Android. Specifically: whether it's the same or lower latency to pause/stop an audio clip than to play it, and likewise whether it's the same or lower latency to set the volume of a clip (or of the system volume) than to play it.
For context, suppose the latency of playing an audio clip in Android is 150ms, i.e. SoundPool.play is executed at T=0m and the end-user hears the sound at T=150ms.
At T=200m, the program executes SoundPool.pause. If the pause latency is also 150m, that means the pause won't be heard by the end-user until T=350m, after they have heard 200m of the clip. If, however, the pause latency is, say 50m, then the sound will stop at T=250m, after only 100m has been head by the end-user.
Obviously latency isn't constant, exact, or consistent across devices, so to be more precise, what I'm really asking is whether Android uses a separate pathway or technique to pause/stop/change volume of audio (either program-specific or system-wide volume) that is inherently lower-latency than the way audio is played.
Setting up Play takes more time as it has to initialize the play the following actions takes path
find the MIME type of the media file, this needs parsing of the media format and looks for specific header
initialize audio decoder(usually hardware), the OMX decoder has to be loaded into memory
setup the buffers say allocate 10 buffers in the parser and 10 buffers in the decoder.
Setup the paths between parser and decoder and playback audio device (Speaker)
Play happens at this step, data flows from parser buffers to decoder buffers, when the decoder buffers are filled, OMX (decoder framework) will notify player engine, engine passes the buffer data to AudioManager -> AudioTrack etc.
Decoder will again process the data from Parser buffers and this process goes on until EOF or user press pause/stop
During pause latency should be much low than play because, only the data exchnage is paused, but buffers are not released.
During stop buffers are released and player is also released, so need to do same process for play again if user needs to play again.
Volume up and down is simple calls to AudioManager to adjust the call voleumes. So its latency should be lower than play/stop
Is there a way I can tell if a certain sound is playing in SoundPool???
I.E.
if(MySound./*Command Goes Here*/()==true{
//Do stuff
}
I would appreciate if you could point me in the right direction or give me the code. I am not able to find any thing that does this on the docs.
This is not possible using SoundPool.
See Android SoundPool: get notified when end of played for two other ideas:
Use MediaPlayer, which provides an OnCompletionListener, instead of SoundPool
Use MediaPlayer in conjunction with SoundPool. Load the sound in a MediaPlayer beforehand to get the duration and keep track of whether the sound is done playing based its duration when played with SoundPool.