All of lore.kernel.org
 help / color / mirror / Atom feed
* ALSA OSS Emulation - Read - EAGAIN Errors
@ 2008-07-30 15:20 Rahul Iyer
  2008-07-31 10:04 ` Takashi Iwai
  0 siblings, 1 reply; 4+ messages in thread
From: Rahul Iyer @ 2008-07-30 15:20 UTC (permalink / raw)
  To: alsa-devel

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ALSA OSS Emulation - Read - EAGAIN Errors
  2008-07-30 15:20 ALSA OSS Emulation - Read - EAGAIN Errors Rahul Iyer
@ 2008-07-31 10:04 ` Takashi Iwai
  2008-08-09  2:18   ` Rahul Iyer
  0 siblings, 1 reply; 4+ messages in thread
From: Takashi Iwai @ 2008-07-31 10:04 UTC (permalink / raw)
  To: Rahul Iyer; +Cc: alsa-devel

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ALSA OSS Emulation - Read - EAGAIN Errors
  2008-07-31 10:04 ` Takashi Iwai
@ 2008-08-09  2:18   ` Rahul Iyer
  2008-08-09  6:41     ` Hannu Savolainen
  0 siblings, 1 reply; 4+ messages in thread
From: Rahul Iyer @ 2008-08-09  2:18 UTC (permalink / raw)
  To: Takashi Iwai, alsa-devel; +Cc: Alexandre Ratchov

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ALSA OSS Emulation - Read - EAGAIN Errors
  2008-08-09  2:18   ` Rahul Iyer
@ 2008-08-09  6:41     ` Hannu Savolainen
  0 siblings, 0 replies; 4+ messages in thread
From: Hannu Savolainen @ 2008-08-09  6:41 UTC (permalink / raw)
  To: rahul.iyer; +Cc: Takashi Iwai, alsa-devel, Alexandre Ratchov

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-08-09  6:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-30 15:20 ALSA OSS Emulation - Read - EAGAIN Errors Rahul Iyer
2008-07-31 10:04 ` Takashi Iwai
2008-08-09  2:18   ` Rahul Iyer
2008-08-09  6:41     ` Hannu Savolainen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.