Comments (5)
Just to avoid, double work: I created a branch for this devel/FixMath2
. There is basically nothing in there so far, but feel welcome if you want to join the fun!
from mozzi.
I believe it should be possible to even go one step further and replace (or supplement) the QXnY typedefs with proper classes. For the purpose of this discussion, let's call the replacement type NXnY
(which I don't think will be the final name).
Internally these would simply carry an integer (8, 16, or 32 bits), but importantly they would have operator overloads so, you can simply write:
N16n16 number a = ...;
N8n8 number_b = ...;
number_a += number_b; // compiler does the right thing, automatically.
. The compiler keeps track of what type each is, and do the appropriate thing, without ever have to spell out the types a second time.
This would also effectively do away with the complexity of specialized members in other classes such as Oscil::setFreq_Q16n16()
etc. That would instead become an overload Oscil::setFreq(N16n16 freq)
.
Now, you are quite right in pointing out that not just two, but three types may be involved in a single calculation, e.g. a multiplication exceeding the original value range. We could again organize this in member functions such as: T2::mult<T1>(T3 factor_b)
. Alternatively, of course, we could stick to a simple rule of "first operand is always the return type". In that case, for a multiplication use a larger value range, users would write e.g.
N8n8 number_a, number_b;
number_c = ((N16n16) number_a) * number_b; // excessive quotes added for clarity. Same as (N16n16) number_a * number_b
. Not quite incidentally, the latter looks much like what you'd do with regular integers.
As for your questions:
Is it a good idea? Sounds like it would definitely be super-neat to have. I'm not entirely sure on how much work it will be. Perhaps we can try starting out with a smallish example of two or three supported types, and take a look at how that seems to work out?
Templates or macros? Templates would be great. Note that using templates does not imply we need to come up with a generic formula covering all cases (even if that would be the ideal). We can also spell out "specializations" one by one, if needed.
Signed and unsigned: Tricky question, but of course, if we can have completeness, then why not have completeness. Again, I'd suggest to start looking at a reduced example, at first, to see, how things work out.
from mozzi.
Hi,
Thanks for your comments!
Indeed replacing everything with classes would be quite neat. But at the same time, I wonder if we should throw away the current paradigm so easily… IMO, replacing the current types with classes, with overload of the operators, is not a good idea, basically because the way it is done can usage specific. For instance, when multiplying two Q16n16
with a wanted result of Q16n16
, the total >>16
shift that is needed can be distributed differently depending on where the precision should be kept:
Q16n16 a = (b>>8) * (c>>8);
or
Q16n16 a = (b>>12) * (c>>4);
are not exactly equivalent.
Overloading the standard operations (on the old types) would prevent that to be done (and potentially break quite a few codes that are using that, maybe it is just me). It is clearly not an easy question but I think the final paradigm should allow both inexperienced users to learn and do things easily while not preventing advanced one in going into micro-optimizations. It would of course be super neat to have fixed maths that could be handled as easily as floats, but I am not sure it is possible to have it behaving as freely as possible at the same time. Having new, class based types, would be the solution but we have to think how these two paradigms (Qxny and Nxny) do interact. Do we want two fix maths paradigms (legacy and new)? I do not have a clear answer on that basically.
I am probably over-thinking it though. I think the multiplication is the main problem with fix_math and will try to focus on that first, trying to make an operation that handles automatically the shifts and so on. As you said, it will probably become clearer with implementation so I'll try to start one as a branch here soon. I think I'll start by adapting the fix types already present in Mozzi and see how things and examples turn out. Even if moving to separate classes, the implementation in itself will probably be reused. That branch will also be a good discussing space!
from mozzi.
Q16n16 a = (b>>8) * (c>>8); or Q16n16 a = (b>>12) * (c>>4); are not exactly equivalent.
Point taken. However, I'll throw in that for advanced tweaks, we could easily offer direct access to the underlying int in a class, too. Also, of course, we could have a member customMult(...)
or so for this sort of thing. The operator methods would simply mean to wrap the "regular" case, comfortably.
As for breaking existing code, I'll admit that would be the case, but it would break at compilation (because shift operators will not be defined; access to the underlying integer would use a getter such as toInt()
to prevent that kind of type-confusion). More to the point, adding real type-safety would be a central feature to the plan.
But yes, of course, this would leave the QXnY as a mostly independent legacy paradigm. More bloat to carry around...
from mozzi.
Very good points, you are always a few steps ahead ;) !
Looking a bit around, I actually found an Arduino library that is performing fixMaths calculations: https://github.com/Pharap/FixedPointsArduino (it actually has a get getInteger
member…).
The only problem is that, if I am correct, this library is made to ensure correct results, hence is promoting types automatically. Whereas I think Mozzi should ensure types. That being said, it is a good source of inspiration, will create a branch soon to try to do something similar for Mozzi (probably dev/fixMath).
As per the QXnY, more on the long run, we can keep it at first but plan to deprecate them for a Mozzi 2.0. Has it will probably not be completely back compatible, that's our chance!
from mozzi.
Related Issues (20)
- triangle warm 8129 table includes values outside valid range HOT 1
- Arduino giga port HOT 4
- getAudioInput not defined HOT 2
- The randSeed() argument type is different in the header and source files. HOT 2
- Stereo - Strange error compilation depending if a function was define before updateAudio() - Problem with preprocessor ? HOT 3
- Compilation errors when including both WaveFolder.h and ResonantFilter.h HOT 3
- Unable to compile for Atmega328PB with Arduino IDE HOT 3
- Sample example not working on UNO R4 HOT 11
- Arduino Nano 33 IoT tested and works with the output on DAC0, which is also called A0 HOT 2
- Output frequency 0.25% off on AVRs HOT 1
- RFC: Mozzi 2.0 part 1: Single compilation unit HOT 7
- RFC: Mozzi 2.0 part 2 - Configuration restructuring HOT 7
- Please Change Mozzi's License HOT 10
- Using Mozzi and I2C library for LCD HOT 14
- RFC: Mozzi 2.0 part 3 - Miscellanious
- UNO R4 port broken HOT 2
- Compatability/Compilation Issues w/ Nano 33 BLE Sense HOT 5
- Apparent frequency drops when amplitude increased beyond 8 bits on AVR HOT 3
- mozzi_rand cannot go full range HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mozzi.