News feed

  • M17 Project: open-source, but open for whom?

    Since the very beginning of the M17 Project, the primary aim of the whole idea has been to provide People – the Amateur Radio Community – with freely available hardware and software solutions. The paramount concern has always been documentation accessibility and reproducibility of all devices and programs.

    During the recent years, quite a few people reached out to us commenting on the licensing choices and wording that we use throughout – specifically the open-source phrase. These critics’ issue was with that phrase’s definition and our (mis)use of it. For them, open-source doesn’t merely mean free, but free to anyone, “not discriminating any field of endeavor”, as they said.

    Our projects were, are, and will always be free for the People, the Amateur Radio Community. We care about humans, living beings, not commercial entities and their greed for money – exploitation without fair compensation. Former U.S. Secretary of Labor, Robert Reich, famously stated: “I’ll believe that corporations are people when Texas executes one”1. I do not consider companies people either. And while I acknowledge that our interpretation of openness differs from the Open Source Initiative’s definition, I question whether that definition should be treated as the final word on the subject.

    The M17 Project (or the M17 Foundation) does not have any moral obligation to serve commercial interests simply because we publish our work. Making our work publicly available should not automatically entitle commercial interests to appropriate the results of our volunteer labor for private gain. We are a volunteer-driven community, not an unpaid R&D department for someone else’s business. We are not to be exploited. Volunteers seeing their work commercialized for the profit of third-party companies, without recognition or reciprocity, inevitably risk losing the incentive to keep contributing. This is something we will not let happen.

    We believe that the fruits of community effort should remain accessible to the community that created them. Licensing should protect that principle, rather than allow the appropriation of volunteer labor without reciprocity. In an ideal utopia, the OSI’s non-discrimination clause would work, but we do not live in such a world. One of the solutions that I can identify is for the commercial entities to reach out to the copyright holders asking them to grant a separate permission to use their work for a particular purpose.

    Should the definition of open-source be treated as an unquestionable doctrine (vide: OSI), or should the community be allowed to challenge what openness actually means?

    1. https://www.guernicamag.com/robert-reich-why-bp-isnt-a-criminal/ ↩︎

  • LinHT Rev C is alive: what works and what comes next

    The first LinHT Rev C board is alive. We brought it up in two evenings in the middle of October, and so far Rev C does what Rev B didn’t: it boots without hardware workarounds, enters USB boot mode from the side button, plays audio, gets a GNSS fix and transmits M17.

    This post summarizes what we changed in Rev C, how the bring-up went, what works, what we still have to measure, and, most importantly, what comes next. Many of you are asking when you can get a board. The short answer is: we are preparing the first production batch, and the price of the SoM decides most of the rest. The long answer is below.

    If you missed the previous status, start with LinHT Rev B status: what works, what broke, and why Rev C is next. Rev C is the direct result of that list.

    TL;DR

    • LinHT Rev C works. M17 TX, USB-C networking, audio, microphone, GNSS, USB boot from the side button and power management are verified.
    • Most of the original C62 board stays untouched. Only the display and, for now, the SMA connector come from the donor.
    • Seven Rev C boards exist or will exist next week, using all the SoMs we had.
    • Next is a production batch of at least 50 kits. We are waiting for the SoM quote from CompuLab.
    • Ballpark: EUR 250–400 per kit, tax included, shipping not included, to be refined within a few weeks. The donor C62 (around USD 65) is not included.
    • LinHT will be sold as a kit for radio amateurs. Assembly and operation according to the rules of your country are your responsibility.
    • How we will sell it (crowdfunding, Lectronz threshold pre-order, or Foundation-funded) will be decided by the M17 Foundation. Tell us what you prefer.
    (more…)
  • M17 on the Unihertz Atom XL

    I’ve had this radio for a few years now and always wanted to use it for M17. Today is the day! The app supports AGC known from DroidStar and also adds FARGAN neural synthesizer for Codec2 payload. If you own an Atom XL, give it a try. This is not a Zello-type app, it works with RF only.

    Repository: https://github.com/sp5wwp/AtoM17

  • M17 AES256+ECDSA test with OpenRTX + SDR#

    I successfully transmitted an encrypted and signed M17 stream carrying Codec2 speech payload with a CS7000. The stream was successfully deciphered using our fresh SDR# M17 plugin. The ECDSA signature was successfully verified as well.

    Splitting the signing process into “precompute” and “finish” was a great idea. The “precompute” step picks a random nonce, does the expensive point multiplication and computes the nonce’s inverse (using the elliptic curve). This happens when the PTT is pressed and takes roughly 30ms. When PTT is released, the “finish” function does the rest, and that part is shorter – about 2ms.

  • M17/OpenRTX at OpenAlt 2026

    Vlastimil OK5VAS (one of the guys behind LinHT!) is preparing an awesome presentation Hackněte si éter: radioamatérství 21. století (Eng.: Hack the radio waves: 21st century amateur radio) for this year’s OpenAlt in Brno. His presentation is scheduled for Sunday, November 8, at 11:00, room D0207.

    It is very likely that the event will be livestreamed. Follow OpenAlt’s YouTube channel for updates.

    Update: the slide deck is here: https://uart.cz/3061/hack-the-air-amateur-radio-in-the-21st-century/

  • M17 SDR# plugin

    I prepared an M17 plugin for SDR#. It supports streams and packets. It also verifies ECDSA signatures and can decrypt streams .

    Repository: https://github.com/sp5wwp/m17_sdrsharp

  • An unmodified C62 can not decode TETRA… Or can it?

    Am I crazy? Without a doubt, but at least I focus my craziness on a good purpose. My last idea was to find out if all of the following assumptions are viable:

    1. demodulating pi/4-DQPSK is possible with a plain, analog FM demodulator that works wide enough
    2. Beken BK4819 chip can work wide enough to demodulate 25kHz channels
    3. the CSK6011B MCU can run the whole TETRA stack plus the vocoder on top of it

    The answer is… yes to all.

    Let’s analyze it step by step.

    1. The modulation is differential (note the D in its name, it stands for Differential), meaning that we only need to care about phase transitions. Phase transitions are nothing but frequency changes, therefore pi/4-DQPSK can be treated as 4-level FSK after frequency demodulation.
    2. It turned out that BK4819 can indeed work with 25kHz-wide channels, it is a matter of setting a single register. Its response is not completely flat, but can be equalized using a simple FIR filter.
    3. Yes, but that required dumping osmo-tetra and ETSI’s vocoder reference code completely. I had to replace both with libtetra and OpenACELP. They are based on ETSI EN 300 3xx-x TETRA standards and are optimized for 32 bit MCUs, including our beloved Cortex-M4/M33 (seen in most of OpenRTX targets).

    I wrapped it all up on top of turnrye’s OpenRTX fork (this one is focused on M17 and uses the DSP firmware part setting the baseband sample rate to 48kHz). My fork is here. The build process pulls ETSI’s codebooks for their ACELP vocoder, so make sure you do not distribute the binaries (as they are embedded). TETRA is available through the quick menu key, the [5] key switches between M17, FM, and TETRA.

    Below, I attach a video showing a successful TETRA decode using a TMO transmission sample from the HamTETRA group. Big shout out to Manoel ON6RF for granting me access to their samples database.

    Have fun!

  • OpenACELP update

    OpenACELP vocoder has been updated to pull ETSI EN 300 395-2 tables at build-time. It is now a clean-room implementation of the TETRA voice coder.

    The build process offers two solutions:

    • a speech corpus file can be used to generate user’s own LSP codebooks, the gain codebook remains WIP
    • download and use ETSI’s codebooks making OpenACELP TETRA-compatible

    When using ETSI’s codebooks, make sure you do not distribute the compiled binary, as distribution of the codebook tables is prohibited. More details in the repository’s readme files.

  • Neural Codec2 decoding for DroidStar

    Our experimental fork of DroidStar can now decode M17 voice with a neural vocoder. The new decoder comes from Codec2-mod-neural, which uses the FARGAN network from the Opus project. It takes the same Codec2 3200 frames every M17 radio already sends and turns them into wideband 16 kHz speech instead of the classic 8 kHz sinusoidal synthesis. Nothing changes on the transmitting side, the bitstream is untouched, so you get the improvement on every 3200 bps M17 stream you receive, no matter who is talking.

    Installing

    1. Download the zipped APK file below.
    2. Unpack it and open the DroidStar.apk file. Android will ask you to allow installs from your browser or file manager – allow it.
    3. If you already have DroidStar installed and Android refuses to update it, uninstall the old version first and install again. Your settings (callsign, hosts) will need to be entered again.

    To enable the neural synthesizer, go to Settings and scroll down to “Neural Codec2 decoder (M17 3200)” – tick it. Connect to a reflector afterwards, as usual.

    Tell us how it sounds and which phone you use. Waiting for comments!

  • Codec2 3200 meets FARGAN

    Codec2 3200 carries M17 voice, and its classic decoder is the weak spot. It’s limited to 8 kHz and has that recognizable buzzy, synthetic sound. Instead of designing a new codec, I wanted to know how far a better receiver could go with exactly the same bits on the air.

    The answer is FARGAN, the low-complexity neural vocoder from Xiph’s Opus codec (Valin et al.). The idea is simple. The Codec2-mod decoder unpacks each 8-byte frame into its usual parameters: pitch, voicing, energy and LSPs. Instead of feeding those to the sinusoidal synthesizer, we map them to 20 features per 10 ms and let FARGAN generate 16 kHz speech.

    Data: the Opus speech corpus, processed with Opus’s own augmentation recipe, but with features computed by the real Codec2-mod encoder and decoder. An important early lesson: never pair noisy features with a clean target. The network can’t denoise, and my first attempts sounded like speech through a pipe.

    Training: Opus’ two stage recipe on rented GPUs1. Stage 1 was 400 epochs (about 14.5 hours), and stage 2 was 50 adversarial epochs (about 37 hours on an RTX 5090). The adversarial stage made a clearly audible difference from its first few epochs.

    C library: the model uses about 818,000 parameters, runs on Opus’ own C inference code, and takes about 1.6 ms of CPU time per 20 ms frame on a single x86 core. The ARM64 NEON build compiles and produces matching output, real hardware timing test will follow.

    The result is Codec2-mod-neural, a drop-in alternative to codec2_decode(): 8 bytes in, 320 samples at 16 kHz out. Nothing changes for transmitters, and every existing Codec2 decoder still works on the same stream.

    Code, training scripts, and the model: https://github.com/M17-Project/Codec2-mod-neural

    Next up: integration into DroidStar and mvoice, and later a look at running it on LinHT. ViSQOL benchmarks will also be ran along with synthetic BER tests to assess synthesizer’s noise immunity.

    1. M17 Foundation covered the expense (200 USD) with most of it left for future runs. ↩︎