From alsa-devel-owner@alsa.jcu.cz  Mon Jun 22 22:32:44 1998
Received: from entry.jcu.cz (perex@entry.jcu.cz [160.217.1.111])
	by marvin.jcu.cz (8.8.8/8.8.8) with SMTP id WAA18137;
	Mon, 22 Jun 1998 22:32:31 +0200
Date: Mon, 22 Jun 1998 22:32:31 +0200 (MET DST)
From: Jaroslav Kysela <perex@jcu.cz>
To: Andy Lo A Foe <arloafoe@cs.vu.nl>
cc: alsa-devel@jcu.cz
Subject: Re: SNDCTL_DSP_SETFRAGMENT
In-Reply-To: <Pine.LNX.3.96.980622195010.3317A-100000@orbital>
Message-ID: <Pine.LNX.3.96.980622220603.25837A-100000@entry.jcu.cz>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Reply-To: alsa-devel@alsa.jcu.cz
Sender: alsa-devel-owner@alsa.jcu.cz
Precedence: list

On Mon, 22 Jun 1998, Andy Lo A Foe wrote:

> Hi,
> 
> I'm coding an app that needs quick response from the DAC device so I'm
> using the SNDCTL_DSP_SETFRAGMENT ioctl call to set a fragment size.

Why you are using old OSS interface? ALSA PCM have better interface to do
it..

> My code looks like this:
> 
> long param;
> 
> param = ( 0x0200 << 16) + 0x0008;
> 
> if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &param) == -1) {  
>                 ...error handling...
> }
> 
> This will create a fragment size of 0x200 (512 bytes), I think :)
> But what does the  number in the lower 16-bits really do (0x0008)?

OK. 0x0008 means that ring buffer for playback will be separated to 8
fragments (if possible). Total used size of ring buffer is in your case
4096 bytes (8 * 512). If you are using some big rate (for example 44.1kHz,
stereo, 16-bit) - 4096 bytes contains only 0.02322 seconds
[4096/(44100*2*2)] of sound. This is very very small buffer for this
operation - scheduling is working at 100HZ - this means that program have 
only 2.322 scheduling ticks to process new data. Good buffer should have
about 0.2sec latency - good value should be 8192 - DMA buffers are
64kB or 128kB long - you can allocate 4 fragments for your purpose.
If all fragments will be filled  - 4 * 8192 = 32768 bytes. Now compute:
32768/(44100*2*2) = 0.186sec - this should be reasonable value, but if you
use bigger ring buffer, you can expect low underruns..

Wakeup latency: driver wakeup process if some fragment is free (all
free fragment, not if partial fragment is free). This is default setup for
OSS and ALSA PCM. With ALSA PCM you can set this wakeup mark to some
another value - for example - wakeup only if at least three fragments are
free etc..

I must say, that some OSS programs have trouble with fragment setup.
In most cases are used ring buffer very small (x11amp, RealVideo) and
system in most cases produces underruns.

> Now, when doing playback I sometimes experience small (barely
> noticable, but they're there) hickups in the stream. This seems to happen
> with both the ALSA driver and the kernel sound driver. I'm using write()
> to send data to the DAC device. Is this the right thing to do?

Yes, it's right way..

> When not using the fragment code everything sounds ok, but then latency
> is bad of course...

						Jaroslav

-----
Jaroslav Kysela <perex@jcu.cz>
Academic Computer Centre, University of South Bohemia
Branisovska 31, C. Budejovice, CZ-370 05 Czech Republic


