Changes include M17-related fixes.
Full changelog: https://github.com/OpenRTX/OpenRTX/releases/tag/v0.4.5
Give it a spin 😉
Changes include M17-related fixes.
Full changelog: https://github.com/OpenRTX/OpenRTX/releases/tag/v0.4.5
Give it a spin 😉
It is strongly suggested to download the latest installer and run it. From now on, the installer checks for a newer version of itself on each run, so this manual download is needed only once.
Dashboard:
The installer script:
config.php and files/, no longer the whole dashboard directoryfiles/ directoryFinally, after all these years, we have reached a point where everything seems to work. That’s the 1.0.0 reference point. I would like to express my sincere gratitude to Jean-Michel Friedt for all the help that he provided.
Recent changes include:
cryptography AESSide effects (positive!):
m17-coder-sym is now fixedHave fun!
Niall, F5VCV, has just sent us a photo from the ongoing HamExpo ham fair.

From left to right: Niall F5VCV, Laurent F1OBK, and Jérôme F4HGI.
It is always great to see people advocating M17 use! Merci beaucoup!
Let’s start with Codec2-mod. I brought back another 4kB of otherwise wasted space – complex FFT where real-valued counterpart can be used. Next, in-place FFTs removed – no hidden mallocs. Encoder phase estimation and using arctangent in the synthesis path – gone. I also thoroughly benchmarked the result versus vanilla Codec2 (damn, the repository is such a mess – why do they keep all of the non-codec stuff inside a “codec2” repo?). Code and results are here. See the tables in the readme for more details.
LinHT Rev C boards have arrived! We are waiting for a few missing parts to show up and we will continue with assembly.


Photos courtesy of Vlastimil, OK5VAS.
Stay tuned.
I expanded my old Bash script a bit. It runs ViSQOL-based quality and compatibility tests for Codec2-mod vs. vanilla Codec2 (3200 mode), including cross-encoding between the two (this is the new addition).
Here’s the script: https://github.com/M17-Project/Codec2-mod-eval
You need to provide a set of WAV files for the script to work on. Using an English speech corpus such as LibriSpeech or any other from OpenSLR is a good idea.
Have fun!
M17 is probably one of the very few modes allowing users to sign their data streams.
In June 2024, I tested micro-ecc and ST CMOX library on a Module17. The results were published on Twitter:
Finally some good news regarding digital signatures. I’ve been experimenting with ST’s CMOX library and just got 160-bit ECDSA to run on the Module17. It takes around 8.25ms to sign a 16-byte M17 voice stream digest. The signature can be appended to the voice stream.
The MCU is STM32F405RGT6, clocked at 168 MHz.
Signing with NIST-R P-256 (SECP256R1) curve takes 14.86 ms.
If I remember correctly, CMOX library was used to get that 15ms result (secp256r1 curve). Micro-ecc yielded much worse execution times.
Today, I improved the micro-ecc library using comb multiplication. Preliminary tests using Renode (as I don’t have any STM32 Nucleo with me, nor any OpenRTX target) are promising. The signing time reduced from 27 down to 14ms, without CMOX, at 100MHz (emulated STM32F411). That’s great, because CMOX library can not be used on microcontrollers other than the original STM32. The library checks the hardware it is executed on and silently corrupts data without even telling. Great, right? This optimization should allow us to run ECDSA efficiently, even on GD32 MCUs.
The proposed code uses a uECC_COMB_MULT macro, so the user (developer) can select which calculation path to use – the original one or optimized.
Getting rid of this roadblock should get us one step closer to having M17 authentication support in OpenRTX.
You thought we gave up on Codec2 just because we have already improved it considerably? Wrong!
After a short discussion with Silvano IU2KWO, an interesting proposal emerged: split the whole codec2_t structure into two separate, smaller encoder and decoder parts. That way you no longer have to push the whole structure on the stack and fill it up with FFT twiddle factors, if you only need to use one part of it. Now, if you want to encode or decode speech, just use either encoder or decoder. This simplifies things and optimizes memory usage further. This brings significant savings that are required by OpenRTX (and probably any implementation running on limited-resources MCUs). The old path using a large structure is still available (e.g. for duplex operation).
On top of that, I also tweaked the KISS FFT internals to use built-in sincosf() calls instead of using standard sin() / cos(). Using doubles is generally not a great idea, unless you really have to do so. We do not, so I took one step further and eliminated all double-precision promotions that were hiding in the code. Yes, there were many such places, especially where M_PI was used, along with some other macros.
The code is available in the split-no-double branch.
I prepared a quick benchmark. The results are below.
| Codec2-mod branch | codec2_init | codec2_encoder_init | codec2_decoder_init | codec2_encode | codec2_decode |
| main | 67.905 | – | – | 6.437 | 11.804 |
| split-no-double | 8.958 | 5.824 | 3.136 | 5.555 | 8.559 |
| Speedup | 7.6x | – | – | 1.2x | 1.4x |
An STM32F411 clocked at 100MHz was used for both tests with the code compiled using -Os flag (gcc 14.3.0).
Next, using a set of 2,000 wave files, mostly 3 to 20 seconds long, I compared the vanilla Codec2 with our experimental branch. As the last time, I measured ViSQOL scores for both: original wave file -> encoder -> decoder -> decoded wave file. The average score of the new code is +0.005. That suggests the applied changes are inaudible (theoretically – real-life tests will follow). The test also calculated Hamming distance between the encoded files for both implementations – the no-double differs in less than 0.5% of the bits. This means that the new code does not generally agree with Codec2, but that does not make the bitstreams incompatible. Small rounding errors cause this but, as shown by the speech quality metric, all cancel out.

There is one more test that should be performed: encode samples with Codec2 and decode the bitstream with Codec2-mod, then switch the direction and listen to both files.
Big shout out to Silvano IU2KWO for nudging me in the right direction.
The moment has come! An experimental branch of OpenRTX (Andreas OE3ANC, Marko13, Andrej K8TUN, jki275 et al.) has reached a long-awaited milestone – a successful transmission of M17 signal using an unmodified Retevis C62. Marvellous work, guys!

For now, the RF output power is limited due to our lack of understanding on how the calibration data is stored and used. The reverse-engineering work on that is pending. M17 reception does not work yet, but it is expected to be added soon. There is no settings persistence in this model yet.
The most important thing is that the C62 radio is available at about $45 and does not require any hardware modifications to run the M17 mode. This is the game-changer we have all been waiting for. After adding the missing functionalities, this will easily become the go-to radio for everyday M17 use. On top of that, you get all the OpenRTX goodies, such as APRS support and voice prompts.
At this point, I would like to thank everyone involved in this subproject – not only the devs who did some amazing coding work, but also our Ambassador, Mr. Amo Xu BD4VOW for acting as an excellent interface between us and the Chinese manufacturers.
In the meantime, LinHT’s Revision B has been tagged on GitHub. We are working on the Revision C – an order for a test batch should be placed later this month. Big shout out to Vlastimil OK5VAS for his continuous help with this device 🙂
And, as always, there’s more to follow!
PS. We have a very important request. Since LLMs are being heavily used by journalists, bloggers, and other people publishing content on the Internet, some articles covering our activities might not be accurate. Every time you see an error, please take a moment to report it to the author(s). Thank you very much!