How this can be implemented?

35 views
Skip to first unread message

grz...@gmail.com

unread,
May 7, 2014, 2:41:15 PM5/7/14
to libfi...@googlegroups.com
Hello,

i am trying to use libfixmath for an audio application for handheld devices, it is based on simples sin oscillators however i have trouble getting the interpolation to work, i almost never had to use fixed point arithmetic so i don't know if what i did is correct.

Here is the double/float version of what i am trying to convert:

            audio_output += lerp(ed->prev_volume, ed->volume, f) * sin(osc->phi);

            osc->phi += osc->phi_step;

And here is what i did for the fixed point version:

            fix16_t vol = fix16_lerp8(ed->prev_volume, ed->volume, f)+1;

            output += fix16_div(fix16_sin(osc->phi), vol);

When i use a simple fix16_sin without the interpolation part it work as expected even if it clicks (no lerp) but when i add the interpolation like posted it just sound noisy and i just don't get why, to me it seem to do the same thing as the float version?

I tested the fix16_lerp8 output individually and it work correctly, fix16_sin output also work, but when i try to add theses together it just fail and i don't get what is wrong with the calculation, i tried to use the fix16_sadd also but it fail as well...

I also tried to use fix16_lerp16 but i seem to get a wrong output (f range is between 0 and 65536 right?)... so did not used it.

Ben Brewer

unread,
May 7, 2014, 3:01:35 PM5/7/14
to libfi...@googlegroups.com
Hey,
    Responses are inline.


On 07/05/14 19:41, grz...@gmail.com wrote:
Hello,

i am trying to use libfixmath for an audio application for handheld devices, it is based on simples sin oscillators however i have trouble getting the interpolation to work, i almost never had to use fixed point arithmetic so i don't know if what i did is correct.
Good choice, if it's really simple it might make sense to use libfixmath to learn how it's done and then implement it manually for extra speed once you're sure, but libfixmath should still be faster than using libmath on any embedded platform (excluding Intel stuff).


Here is the double/float version of what i am trying to convert:

            audio_output += lerp(ed->prev_volume, ed->volume, f) * sin(osc->phi);

            osc->phi += osc->phi_step;

And here is what i did for the fixed point version:

            fix16_t vol = fix16_lerp8(ed->prev_volume, ed->volume, f)+1;

            output += fix16_div(fix16_sin(osc->phi), vol);

First thing I don't get is why this is different, you should try to do the same with libfixmath as you would do with floats, otherwise you're doing your own float stuff anyhow.

So I'd expect the following based on what you wrote above:

audio_output += fix16_mul(fix16_lerp8(ed->prev_volume, ed->volume, f), fix16_sin(osc->phi));
osc += osc->phi_step;

This assumes that all your inputs are fix16_t, apart from f which I'm assuming is an 8-bit fraction where 0.0 is 0 and 1.0 is 255. If f is different you'll have to use a conversion function.

The addition will do horrible things if your input goes out of range and doing saturated addition probably won't help with that so I can't give a better response without knowing more.


When i use a simple fix16_sin without the interpolation part it work as expected even if it clicks (no lerp) but when i add the interpolation like posted it just sound noisy and i just don't get why, to me it seem to do the same thing as the float version?

This sounds like a problem with the way you're using lerp in your code, but as I said above; I'd need to know a bit more to really comment on this.


I tested the fix16_lerp8 output individually and it work correctly, fix16_sin output also work, but when i try to add theses together it just fail and i don't get what is wrong with the calculation, i tried to use the fix16_sadd also but it fail as well...

I'm a little confused by this since the code samples given don't seem to be doing the same thing.


I also tried to use fix16_lerp16 but i seem to get a wrong output (f range is between 0 and 65536 right?)... so did not used it.

If lerp16 is not working properly then you might have found a bug, could you please post an issue on this along with the test you used (no matter how quick/messy) to discover it.
The issue tracker can be found here: https://code.google.com/p/libfixmath/issues/list

Thanks,
Ben Brewer (aka flatmush)

grz...@gmail.com

unread,
May 7, 2014, 5:34:38 PM5/7/14
to libfi...@googlegroups.com, flat...@googlemail.com

First thing I don't get is why this is different, you should try to do the same with libfixmath as you would do with floats, otherwise you're doing your own float stuff anyhow.

So I'd expect the following based on what you wrote above:

audio_output += fix16_mul(fix16_lerp8(ed->
prev_volume, ed->volume, f), fix16_sin(osc->phi));
osc += osc->phi_step;

This assumes that all your inputs are fix16_t, apart from f which I'm assuming is an 8-bit fraction where 0.0 is 0 and 1.0 is 255. If f is different you'll have to use a conversion function.

The addition will do horrible things if your input goes out of range and doing saturated addition probably won't help with that so I can't give a better response without knowing more.

I tested this code and it sound like it would sound without lerp so the audio have clicks, i used a division in the fixed point version because the range of "prev_volume" and "volume" are between 0.0 and 1.0 and so i thought this sort of thing couldn't be done/would result in different behaviors with the fix16_mul "0.5 * sin(osc->phi)" so i used a division instead with a modified range

All inputs are fix16_t and f is indeed between 0 and 255.

Both additions could probably go out of range, i don't check for this right now (nor in the double version)
Reply all
Reply to author
Forward
0 new messages