On Sat, 2007-12-01 at 19:17 +0000, Krzysztof Foltman wrote:
And as for fixed point timestamps - yes, I admit(ted)
the fixed point is
*usually* more PITA than floating point. But it all depends on context.
I can't say "fixed point is always bad", because for some things it's
really good :) Say, wavetable oscillators - you can't really get good
performance when you store sample position as floating point. Just try it :)
However, I'm not advocating for using fixed point numbers everywhere.
Let me give a concrete example, so that you know *why* I'm so stubborn
about this issue. Perhaps I'm making a wrong assumption here.
uint32_t optr = 0;
while(i<count) {
uint32_t ×tamp = events[i].timestamp; // just saving on typing
here :)
uint32_t nsamples = (timestamp >> 16) - optr; // fixed point case
uint32_t nsamples = fast_f2i(timestamp) - optr; // floating point case
if (nsamples) {
process_samples(optr, nsamples); // buffer offset, nsamples
optr += nsamples;
}
float frac_pos = (timestamp & 0xFFFF) * (1.0 / 65536.0); // fixed
point case
float frac_pos = timestamp - floor(timestamp); // floating point case
process_event(&events[i], frac_pos);
i += (events[i].size + 7)&~7;
}
process_samples(optr, output_size - optr);
Ew. Definitely separate the integer part from the fractional, this is
just fugly for no reason...
As you see, I'm not pushing on fixed point use
everywhere. Just in that
particular case, because - in my opinion - it's worth it. The loss of
precision is pretty acceptable (1/65536th of a sample? that's 0,34
nanosecond resolution with sr = 44100, pretty impressive in my opinion,
I think DRAM access times are more than 0,34 nanoseconds, just to give
you some point of reference :) ). The code is very similar, only a bit
faster.
No argument that it's faster. With separate int fractional parts it's
even probably cleaner. I may be convinced...
Taking a step back, it would be nice to have these events (being
generic) able to use something other than frame timestamps, for future
dispatching/scheduled type event systems. OSC uses 64 big fixed point
absolute time stamps, giving a resolution of about 200 picoseconds
absolute time (epoch January 1, 1900). This is equivalent to NTP time
stamps apparently - ie huge precedent.
Whether stamps are in frames or absolute time could be a property of the
port. Maybe we should up it to 64 bits fixed point? The additional 32
bits aside, doing that gives us all the range or precision in frames
needed, and the ability to map to a widespread absolute timestamp
format, and parity with OSC. That's a lot of pros...
(This may sound a bit esoteric, but to do something like Max right, you
need absolute time stamps).
Currently in MIDI we have 64 bits in there anyway.. I never thought of
using fixed point, but the OSC/NTP parity and potential for very precise
absolute time stamps is very, very tasty to me.
Also, the frame part would be a uint32_t - equivalent to Jack MIDI
timestamps, another win (and cutting out more conversion overhead).
Thoughts?
-DR-