Sunday, September 29, 2024

Python code to generate WSPR audio tones

Ross, EX0AA, is working to do WSPR on very low frequencies and asked for some help generating WSPR tones as audio directly. There are several projects around that generate WSPR via GPIO pins, Si5351s or an AD9851 DDS.

I grabbed the AD9851 code from PH0TRA, removed the DDS code, and with the help of ChatGPT, modified it to generate audio directly using pyaudio. This works both on my Mac and on a Raspberry Pi with no modification. The audio comes out of the default device, and if you plug in a USB audio dongle it comes out of there.

It seems to decode just fine with acoustic coupling.


My code is here. You'll also need genwsprcode.py by the fabulous Mark VandeWettering K6HX.

You'll need to use Python 3 (of course) and install pyaudio and probably numpy.

Usage: python3 wsprgen.py CALLSIGN GRID dBPower BASE_AUDIO_FREQUENCY

Thanks Ross for the push to make this. It could be handy for others.

Installing on a raspberry Pi

Thanks for the prompt from AA7US asking how to get going on a raspberry pi.
  • Grab my code from the GitHub gist. (you can download the file or copy and paste).
  • Grab K6HX's code from here. Put it in the same directory.
  • Install the needed python modules:
    • sudo apt install python3-pyaudio
    • sudo apt install python3-numpy
  • In a terminal run the program like this:
    • python3 wsprgen.py --no-delay CALLSIGN GRID4 DBM 1500
Obviously replace CALLSIGN GRID4 DBM. 1500 is the base audio output frequency in Hz.

--no-delay starts outputting right away, good for testing. Remove that to have it wait for the top of the 2 minute block. You'll get a bunch of output from the audio software but it seems to work after a few complaints. Here's my output:

python3 wsprgen.py --no-delay vk3tpm qf22 33 1500
symbols
 3,1,0,0,0,2,0,0,1,2,0,2,1,1,1,0,2,2,1,0,2,3,0,1,3,1,1,0,0,2,0,2,0,0,1,2,2,1,0,3,2,2,2,2,2,2,3,0,3,1,2,0,3,3,0,3,2,2,0,3,3,2,3,2,2,2,0,1,1,0,1,2,1,2,3,2,3,2,0,3,2,0,3,2,3,1,2,0,2,1,1,0,3,2,1,2,0,0,3,2,2,2,0,0,3,2,2,3,2,2,1,3,1,2,3,1,2,2,3,1,2,1,2,2,0,1,1,3,2,2,2,0,2,1,2,3,2,2,3,1,0,0,0,0,0,0,2,1,1,2,1,2,3,3,0,2,2,3,1,2,0,2
ALSA lib pcm_asym.c:105:(_snd_pcm_asym_open) capture slave is not defined
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.front.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM front
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround51.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround21
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround51.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround21
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround40.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround40
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround51.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround41
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround51.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround50
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround51.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround51
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.surround71.0:CARD=0'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM surround71
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM iec958
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM spdif
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM spdif
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
ALSA lib pcm_oss.c:397:(_snd_pcm_oss_open) Cannot open device /dev/dsp
ALSA lib pcm_oss.c:397:(_snd_pcm_oss_open) Cannot open device /dev/dsp
ALSA lib pcm_a52.c:1001:(_snd_pcm_a52_open) a52 is only for playback
ALSA lib confmisc.c:1369:(snd_func_refer) Unable to find definition 'cards.0.pcm.iec958.0:CARD=0,AES0=6,AES1=130,AES2=0,AES3=2'
ALSA lib conf.c:5180:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory
ALSA lib conf.c:5703:(snd_config_expand) Evaluate error: No such file or directory
ALSA lib pcm.c:2666:(snd_pcm_open_noupdate) Unknown PCM iec958:{AES0 0x6 AES1 0x82 AES2 0x0 AES3 0x2 CARD 0}
ALSA lib confmisc.c:160:(snd_config_get_card) Invalid field card
ALSA lib pcm_usb_stream.c:482:(_snd_pcm_usb_stream_open) Invalid card 'card'
ALSA lib confmisc.c:160:(snd_config_get_card) Invalid field card
ALSA lib pcm_usb_stream.c:482:(_snd_pcm_usb_stream_open) Invalid card 'card'
ALSA lib pcm_dmix.c:999:(snd_pcm_dmix_open) unable to open slave
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Waiting for next WSPR TX window...
Start of transmission on: 03:20:04
Frequency: 1,500 Hz
symbol = 3, out_frequency = 1504.39453125
symbol = 1, out_frequency = 1501.46484375
symbol = 0, out_frequency = 1500.0
symbol = 0, out_frequency = 1500.0
symbol = 0, out_frequency = 1500.0
symbol = 2, out_frequency = 1502.9296875
symbol = 0, out_frequency = 1500.0

You'll hear the tone on the default output. In my case I plugged in a USB audio dongle.

1 comment:

AA7US said...

This is fantastic Peter! It's exactly what I’ve been looking for as an audio generator replacement for WsprryPi (https://github.com/JamesP6000/WsprryPi ). For those of us who aren’t programmers, can you please spell out step-by-step how exactly to install (and compile if needed) the necessary libraries to make this work on a Raspberry Pi? Specially, you mentioned genwsprcode.py is needed. How is that installed or used on the Pi to make your python script work? Thank you and 73!