Closed GoogleCodeExporter closed 9 years ago
I have investigated this a little further. It seems to be related to the number
of
channels that the ALSA device supports on the recording interface. I have
written a
very simple audio playback app and audio record app that use the Audio track API
directly.
If the channel count is set to 2 in this API call then the following is seen in
the log:
D/dalvikvm( 792): GC freed 8745 objects / 398584 bytes in 73ms
W/AudioHardwareInterface( 779): getInputBufferSize bad channel count: 2
E/AudioRecord( 929): Recording parameters are not supported: sampleRate 8000,
channelCount 2, format 1
If the channel count is set to 1 then everything gets further, but then the ALSA
interface generates an error (I have added a couple of new messages but most of
these
are in the standard log):
I/AudioHardwareALSA( 779): Attempt to open ALSA device. Mode 0 device 2
I/AudioHardwareALSA( 779): Attempting to open ALSA CAPTURE device
AndroidRecord_Speaker_normal
E/ALSALib ( 779): external/alsa-lib/src/pcm/pcm.c:2201:(snd_pcm_open_noupdate)
Unknown PCM AndroidRecord_Speaker_normal
I/AudioHardwareALSA( 779): Attempting to open ALSA CAPTURE device
AndroidRecord_Speaker
E/ALSALib ( 779): external/alsa-lib/src/pcm/pcm.c:2201:(snd_pcm_open_noupdate)
Unknown PCM AndroidRecord_Speaker
I/AudioHardwareALSA( 779): Attempting to open ALSA CAPTURE device
AndroidRecord
E/ALSALib ( 779): external/alsa-lib/src/pcm/pcm.c:2201:(snd_pcm_open_noupdate)
Unknown PCM AndroidRecord
I/AudioHardwareALSA( 779): Failed to open requested device. Openiing default
device
hw:00,0
I/AudioHardwareALSA( 779): Initialized ALSA CAPTURE device hw:00,0
D/AudioHardwareALSA( 779): Set CAPTURE PCM format to S16_LE (Signed 16 bit
Little
Endian)
I/AudioHardwareALSA( 779): Channelcount set to 1
E/AudioHardwareALSA( 779): Unable to set channel count to 1: Invalid argument
W/AudioFlinger( 779): AudioRecordThread: buffer overflow
W/AudioRecord( 936): obtainBuffer timed out (is the CPU pegged?) user=00000000,
server=00000000
Querying the driver as to how many channels it supports gets the following:
I/AudioHardwareALSA( 779): Failed to open requested device. Openiing default
device
hw:00,0
I/AudioHardwareALSA( 779): Initialized ALSA CAPTURE device hw:00,0
D/AudioHardwareALSA( 779): Set CAPTURE PCM format to S16_LE (Signed 16 bit
Little
Endian)
I/AudioHardwareALSA( 779): Channelcount set to 1
I/AudioHardwareALSA( 779): Attempt to set channelCount to 1
I/AudioHardwareALSA( 779): Supported channel count 2
E/AudioHardwareALSA( 779): Unable to set channel count to 1: Invalid argument
Now it seems there is a bit of a conflict as the ALSA driver only supports 2
channels, but the Android framework only supports 1 (See
AudioHardwareBase::getInputBufferSize in AudioHardwareInterface.cpp)
I am afraid that I am not familier enough with the Audio systems in Android to
offer
a solution.
Original comment by brychein...@gmail.com
on 18 Aug 2009 at 10:15
Hi, Jonathan:
Ya, I got the log when clicking record button similar as below:
I/AudioHardwareALSA( 733): Initialized ALSA CAPTURE device hw:00,0
D/AudioHardwareALSA( 733): Set CAPTURE PCM format to S16_LE (Signed 16 bit
Little
Endian)
E/AudioHardwareALSA( 733): Unable to set channel count to 1: Invalid argument
W/AudioFlinger( 733): AudioRecordThread: buffer overflow
W/AudioRecord( 733): obtainBuffer timed out (is the CPU pegged?) user=00000000,
server=00000000
W/AudioRecord( 733): obtainBuffer timed out (is the CPU pegged?) user=00000000,
server=00000000
But I have not seen the error "Failed to open requested device." here.
and when I trying to stop the recording, it can not succeed stopping.
The log of "stop recording" is as below. It seems like something wrong the key
event
dispatching..
W/WindowManager( 779): Key dispatching timed out sending to
com.android.soundrecorder/com.android.soundrecorder.SoundRecorder
W/WindowManager( 779): Dispatch state: null
W/WindowManager( 779): Current state: {{null to Window{43673318
com.android.soundrecorder/com.android.soundrecorder.SoundRecorder paused=false}
@
1244838253389 lw=Window{43673318
com.android.soundrecorder/com.android.soundrecorder.SoundRecorder paused=false}
lb=android.os.BinderProxy@43673128 fin=false gfw=true ed=true tts=0 wf=false
fp=false
mcf=Window{43673318
com.android.soundrecorder/com.android.soundrecorder.SoundRecorder
paused=false}}}
and I can see it keeps printing "W/AudioRecord( 733): obtainBuffer timed out
(is the
CPU pegged?) user=00000000, server=00000000".
I am looking into why android_media_MediaRecorder_stop() function in
android_media_MediaRecorder.cpp can not stop that.
Original comment by ShunYu.C...@gmail.com
on 18 Aug 2009 at 11:17
My interest in this is related to using the native AudioTrack and AudioRecord
APIs to
gain access to the AUdio Flinger from another Native Library. I wrote a couple
of
simple applications using these APIs to try things out and I have attached the
audio
recording application here. It can be built using the droid-g++ wrapper from
here:
http://github.com/tmurakam/droid-wrapper/tree/master
The command line to build is:
droid-g++ -o audio_input audio_input.cpp -laudio
Running this initially resulted in the same errors as the Ringdroid application
shows. This was due to the Android framework only supporting 1 channel for
recording,
but the ALSA implementation only works if 2 are specified. To get around this I
modified AudioHardwareBase::getInputBufferSize in AudioHardwareInterface.cpp so
that
it supported N channels:
size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format,
int
channelCount)
{
if (sampleRate != 8000) {
LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
return 0;
}
if (format != AudioSystem::PCM_16_BIT) {
LOGW("getInputBufferSize bad format: %d", format);
return 0;
}
/* if (channelCount != 1) {
LOGW("getInputBufferSize bad channel count: %d", channelCount);
return 0;
}*/
return 320*channelCount;
}
Making this change enabled my application to work provided the framecount
(Parameter
5 in the call to mpAudioRecord() was set to 16384. This is not really
acceptable for
my application as this results in the audio being presented in 32kb buffers
which
gives a massive latency. Setting a figure of less than 16384 results in the
callback
never being called.
The solution to this is to modify the default ALSA buffersize in
AudioHardwareALSA.cpp to be 320 samples instead of 16384:
AudioStreamInALSA::AudioStreamInALSA(AudioHardwareALSA *parent) :
mParent(parent)
{
static StreamDefaults _defaults = {
devicePrefix : "AndroidRecord",
direction : SND_PCM_STREAM_CAPTURE,
format : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT
channels : 1,
sampleRate : AudioRecord::DEFAULT_SAMPLE_RATE,
latency : 250000, // Desired Delay in usec
bufferSize : 320, // Desired Number of samples
};
setStreamDefaults(&_defaults);
}
Once this change is made everything seems to work ok (With my application at
least)
with the framecount set to 320. I have no idea if this is the correct way to
resolve
the problem as the Android documentation is very lacking in this area.
Original comment by brychein...@gmail.com
on 19 Aug 2009 at 10:40
Attachments:
Thanks Jonathan,
As I tried, here is my minimal modification to make it work normally, as the
patch.
Though I still can't record the voice on BeagleBoard.
Original comment by ShunYu.C...@gmail.com
on 20 Aug 2009 at 9:56
Attachments:
Thanks. I think there was a small error in the record app I uploaded yesterday.
Here
is a working copy.
Original comment by brychein...@gmail.com
on 20 Aug 2009 at 10:09
Attachments:
To Jonathan,
Even trying with demo image from Angstrom distribution (
http://beagleboard.org/demo/angstrom ), the audio recording doesn't really
record
anything using ALSA utilities. Can you share the configurations and approaches
that
you tried? Thanks!
Original comment by jserv.tw@gmail.com
on 27 Aug 2009 at 11:54
My tree that has working recording is exactly as I described earlier in the bug
with
onlythe addition of the two changes in the patch you created. Did you try my
native
recording app?
Original comment by brychein...@gmail.com
on 27 Aug 2009 at 12:37
The reason of unable to record the voice is I used the microphone connector. The
audio in jack on beagleboard expects Line-in cable connected from PC or any
player.
At the environment as the image attached shows, the sound from PC can be
record.
Using alsa utilities to test is pretty ok. I am still trying to figure out a
wav file
with right format to feed Ringdroid and then the recording can be played well.
Original comment by ShunYu.C...@gmail.com
on 31 Aug 2009 at 4:12
Attachments:
There are already several fixes in Jeremy's workspace. He is about to complete
Audio{In,Out} functions.
Original comment by jserv.tw@gmail.com
on 4 Sep 2009 at 7:06
Now the record file record by Ringdroid sounds deep and distorted.
I copied the recording file made by Ringdroid to my laptop and use mplayer to
play
the 3gpp amr encoded file.
The voice sounds distorted as the same as playing on beagleboard using
Ringdroid. I
am wondering something wrong with the recording process.
The mplayer outputs the message as like below:
==========================================================================
Opening audio decoder: [ffmpeg] FFmpeg/libavcodec audio decoders
AUDIO: 8000 Hz, 1 ch, s16le, 128.0 kbit/100.00% (ratio: 16000->16000)
Selected audio codec: [ffamrnb] afm: ffmpeg (AMR Narrowband)
==========================================================================
Original comment by ShunYu.C...@gmail.com
on 7 Sep 2009 at 2:54
As Jonathan said, Android framework only supporting 1 channel for recording,
but the ALSA implementation only works if 2 are specified.
Opencore supposes recording and amr encoding would be using 1 channel only. I
think
that's the reason that the record file sounds distorted if setting channel
count to 2
in ALSA audio library (libaudio.so).
So, I think this shows that there has two possible ways. One is to make OpenCore
support 2 channel recording and amr encoding as well while the other is to make
it
support one channel recording through ALSA.
Original comment by ShunYu.C...@gmail.com
on 8 Sep 2009 at 4:17
After making Alsa support one channel recording, recording can work on
beagleboard
finally.
This includes two commits #f31b4c1a835dc850652bb27e001713a8010d6643 and
#8004ab931e08b5c151e311892e47fe4c0f0e7b5e that are at alsa-lib and
hardware/alsa_sound respectively.
To make applications like Ringdroid work, we still need to modify the default
ALSA
buffersize in
AudioHardwareALSA.cpp to be 320 samples instead of 16384, as Jonathan says.
Commit
#5b2499cfb2e3d8221ca3b5d843bb1be14df69649 is for this.
Original comment by ShunYu.C...@gmail.com
on 10 Sep 2009 at 5:38
Goes to fixed.
Original comment by ShunYu.C...@gmail.com
on 11 Sep 2009 at 2:46
Shun Yu.Chang,
I am getting recorded sound distorted in android. I have seen your posting
"After making Alsa support one channel recording, recording can work on
beagleboard
finally.
This includes two commits #f31b4c1a835dc850652bb27e001713a8010d6643 and
#8004ab931e08b5c151e311892e47fe4c0f0e7b5e that are at alsa-lib and
hardware/alsa_sound respectively."
Can u share what to be changed to make alsa support one channel recording in
beagleboard.
Thanks and Regards,
HarishKumar.V
Original comment by harishpr...@gmail.com
on 24 Sep 2009 at 12:32
Shun Yu.Chang,
thanks, got the changes fron git.0xlabs.
it works....
Original comment by harishpr...@gmail.com
on 24 Sep 2009 at 1:00
Original issue reported on code.google.com by
jserv.tw@gmail.com
on 13 Aug 2009 at 9:41