Samoyed - An Amateur Radio Software Modem ========================================= 2026-04-03 `Samoyed `__ started out as a Go port of Dire Wolf, the well-known AX.25/APRS modem software. As part of wanting to learn more about packet radio, I started reading the Dire Wolf source, but found it challenging. Being written in C, there was a whole bunch of manual memory management, pointer arithmetic, argument-mutation, fixed-size-buffer wrangling, and more, and I found that all made it a whole bunch harder to reason about operations in a complex ecosystem. So I started porting it to Go for a mix of education and fun - I got to spend time in the internals of KISS and AGWPE and APRStt implementations and more, and I got the jigsaw-puzzle-esque satisfaction of incrementally migrating it piece by piece. As part of that, it became easier to add test infrastructure, eliminate whole classes of bugs, and ultimately easier to iterate and improve on what had already been built. And so I and others have started using it for real packet radio, and I hope more people find it useful too. Who’s it for? ------------- My goal is for Samoyed to be valuable for both users *and* developers. Users because, being in Go, it’s become so much easier to add features and functionality, from UX improvements like ensuring all command-line options have a long-form and are documented in ``--help`` (thanks to pflag) to improving interoperability with all the NinoTNC users out there by adding BPSK and IL2P CRC support. Developers, because I want to make the various protocol and functionality implementations far easier to understand and work with, and the codebase as a whole more accessible with formatters and linters and an improved test suite. Where it stands --------------- Samoyed’s entire codebase is now Go - every line of C from Dire Wolf has been replaced or removed. That’s **743 commits** between June 2025 and April 2026, with **121k lines "added"** and **163k lines "removed"**. Linux (x86_64 and arm64) and macOS are supported. It should be drop-in compatible with Dire Wolf and my intent is to maintain that as much as possible. In theory it all works - certainly my test instances are talking to each other and to other Dire Wolf instances quite happily. In practice, I need alpha/beta testers to help me confirm that please! (One known issue: gpsd support - I needed to break that in the port, and haven’t quite got it sorted yet). Lessons Learned --------------- The biggest thing really has been just how much I could delete and/or simplify when rewriting functionality in Go. Go fundamentals like being able to return both a slice/array and an error object from a function enabled me to delete a whole bunch of pointer passing, and then good libraries like ``spf13/pflag`` and ``stretchr/testify`` saved me a whole bunch of boilerplate, so I could focus on the actual core functionality. On AI ----- Almost the entirety of the Go port was done by hand (“tradcoded”, as I believe they’re calling it nowadays…). I wanted to really dive into the code to learn more about the protocols and how it all fit together etc., and it was a lot like doing a jigsaw puzzle, with the satisfaction of putting it together one piece at a time. But I do a lot of work with LLMs, and they’ve been especially valuable in a whole bunch of ways: For code review, as a solo developer working on this, GitHub Copilot Code Reviews have been incredibly valuable - they’ve spotted a whole host of things I’ve missed or not considered, and even occasionally found bugs upstream! When it came to evaluating Go audio libraries, I could have sat down doing detailed evaluations one by one, but actually it was great to be able to quickly prototype integrations with each and rapidly learn that e.g. `gen2brain/alsa doesn’t support subdevices `__ and so on. Finally, I said *most* of the port was done by hand - some of the less interesting and more fiddly things like wrangling Reed-Solomon codes was really nice to hand off to Claude. What I’d love from you ---------------------- Fire it up and let me know how it goes! Whether it’s usage reports or bug reports or something else, it’s all good to hear about. Meanwhile on the development side, fundamentally I’m a software engineer first and foremost, and my digital signal processing skills aren’t that great - that’s something where John WB2OSZ, the Dire Wolf author, is far better than me, and I’m very much building upon his great work here. So while I’m very comfortable refactoring the internals for easier testing, improving diagnostic logging, and extending the config to increase functionality, something like implementing BPSK is very much out of my comfort zone, and I’d definitely appreciate more eyes and hands on it! You can find Samoyed on GitHub at https://github.com/doismellburning/samoyed/