[LAD] "enhanced event port" LV2 extension proposal

Krzysztof Foltman wdev at foltman.com
Sat Dec 1 19:17:50 UTC 2007


Dave Robillard wrote:
> Read the comment... the buffer format couldn't be more clear.
>   
That was the problem - the comment contradicted the code, but - as human 
language is usually more ambiguous than C code -  I assumed that the 
true intention is in the code, not in the comment.

Just to clear it up.

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 &timestamp = 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);

This is how I imagine an event processing loop (main "process" function) 
in an average plugin. Note that there's not a lot of difference between 
fixed point and floating point (assuming we want fractional position as 
float number, which is a fair assumption, IMHO). However, floor is slow 
(though you need it only if you need fractional position). Float-to-int 
is slow, even if implemented via bit-manipulation trickery. Shift is 
fast. AND is fast. float*int is fast, at least faster than floor() :)

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.

Come on, we're arguing about changing two lines of code here (with the 
rest - process_samples, process_event etc - being exactly the same!). 
Don't present it as if I wanted everyone to code thousands of lines of 
fixed point handling libraries. THAT would be both stupid and evil. I 
obviously don't want that.

I'd gladly sacrifice very large runs to not have to use the horribly 
inefficient things like float-to-int - and you don't really have to 
sacrifice them (just add a "65536 sample time period have pased" event 
type). I think it's not "premature optimization", it's more of "not 
forcing everyone waste CPU cycles".

Krzysztof




More information about the Linux-audio-dev mailing list