[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Linux sound



Mads Bondo Dydensborg wrote:

> > Sharing of the SIGUSR1/2 signals, eh? I saw that coming a mile up front!
> > Annoys the hell out of me when *libraries* take over signals in this
> > manner!
> 
> Yes, you are right. Actually I did know that svgalib uses SIGUSR{1,2}, but
> I did not know that pthread did. (In earlier versions then the one
> bundled with glibc 2.1)

Yes, but most system still are with glibc 2.0.x... At least, going from
glibc 2.0 to 2.1 is much easier than switching from libc5 to glibc2, so
this should be a lot quicker to come...

> > > - I almost know exactly how long it takes to enqueue a new sound.
> > >   (Meaning, a call to sound_play(sound) returns almost immidiatly.
> > >   If I had to write to a buffer, it could take variable length. Not a
> > >   big deal.)
> >
> > The mixing is done a buffer at a time in process_sound(), so it runs in
> > bounded time (it can take from almost no time (if the sound device has
> > no space for a buffer) to the time it takes to mix one buffer (not very
> > long)).
> 
> I know the time is bounded. I jast gave you the only two reasons I had :-)
> (none of them was any good. :-)

I just thought you were thinking that our equivalent to the sound_play()
routine was taking time proportional to the size of the sound being
played (which wouldn't be bounded)...

> > In my experience, letting the OS do it leads to bonehead scheduling. The
> > mixer loop for example, has most of the loop counters in registers, the
> > code is small and fits into the code cache, data is taken in small
> > chunks, so it also fits into the data cache. Interrupt in the middle of
> > this: registers are stowed to main memory (consider that in a few loop
> > iteration, they were simply going to be thrown away) and both code and
> > data cache are crapped out (aaargghh!).
> 
> I had not considered this. You are right. The game I am using it for is
> not really in need of CPU cycles. If it was, my approach would kill the
> registers and cache.

Yes, of course, it depends on the game. If you are writing a Minesweeper
kind of game, just lay back, relax and forget about it... :-)

But if you're writing a Quake kind of game, this is becoming very
interesting details...

Quadra isn't exactly as hard on the machine as Quake is, but it isn't
exactly easy either. Note how the blocks move in a smooth fashion, and
the fade used to make the lines disappear, then the scrolling used to
make whatever is on top fall down... This might seem like not much, but
heck, when we were developing Remtris 2 (the precursor of Quadra) on our
486's, we had to devise things like dirty rectangle updating and other
techniques, because we had a few hot spots that were far too hot and
blocked the game performance. It took a few development iterations
before we had the blocks falling in a smooth manner rather than a line
at a time like classic Tetris!

And we plan to use our library for future games which should push the
envelope a lot more than that!

> > Also, writing thru a pipes involves at least two memory copies (still
> > not too bad) and a forced context switch (this is bad), our resource
> > manager uses compresses resources that are uncompressed in memory (two
> > sets of buffer, one for each processes).
> >
> > I would venture that using shared memory for communication would be a
> > big improvement, but SysV shmem simply freaks me out and you can't have
> > anonymous shared mmap() to do this (to my knowledge, if anybody knows
> > how, that would be great!).
> 
> By using the thread, I actually use shared memory. It is like yours (and
> others I guess) setup, where a int is enqueded. (Actually a bit more, if a
> looping sound is requested), I simply use the thread for scheduling. I had
> not given it any thought that this means that the cache and registers are
> destroyed. (The sound mix code is hugely ineffecient anyway - my lack of
> knowledge in C ensures that ... :-)

Yes, that's true, you used a thread. I was confused with the fork()ed
sound server approach. Thread "shared memory" doesn't have the problems
SysV shmem has (and is like this idealistic anonymous shared mmap(), for
that matter!).

> > > One thing that needs to be considered in both cases is the size of the
> > > buffer, as this will influence lag etc much. I have choosen 3 buffers of
> > > 512 bytes at 11khz - this seems to work good. (not on sblive though).
> >
> > We have two of them, at 8192 bytes each. We run the sound device at full
> > resolution, 44.1kHz, 16 bit samples, stereo, which goes for about 47
> > milliseconds of sound. We have a 10 millisecond timebase, so on
> > reasonable hardware, it makes sense. Mixing for too much ahead get you
> > lagged...
> 
> Yes. I mix approx 3 * 22 ms ahead, but mostly I am only approx. 2 * 22 ms
> ahead.

How many bits per sample and channels do you use?

> > What's your experience with the SBlive? We have one nearby, but couldn't
> > try the Linux version of our game with it...
> 
> When I tried to allocate 3 buffers of 512 bytes each, it would only give
> me 1 buffer of 512 bytes. When I tried to play to this, the sound was
> lagging way behind. I have written creative labs about this, but has yet
> to hear from them.

I see... Have you tried asking only for two buffers?

BTW, did you try Quadra on this SBlive? We'd be interested in knowing
how the sound is on that card (if it is acting a bit weird)...

And anyway, you also have to try Quadra just for the sheer value of it!
;-)

> > We set the /dev/dsp file descriptor to be async, but we're not sure this
> > actually does anything when there is sufficient space in the sound
> > device.
> 
> What difference should it make, if you set it to async? (I probably should
> be able to figure this out myself, but it kinda confuses me.)

Well, when you write to a file descriptor that has enough buffers to do
your write and that it has the O_NODELAY flag, it returns very quickly.
If there is no free buffers, it acts normally. But I think this could be
the behavior of /dev/dsp when no O_NODELAY flag is applied. :-)

-- 
Pierre Phaneuf
Ludus Design, http://ludusdesign.com/
"First they ignore you. Then they laugh at you.
Then they fight you. Then you win." -- Gandhi