Craig Edwards wrote:
A period/fragment is a portion of the buffer that is sent to the
sound chip when it generates an interrupt.
So it isn’t necessary to provide a callback – just send the kernel
driver a period/fragment’s worth of data whenever it’s ready.
Thanks for the reply. As I understand it, when the interrupt is
generated, the driver (ALSA/OSS/my XBOX code) is responsible for giving
the next buffer to the chip.
Yes, but let’s call it a period or fragment, instead of “buffer”,
because it’s only a portion of the output buffer.
This has two separate (but related)
- Where does the driver get the data from?
From the SDL output driver, which got it from an SDL output routine,
which got it from an application program, which calculated it somehow
and called the SDL output routine to play it.
You said “just send the
kernel driver a period/fragment’s worth of data whenever it is ready”…
I presume the “sender” in this case is the application code? If I
understand you correctly, you are saying the driver code is interrupt
based, but the application code is not.
It might be interrupt based, but it needn’t be. The Alsa library
routines let you set up callbacks to service the buffer, but you
don’t need to use callbacks. You (the application) can just
deposit a fragment into the buffer whenever there’s room for it.
i.e. The application code
just gives buffers to the driver as they become available, and the
driver gives them to the chip upon interrupt. Is that right?
this cope with the fact that the application code might not be cooking
the buffers fast enough to keep up with the interrupts?
Then the kernel driver tells you there was an underflow, and you just
have to deal with that.
I think the SDL library code handles this situation on behalf of an
application by putting silence into the kernel driver’s buffer,
so it’s happy and never knows about the underflow.
driver (and SDL, as I understand it) has the capability to register a
application code callback to get more data if the driver has none left
when an interrupt is triggered.
That sounds right, but I’ve never used either SDL’s or Alsa’s callback
facilities, and I’m not familiar with them.
- How do we cope with possible lag between interrupt firing and
setting up of new data?
Well, that’s the problem, isn’t it? We cope the best we can. If
there’s a lot of calculation to do, it may just not be possible
for the application to feed the driver fast enough.
This scenario might happen if the application
code has not provided enough data to the driver. For example, it has
sent only one buffer to the driver which then passed it on to the
chip. The chip processes that buffer, realises there are no more
descriptors set up, so fires an interrupt. The driver catches that
interrupt and calls the application callback for more data. However,
there is a time-gap between the interrupt firing and the application
code providing more data, which means the audio chip will either play
silence (or the last sample). This is what I am trying to avoid. My
current thinking is that before playing the very first sample, my
driver could call the application callback a couple of times to make
sure it has a couple of buffers that can be playing while waiting for
the callback to provide the next buffer (an audio form of
double-buffering, I guess).
Alsa allows you to specify whether you want it to wait until the buffer
is full of fragments, on startup, before initiating the playback.
That’s a good option to choose. It helps prevent an initial stutter.
My problem is that this is not my area of expertise, so I am not sure
if what I am proposing is typical, not recommended, or just plain
foolish. Looking through the SDL code, I see that it appears (I think)
to have the notion of double buffering through the user of the
fake_stream element. However, I am just not sure…
I think the fake stream business concerns concealing underflows
by inserting silence into the output buffer, but I don’t
understand the details. I don’t think it’s necessary to
do it that way. You can just let the underflow happen, and
it you service the error you get from the kernel driver
appropriately, you will just get silence during the
Greg> On Tue, 26 Oct 2004 02:59:53 -1000, Greg Lee <@Greg_Lee> wrote: