Open DatanoiseTV opened 2 years ago
Are you ready to help? Have you read https://faustdoc.grame.fr/manual/architectures/ ?
Yes, but I am not sure where to start best. The RP2040 doesn't have a floating point unit, so all the calculations should be done using fixed point calculations. Vult DSP has included a compile option for this which transcompiles it to use 32-bit fixed point.
Hum, Faust does not have a 32-bit fixed point code generator yet. But it should have one at the end of the FAST project
I'm also interested in this and been playing with CNL. I got it to compile, but the main problem I encountered is the structure, so to speak, of the computations in the generated code. Fore example even the beginning:
fixpoint_t fConst0 = fmin((fixpoint_t)192000.0, fmax((fixpoint_t)1.0, (fixpoint_t)(dsp->fSampleRate)));
fixpoint_t fConst1 = tan((fixpoint_t)25132.7422 / fConst0);
fixpoint_t fConst2 = (fixpoint_t)1.0 / fConst1;
blows the range of even 128bit fixed point variables... Thetan
and divisions are to blame. With 32bit fixed point numbers, like in Vult, it will only get worse. Any ideas how to fix this?
Interesting use of CNL. Is you project visible somewhere?
No, not yet. Too experimental for now :) Also, CNL is not really suited for low-end embedded platforms (uses advanced features of C++, requires C++20, g++-10, etc..)
Actually one more update on this topic. The code for sin oscillators behaves fairly okay with fixed point. The noise generator has problems. no.noise
generates code like this:
int i0;
for (i0 = 0; i0 < count; i0 += 1) {
dsp->iRec0[0] = (1103515245 * dsp->iRec0[1]) + 12345;
output0[i0] = fix_to_float(fix_mul(float_to_fix(4.65661287e-10), int_to_fix(dsp->iRec0[0])));
dsp->iRec0[1] = dsp->iRec0[0];
}
Multiplication by 4.65661287e-10 is the problem. Anyone knows how to fix this?
Are fix_to_float, fix_mul
kind of functions manually coded? (they are not yet generated but the code generator AFAICS..)
Are
fix_to_float, fix_mul
kind of functions manually coded? (they are not yet generated but the code generator AFAICS..)
Yes. I'm aiming at C generator, so I modified it to use explicit functions instead of binary operators (C doesn't have operator overloading).
Signals in the Faust compiler have an associated interval (like a [min, max]
range) with an associated symbolic computation done at each step (even is still imperfect, particularly in the presence of recursive signals).
The proper way will then be to add an additional kind keep the range in this fixed-point domain constraint in the interval calculus, so that to finally generate correct code. This is not a trivial task... (and actually part of the FAST project).
How does VULT deal with fixed-point compilation?
I know VULT even less than Faust :) . I think that VULT is much simpler and doesn't have so many pre-defined blocks. I've made quick experiment. In Vult there is a simple noise example:
fun pinker(x:real){
mem w1;
val b0 = 0.02771298631913731;
val b1 = 0.02771298631913731;
val a1 = -0.9445740273617255;
val w0 = x - a1*w1;
val y0 = b0*w0 + b1*w1;
w1 = w0;
return y0;
}
and this translates to:
fix16_t Ex_pinker(Ex__ctx_type_0 &_ctx, fix16_t x){
fix16_t b0;
b0 = 0x718 /* 0.027713 */;
fix16_t b1;
b1 = 0x718 /* 0.027713 */;
fix16_t a1;
a1 = -0xf1cf /* -0.944574 */;
fix16_t w0;
w0 = (x + (- fix_mul(_ctx.w1,a1)));
fix16_t y0;
y0 = (fix_mul(_ctx.w1,b1) + fix_mul(b0,w0));
_ctx.w1 = w0;
return y0;
}
The proper way will then be to add an additional kind keep the range in this fixed-point domain constraint in the interval calculus, so that to finally generate correct code.
I don't think there is a way around re-implementing some (all?) of the blocks/functions into more fixed-friendly versions. Just limiting the range will still introduce artifacts and problems with more complex topologies.
Until we improve the compiler interval calculus, I don't think we can move on in the general case.
I can possibly improve the C backend so that -fx
would generatefix_to_float, fix_mul
kind of functions, so that as least the generated code does not have to be manually editing. Would this help?
But you'll still have range issues in a lot of DSP examples.
I can possibly improve the C backend so that
-fx
would generatefix_to_float, fix_mul
kind of functionq, so that as leaqt the generated code does not have to be manually editing. Would this help?
Yes, I think this would be better. Will work for C and C++. Also explicit casting functions would be needed (float_to_fix, fix_to_float, int_to_fix, etc).
Hum, Faust does not have a 32-bit fixed point code generator yet. But it should have one at the end of the FAST project
I see that Syfala is now available. It seems to have fixed point for VHDL. Any updates on fixed point support in Faust? Maybe it would be possible to convert VHDL form Syfala to C?
Hello - is there any new status on this? is -fx
enough now?
I have created the PicoDSP and some DSP boards around the easily available RP2040 MCU. Here is my sample code (using Vult currently instead of Faust) https://github.com/DatanoiseTV/RP2040-DSP-FreeRTOS-Template
It would be nice to see Faust support for RP2040.