CSVF2 RADIO MODEM

CSVF stands for client server via frequency. Send text and files over a voice radio as audio tones, receive them again, and identify with your callsign spoken in NATO phonetics or sent in Morse code. Current version: 3.6.3 (released 2026-10-17 08:00 CDT).

Made by Reed Gabriel (KE9GDP). Licence: Creative Commons BY-NC-SA 4.0: you may share and change it, non-commercially and under the same licence, and you must give credit to the original author in a reasonable, easy-to-see way (not fine print): anyone using your copy should know it was originally made by Reed Gabriel (KE9GDP).

Download

Windows desktop app: the window, the automatic server, the modem, the spoken-callsign clips and website.wav. Two ways to run it: the Python version (recommended, the reference) or the exe (no Python needed). Both need a free ke9gdp.com account, which the program asks you to sign up for or log into the first time it starts.

How to run it: Python version

  1. Unzip csvf2.zip to a folder you keep (for example in Documents).
  2. Install Python 3.10 or newer from python.org (tick "Add python.exe to PATH"; the tkinter window toolkit comes with it).
  3. In a terminal, in that folder: pip install -r requirements.txt (that installs numpy, scipy and sounddevice).
  4. Double-click CSVF2.pyw -- that is the real program: the window opens with no console window behind it, and the CSVF2 logo shows for 3 seconds. (Running python radio_gui.py does the same but leaves a console open.)
  5. Updates: the "Check for updates now" button (Settings tab) downloads the new version, checks its checksum, replaces the program files (the old ones go to update_backup) and asks you to restart. Your settings, document texts and audio clips are left alone.

How to run it: exe version

  1. Unzip csvf2-exe.zip to a folder you keep. Keep the whole CSVF2 folder together: CSVF2.exe needs the files and folders next to it, so do not move the exe out of it (a shortcut to it is fine).
  2. Double-click CSVF2.exe. No Python and no installing. The first start can take a few seconds. Windows may warn about an unknown publisher because the exe is not signed: choose "More info", then "Run anyway".
  3. Updates (v3.4.4 and newer): the "Check for updates now" button (Settings tab) downloads csvf2-exe.zip, checks its checksum, closes the program, replaces the files and starts it again by itself. Your settings, document texts and audio clips are left alone, and the old program files are kept in update_backup. Older exe versions cannot do this: download the new zip and unzip it over the old folder once.
  4. Servers as exes (v3.6.1): the same folder also has CSVF2-Server.exe (ping and pong, and a document), CSVF2-Server25.exe (the same plus ChatGPT, Google and social posts), CSVF2-Echo.exe (Server 2.0 echo) and CSVF2-Web.exe (a Server 2.0 web site; its pages are in the www folder). Double-click one: it is its own window, it listens by itself, and its settings are kept next to it. They are not signed either.
  5. The exe is the same program compiled to C and built with MSVC; it has not been run over the air yet, so if something behaves differently from the Python version, tell me with the Feedback button.

