* 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 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
* 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
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.