[SDL] on timing and SDL (and message queues for that matter)
david.olofson at reologica.se
Fri Mar 2 07:59:25 PST 2001
On Friday 02 March 2001 13:08, winterlion wrote:
> On Thu, 1 Mar 2001, David Olofson wrote:
> > On Wednesday 28 February 2001 18:38, winterlion wrote:
> > > Could this be something to add to next SDL?
> > Why not?
> good :)
> I've just realized (reading this) that I was talking about several
> different types of time-synchronization and time issues - I guess I should
> have defined them all...
> On platform dependency:
> Accurate timing is platform-dependant yes.
> (RDTSC for some reason doesn't work on my computer for instance -
> or didn't before I upgraded everything :)
It can't fail if it's there, as it's built right into the CPU core and
instruction set. However, if you don't have an Intel CPU (Pentium MMX or
later, IIRC), it won't be using the same opcode, if it exists at all... ;-)
Most modern CPUs seem to have something like the Time Stamp Counter, so it
should just be a matter of identifying the CPU and plug in a suitable
function. If it's not there (or the CPU is on an unknown type), one has to
resort to other methods, like Win32 multimedia timers or similar.
It would probably be a good idea if the API could give a hint about the
actual resolution, in cases where it would be better to use some other method
if the timers are too coarse.
> any action or set of actions that are supposed to take place
> at a selected coherency are a frame. In video, framerate is how
> many video frames can be updated per second. In audio it's how
> many frames (ie: packets) can be played. In networking, it's how
> many packets (ie: frames :) can be sent... or the rate they
> should be sent...
> Unless there's a better definition this is what I use.
BTW, with low frame rates, it's not always sufficient to use one frame as the
unit of time. Higher accuracy might be required for some things.
> a coherent channel of actions. May correspond to a hardware
> thread but it's a lot easier to just make it a 'cooperative'
> thread unless actually necessary to make it a hardware thread.
Also, cooperative "threading" is a lot more solid WRT timing, as you can
control exactly what's done when, synchronously in all "threads". For any
system that has only one frame rate to deal with, that's a lot easier to get
right, and it also allows less buffering and thus lower latency.
> Incidentally except where real-time is really necessary accurate current
> time-keeping really isn't all that necessary - but measuring how much time
> has passed -is-. *g* (SDL_GetTicks works quite nicely for me :)
Well, the problem is that unless you know the exact video refresh rate and
sync the video thread to it, you have to check the current time before you
start rendering each frame, in order to render everything in the exact right
position. (That's actually the same thing as syncing to the refresh rate, as
long as you stay at full frame rate - just different ways of getting the
If you're going to use subpixel accurate positioning, you absolutely *must*
know the exact display time of each frame, or there's just no point. The
timing jitter of +/- 0.5 frames corresponds to +/- 0.5 pixels at 1
pixel/frame speed, so you might as well drop the interpolation if you don't
get the time right within a fraction of a frame.
Now, if you know you're going to stay at full frame rate, you can just check
the frame rate and then use that to update the control system time every
frame. Just tweak some if it should drift from wall clock time, and make
"brutal" changes only if you should miss frames.
> on multithreaded music:
> the trick is cooperative threading - not preemptive *g*
> MOD files have 4-16 threads. XM have up to 32.
> MIDI has umm
> up to 32 threads... (but usually one. I've got several MIDI
> files that push this though..)
One? 32? Are you referring to tracks? I'm not sure there is a limit at 32,
but it might be - I haven't investigated MIDI files very carefully. (I find
MIDI useless outside custom studio setups. GM/GX etc is crap - no control, no
real timbre standard, no level standard whatsoever etc etc. I'd rather use
either OPL3 FM or modules.)
Anyway, I do know that there is rudimentary channel + port support, so at
least it's possible to deal with more than 16 channels. However, I'd *never*
use that in a GM or other standard file, as it's impossible to tell where the
ports are routed. (Playing such a file on my setup, only the first port will
play GM; the other one will hit a custom non-standard JV-1080 performance
> I should explain more - you're right, planning (and passing information)
> ahead of time is The Right Way. That's how my movie/music players work...
> and yah syncing is a real pain with latency-rich hardware such as audio
> players... (or even videocards in old days) Or anything to do with
> internet communications for that matter. (ie: videoconferencing :)
Internet? Latency!? *hehe*
> When I last played with MIDI btw - veryvery long time ago - MIDI supported
> posting messages with timestamps.
Thinking about the MPU-401? (The *real* one, that is; not the crippled
copies.) Yeah, it had hardware timing support, but that's pretty much the
only interface that ever had that, short of some of the latest high end
Some fools concluded that "computers are now sufficiently fast to do the MIDI
timing in software, so we don't need to mess with MPU-401 style h/w timing."
Well, they were right, and software based solutions are more flexible.
However, they didn't realize that the days when you could hog the CPU without
restrictions to do hard real time stuff were soon to be over...
> I don't know if any hardware actually
> supports this though - I've never owned any MIDI hardware.
Some of the external multichannel interfaces do. Not sure if standard driver
APIs support it, though. Win32 does have a new API with timestamps, but I
don't know if everything is actually implemented all the way down to the
> And this is
> where the 'frame rate' mattered - each MIDI channel had it's own 'frame
> rate' that messages were set in.. No wait, that's quicktime - MIDI has a
> fixed time scale...
> Thank you MUCHLY for the MIDI info - I do intend to work with MIDI, I've
> just never had the resources to do so until now...
Just keep it in the studio, will you? ;-) That's where it works.
Right, you could add an E-mu Proteus 2000 or a Roland JV-2080 to the system
spec for music playback, but other than that, you're either limited to no
control at all, or to SoundFonts. (And SoundFonts don't play correctly on all
cards either; actually not at all on most cards...)
What I'd like to do for game music, as an alternative to the usual CD track
or mp3 solution, is to throw in a soft synth controlled by something similar
to MIDI files, instead of relying on any hardware dependent (non-)standard.
Beats modules hands down in all respects, unless you just can't create with
anything but a classic tracker UI. (I almost forgot how to do that, so I
don't care much...)
> > > And how do, say, the game writers handle video render timing,
> > Render as fast as you can, preferably trying to figure out when the frame
> > is actually going to be displayed. *That* is the engine time you should
> > advance to before rendering a scene using the current state.
> > > action timing,
> > No problem if you get the above right. Just *don't* base game time or
> > frame rate on anything but game consoles - preferably not even there, as
> > there are 50 and 60 Hz standards even there. (While computers have no
> > standard at all; just expect anything from 60 through 200+ Hz, and
> > *don't* expect to be able to set a desired refresh rate, as it's either
> > not going to work, or will make the monitor freak out on some systems.
> > I'd rather not look at a 60 Hz display on my Eizo F980... Stroboscope!
> > :-)
> yah my 'timer' tells how advanced each individual 'time channel' has gone
> based on being told how much time has passed. I think I set it around
> 100khz for accuracy as that small measure is rarely used and any time
> block could be measured within :)
> It doesn't actually try and run that fast - it's designed to keep track of
> when things should take place... hrm - hard to explain...
> I tend to run -it- buffered ahead too - that way it posts messages to the
> threads that handle actual situations and they can handle the right
> delays. So far SDL_Delay works quite nicely here. Most other delay
> methods I checked into caused artifacts (ie delays) to threads other than
> current one...
> I've never looked too closely on handling video frame updates against the
> hardware - mostly because as you say it's way hard. And often on older
> (and really new hardware at very high rates) the frame update is slower
> than the graphics card...
Actually, in that case you *should* lower the refresh rate, or upgrade the
machine. (Unless you can accept the unsmooth animation, that is.)
The frame rate *cannot* be dropped below the refresh rate without visible
artifacts, no matter how high the latter is! You'll always get those ghost
image effects on fast moving objects, although they do get slightly less
visible at extremely high refresh rates, like 150 Hz or higer, depending on
(Note that the objects will mode less between the frames at higher frame
rates, which also reduces the ghosting effect slightly - *maybe* enough to
produce an acceptable result in some cases. I wouldn't bet on it though; try
it with a good 21" monitor, and you'll be surprized how every minor artifact
becomes very visible...)
The reason for this appears to be similar to the reason why you have to use
oversampling/linear interpolation and/or filtering in audio DACs to avoid
audible artifacts - you can't just pump a staircase shaped signal out and
expect a clean sound.
In both cases, we're dealing with frame rates that are way beyond the
frequency range of the eye and the ear respectively, but still, we have to do
things right to avoido visible/audible artifacts.
> Double (or triple) buffering -is- a necessity
> for high-traffic video.
> > > I'm interested in time messages over message queues in SDL
> > > btw... controlling timing across multiple threads is a -real- pain!
> > > (feed the 'delay' into thread, thread delays set time to next action)
> > Why are you using threads in the first place? Unless they're *directly*
> > interacting with multiple external interfaces (user input, audio output,
> > video output), and doing it at different timing resolution, threads will
> > usually just complicate things and make everything behave less reliably
> > WRT timing.
> I'm not writing a videogame at the moment. (actually I am but it's low
> priority... :)
Personally, I'm thinking about giving up talking about priority - as you
might expect, I'm a hacker since the age of 10, and hacking *always* (well,
almost ;-) has top priority! The problem is just that I have too many
projects going on... *heh*
> for a 'browser' (fancy database front-end) multiple threads (and tasks) is
> how it runs. So it seemed simple enough to take this model to videogames
> :) (although maybe a bit 'heavyweight'... hrm...)
Yeah... It would be *possible* to do it that way with an OS with decent real
time scheduling and/or enough buffering + timestamping, but I doubt it's
worth the efforth if you want real smooth animation. It's just too messy to
keep things in exact sync and getting the interpolation right.
> I got curious how other programmers handled timing - be it tracking
> timing, queued timestamped messages (that's what I use) and handling
> multiple 'frame' rates. (ie: audio is running 44khz but blocks are in 512
> sample blocks which means framerate is ~86fps, actions on objects vary
> from 1 fps to 1000+fps... video can float anywhere from 10fps up to 60fps
> in videocapture, rendering COULD be up to 200+fps). I end myself with a
> lot of 'delta' objects (dD (velocity), dV (acceleration), dA (ummm rate of
> acceleration?), and such)
In some very "pixel oriented" games, it seems hard to get coherent behavior
regardless of video frame rate with "theoretically correct" timing (pos, v, a
etc and dt).
In the port of Project Spitfire (which was locked at 60 Hz, depending on a
custom VGA mode), I'm basically reconstructing the original control system
(which *did* use pos, speed and acc), but I keep it running at 60 Hz, as it
did in the original game. In order to get smooth animation, I've added an
linear interpolation filter to the "point" object, which means that I can
advance the control system with sub frame accuracy, and extract all
coordinates with sub pixel accuracy.
In the current version, I'm just rounding to the nearest integer pixel
position, but I'll use the full resolution when I throw the OpenGL rasterizer
> (hertz would be a nice translation for how I use framerate actually -
> except I find it also tied to close to audio/radio)
Hz would be the *unit* of framerate, I think... :-)
> hrm - hope this message is coherent. I've edited it a couple of times but
> can't be sure. (shrunk it some too - I've got a bad habit of rambling :)
So do I...! :-)
.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
`----------------------> http://www.linuxaudiodev.com/maia -'
.- David Olofson -------------------------------------------.
| Audio Hacker - Open Source Advocate - Singer - Songwriter |
`--------------------------------------> david at linuxdj.com -'
More information about the SDL