Versions the Python version is developed and tested with: Python 3.12.4, numpy 2.1.0, scipy 1.16.2, sounddevice 0.5.2, tkinter 8.6, on Windows 10. Other recent versions should work (numpy 1.24+ or 2.x, scipy 1.10+, any sounddevice 0.4+) but I have not tried them. Python 3.10 and 3.11 are untested too. The two server scripts are started with python radio_server_template.py or python radio_server_25.py (they have no .pyw: you want their log window's console output anyway).

The first time you run it, the program asks you to accept the privacy policy: it sends the callsign you enter, once, to the public CSVF2 users list on this site, and nothing else about you. If you do not accept, it closes.

What it does

CSVF2 Transmit tab

Transmit tab.

CSVF2 Receive tab

Receive tab (example log: green = checksum OK, red = garbled reception).

CSVF2 Settings tab

Settings tab.

Example: a picture over the radio

This picture, ABCDE.png (55 x 64 pixels, 8,053 bytes), was sent over the radio with CSVF2 at Fast speed in 16 minutes. As tones that is 12,927 of them, sent in 8 bursts of about 2 minutes.

ABCDE.png, a small photo of a dog

ABCDE.png, shown enlarged. Download the file

Biggest file sent so far

forest.png (650 x 544 pixels, 145,681 bytes, about 143 KB) -- sent over the radio with CSVF2 at Extra extra extra fast (new) with Medium error correction, in about 40 minutes, and received with its checksum OK. It is the biggest file so far, and the first over-the-air result for Extra extra extra fast (new). Everything arrived fine, so the error correction turned out not to be needed this time; it stays on as insurance, at a cost of some speed.

forest.png, a sunset through pine trees, the biggest file sent over CSVF2

forest.png, as received. Download the file

The record before it was 65.mp4 (about 65 KB) -- sent at Extra extra fast with Low error correction, and received with its checksum OK. It was the first over-the-air result for both Extra extra fast and Error correction.

65.mp4, as received. Download the file

The record before that was skull_and_roses.png (128 x 128 pixels, 26,157 bytes), sent at Extra fast speed in about 20 minutes. As tones that is 41,909 of them, sent in 9 bursts of about 2 minutes, with the callsign spoken 4 times along the way.

skull_and_roses.png, the previous biggest file sent over CSVF2

skull_and_roses.png. Download the file

Tones

Every character or piece of data is one audio tone at a time (single-tone MFSK), except at Extra fast, which uses two at a time (see below). There are 37 data tones, then three control tones:

tone  0..25   q w e r t y u i o p a s d f g h j k l z x c v b n m
tone 26..35   1 2 3 4 5 6 7 8 9 0
tone 36       space
tone 37       SHIFT   (makes the NEXT tone a capital, or a symbol)
tone 38       END
tone 39       SYNC

Shift works like the key on a keyboard, for one tone only. Shift + a letter is the capital. Shift + a digit is its symbol: 1 2 3 4 5 6 7 8 9 0 become ! @ # $ % ^ & * ( ). So Hi! is SHIFT h i SHIFT 1. A capital or symbol costs one extra tone. Two shifts in a row (new in v2.3) select a second layer: SHIFT SHIFT then a digit gives , . / ; ' [ ] \ - = (digits 1 2 3 4 5 6 7 8 9 0 in that order), three tones for one character. No new tone is used; older versions show those ten characters as ?.

The tone spacing is exactly 1 divided by the symbol time, so the tones are orthogonal: the receiver can tell them apart even when they are only a few Hz apart. That is why a shorter symbol needs wider spacing.

Extra fast makes each tone 25 ms long, so the tones have to be 40 Hz apart, and only 15 of them fit between 560 and 1120 Hz: too few for 40 characters. So each character is sent as a pair of tones played together, 80 to 200 Hz apart, and every character has its own pair. The tone numbers above, the shift rule, the checksums and the bursts are all exactly the same; only the sound of each tone changes.

Speeds

Fast (default)Extra fastNormal
One tone lasts66.7 ms25 ms200 ms
Tones per second1540 (pairs)5
Tone spacing15 Hz40 Hz5 Hz
Data tones555 - 1095 Hz560 - 1120 Hz (two at once)550 - 730 Hz
SHIFT / END / SYNC1110 / 1125 / 1140 Hztone pairs735 / 740 / 745 Hz
Text15 characters/s40 characters/s5 characters/s
Filesabout 9.4 bytes/s25 bytes/sabout 3.1 bytes/s
1 KB file1 min 49 s40 s5 min 27 s
10,000 byte fileabout 18 minabout 7 minabout 54 min
Usual largest file (a warning, not a limit)10,000 bytes100,000 bytes (about 67 min)10,000 bytes
Frequency error it can takeabout 3 Hzabout 3 Hzabout 1.5 Hz

The faster modes, which need a cleaner audio path (a wider band, or tones that overlap a little):

Extra extra fastExtra extra extra fast (new)Amplitude extra fast
One tone lasts10 ms10 ms25 ms
Tones per second100 (pairs)100 (pairs)40 (pairs)
Tone spacing100 Hz50 Hz40 Hz
Data tones600 - 2000 Hz (two at once)600 - 2000 Hz (two at once, 29 tones, 64 pairs)560 - 1120 Hz (two at once, unequal)
SHIFT / END / SYNCtone pairstone pairstone pairs (own SYNC)
Text100 characters/s100 characters/s40 characters/s
Files62.5 bytes/sabout 74 bytes/s (6 bits a tone pair)35 bytes/s (experimental)
1 KB fileabout 16 sabout 14 sabout 30 s
10,000 byte fileabout 2 min 40 sabout 2 min 15 sabout 5 min
Usual largest file (a warning, not a limit)100,000 bytes (about 27 min)100,000 bytes (about 22 min)100,000 bytes
Frequency error it can takeabout 8 Hzat least 8 Hz (simulated)about 3 Hz

The slower modes (new in v2.9), for weak, noisy or fading signals. Both are Normal with longer tones, so each tone collects more energy and the receiver scores it against its own band only. The receiver must be v2.9 or newer, and the sender should switch on error correction as well:

SlowSuper slowSlowest (v3.0)
One tone lasts400 ms800 ms1.6 s
Tones per second2.51.250.625
Tone spacing2.5 Hz1.25 Hz0.625 Hz
Data tones1200 - 1288 Hz1400 - 1444 Hz1600 - 1622 Hz
SHIFT / END / SYNC1292.5 / 1295 / 1297.5 Hz1446.25 / 1447.5 / 1448.75 Hz1623.1 / 1623.75 / 1624.4 Hz
Text2.5 characters/s1.25 characters/s0.6 characters/s
Filesabout 1.6 bytes/sabout 0.8 bytes/sabout 0.4 bytes/s
1 KB fileabout 11 minabout 22 minabout 44 min
Usual largest file (a warning, not a limit)5,000 bytes (about 53 min)2,000 bytes (about 43 min)1,000 bytes (about 43 min)
In simulation, a short text still arrived at-12 dB signal to noise-15 dB signal to noise-18 dB signal to noise

The last row is a computer simulation (white noise in a 300 - 3000 Hz band; Normal stopped working between 0 and +3 dB in the same test). It is not a measured radio sensitivity: nothing has been tried over the air yet.

Fast is 3x quicker in total, not just for the data: the start marker, type tone and end tone shrink too. Normal keeps every tone between 550 and 745 Hz. The receiver listens for both at once, so the receiving side never needs a setting.

Extra fast is 8x Normal (2.7x Fast) and stays inside Fast's frequency range. It needs a slightly cleaner signal than Fast (in simulation, about 1 to 2 dB more). A 100,000 byte file is about 74 minutes on the air once the pauses and callsigns are counted. The times in the table count the tones only. Extra fast is new in v1.9. The first version of it did not receive on a real FM link; it was redesigned after that test, and the redesigned one has since been confirmed working over the air on analog FM.

Extra extra fast (new in v2.4) is Extra fast with 10 ms tones instead of 25 ms: the same pairs of tones, the same start marker and framing, but 100 tones a second, so files go 2.5x faster than Extra fast (62.5 bytes a second, about 27 minutes for 100,000 bytes) and text 100 characters a second. It uses plain frequency coding, no loudness, which is why it is built this way rather than on top of Amplitude extra fast. The price is bandwidth: a shorter tone needs wider spacing to stay clean, so its 15 tones are 100 Hz apart from 600 to 2000 Hz instead of 40 Hz apart from 560 to 1120 Hz. In my simulated channel it decoded as far down in noise as Extra fast (about 2 dB signal-to-noise) and survived the same abuse: a hard limiter, pre-emphasis, clock errors of 1000 ppm, a frequency shift of 8 Hz, and speaker and microphone roll-offs of up to 18 dB per octave. Its weak spot is a steeply tilted level across the band, where a weak tone next to a much louder one gets swamped (a smooth tilt of 9 dB per octave is its limit). First over-the-air result: a 65 KB file (65.mp4, see Biggest file sent so far) arrived with its checksum OK at this speed, with Low error correction. That is one test, so it may still need a radio with a clean audio path up to 2 kHz; tell me what yours does. Older versions do not hear it at all.

Amplitude extra fast (new in v2.3) is Extra fast with a second piece of information in every file symbol. The two tones of a pair are sent slightly unequal, and which one is louder, and by how much (four balances: +4, +1.3, -1.3, -4 dB), carries 2 more bits. Files go about 1.4x faster than Extra fast (35 bytes/s); text, the file header and the end tone are plain Extra fast, so text gains nothing. Every burst starts with its own start marker and about 1.2 s of calibration tones (all 40 pairs equal, then the four balances) so the receiver learns what the link does to them. It needs roughly 10 dB more signal-to-noise than Extra fast in simulation, and older versions do not hear it at all.

Experimental for files. In the first over-the-air tests, text at Amplitude extra fast was received reliably, but files failed often (a radio's limiter and level control change loudness, and the balance only partly survives them). A damaged file is reported as lost or as failing its checksum and is never saved as good. For files use Extra fast; use Amplitude extra fast for files only to experiment, and tell me what your radios do.

Extra extra extra fast (new) (new in v2.6) is Extra extra fast with more data in every tone pair. The symbols are the same 10 ms, but the tones are 50 Hz apart instead of 100 Hz, so there are 29 of them between 600 and 2000 Hz, and a file symbol picks one of 64 pairs (two banks of 32) instead of 32: 6 bits a symbol instead of 5. Files go about 74 bytes a second (1.2x Extra extra fast); text is the same speed as Extra extra fast. Tones that close overlap a little (a tone leaks 40% into the next 50 Hz slot), so the 64 pairs are picked to keep look-alikes out, and after a file is in the receiver decides it again with each pair's own average level. In my simulated channel it holds about 3 dB less noise than Extra extra fast (each extra bit costs roughly that) and passes the same abuse (hard limiter, clock errors, roll-offs, 6 dB per octave of tilt). First over-the-air result: a 143 KB picture (forest.png, see Biggest file sent so far) arrived with its checksum OK in about 40 minutes, with Medium error correction (which was not needed). That is one test, so tell me what your radio does. Older versions do not hear it at all.

Old modes (new in v2.6). Amplitude extra fast and the first Extra extra extra fast (6.67 ms tones, 150 Hz apart, below) are no longer in the Speed list. To use them, tick Show old modes on the Settings tab and accept the warning. Receiving needs no setting: every mode is always listened for.

Extra extra extra fast (old) (new in v2.6) was Extra extra fast shortened to 6.67 ms tones 150 Hz apart (600 to 2700 Hz): files about 94 bytes a second. Over the air it was not good. On the one radio I tried, the first test did not even start a frame; the second received the whole file but about 1 symbol in 38 was wrong even after the receiver's repairs (4% of the bytes: more than Low error correction can fix, so it needs Medium or High and gives back most of the speed). The recording showed why: that radio put loud low-frequency junk under the tones and sent the pairs at very unequal levels, so the weak ones lost. That is what led to the receiver re-deciding a file once it is in, and to the new design above.

Error correction (new in v2.4)

Until v2.4 the checksums could only detect damage: a transfer with a bad tone had to be sent again. The Error correction box (Settings tab, and both server scripts) adds a Reed-Solomon code, the same family of code QR codes use, so the receiver can repair damage up to a chosen amount. It works for text and for files at every speed, and the receiver needs no setting: it reads the level from the transmission.

LevelExtra time on air (long messages)Wrong tones it repairs Gap it bridges (tones not heard at all)
Offnonenonenone
Low+7%about 3% of the messageabout 6%
Medium+14%about 6%about 13%
High+34%about 13%about 25%
Maximum+101%about 25%about 50%

First over-the-air result. The 65 KB file 65.mp4 (see Biggest file sent so far) was sent at Extra extra fast with Low error correction and arrived with its checksum OK; I do not know how much, if anything, the correction had to repair. Apart from that this has only been tested in simulation: the code itself at its exact limits, and whole transmissions at every speed and level through clean audio, band-passed noise, dropouts of 1 to 8 seconds and bursts of noise. At 1 dB signal-to-noise on plain band-passed noise, Off and Maximum both delivered 6 of 6 files in my test, so do not expect it to add range by itself; it is for dropouts, fades and bursts of interference, which is what a checksum could not help with. Tell me what your radios do.

What goes on the air

[KEY tone] [SYNC x11] [TYPE] [PATH x8] [ ...data... ] [END] [website.wav] [end tone]

PATH and the end tone are only in messages sent with the Server tab. Your callsign is sent with its own button (see Station ID), and goes into a transmission only when the 10 minute rule needs it. The automatic server scripts still put it at the start and the end of every reply.

Talking to a server (Server tab)

The Server tab is the client side of client and server on one frequency. It works like the Transmit and Receive tabs together and uses the same settings (they are the same settings: change one and the other tabs change too), plus one extra box. Looking for a server to talk to, or want to list your own? See the CSVF2 Server Map.

CSVF2 Server tab

Server tab.

Server: automatic ping / pong, and your own commands

radio_server_template.py is a station that runs by itself. It listens all the time, and when it hears the text ping it transmits pong; sent to the path document, it sends document.txt's text back instead, as a plain message, not a file. That is the first step toward client and server on one frequency.

CSVF2 server window

The server window.

radio_server_25.py: a worked example (chatgpt, smpost, smget, google)

radio_server_25.py started as a copy of the template above and has since grown four more paths, to show what building your own server on top of it looks like. It has the same window, the same settings, and the same "document" idea -- just its own document_25.txt, a short reference for these paths (not the path/end-tone mechanics already covered above).

Radios with a time-out (bursts and VOX)

Most radios cut the transmitter after a set time (the time-out timer), and a VOX radio takes about a second to key and clips the start of the audio. CSVF2 works around both. Set Radio time-out (on the Transmit and Server tabs, and in the server programs) to your radio's time-out timer, 30 to 600 seconds. It starts at 180. For a radio with no time-out at all, set it to 0 (off) (new in v3.1): the transmission is then sent in bursts of 8 minutes, so a long one still pauses for your callsign. Receivers before v3.1 cannot read such a transmission.

The pauses and keying tones add about 10% to the time on air.

Station ID

Built around the amateur rule that you identify at the end of a communication and at least every 10 minutes during one.

You are responsible for operating within your licence and local rules, including for anything radio_server_25.py's "chatgpt" or "google" paths relay from a third-party service or web page.

Receiving

Limits and notes

Users list, privacy and updates (new in v2.5)

Update log

Site - 2026-10-18 - New biggest file: forest.png, 143 KB (650 x 544 pixels), sent over the radio at Extra extra extra fast (new) with Medium error correction in about 40 minutes, checksum OK, and no corrections needed. The earlier records (65.mp4, skull_and_roses.png) are kept on the page. This is the first over-the-air result for Extra extra extra fast (new).

v3.6.3 - 2026-10-17 08:00 CDT - Servers: the server windows (radio_server_template.py, radio_server_25.py and the Server 2.0 servers) now use the callsign of the logged-in account, read-only, as the main window does (it was editable). The Server 2.0 servers also stop repeating the connecting station's callsign on every log line: it appears once per exchange on the TCP segment line (with where it said it was); the plain template keeps its "is sending a message" lines.

v3.6.2 - 2026-10-17 06:30 CDT - Server 2.0 fix, from the first real radio log: a server whose SYN+ACK never reached the client kept that half-open connection and then refused the client's second attempt, spending 21 s of airtime on a reset. A station has one connection at a time, so a new connection from the same station now replaces its old one, silently. Also, a server's first SYN+ACK was labelled a repeat and used up one of its tries; it no longer is. Both ends need no change to interoperate (the client side was already right).

v3.6.1 - 2026-10-17 04:30 CDT - Servers as exes: the exe download now has CSVF2-Server.exe, CSVF2-Server25.exe, CSVF2-Echo.exe and CSVF2-Web.exe beside CSVF2.exe, so a server can run without Python (the Python version is unchanged). The exe's Update button installs them.

v3.6.0 - 2026-10-17 01:00 CDT - Other programs can use Server 2.0: a new box on the Server 2.0 tab opens a TCP port on 127.0.0.1 (this computer only, off by default). What the radio connection receives is sent to every connected program, and what they write is transmitted on the open connection, so any program that can open a socket (or telnet) can use CSVF2. Browser client: a second box serves csvf2_client.html on 127.0.0.1 that connects to a station, requests its pages over the radio and draws them as they arrive. New servers: radio_server2_echo.py (sends back what it hears) and radio_server2_http.py (a small HTTP/1.0 web server with endpoints, a guestbook and a www folder; no encryption, no music), both built on radio_server2.py. Fix: several places did nothing without a location since v3.5.0 (Server 2.0 Connect, Accept connections, Send, Auto callsign, closing the window); they now say what is missing and take you to the Settings tab.

v3.5.0 - 2026-10-16 23:00 CDT - Location required to transmit: the program will not transmit (Transmit, Send callsign, the Server tabs) until you have entered a location (Settings tab), and it always goes out next to your callsign, so the window uses only the New callsign mechanics. You still choose how coarse it is. Receiving needs no location. This changes the privacy policy (now version 6), so the program asks you to accept it again once. Small screens: every tab scrolls (mouse wheel, Shift+wheel sideways, scroll bars that appear only when needed) and the window can be made much smaller. Lag while receiving: the receiver did about 40 times more arithmetic than needed and did it in the window's own thread, so a slow computer froze while listening. It now computes the same numbers with a sliding sum and decodes on a separate thread (the window only shows results). The exe update installs this.

v3.4.5 - 2026-10-16 21:15 CDT - Fix (exe): the exe build was missing part of the sound library, so it said to install sounddevice and could not listen or pick a sound device. It is now included. If the sound library still cannot load, the message shows the reason. Exe v3.4.4 can install this with its update button.

v3.4.4 - 2026-10-16 20:30 CDT - The exe updates itself: the Update button in the exe build downloads csvf2-exe.zip, checks its SHA-256, closes the program, copies the new files over the old ones (your document texts, settings and existing audio clips are kept; the old program files go to update_backup\previous) and starts it again. To get this, install v3.4.4 by hand once; v3.4.3 and older exes cannot do it. In the Python version the update box now says so when the files on disk were already current.

v3.4.3 - 2026-10-16 19:10 CDT - exe fixes: the icon is now built into CSVF2.exe (shortcuts and the pinned taskbar button no longer show a blank icon), and the exe finds its own files and libraries when started from a shortcut or another folder. Small code clean-ups.

v3.4.2 - 2026-10-15 19:36 CDT - Credit corrected: the author credit in the program, LICENSE.txt and on this site now reads Reed Gabriel (KE9GDP). The C source is no longer offered as a download (the exe is built from it; the Python is the reference).

v3.4.1 - 2026-10-15 17:30 CDT - Licence: CSVF2 is now under Creative Commons BY-NC-SA 4.0 (LICENSE.txt in every download). The credit to the original author, Reed Gabriel (KE9GDP), is shown at the bottom of every tab and in the window title, and must be kept. Time stamp: the window title and the Settings tab show the version with its build time. Fix: v3.4 still reported itself as 3.3.2, so it offered to update to itself; it now reports its real version.

v3.4 - 2026-10-15 - Three downloads: the same program as Python (recommended; updates itself), as C source and as a ready-built exe that needs no Python. The C is generated from the Python with Cython and the exe is that C compiled with MSVC; the Python is always the reference. The C and exe builds do not update themselves: download the new version here. The exe has been started and its modem round-trips a message in a check, but it has not been used over the air. Callsign: the Callsign box is now locked to the one on your account and cannot be edited.

v3.3.2 - 2026-10-12 - Fixes: tutorial boxes no longer run off the window or the screen (each box is fitted to the window, and its position was not being applied); the program's window is now fitted inside the screen when it opens, which at a high display scale used to put its bottom edge off the screen. Wording: the Maidenhead locator is now called a grid square in the program and on this site (the official name is still mentioned once).

v3.3.1 - 2026-10-12 - Fixes: the tutorial's grey layer now follows the window when you move it, and the window's Maximize and full-screen buttons work during the tutorial (it no longer holds the mouse; a nearly invisible layer blocks clicks on the highlighted controls instead). The licence upload no longer refuses files by type: it accepts any file up to 6 MB and the site owner reviews it by hand.

v3.3 - 2026-10-12 - Accounts. CSVF2 now needs a free ke9gdp.com account: sign up with an email, a password and your callsign, confirm the email, and send your licence exactly as issued; it is reviewed by hand, deleted once decided, and the account is then approved. The users list, server map and feedback all use the approved account's callsign, so a callsign can only act through the account approved for it. An approved account keeps working without the internet for 14 days. Feedback tab: a private chat with the author about feedback you sent, shown only to your account and fetched only when you open the tab or press Check for replies. Privacy policy version 5 (you are asked to accept it again). The website also rate-limits requests. Older programs can still use the radio, but not register a callsign or send feedback.

v3.2 - 2026-10-12 - Server 2.0: a new tab next to Server for TCP-style connections between two stations (handshake, numbered bytes, acknowledgements, repeats, closing). Warning: it has only been tested in simulation, not over the air. The server map now shows Server 1.0 and Server 2.0 stations in different colours.

v3.1 - 2026-10-12 - Radio time-out off: set Radio time-out to 0 to turn it off (instead of typing a huge number); long transmissions are then sent in 8 minute bursts so the callsign still goes out at least every 10 minutes. Both ends need v3.1 for such a transmission. Speed list is now ordered fastest to slowest (Fast is still the default).

v3.0.1 - 2026-10-11 - Fix: the taskbar icon. Started by double-clicking CSVF2.pyw (above all with the Microsoft Store Python), Windows showed Python's icon on the taskbar instead of the CSVF2 icon; the program now tells Windows its own identity and icon for the window. Nothing else changed.

v3.0 - 2026-10-11 - Compression for text and files: a list on the Settings tab with None, Lossless and three Lossy levels (simplified text, scaled images, lower-rate WAV audio), used only when it makes the transmission shorter; the receiver unpacks it by itself. New speed Slowest (1.6 s tones, 1/8 of Normal; in simulation still reads a short text at -18 dB signal to noise). A guided tour (offered on first start, replayed with the Tutorial button) and the site favicon as the window icon. Fix: Send callsign (and the callsign sent when the window closes) now goes out at the speed chosen on the Settings tab instead of always at Fast. Slow modes use less processor time. Older programs do not hear Slowest and save compressed files as .csvz.

v2.9 - 2026-10-11 - New speeds Slow (400 ms tones, half of Normal) and Super slow (800 ms tones, a quarter of Normal) for rough conditions. In simulation they decode a short text at -12 dB and -15 dB signal to noise, where Normal stops between 0 and +3 dB; files go at about 1.6 and 0.8 bytes per second. They use tones at 1200 and 1400 Hz, so older programs do not hear them at all. Not yet tried over the air.

v2.8 - 2026-10-11 - Direct messages: text or a file can be addressed to a callsign (Transmit tab, Direct message to). Programs with a different callsign hide it and say "<callsign> sent a dm to somebody else"; ordinary messages are announced as "is sending a public message". Not encrypted, and documented on the protocol page (address = dm plus six characters made from the callsign, in the PATH). Map: a station heard from a new location keeps its earlier positions as pale dots, and tiles that failed to load are retried.

v2.7 - 2026-10-11 - New callsign mechanics (default): the callsign is sent as a data frame at the start and the end of every transmission and receivers show "<callsign> is sending you a message" (Legacy mechanics stay available on the Settings tab). Feedback button in every tab (sent only when you press Send), a Notifications tab, dark mode (default) and a Sleek (default) or Legacy look on the Settings tab. The protocol specification page documents the whole on-air format. Location and Map: your neighbourhood (an 8-character grid square) is sent next to your callsign in those frames, switchable and on by default once you enter one; the new Map tab shows you as a red dot and the stations you hear as blue dots joined to you by lines (click one for its callsign). The privacy policy is version 3 (feedback, notifications, location and the map tiles), so the program asks you to accept it again once. The server scripts take the same callsign and location options.

v2.6 - 2026-10-11 - New speed Extra extra extra fast (new): Extra extra fast's 10 ms symbols with the tones 50 Hz apart and 64 file pairs, 6 bits a symbol, about 74 bytes a second (so far tested in simulation only). Old modes: Amplitude extra fast and the first Extra extra extra fast (6.67 ms tones; poor over the air, see Speeds) are only listed when Show old modes is ticked on the Settings tab, after a warning. Start-up: double-click CSVF2.pyw to run the window with no console; the CSVF2 logo shows for 3 seconds; the window hides its own console if it has one. Receiver: a file or corrected transmission is decided again once it is all in, with each pair's score compared to that pair's own average on the link; a transmission that stops and starts again at once is picked up from its new start instead of being read as the old one's continuation; the first tones of a frame are chosen from the few valid ones; the receiver ranks competing speeds by how well their tones scored. The Receive tab can show how close each speed came to starting a frame and can save everything it hears to heard.wav for debugging. The updater keeps a replaced csvf2.png logo.

v2.5 - 2026-10-10 - Privacy policy and users list: the program asks you to accept a privacy policy once, then sends your callsign once to a public CSVF2 users page (10 most recent, and the whole database to download). Updater: the window looks for a newer version when it starts, asks before installing, verifies the download, keeps a backup and never overwrites your settings, document texts or clips. New radio_online.py (the only code that talks to this site). Older versions cannot update themselves; download this one by hand.

v2.4.1 - 2026-10-10 - Receiver fixes found over the air at Extra extra fast. With the Sensitivity turned up, the receiver for another speed could start on the data of a file that was arriving and show random text, save-prompts for random files, or "heard what sounded like the start of a transmission" in the middle of it. The speed that is really receiving now takes priority, and anything whose tones hardly scored (speech, noise) is left unsaid. The status line said "Receiving file None" for a file sent with error correction, because its name is only known once everything is decoded; it now says so. A damaged tone that read as the end marker could stop a file early; a file now ends at its known length. The Biggest file record is now 65.mp4, about 65 KB, at Extra extra fast with Low error correction, checksum OK.

v2.4 - 2026-10-10 - New speed Extra extra fast: Extra fast's tone pairs at 10 ms, 100 Hz apart (600 to 2000 Hz), 2.5x faster for files (62.5 bytes a second), plain frequency coding with no loudness. Simulated only, not yet tried over the air. New Settings tab holds the radio and sound and the speed and reliability settings. website.wav now plays with the first transmission and then every 10th, not with every one. The Morse callsign tone moved from 1500 Hz to 2400 Hz so it stays above every data tone. New Error correction (Reed-Solomon, the code QR codes use): Low, Medium, High and Maximum levels repair damaged or unheard tones in text and files at every speed, instead of the transfer having to be sent again. Simulated only so far, not yet tried over the air. Receivers older than v2.4 report corrected transmissions as lost; with the box on Off nothing changes. New Auto callsign checkbox: your callsign goes out by itself when it is due or after a communication, once nobody (you included) is sending. The window was reorganised into grouped boxes and restyled, both server scripts have the Error correction setting and the same look, and radio_fec.py joins the download.

v2.3 - 2026-10-10 - New speed Amplitude extra fast: Extra fast with the balance of each pair's two tones carrying 2 more bits, about 1.4x faster for files (text is unchanged). Experimental for files: in over-the-air tests text worked but files often failed, so use Extra fast for files that matter. A second shift layer (SHIFT SHIFT then a digit) sends , . / ; ' [ ] \ - =. File size limits are gone, replaced by warnings. Older versions cannot receive Amplitude extra fast, and show the new punctuation as ?.

v2.2 - 2026-10-04 - Your callsign is no longer sent with every transmission: a Send callsign button with a timer since your last callsign, flashing red from 9:30. A transmission still gets the callsign by itself whenever it would otherwise go past 9 minutes without one, and closing the program sends it once the channel has been quiet for 2 seconds. website.wav plays 1.5x faster at the same pitch. A short message is now about 15 seconds on the air instead of 27. The server scripts still identify every reply. Extra fast is now confirmed over the air on analog FM. The tones themselves are unchanged, so older versions still read it.

v2.1 - 2026-10-03 - The callsign can be sent in Morse code instead of spoken: a Send in Morse code checkbox on the Transmit and Server tabs and in both server scripts (20 words per minute on 1500 Hz, outside the data tones, so receivers of any version ignore it). The Sensitivity slider now goes all the way to 1% (it stopped at 30%); the middle is still the usual 55%. Nothing about the data tones changed, so v2.0 and v2.1 read each other.

v2.0 - 2026-09-26 - New Radio time-out setting (30 to 600 s, default 180): the burst length now follows it, so radios with a short time-out can send long files. Files and messages with long runs of one byte are scrambled so they no longer slip. A file over the receiver's size limit is reported with its name and size instead of "signal lost". At the default time-out, ordinary transmissions are unchanged and older versions still read them.

v1.9 - 2026-09-26 - New Extra fast speed: 40 characters a second (25 bytes a second for files), 8x Normal, in the same 555 - 1140 Hz range as Fast, by sending two tones at once. Files up to 100,000 bytes at Extra fast (still 10,000 at Fast and Normal). Receivers listen for all three speeds automatically. Older versions cannot receive Extra fast. (Confirmed over the air on analog FM since; see v2.2.)

v1.8 - 2026-09-22 - radio_server_25.py gains a fourth path, google: a DuckDuckGo search that lists up to 5 numbered results, then a second message with one of those numbers fetches that page and sends back up to 800 characters of its plain text. Capped at 100 calls a day, like "chatgpt" but counted separately.

v1.7 - 2026-09-21 - radio_server_25.py now has three more paths: chatgpt (relays to OpenAI, capped at 100 calls a day, needs your own OPENAI_API_KEY), smpost and smget (a small 5-post log). It is public from this version on -- previously it was mentioned nowhere but the code itself.

v1.6 - 2026-09-21 - The "document" path now sends document.txt's text back as an ordinary message instead of a file; characters it cannot carry (anything but letters, digits, space and !@#$%^&*()) are dropped and logged, not fatal.

v1.5 - 2026-09-21 - radio_server.py renamed to radio_server_template.py and set up as a template you copy and edit to build your own server. First built-in route: sending to path document gets document.txt sent back as a file, whatever the message says.

v1.4 - 2026-09-21 - New Server tab in the window: an 8-character path is sent right before the message, the tab starts listening the moment the send is finished, and it sends an end tone (450 Hz, 2 seconds) after the last callsign. radio_server.py now waits for that end tone before it replies (1 second later) instead of always waiting 30 seconds; the 30 seconds stays as the fallback for messages that have no end tone. Ordinary Transmit-tab messages are unchanged and older versions still read them, but an older version cannot read messages that carry a path and reports them as lost.

v1.3 - 2026-09-21 - New radio_server.py: an automatic station that answers ping with pong after 30 seconds, with the same settings as the window. New Sensitivity slider on the Receive tab. Fixed the receiver locking onto the start-of-message pattern too early when the sensitivity is set high.

v1.2 - 2026-09-20 - The VOX keying tone can be switched off with a checkbox on the Transmit tab, for radios that are not VOX keyed.

v1.1 - 2026-09-20 - For radios with a time-out timer and VOX. Long transmissions are sent in bursts of 2 minutes with a silent gap between them, each burst starts with a 400 Hz VOX keying tone, and the Transmit tab shows the longest keyed stretch. The callsign is now spoken often enough to stay within 10 minutes at any settings, and the recorded clips are trimmed so a VOX radio does not un-key between words. Older versions cannot receive a transmission longer than 2 minutes from this version.

v1.0 - 2026-09-20 - First release. Text and file sending, shift tone, digits and symbols, Fast and Normal speeds, automatic receiving with a save prompt for files, station ID at the start, at the end and every 9 minutes, and website.wav played after the tones and before the last callsign.

Protocol specification

Everything that goes on the air, written out so anyone can build their own client: tones, speeds, frames, checksums, error correction, bursts, station ID, receiving, and test vectors.

← back to KE9GDP