Gap buffering in Android devices - android

I'm building a buffering engine to play streams from url.. I need to buffering both mp3 and aac ( on device that can support it ) so I can't pass directly the url to MediaPlayer.. I tried this method: I have 2 synchronized thread, one that running creates some file with data from buffer and the second playing files created: the problem is that when mediaplayer switch from a file to another, there is a little gap... how can I remove it?? is very annoying...
Maybe my method is wrong, if so can anyone provide a working method without chopping sound??
Thank you very much in advance..

It seems you are trying to implement Gapless Playback. (Right ? )
Towards this you need to define level of Gapless Playback you want to achieve. Should it be across fileformats / codecs, audio attributes like sample rate, number of channels etc.
With your approach, you ll surely see gaps across different streams. (Fileformats , compression, audio attributes).
To achive true Gapless playback at application level (My Approach) you need to do the following
Implement custom stack, that would take the input files, decode it and produce pcm samples. This stack will have Parsers (MP3, AAC), and decoders (MP3, AAC..)
Pass pcm samples through resampler, to produce pcm samples having same sample rate.
Add buffering modules at input (File) and output (resampled pcm data).
Use AudioTrack class of Android SDK for playout.
If you stick to one fileformat, Codec and audio attributes, then at application level, you can concatenate all the files in the playlist and provide it to MediaPLayer for playback. (Since audio streams have less size, this solution can be practical. Only obstacle would be streams attributes. If the Audio OMX Components within Android Multimedia stack support dynamic reconfiguration, then this should be no issue at all)
Shash

Related

How to loop an audio file in android without any delay?

I have started a android.media.MediaPlayer file with:
mp1.start()
and then trying the looping with:
setLooping(true);
but this is ending up with a delay in playing the file again.
I am trying to run an mp3 file containing a rhythm with a set tempo. Is there any better way of looping it in such a manner that the tempo timing does not get disturbed and the rhythm plays seamlessly without any stutter/delay?
Should I use SoundPool instead?
Most of best practices for this particular case recommend using .ogg format. You can convert you file easily using VNC media player.
Wiki for .ogg file format - http://en.wikipedia.org/wiki/.ogg
Another solution is the SoundPool and the third one - is to use Audacity and cut the quiet/“blanksound” from you audio file.
If your audio is not long, then use SoundPool for low-latency media playback, instead of MediaPlayer. Also convert it to ogg, as others have already pointed it out.
Edit: if it is just a tempo, and not a continous sound, then maybe you can also measure the latency and seek your audio based on that, but I am not sure you will get better results this way.
Mediaplayer solutions:
If you insist on using MediaPlayer, then you can:
either crop the sound at the end of your audio files, so there's no sound gap between two playback loops
or create a custom solution yourself as the one described here.
Soundpool alternative:
Now, from my personal experience, if you want to loop files small in size and duration, not more than 1MB, then Soundpool is more convenient and it seems that not any relevant problems are reported in contrary to the MediaPlayer. There have been many complaints when trying to loop sounds using MediaPlayer, so generally Soundpool is usually preferred for looping.
Soundpool size limit:
If you are concerned about Sounpool's size limit, keep in mind that it has 1Mb buffer size limit per track. But this limit applies not to file size but to decompressed raw PCM data. SoundPool is going to decompress the loaded audio to PCM data so it is ready to play instantly without the latency of decoding. If the audio you are loading is compressed heavily, such as MP3, then that can get blown up quite a bit.
Improve performance:
Also, as suggested in another answer, files of type ".ogg" according to many sources appear to perform better than ".mp3" in general. So, you should try to convert your files for better performance, but I don't think you will see an improvement concerning looping.
To convert your files you can use an online tool such as this. If you convert your files remember to also make these changes:
Change your sound file's sampling rate to 16000 Hz
Change your audio channel to mono, instead of stereo.
Make sure your file after these processes is smaller than 1 mb in size.
Please try to do it this way.
audio = MediaPlayer.create(this, R.raw.pl);
audio.setLooping(true);
audio.start();

Android mix audio into a playing stream

I am looking for a way to mix an audio into an already-playing mixed audio stream. For example, when a sound is being played half way through, I want to add in another sound to play together without interrupting the first sound to continue. I would also like to have an ability to withdraw a playing sound stream from the mixed playing stream. Going through Android's relevant document, I think that the only possible solution is to use native OpenSL ES via JNI to develop my own library where I can programmatically mix in/take out an audio stream from mixed audio streams. I would like to hear if anyone has a way to achieve it with less effort.
Thank you
Chris
Have you considered SoundPool?
http://developer.android.com/reference/android/media/SoundPool.html

Streaming multiple OGG simultaneously in Android

I need to be able to play two or more (let's say, up to 5) short ogg files simultaneously. And by simultaneously I mean in perfect synchrony. I am able to load them to SoundPool and play, but this sometimes creates a noticeable difference in playback start time, which I want to get rid of.
From my understanding this can be avoided if mixing PCMs into one buffer and playing. But OGG's are not PCMs and need to be somehow efficiently decoded before playing and latency must be very low, ideally as soon as user presses the button. So I figured I need a way to stream OGG into PCM and as I receive buffers I would mix them and feed to AudioTrack. My requirement is Android 2.3.3+, so I cannot use any new codecs provided in Jelly Bean.
Also although OGGs themselves are small, there is a lot of them. So keeping them all decoded in memory (SoundPool or some pre-decoding) may case problems too.
Can someone give me a tip where to dig? Can OpenSL ES do that for me? Or should I think about integrating ffmpeg? And is it even possible to stream simultaneus files with low latency?
Thanks
You can play sounds using AssetPlayers, but this sometimes creates a noticeable difference in playback start time, yeh...
So, i recomend to decode ogg using Ogg Vorbis (like here) and then using this PCM buffer for BufferPlayer.
Btw, check this OpenSL ES wrappers
https://github.com/Suvitruf/Android-ndk/tree/master/OpenSLES

Is There a Way to Playback Raw Audio/Video Streams in Android API's?

I have a Vorbis stream that I can decode to PCM if necessary, and I have a raw h264 stream all three of which are supported by Android when in a container. Wondering if there is any way to manually feed video and audio samples into the android MediaPlayer without any container. I would imagine I would have to override methods within the MediaPlayer. Does anyone have experience with this or have an easier way to do this? I can't imagine its impossible...
You may be able to play the audio pcm samples (For that also, I guess you may have to put a wav header) but you may not be able to play the H264 elementary stream without a container. In the media framework (Stagefright), there are sniffers functions registered for various container formats which could tell what kind of parser need to be used and then extractor(parser) is created. I don't think that you will be able to play the H264 elementary stream from the application using the inbuilt media framework of Android.

3GP/AMR mix/merge tracks

Is there an easy way to merge 2 3gp (amr) audio files into a single audio file?
I need them to be synchronous/over top of each other not one after the other. I am using android to do this. I have heard somewhere that for some audio formats you can simply add the bytes (being careful that you dont get a too high or too low result). Is this true with the 3gp/amr format on android?
Android only allows playback/recording of 3GP/AMR files. To mix audio you will need the decoded PCM data. This means you have to decode both streams mix (this is indeed adding + normalizing) and then playback.
The bad side - there no way to get access to the build in AMR decoder which allows you to decode without playback.
So ... no easy way.

Categories

Resources