ALSA recording audio on Donut problem

231 views
Skip to first unread message

Diego Rondini

unread,
Jul 13, 2011, 12:38:22 PM7/13/11
to android...@googlegroups.com
Hi,

I'm porting Android 1.6 Donut to a Freescale i.MX233 EVK board and I'm having a problem when recording audio. Let me introduce my problem.

What works:
- playing audio with alsa_aplay;
- recording audio with alsa_aplay -C;
- playing audio inside Android (e.g. with Music player).
What doesn't work:
- recording audio inside Android (e.g. with SpeakWrite or with the builtin SoundRecorder)

The problem I get is similar to this:
http://groups.google.com/group/android-porting/browse_thread/thread/0c08af7b7e3a37e8
but I've managed to solve the "Unknown PCM AndroidPlayback" by adding a proper entry in asound.conf.
Unfortunately I still get the "Failed to Initialize any ALSA PLAYBACK device: Unknown error: -16" problem.

I've googled for a solution but I did not found anything relevant.

Here you are my asound.conf: http://pastebin.com/bbRtWhyd
alsa_amixer output: http://pastebin.com/SnWWxzxE

I'm trying to find were the error comes from and I got to the "snd_pcm_open_conf" function in "src/pcm/pcm.c":
http://tinyurl.com/6ymgtcj

I've modified it this way to print some output debug:
http://pastebin.com/Rtbd81JG
and I get is:
http://pastebin.com/gktYstxT

I don't get while I see the "err = ..." line multiple times, and it's not clear to me what's happening in this method. Can anybody help me?

Thank you,
Diego

Ashwin Bihari

unread,
Jul 13, 2011, 7:56:08 PM7/13/11
to android-porting
If you are starting a port to a new board, why are you starting with
such an old version of Android? You should start with Gingerbread and
at the worst FroYo..

-- Ashwin

> --
> unsubscribe: android-porti...@googlegroups.com
> website: http://groups.google.com/group/android-porting
>

Diego

unread,
Jul 14, 2011, 4:10:14 AM7/14/11
to android-porting
On 14 Lug, 01:56, Ashwin Bihari <abih...@gmail.com> wrote:
> If you are starting a port to a new board, why are you starting with
> such an old version of Android? You should start with Gingerbread and
> at the worst FroYo..
>

The device I'll use isn't powerful enough to run Froyo smoothly, it
has just 64MB Ram:
http://groups.google.com/group/android-porting/browse_thread/thread/6a510a5f345ac0f8

Newer version use more resources.

Diego

Diego

unread,
Jul 15, 2011, 12:18:53 PM7/15/11
to android-porting
On Jul 13, 6:38 pm, Diego Rondini <diego.rond...@kynetics.it> wrote:
> I don't get while I see the "err = ..." line multiple times, and it's not clear to me what's happening in this method. Can anybody help me?
>

Ok, found out some more: the "err = ..." line is present several times
because the function is recursive, and the actual problem is that the /
dev/snd/pcmC0D0p is busy.
I infact discovered that the "error -16" is coming from the
"snd_pcm_hw_open" method in the "pcm_hw.c" source file, from the line:
fd = snd_open_device(filename, fmode);
According to file "bionic/libc/kernel/common/asm-generic/errno-base.h"
the error:
#define EBUSY 16
which means "Device or resource busy".

