I'm using OpenSL ES in Android to decode and play an mp3 file using an AndroidSimpleBufferQueue. This works fine until you connect a bluetooth headset, at which point performance comes down to a crawl, and playback is very slow and stutters.
Any ideas on how to fix this?
edit:
I seem to have narrowed it down to the buffer queue portion of it. If I just load and play the sound file, it seems to work fine, but with a buffer queue in the middle, performance is terrible. I need the buffer queue to manipulate the data, so any help figuring this out is appreciated.
edit2: It appears that the minimum acceptable buffer size changes when bluetooth is connected. I was using a 4096 buffer, but to get acceptable/uninterrupted audio playback with a bluetooth headset, I had to bump it up to 16384. The latency on that is, however, kind of unacceptable for my needs, so I'm still looking for suggestions on how to improve this.
Related
I am using the following code in my messenger calling app :
this.audioRecord = new AudioRecord(
MediaRecorder.AudioSource.DEFAULT,
Constants.SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
Constants.BUFFER_SIZE_RECORDING);
Is this the best setting for audio in calls? I have a couple of issues with echos. I tried AudioSource.MIC and VOICE_COMMUNICATION, but they perform worse. I wonder if changing any of the other variables would improve the audio quality? Any ideas about the best variable for a calling app.Also, I don't hear any audio often on Nexus 6 or pixel 2
Audio on Android is always a tough problem because manufacturers put in different audio chips with different capabilities in all phones.
That being said VOICE_COMMUNICATION should be your best bet. It is "Microphone audio source tuned for voice communications such as VoIP. It will, for instance, take advantage of echo cancellation or automatic gain control if available."
So it should already use AcousticEchoCanceler and NoiseSuppressor to get rid of echoes and other disturbing noises. But in the end, it comes down to your use-case, if you rather want unfiltered or filtered audio.
You can also try to increase the sampling rate (Constants.SAMPLE_RATE 48000 should be best since that is the sampling rate of most modern phones) and bit depth (ENCODING_PCM_16BIT to ENCODING_PCM_FLOAT) to get a better signal. Note that supported sampling rates differ from phone to phone. To find out what your phone supports adapt the solution from audio sampling rates discussion. More information about sampling rates is covered in the Sampling Audio docs.
To the problem that you often don't hear anything, that can happen if either your gain is too low (can happen with AudioSource.MIC) or if your recorder is not ready yet (I'm making an educated guess here since I don't know your code).
I need to create a VOIP app and I'm using OpenSL ES. I need to capture and play pcm audio data at 8KHz sampling rate for all android devices. But, when i capture audio at sampling rate 8KHz and play it at the same time (voice communication), it produces noise and the audio is distorted for some devices like Samsung Galaxy S3, S4 etc. I know, there's a specific preferred sampling rate for each device and I want to know is there any workaround or any way to work with 8KHz sampling rate only without any distortion?
I tried increasing buffer size and many other things but failed to find an optimum and generic solution. I need audio data sampled at 8KHz for my encoder and decoder. I took re-sampling audio data before it is passed to my encoder or decoder as my second thought, but its not the solution i'm looking for.
I found CSipSimple used OpenSL and I went through some of their codes too. But, yet I couldn't find a solution and may be I failed to understand where to concentrate.
I'm stuck here!
Here's how I solved my problem:
I was working on audio streaming for Android using OpenSL ES and this tutorial helped me a lot. I followed the instructions here and got the thing working. Then i found audio streaming with this approach doesn't work very well for some devices (mostly samsung devices). I tried many things like increasing buffer size, disabling environmental reverb etc etc. I found this answer very useful for improving streaming performance.
Finally, I found the audio is distorted because of theadlocks I had to use for synchronizing the buffer switches. Using lock free structure is suggested for better audio performance. Then I went with another approach of Victor Lazzarini which is a lock free Audio IO. This article of Lock-free audio IO with OpenSL ES on Android helped a lot to implement a lock free structure along with a better audio performance.
I am trying to receive audio from headset's microphone using AudioRecord and playback the audio in real time to the Headphones using AudioTrack.I have implemented required code but the problem is that there is a disturbing Echo. I'm not using speakers and i'm using headphones. So,whats causing this echo? I used device's echocanceller which introduced in API level 11 and echo decreased but didn't go away.Im aware of audio latency in android devices but i can't understand how the delay may cause echo while i'm using headphones. Please guide me in the right direction.
I dont think there is a generic solution to this problem.
The reason are
1) the headphone quality may be bad, there may be internal coupling between the mic and headphones as the wires are very close in headphones
2) The echo canceler in android is not mandatory to be implemented by all devices. Try querying it first and settings. also the echo canceler implementation may vary from device to device
3) the latency affect the performance of the echo canceler a lot as the algorithm has to adapt to the delay and buffer that much audio.
4) lower versions of android have horrible delay problems acknowledged by google itself. You may want to move to higher android version as these things have been improved greatly.
In general any API that has some direct hardware access like mic and camera , the performance varies from device to device and performance cannot be guaranteed.
you may want to look at openSLES for better audio performance and easier integration to AEC library if you are thinking of integrating.
Please look at -
https://source.android.com/devices/latency_design.html
Low-latency audio playback on Android
https://www.youtube.com/watch?v=d3kfEeMZ65c
Hope this helps,
Regards,
Shrish
I can access and view RTSP streams from IP cameras on Android via the VideoView component without problems.
Now I need to play the RTSP stream with a delay (i.e. if I specify a 30 second delay, the playback on screen should be 30 seconds behind the source and the delay needs to be variable though not during playback, only at the point of connecting to the source).
I originally thought this would not be a problem as I could simply change the RTSP buffer duration before connecting to the camera but unfortunately it seems the buffer size is baked into the firmware and cannot be changed in software. Now I have got a horrible feeling that my way forward will be to compile a version of FFMpeg for Android and somehow get the stream data out from the library, buffer it and then render it myself and I have no experience with FFMpeg.
I am unsure how I would now go about solving this problem and any help or pointers in the right direction would be greatly appreciated.
Update:
Sorry I forgot to mention, the RTSP stream is being accessed over WiFi on a LAN so no huge latency issues here from going over the Internet.
I'm new to the android platform, and I wanted to develop an app that runs in the background and reads the microphone input, applies a transformation to it, and outputs the resulting audio to the speaker.
I'm wondering if there is any lag perceived by the user in this process, or if it's possible to do it in near-realtime so that the user can hear the transformed audio in sync with the ambient audio. Thanks!
Yes, users will hear a severe latency lag or echo with attempts at real-time audio on current unmodified Android devices using the provided APIs.
The summary is that Android devices are configured for fairly long audio buffers, which has been reported to be in the somewhere around the range of 100 to 400 milliseconds long, depending on the particular device and the Android OS version it is running. (Shorter buffers might be possible on Android devices on which one can build and install a modified custom build of the OS with your own custom audio drivers.)
(Humans hear echoes at somewhere around or above 25 mS. Audio buffers on iOS can be as short as 5.8 mS, so you may have better luck trying to develop your near-real-time audio processing on a different device platform.)
Audio processing on android isn't all the great, in fact to be honest, it sucks. The out-of-the-box latency on android devices for such things is pretty awful. You can however tinker with the NDK and try to put together something based on OpenSL ES which will have significantly low latency.
There is a similar StackOverflow question: Playing back sound coming from microphone in real-time
Some other helpful links:
http://arunraghavan.net/2012/01/pulseaudio-vs-audioflinger-fight/
http://www.musiquetactile.fr/android-is-far-behind-ios/
http://www.geardiary.com/2012/02/21/the-dismal-state-of-android-as-a-music-production-solution/
On the other side of the coin, android mic quality is way better than IOS quality. I have a galaxy s4 and a huawei very low end phone and both have a wonderful mic quality when recording.