* Improving wine support for alsa.
@ 2004-05-06 18:15 James Courtier-Dutton
2004-05-06 22:30 ` Arve Knudsen
2004-05-07 1:14 ` Ove Kaaven
0 siblings, 2 replies; 9+ messages in thread
From: James Courtier-Dutton @ 2004-05-06 18:15 UTC (permalink / raw)
To: ALSA development
Hi,
I have been updating the wine alsa driver to work better with alsa.
So far, all I have done is update it to use the new alsa api.
Windows uses an api called Direct Sound.
Direct Sound uses direct hardware buffer access.
A Win32 program can quiry the sound driver and ask for the currently
playing position, together with the first available possition that the
application could write to. I will call these "PlayPos" and "WritePos"
respectively.
E.g. If the hardware is halfway through playing one period(the PlayPos
is in the middle of a period), the beginning of the next period's
position is returned as the "WritePos".
The problem arrives because the Win32 app expects to have full write
access to the hardware buffer, and can write to any parts of it at any
time. The sound card should just happily move through the buffer playing
each sample as it goes, and when it reaches the end, just start at the
beginning again.
The alsa api is based more around the sound card asking for the next
block of samples.
Strangely enough, it Direct Sound works fine when using oss emulation in
alsa.
I was trying to just get alsa to copy samples from the Direct Sound
buffer on a just in time basis.
I was starting with writing one period to the sound card, calling
snd_pcm_start(), then setting snd_async_add_pcm_handler(), expecting the
handler to be called on each period, but the handler is never called.
For some reason, the handler does not seem to get called on each period
elasped as I was expecting.
Another problem is that if I want to stop the stream, I call
"snd_pcm_drop(). With this I would expect snd_pcm_delay()==0 and
snd_pcm_avail_update()==buffer_size.
It seems that these values are only reset to 0 after first calling
snd_pcm_prepare().
After stopping the stream in this way, I want to restart it again
without having to close/open the pcm.
Can anyone give me advice as to what I am doing wrong ?
Cheers
James
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Improving wine support for alsa.
2004-05-06 18:15 Improving wine support for alsa James Courtier-Dutton
@ 2004-05-06 22:30 ` Arve Knudsen
2004-05-06 23:42 ` Glenn Maynard
2004-05-07 1:14 ` Ove Kaaven
1 sibling, 1 reply; 9+ messages in thread
From: Arve Knudsen @ 2004-05-06 22:30 UTC (permalink / raw)
To: James Courtier-Dutton, ALSA development
James, I don't know if this is of any help, but you could always have a
peek at the PortAudio (www.portaudio.com) code (pa_linux_alsa.c). We don't
use snd_pcm_async_handler though, but implement async and blocking IO
ourselves.
Hope this helps
Arve Knudsen
On Thu, 06 May 2004 18:15:56 +0000, James Courtier-Dutton
<James@superbug.demon.co.uk> wrote:
> Hi,
>
> I have been updating the wine alsa driver to work better with alsa.
> So far, all I have done is update it to use the new alsa api.
> Windows uses an api called Direct Sound.
> Direct Sound uses direct hardware buffer access.
> A Win32 program can quiry the sound driver and ask for the currently
> playing position, together with the first available possition that the
> application could write to. I will call these "PlayPos" and "WritePos"
> respectively.
> E.g. If the hardware is halfway through playing one period(the PlayPos
> is in the middle of a period), the beginning of the next period's
> position is returned as the "WritePos".
>
> The problem arrives because the Win32 app expects to have full write
> access to the hardware buffer, and can write to any parts of it at any
> time. The sound card should just happily move through the buffer playing
> each sample as it goes, and when it reaches the end, just start at the
> beginning again.
>
> The alsa api is based more around the sound card asking for the next
> block of samples.
>
> Strangely enough, it Direct Sound works fine when using oss emulation in
> alsa.
>
> I was trying to just get alsa to copy samples from the Direct Sound
> buffer on a just in time basis.
>
> I was starting with writing one period to the sound card, calling
> snd_pcm_start(), then setting snd_async_add_pcm_handler(), expecting the
> handler to be called on each period, but the handler is never called.
>
> For some reason, the handler does not seem to get called on each period
> elasped as I was expecting.
>
> Another problem is that if I want to stop the stream, I call
> "snd_pcm_drop(). With this I would expect snd_pcm_delay()==0 and
> snd_pcm_avail_update()==buffer_size.
> It seems that these values are only reset to 0 after first calling
> snd_pcm_prepare().
> After stopping the stream in this way, I want to restart it again
> without having to close/open the pcm.
>
> Can anyone give me advice as to what I am doing wrong ?
>
> Cheers
> James
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Improving wine support for alsa.
2004-05-06 22:30 ` Arve Knudsen
@ 2004-05-06 23:42 ` Glenn Maynard
2004-05-07 1:49 ` Paul Davis
0 siblings, 1 reply; 9+ messages in thread
From: Glenn Maynard @ 2004-05-06 23:42 UTC (permalink / raw)
To: alsa-devel
On Fri, May 07, 2004 at 12:30:00AM +0200, Arve Knudsen wrote:
> James, I don't know if this is of any help, but you could always have a
> peek at the PortAudio (www.portaudio.com) code (pa_linux_alsa.c). We don't
> use snd_pcm_async_handler though, but implement async and blocking IO
> ourselves.
It looks like SND_PCM_ASYNC isn't used, and SIGIO is never handled;
instead, it just poll()s.
Kernel people: is poll() less effective than using SND_PCM_ASYNC and a
signal handler for low-latency sound? I'm guessing it is, but there
isn't much documentation for doing low-latency sound in ALSA, or about
the Linux kernel's treatment of SIGIO. (I'd expect that SIGIO would be
triggered from an interrupt, but poll() wouldn't wake up as quickly,
but I'm not sure.)
--
Glenn Maynard
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Improving wine support for alsa.
2004-05-06 18:15 Improving wine support for alsa James Courtier-Dutton
2004-05-06 22:30 ` Arve Knudsen
@ 2004-05-07 1:14 ` Ove Kaaven
1 sibling, 0 replies; 9+ messages in thread
From: Ove Kaaven @ 2004-05-07 1:14 UTC (permalink / raw)
To: James Courtier-Dutton; +Cc: ALSA development
tor, 06.05.2004 kl. 20.15 skrev James Courtier-Dutton:
> I have been updating the wine alsa driver to work better with alsa.
> So far, all I have done is update it to use the new alsa api.
> Windows uses an api called Direct Sound.
I think this problem has been discussed on this list before, with
WineX's version of winealsa delivering good performance as a result. You
can see the current code at
http://cvs.transgaming.org/cgi-bin/viewcvs.cgi/winex/dlls/winmm/winealsa/
and
http://cvs.transgaming.org/cgi-bin/viewcvs.cgi/winex/dlls/dsound/
(there are some changes to how the mixer thread puts changes into the
primary buffer, specifically the primary buffer is locked/unlocked
before data is written to it)
TransGaming is currently willing to donate at least the winealsa parts
to ReWind and Wine under the MIT license, so you should be able to merge
any winealsa changes you like into Wine.
> Direct Sound uses direct hardware buffer access.
If possible. It can do without.
> A Win32 program can quiry the sound driver and ask for the currently
> playing position, together with the first available possition that the
> application could write to. I will call these "PlayPos" and "WritePos"
> respectively.
> E.g. If the hardware is halfway through playing one period(the PlayPos
> is in the middle of a period), the beginning of the next period's
> position is returned as the "WritePos".
>
> The problem arrives because the Win32 app expects to have full write
> access to the hardware buffer, and can write to any parts of it at any
> time.
Well, not exactly at any time. It must lock the portion it wants to
write to first. But perhaps you're talking about not the Win32 app, but
Wine's mixer thread. This thread should also lock the primary buffer;
not doing so is a bug, which is now fixed in WineX. This would allow
operation where the software mixer does not write to the hardware
buffer, but the driver transfers the data there upon unlock, without
most of the problems associated with using a pcm callback that attempts
to copy data just in time. It even allows operation where the software
mixer *does* write directly to the hardware buffer...
And when the mixer thread does the proper locking, then the driver's
Lock/Unlock calls can be implemented in terms of ALSA's mmap_begin and
mmap_commit calls, it just takes some juggling with the application
frame pointer. And you end up as close to the hardware as you need to
be, without using a PCM callback. Using this design, WineX's winealsa
seems to perform about as well as wineoss.
> The sound card should just happily move through the buffer playing
> each sample as it goes, and when it reaches the end, just start at the
> beginning again.
The set_stop_threshold call in WineX's winealsa kinda lets the card do
this (thanks Jaroslav).
> Another problem is that if I want to stop the stream, I call
> "snd_pcm_drop(). With this I would expect snd_pcm_delay()==0 and
> snd_pcm_avail_update()==buffer_size.
> It seems that these values are only reset to 0 after first calling
> snd_pcm_prepare().
> After stopping the stream in this way, I want to restart it again
> without having to close/open the pcm.
Well, the solution is pretty simple. After calling snd_pcm_drop(), just
call snd_pcm_prepare(). Works for us.
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Improving wine support for alsa.
2004-05-06 23:42 ` Glenn Maynard
@ 2004-05-07 1:49 ` Paul Davis
2004-05-07 4:02 ` Glenn Maynard
2004-05-07 12:35 ` James Courtier-Dutton
0 siblings, 2 replies; 9+ messages in thread
From: Paul Davis @ 2004-05-07 1:49 UTC (permalink / raw)
To: Glenn Maynard; +Cc: alsa-devel
>Kernel people: is poll() less effective than using SND_PCM_ASYNC and a
>signal handler for low-latency sound? I'm guessing it is, but there
at the risk of endlessly repeating myself, SIGIO is basically
useless. your handler executes in signal-handling context, and can do
very, very little. not even all system calls are legal in this context.
SIGIO is basically a "poor man's thread system", and not much more.
also, poll wakes a task quicker than a signal. this is easy to
establish empirically. from a theoretical perspective, signal handling
is a much more complex situation that simply continuing on with
whatever function was blocked.
--p
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Improving wine support for alsa.
2004-05-07 1:49 ` Paul Davis
@ 2004-05-07 4:02 ` Glenn Maynard
2004-05-07 10:12 ` Ferenc Wagner
2004-05-07 11:03 ` Paul Davis
2004-05-07 12:35 ` James Courtier-Dutton
1 sibling, 2 replies; 9+ messages in thread
From: Glenn Maynard @ 2004-05-07 4:02 UTC (permalink / raw)
To: alsa-devel
On Thu, May 06, 2004 at 09:49:31PM -0400, Paul Davis wrote:
> at the risk of endlessly repeating myself,
If you're being asked this frequently, I'd recommend adding some notes to
the documentation, recommending using poll() and not SND_PCM_ASYNC, and
offering a brief explanation like this one.
> SIGIO is basically
> useless. your handler executes in signal-handling context, and can do
> very, very little. not even all system calls are legal in this context.
> SIGIO is basically a "poor man's thread system", and not much more.
Practical use aside, isn't that common conditions for a sound callback
(which under some architectures, as I understand it, are called from an
interrupt)?
By the way, do you have a reference to system calls which are not legal
from a signal handler in Linux? I've never seen things not work in a
signal handler, even when writing a crash handler that forks a child (to
output crash info in a clean environment) and at one point even did some
ptracing of other threads, all from a SIGSEGV handler.
--
Glenn Maynard
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Improving wine support for alsa.
2004-05-07 4:02 ` Glenn Maynard
@ 2004-05-07 10:12 ` Ferenc Wagner
2004-05-07 11:03 ` Paul Davis
1 sibling, 0 replies; 9+ messages in thread
From: Ferenc Wagner @ 2004-05-07 10:12 UTC (permalink / raw)
To: alsa-devel
Glenn Maynard <g_sf@zewt.org> writes:
> On Thu, May 06, 2004 at 09:49:31PM -0400, Paul Davis wrote:
>
>> SIGIO is basically useless. your handler executes in
>> signal-handling context, and can do very, very
>> little. not even all system calls are legal in this
>> context. SIGIO is basically a "poor man's thread
>> system", and not much more.
>
> do you have a reference to system calls which are not
> legal from a signal handler in Linux?
See for example info libc Nonreentrancy and related nodes.
--
Feri.
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Improving wine support for alsa.
2004-05-07 4:02 ` Glenn Maynard
2004-05-07 10:12 ` Ferenc Wagner
@ 2004-05-07 11:03 ` Paul Davis
1 sibling, 0 replies; 9+ messages in thread
From: Paul Davis @ 2004-05-07 11:03 UTC (permalink / raw)
To: Glenn Maynard; +Cc: alsa-devel
>On Thu, May 06, 2004 at 09:49:31PM -0400, Paul Davis wrote:
>> at the risk of endlessly repeating myself,
>
>If you're being asked this frequently, I'd recommend adding some notes to
I'm not. I'm just a big mouth who always pipes up when SIGIO is mentioned.
>the documentation, recommending using poll() and not SND_PCM_ASYNC, and
>offering a brief explanation like this one.
Well, since I disagree with other people on the ALSA project about the
wisdom of supporting SIGIO, this hasn't happened. But yes, even a note
to make it clear that there is disagreement about whether it should be
used would be a good idea.
>> SIGIO is basically
>> useless. your handler executes in signal-handling context, and can do
>> very, very little. not even all system calls are legal in this context.
>> SIGIO is basically a "poor man's thread system", and not much more.
>
>Practical use aside, isn't that common conditions for a sound callback
>(which under some architectures, as I understand it, are called from an
>interrupt)?
Only MacOS "Classic" did this, and Apple moved away from that design
as soon as they could. The key part of the design that needs to be
retained is the "callback model". Using poll to implement it is, IMHO,
a very, very much better design than using SIGIO.
>By the way, do you have a reference to system calls which are not legal
I have a list of the legal calls in a book on pthreads
programming. I'm afraid I don't feel like typing it in, but someone
already posted another reference.
--p
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Improving wine support for alsa.
2004-05-07 1:49 ` Paul Davis
2004-05-07 4:02 ` Glenn Maynard
@ 2004-05-07 12:35 ` James Courtier-Dutton
1 sibling, 0 replies; 9+ messages in thread
From: James Courtier-Dutton @ 2004-05-07 12:35 UTC (permalink / raw)
To: Paul Davis; +Cc: alsa-devel
Paul Davis wrote:
>>Kernel people: is poll() less effective than using SND_PCM_ASYNC and a
>>signal handler for low-latency sound? I'm guessing it is, but there
>
>
> at the risk of endlessly repeating myself, SIGIO is basically
> useless. your handler executes in signal-handling context, and can do
> very, very little. not even all system calls are legal in this context.
> SIGIO is basically a "poor man's thread system", and not much more.
>
> also, poll wakes a task quicker than a signal. this is easy to
> establish empirically. from a theoretical perspective, signal handling
> is a much more complex situation that simply continuing on with
> whatever function was blocked.
>
> --p
>
According to the alsa documentation, SND_PCM_ASYNC handlers use SIGIO.
It is just as easy for me to create a thread and do poll, so I could do
that.
I think the best approach will probably be to re-write the wine
DirectSound routines, so that when they wish to write to a particular
place in the sound buffer, they do a call to the alsa driver to do the
actual positioning of the write pointer (snd_pcm_rewind/forward),
followed by a write.
All I then do is turn off XRUN detection on the hardware buffer and let
it freerun. "snd_pcm_sw_params_set_stop_threshold(pcm, sw_params, -1 )"
turns off xruns.
Maybe I won't get that information from directsound.
I might need to find out how to control when the poll() returns.
If the period size is 1000, It would be nice if I could get it to return
at say sample 800, so the mmap copying can happen just in time, before
the DAC reaches the next period. This would give me sub-period latency,
but I doubt that will work due to scheduling latencies etc.
I probably have to initially write 2 periods to the buffer, so that when
the poll() returns, I will be writing to period 3, when the DAC is just
reaching the start of period 2.
Due to scheduling latencies, I think I will write 2 periods on each
poll() and then do a period rewind, so that if there is a scheduling
latency, the sound card will be playing fairly accurate samples.
I just wish DirectSound would be able to tell us if it has changed the
sound buffer at all. I hope this will be possible. It might not if the
application does memcopies directly into the sound buffer without
telling direct sound what it did.
If I can get Direct Sound to tell us when it writes to the sound buffer
and what it changes, I could get the poll() to only memcpy the sections
of the buffer that Direct Sound changes.
The way DirectSound works, is it calles "GetPosition" evert 10ms and
gets returned 2 pointers.
1) Playback Position (The Sample currently at the speakers, or more
accurately, in the DAC.)
2) Write Position. (The sample with the lowest latency that DirectSound
could still re-write to now and it would reach the speakers.)
Normally this equals the start of the next period's position.
These pointers are pointers into the ring buffer using an offset from
the beginning of the ring buffer.
I just hope the application tells direct sound what it is doing with the
ring buffer. I will just have to investigate more.
I have already found out that Direct Sound tries to do multi open on the
sound card, so we will be having multiple channels to mmap copy over on
each poll if we use a sound card that handles multiopen. This could
start to get quite complicated. :-)
Summary: -
I think I will work on the simple poll() approach first, instead of
SND_PCM_ASYNC, with it outputting one period at a time.
Cheers
James
-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver
higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-05-07 12:33 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-05-06 18:15 Improving wine support for alsa James Courtier-Dutton
2004-05-06 22:30 ` Arve Knudsen
2004-05-06 23:42 ` Glenn Maynard
2004-05-07 1:49 ` Paul Davis
2004-05-07 4:02 ` Glenn Maynard
2004-05-07 10:12 ` Ferenc Wagner
2004-05-07 11:03 ` Paul Davis
2004-05-07 12:35 ` James Courtier-Dutton
2004-05-07 1:14 ` Ove Kaaven
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.