Ableton / link

Ableton Link
Other
1.09k stars 149 forks source link

ESP32 requires float #104

Open ctag-fh-kiel opened 3 years ago

ctag-fh-kiel commented 3 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

@ndonald2 I merged the changed filter to master.