Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32 requires float #104

Open
ctag-fh-kiel opened this issue Oct 4, 2021 · 8 comments
Open

ESP32 requires float #104

ctag-fh-kiel opened this issue Oct 4, 2021 · 8 comments

Comments

@ctag-fh-kiel
Copy link

Hi, it's great to see that ESP32 is supported in link.

However, ESP32 fpu is single precision, thus link would benefit from a configuration option to use float instead of double.
I have tested it and jitter seems almost independent of the data type.

Cheers, Robert

@fgo-ableton
Copy link
Collaborator

Interesting! I have not looked into this at all. Did you run into issues related to that?
How exactly have you tested this? Jitter will probably start mattering when the numbers get bigger i.e. due to longer runtimes. Also what is the performance improvement?

@ctag-fh-kiel
Copy link
Author

ctag-fh-kiel commented Oct 6, 2021

The esp32 has a single single-precision FPU (despite its dual core nature).
When using doubles, calculations are hence soft emulated.
In order to optimize runtime performance, everything on the ESP32 should be floats (or fixed point).
Also, float operations should be tied to one CPU, as context switches between CPUs when using the FPU will be slow.
There are some FreeRTOS extensions for the ESP32 to make sure of that, unfortunately no std c++.

In an application scenario with the ESP32, ideally one core would do Link and another core would do other stuff.

In a perfect scenario, Link would use only fixed point (e.g. Q-notation) for all calculations on a single core. Then the other core could use the FPU e.g. for audio processing without interruption from Link calculations.

The jitter I measured between 2 ESP32s when synched to a Live instance through Link where in between +/- 1.5 to 2 ms maximum.
This was independent of Link running with doubles or floats.

I have adapted my fork of Link to floats. Ideally the data type used in Link would be configurable through CMake.
This may be important for Link in the future as more and more embedded devices with Wifi will enter the market (both with and without FPU --> therefore fixed point calculations would be a great benefit).

Cheers, Robert

@fgo-ableton
Copy link
Collaborator

fgo-ableton commented Oct 8, 2021

I totally understand that doubles are problematic on this platform.
However I don't think just using floats everywhere will work. I.e. there are some calculations with host times that have to deal with quite big numbers. Just using floats there will definitely lead to inaccuracies when connecting i.e. with a laptop that has been running for a longer time.
Also, I'd like to understand what the actual performance improvements would be. At may places the data is just pushed around. Besides the measurement which will likely need doubles there is very litte actual calculation happening.

@ndonald2
Copy link

If it's possible without any negative repercussions, allowing the HostTimeFilter to use float instead of double would be a huge help for ESP32, when that class is needed. The 512-point linear regression it's doing involves a lot of double precision arithmetic.

@fgo-ableton
Copy link
Collaborator

fgo-ableton commented Apr 5, 2022

The HostTimeFilter was really designed to be used with Asio drivers on Windows or Alsa drivers on Linux. If filtering should be necessary on whatever you use on the ESP, you will probably be dealing with different numbers than on a desktop OS.

I pushed a branch that adds BasicHostTimeFilter. It can be used with different number types and filter sizes. However, if you look at the tests it gets inaccurate with numbers way lower that what you see on a desktop.
Anyways, give it a try and let me know if it works for you.

@ndonald2
Copy link

ndonald2 commented Apr 5, 2022

Thank you @fgo-ableton I will try that branch out! I had created a branch in a fork which has a variant of the host time filter and linear regression that uses floats. For ESP I have found that the filtering is necessary when trying to synchronize I2S real time audio output with Link, because the system uses a DMA buffer "push" style architecture where you have to write samples to DMA buffers as quickly as you can, and due to the RTOS scheduler the timing of when the buffer fill function is executed can vary a bit, which causes jitter in the synchronized output without using host time filtering.

I could have that totally wrong, but that seems to be the empirical evidence 😆

@ndonald2
Copy link

ndonald2 commented Apr 6, 2022

After some testing, unfortunately it seems that float precision is too low for the host time filter to work properly. After some time everything gets very jittery. However, this templated version is still extremely useful in that I can successfully lower the number of samples it's taking and still have precise timing. So I'm 👍 to keep the change, it's still helpful!

@fgo-ableton
Copy link
Collaborator

@ndonald2 I merged the changed filter to master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants