[alsa-devel] ALSA OSS Emulation - Read - EAGAIN Errors
Hi ALSA Developers
I have a full duplex voice application, that records voice and sends (over a network) as well as receives and plays voice. OSS APIs are used to capture and play voice samples.
The voice quality is noticeably poor in SUSE 10. After further investigation, I see most of the 'read' system calls fail with EAGAIN (resource unavailable) error. This is not the case in SUSE 9.2. This results in poor voice quality -- broken voice, due to loss of voice samples.
Please take a look at the strace stats below for SUSE 9.2 and 10. Check the errors column for SUSE 10.
SUSE 9.2 Process 17533 detached % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 51.54 0.824285 48 17152 gettimeofday 14.36 0.229609 52 4393 693 select 9.85 0.157454 76 2081 692 sigreturn 7.89 0.126199 14 8784 rt_sigprocmask 7.74 0.123765 20 6201 ioctl 4.31 0.068929 33 2067 read 4.31 0.068898 33 2067 write 0.01 0.000083 6 14 alarm 0.00 0.000034 11 3 munmap 0.00 0.000007 4 2 rt_sigaction 0.00 0.000003 3 1 1 open ------ ----------- ----------- --------- --------- ---------------- 100.00 1.599266 42765 1386 total
SUSE 10 Process 11342 detached % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 49.58 1.006722 1 1191090 1189103 read 49.44 1.003873 1 1194607 ioctl 0.95 0.019285 11 1698 write 0.02 0.000453 0 1152 551 select 0.00 0.000038 13 3 munmap 0.00 0.000015 0 9230 gettimeofday 0.00 0.000000 0 1 1 open 0.00 0.000000 0 11 alarm 0.00 0.000000 0 0.00 0.000000 0 793 624 sigreturn 0.00 0.000000 0 6 sched_yield 0.00 0.000000 0 2 rt_sigaction 0.00 0.000000 0 2303 rt_sigprocmask ------ ----------- ----------- --------- --------- ---------------- 100.00 2.030386 2400896 1190279 total BTW, the SUSE 10 machine runs on newer hardware with on board Intel HDA Sound (Realtek ALC262).
Any thoughts on what causes so many read failures? Could this be hardware/driver related? There is nothing fancy about this sound card, its a regular on board card. It would be great if someone can confirm their experience with this card.
Any suggestions are also most welcome...
Thanks for the help.-- Rahul Iyer
At Wed, 30 Jul 2008 08:20:09 -0700 (PDT), Rahul Iyer wrote:
Hi ALSA Developers
I have a full duplex voice application, that records voice and sends (over a network) as well as receives and plays voice. OSS APIs are used to capture and play voice samples.
The voice quality is noticeably poor in SUSE 10. After further investigation, I see most of the 'read' system calls fail with EAGAIN (resource unavailable) error.
EAGAIN is no fatal error but means that samples are not available for read when the stream is opened in non-blocking mode. If it happens so often, it's likely a parameter mismatch. For example, the read period size apps expected doesn't match with the size actually set.
It's better to create a small test-case first then analyze the problem with it.
Takashi
Hi Takashi and Alexandre
Thank you for your attention and previous replies.
I understand EAGAIN errors can be ignored as trivial, but given there are so many of them (600 EAGAIN errors on an average for each successful call) indicates an inherent issue. And I believe it was singularly causing poor voice quality and high cpu usage.
Anyway, I have analysed this further and I think part of the problem is with the driver. With 1.0.11rc3 I notice 2 issues
1. EAGAIN errors if fragment size is not set explicitly (*and* correctly). In our application we don't set fragment size explicitly. And if fragment size is set explicitly, then the best value is 0x7fff0007 (even x7fff0008 also returns EAGAIN errors). Following are some strace stats to prove my point.
--- @160 samples, 8Khz, mono, 8 bit (alsa-driver 1.0.11rc3) - Without setting fragment size. Fragment size computed to 1024 bytes (automatically). Process 13306 attached - interrupt to quit Process 13306 detached % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 49.54 1.017715 1 1794787 1791804 read 48.97 1.005984 1 1797518 ioctl 1.30 0.026751 10 2556 write 0.19 0.004004 2 1752 582 select 0.00 0.000028 0 13905 gettimeofday 0.00 0.000010 0 3503 rt_sigprocmask 0.00 0.000000 0 1 1 open 0.00 0.000000 0 17 alarm 0.00 0.000000 0 3 munmap 0.00 0.000000 0 1477 811 sigreturn 0.00 0.000000 0 19 sched_yield 0.00 0.000000 0 2 rt_sigaction ------ ----------- ----------- --------- --------- ---------------- 100.00 2.054492 3615540 1793198 total
@160 samples, 8Khz, mono, 8 bit (alsa-driver 1.0.11rc3) Set fragment size to 0x7fff0008 (256 byutes) Process 15061 detached % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 89.48 0.068327 45 1534 2 write 5.89 0.004499 0 68564 65641 read 3.31 0.002528 0 507463 sched_yield 0.87 0.000664 0 142230 kill 0.39 0.000296 0 71115 ioctl 0.06 0.000043 0 14771 gettimeofday 0.01 0.000006 0 7613 rt_sigprocmask 0.00 0.000000 0 3 1 open 0.00 0.000000 0 2 close 0.00 0.000000 0 16 alarm 0.00 0.000000 0 3 munmap 0.00 0.000000 0 1502 1433 sigreturn 0.00 0.000000 0 3807 1408 select 0.00 0.000000 0 2 rt_sigaction ------ ----------- ----------- --------- --------- ---------------- 100.00 0.076363 818625 68485 total
@160 samples, 8Khz, mono, 8 bit (alsa-driver 1.0.11rc3) Set fragment size to 0x7fff0007 (128 bytes) Process 15571 attached - interrupt to quit Process 15571 detached % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- nan 0.000000 0 2365 read nan 0.000000 0 2325 write nan 0.000000 0 1 1 open nan 0.000000 0 16 alarm nan 0.000000 0 9448 kill nan 0.000000 0 4724 ioctl nan 0.000000 0 19606 gettimeofday nan 0.000000 0 3 munmap nan 0.000000 0 2340 1984 sigreturn nan 0.000000 0 5135 1984 select nan 0.000000 0 4 sched_yield nan 0.000000 0 2 rt_sigaction nan 0.000000 0 10268 rt_sigprocmask ------ ----------- ----------- --------- --------- ---------------- 100.00 0.000000 56237 3969 total
-------------------------------------------------------------------
However upgrading to alsa-driver-1.0.16 automatically solves the EAGAIN issue without having to set fragment size explicitly.
2. The other issue noticed with alsa-driver-1.0.11rc3 is, read does not always succeed in reading all the bytes requested. I have confirmed there is sufficient data available to read. This is also not an issue in 1.0.16. I understand read can return with less bytes especially when its around end of file or interrupted by a signal, so there is a possibility this is related to issue 1.
So, in conclusion I have been able to improve the quality in SUSE 10 but not to where I would've liked. I find it to be better in 9.2.
The difference between 9.2 and 10 is the alsa driver version. SUSE 9.2 uses alsa-driver1.0.7rc2, whereas 10 uses 1.0.11rc3/1.0.16. The drivers differ in allocating default fragment size. In SUSE 9.2 (1.0.7) the fragment size defaults to 4096 bytes (when not set explicitly). With both 1.0.11 and 1.0.16, they default to 1024. In fact I am unable to set anything beyond 1024 bytes. SNDCTL_DSP_SETFRAGMENT with 0x7fff0012 does not set the fragment size to 4096, it defaults to 1024!
Any thoughts on why this might be the case?
Thanks again in advance Rahul
--- On Thu, 7/31/08, Takashi Iwai tiwai@suse.de wrote:
From: Takashi Iwai tiwai@suse.de Subject: Re: [alsa-devel] ALSA OSS Emulation - Read - EAGAIN Errors To: "Rahul Iyer" rahul.iyer@ymail.com Cc: alsa-devel@alsa-project.org Date: Thursday, July 31, 2008, 10:04 AM At Wed, 30 Jul 2008 08:20:09 -0700 (PDT), Rahul Iyer wrote:
Hi ALSA Developers
I have a full duplex voice application, that records
voice and sends
(over a network) as well as receives and plays voice.
OSS APIs are used
to capture and play voice samples.
The voice quality is noticeably poor in SUSE 10. After
further
investigation, I see most of the 'read' system
calls fail with EAGAIN
(resource unavailable) error.
EAGAIN is no fatal error but means that samples are not available for read when the stream is opened in non-blocking mode. If it happens so often, it's likely a parameter mismatch. For example, the read period size apps expected doesn't match with the size actually set.
It's better to create a small test-case first then analyze the problem with it.
Takashi _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Rahul Iyer wrote:
Hi Takashi and Alexandre
Thank you for your attention and previous replies.
I understand EAGAIN errors can be ignored as trivial, but given there are so many of them (600 EAGAIN errors on an average for each successful call) indicates an inherent issue. And I believe it was singularly causing poor voice quality and high cpu usage.
Application should wait some time after EAGAIN before calling read/write again. Otherwise it will spend all the available CPU time in the system (one core).
In addition the application should check how many bytes actually got written since write() may take only the first few bytes that fit in the buffer. The remaining bytes need to be stored by the application until it becomes possible to write it. Most applications that use O_NONBLOCK fail to do this which will cause badly garbled sound.
IMHO use of non-blocking I/O should be banned. It has absolutely no use. It's far far far too difficult to use even for senior programers. Typical "legacy" OSS applications just turn on O_NONBLOCK and then don't do any error checking. However the application will work just fine if O_NONBLOCK is removed from the sources. In fact OSS4 has a blacklist feature to turn O_NONBLOCK silently off in certain popular applications because they don't use the feature properly.
Use of poll/select is the only proper way to avoid blocking. In fact trying to avoid blocking is completely unnecessary since audio reads/writes will never block longer than few millisecods at time (provided that the app uses relatively short reads/writes).
Best regards,
Hannu
participants (3)
-
Hannu Savolainen
-
Rahul Iyer
-
Takashi Iwai