Has anybody an idea of why it's busy? How can I check what uses it
(Android doesn't have "lsof")?

Thank you,
Diego

Diego

unread,
Jul 19, 2011, 10:16:02 AM7/19/11
to android-porting
Another step: I found out I can use busybox's "fuser". I get:
# busybox fuser /dev/snd/pcmC0D0p
1788
# ps | busybox grep 1788
media 1788 1 17636 1212 ffffffff afe0c51c S /system/bin/
mediaserver

So the pcmC0D0p is opened by the mediaserver process, which seems
normal to me (if I manually kill mediaserver, it restarts and occupies
again pcmC0D0p). Is this behaviour correct?
And why should it prevent the possibility to record audio?

Thanks,
Diego

Diego

unread,
Jul 22, 2011, 10:42:30 AM7/22/11
to android-porting
On Jul 19, 4:16 pm, Diego <diego.rond...@kynetics.it> wrote:
> Another step: I found out I can use busybox's "fuser". I get:
> # busybox fuser /dev/snd/pcmC0D0p
> 1788
> # ps | busybox grep 1788
> media     1788  1     17636  1212  ffffffff afe0c51c S /system/bin/
> mediaserver
>
> So the pcmC0D0p is opened by the mediaserver process, which seems
> normal to me (if I manually kill mediaserver, it restarts and occupies
> again pcmC0D0p). Is this behaviour correct?
> And why should it prevent the possibility to record audio?

Hello, it's me again with my soliloquy.
The answer is "yes, it's the correct behaviour" that pcmC0D0p is
opened by mediaserver, the problem is that pcmC0D0p is the playback
device, while during capture it should open pcmC0D0c. So the problem
is that it shouldn't try to open AndroidPlayback, but it should open
AndroidCapture (while I've seen a lot of other people with recording
problems with the message about "AndroidPlayback"). The problem is
that in "hardware/alsa_sound/alsa_default.cpp" I get a handle with
direction "SND_PCM_STREAM_PLAYBACK" instead of
"SND_PCM_STREAM_CAPTURE". Anybody else with this problem?

Thanks,
Diego

amr.has

unread,
Jul 23, 2011, 9:45:26 AM7/23/11
to android-porting
so the problem is in change SND_PCM_STREAM_CAPTUR by
SND_PCM_STREAM_PLAYBACK ??

can u explain more details about this solution

thanks
amr hassan

Diego

unread,
Jul 28, 2011, 6:29:50 AM7/28/11
to android-porting
On Jul 23, 3:45 pm, "amr.has" <nourha...@hotmail.com> wrote:
> so the problem is in change SND_PCM_STREAM_CAPTUR by
> SND_PCM_STREAM_PLAYBACK ??
>
> can u explain more details about this solution

I hadn't found the solution at the time; I've found it recently.
In "openInputStream" method (donut branch version) in
AudioHardwareALSA.cpp the handle acquired is wrong. The code looks for
the second and last object of mDeviceList, but does it in the wrong
way: it gets the "end()" iterator which is AFTER the last element
(check frameworks/base/include/utils/List.h for reference). The
solution is to get the element after the first like in this patch:
http://pastebin.com/zHAgvq26

After this change Android should try to open AndroidCapture, look in
the log for:
I/ALSAModule( 1788): Initialized ALSA CAPTURE device default

Next problem I get (yeah, not finished yet!) is a "buffer overflow"
issue in AudioFlinger which prevents audio recording to succeed.
Inspecting the code I found out that disabling the second condition of
the if in "AudioFlinger::AudioRecordThread::threadLoop" in
AudioFlinger.cpp makes the recording work correctly.
You can take a look at the code at this link: http://tinyurl.com/3bbmnal
The condition that sometimes fails is "(int)buffer.frameCount ==
inFrameCount" because, if I have buffer size set to 2048 I sometimes
get buffer.frameCount equal to 64.
In particular, like in this log:
http://pastebin.com/dQgDaTQL
I get two times 2048 and one time 64 (then it starts again). I've
tried setting buffer size to 320 as suggested in several places, which
seems to be a proper value because ((2048 * 2) + 64) / 320 = 13, but
it gets rounded to 256 because of this code: http://tinyurl.com/4ypemob

I'm going to investigate further, but does anybody know what's the
best solution (removing the rounding code?) and explain a bit better
what I'm doing?

Thanks,
Diego

Diego

unread,
Jul 28, 2011, 11:15:10 AM7/28/11
to android-porting
On Jul 28, 12:29 pm, Diego <diego.rond...@kynetics.it> wrote:
> Next problem I get (yeah, not finished yet!) is a "buffer overflow"
> issue in AudioFlinger which prevents audio recording to succeed.
> Inspecting the code I found out that disabling the second condition of
> the if in "AudioFlinger::AudioRecordThread::threadLoop" in
> AudioFlinger.cpp makes the recording work correctly.
> You can take a look at the code at this link:http://tinyurl.com/3bbmnal
> The condition that sometimes fails is "(int)buffer.frameCount ==
> inFrameCount" because, if I have buffer size set to 2048 I sometimes
> get buffer.frameCount equal to 64.
> In particular, like in this log:http://pastebin.com/dQgDaTQL
> I get two times 2048 and one time 64 (then it starts again). I've
> tried setting buffer size to 320 as suggested in several places, which
> seems to be a proper value because ((2048 * 2) + 64) / 320 = 13, but
> it gets rounded to 256 because of this code:http://tinyurl.com/4ypemob
>
> I'm going to investigate further, but does anybody know what's the
> best solution (removing the rounding code?) and explain a bit better
> what I'm doing?

Empiric results:
- setting buffer size in "alsa_default.cpp" to 64 doesn't cause
"buffer overflow" in AudioFlinger but causes "(snd_pcm_recover)
overrun occured" in ALSA;
- setting buffer size to 320 AND removing rounding to previous power
of two seems to work fine, no "buffer overflow" nor "overrun
occurred".

So now I'm able to record correctly, but... :)
But if I try to record a second time since booting the device I get a
problem in the log:
W/AudioFlinger( 1788): record start failed, status -17
That is because mOutput ALREADY_EXISTS (see: http://tinyurl.com/3s5joca
), which in turn is because nobody called "closeInputStream" from
AudioFlinger. I'm looking for a proper place to close the input
stream, but it's not quite clear because
"AudioRecordThread::threadLoop" can be interrupted. Again, any
suggestion?

Regards,
Diego
Reply all
Reply to author
Forward
0 new messages