This is Quisk, a Software Defined Radio (SDR). You supply an antenna and a complex (I/Q) mixer to convert the radio spectrum to a low IF. Then send that IF to your computer using the sound card, Ethernet or USB. The Quisk software will read the I/Q data, tune it, filter it, demodulate it, and send the audio to headphones or speakers. Quisk has a microphone input and a key input so it can operate as a complete transceiver. Quisk works with this hardware:
Quisk is small and simple, and has been designed so that it is easy to
change Quisk to suit your own hardware. Quisk rhymes with
"brisk", and is QSK plus a few letters to make it
easier to pronounce. QSK is a Q signal meaning full breakin CW
operation,
and Quisk has been designed for low latency. Quisk includes an input
keying signal that can mute the audio and substitute a sidetone.
Please read the file CHANGELOG.txt
for changes.
When running Quisk for the first time, please press the "Help"
button on the lower right.
The newest versions of Linux and Raspberry Pi OS do not allow installing Quisk in the system Python package directory. Use the Linux Source Installation below instead.
Python 2 is no longer supported. Python 2 was obsolete as of January 1, 2020. And the new code by Ben, AC2YD, needs Python 3. It is troublesome to write code that runs on both Python 2 and Python 3. So it is time to stop supporting Python 2 in Quisk. Please upgrade to Python 3. If you have both versions, use Python 3 for Quisk.
Quisk was originally written by James Ahlstrom, N2ADR.
Thanks to Leigh L. Klotz, Jr. WA5ZNU for configuration improvements,
factoring
out my eccentric hardware control, and adding panadapter and other
hardware
support.
Thanks to Franco Spinelli for a fix for the H101 hardware.
Thanks to Andrew Nilsson VK6JBL for adding support for SoftRock Rx and
Tx.
Thanks to Terry Fox, WB4JFI, for code to support the Charleston
hardware.
Thanks to Maitland Bottoms, AA4HS, for the sub-module linkage patches.
Thanks to Philip G. Lee for adding native support for PulseAudio.
Thanks to Eric Thornton, KM4DSJ, for adding async support for PulseAudio.
Many others contributed to Quisk, and are mentioned in comments in the source code.
Quisk is free open source software written in Python and C. It is hosted on the PyPi repository https://pypi.org and it is available on github.
If you have Python 3 installed on your computer, just continue to use that version. On Windows Quisk requires Python 3.8 or 3.9 or 3.10 or 3.11. If you want to install a more recent version of Python, uninstall the old version first. Running multiple versions of Python is possible but can be confusing and is not necessary. A Quisk installation is needed for each version of Python you have.
Windows does not include Python, so you must first install a recent version of 64-bit Python 3.
If you already have 64-bit Python 3 installed, just keep using it.
On Windows Quisk requires Python 3.8 or 3.9 or 3.10 or 3.11.
There may be newer versions of Python, but until support is added, use the versions listed above.
Python is available from http://www.python.org.
There is an option to Add Python to PATH. You MUST select
this option so that you can start python by just typing "python" instead of the whole path
to your install directory. My install directory is:
C:\users\jim\AppData\Local\Programs\Python\Python39
And "AppData" is invisible. To avoid problems, check Add Python to PATH.
If you forget, it is worth it to uninstall and reinstall Python.
Quisk is really designed for curious people who want to play with the code, but Windows
tries to shield users from program details.
Next open Windows PowerShell (not PowerShell ISE). This is on the Start button menu on Windows 10; or use the search bar. Enter "python --version" to make sure that Python is installed and what version you have. If "python" is not found, it might not be on your Path. You will need to keep typing your_install_directory\python instead of "python".
Next upgrade some Python modules to the newest version, then install Quisk. Enter these commands:
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools
python -m pip install --upgrade wxPython
python -m pip install --upgrade pyserial
python -m pip install --upgrade quisk
You should then be able to start Quisk with the command "quisk".
You can also start Quisk with "python -m quisk".
To create a Quisk shortcut on your desktop, right-click an empty space and select "New" and "Shortcut".
Use "quisk.exe" as the command and "Quisk" as the name.
The "quisk.exe" program is in your_install_directory\Scripts.
If you are curious, Quisk and its Python source files are installed in "your_install_directory\Lib\site-packages\quisk".
If you change to that directory you can run Quisk with "python quisk.py".
To get started you must tell Quisk what kind of radio hardware you have. Press the Config button and select Radios. Then set your sound devices for that radio; the device for the radio speakers, the microphone and so forth. All configuration is (mostly) from the Config button. Ignore old directions and don't bother with a config file.
To upgrade to a newer version of Quisk, use pip. Remember that if Python is not on your Path, you will
need to type out the whole path.
You should check for newer versions of the other modules twice a year.
python -m pip install --upgrade quisk
You can also install an older version of Quisk. You may need to do that if the most recent version fails for some reason. Use:
python -m pip install quisk==4.1.51
python -m pip uninstall quisk
Linux runs on a wide variety of computers with different processors and versions of Linux.
Therefore Quisk is compiled for each one. To do this, Python and a number of other packages are required.
Most likely both Python2 and Python3 are already installed on your computer.
On my Ubuntu machine, "python2" starts Python2 and "python3" starts Python3.
Just "python" starts Python2, but this will change as Python2 is phased out.
Python2 is obsolete, so you should only install Quisk to Python3, and use "python3" to start it.
Install these packages by using your package manager, not Python pip.
If newer versions of these packages become available, Linux will notify you.
Use the most recent version of python3-wxgtk available for your Python version.
These are part of your operating system. You only install them once unless it changes.
sudo apt-get install libfftw3-dev sudo apt-get install libasound2-dev sudo apt-get install portaudio19-dev sudo apt-get install libpulse-dev sudo apt-get install python3-dev sudo apt-get install libpython3-dev
These are part of Python. You only install them once unless the Python started by "python3" changes.
sudo apt-get install python3-wxgtk4.0 sudo apt-get install python3-usb sudo apt-get install python3-serial sudo apt-get install python3-setuptools
If you want to use the SoapySDR module make sure that SoapySDR is installed from its Pothosware site before you build Quisk.
Otherwise Quisk will not have the files it needs. You can install SoapySDR later, but then you
will need to run "make" again. This is also true of any other external packages that have their own C source.
Installation of Quisk using Python tools like pip is deprecated.
Installation to the system Python is no longer allowed, and you may get the message "error: externally-managed-environment". If you used pip to install Quisk you can continue to upgrade with "sudo python3 -m pip install --upgrade quisk" until you get this error message. But it is best to uninstall the pip Quisk. If you installed with pipx, uninstall that too.
sudo python3 -m pip uninstall quisk pipx uninstall quisk
Then use the Linux Source Installation.
On Linux, Quisk is installed from github, and it is contained in a "quisk" directory. First you need to decide where to put the quisk directory. Anywhere will do, but it is best to use a directory where you have write permission so you don't need to use "sudo". The examples below assume you used your home directory indicated by "~". Just replace "~" by your desired location.
To install a fresh copy of Quisk, change to your desired directory, clone the github site, change to the quisk directory and run "make". Then run the python program quisk.py.
cd ~ git clone https://github.com/jimahlstrom/quisk cd quisk make python3 quisk.py
If "make" fails, you probably have missing packages or missing "-dev" packages. Try to figure out what is missing from the error messages. You only clone github for the initial installation. To update Quisk, use pull:
cd ~/quisk git pull
You run Quisk by running the file quisk.py with python3. For example, "python3 /home/jim/quisk/quisk.py". You can create a desktop icon to do that, but the method depends on your version of Linux. Never run Quisk with root privelege by using sudo. Fix the permission problem instead. To get started you must tell Quisk what kind of radio hardware you have. Press the Config button and select Radios. Then set your sound devices for that radio; the device for the radio speakers, the microphone and so forth. All configuration is (mostly) from the Config button. Ignore old directions and don't bother with a config file. To uninstall Quisk, just delete the quisk directory.
These are the Quisk files in the distribution:
The Quisk "Config" button brings up a number of status and configuration screens.
Quisk supports multiple types of radio hardware and each type has different parameters.
Each block of parameters is called a "radio". It is a named block of settings Quisk uses
to control a specific kind of hardware.
So a single Quisk can have parameters for a SoftRock and an HL2.
You specfy the radio you want when starting Quisk.
When you first install Quisk, you will not have any settings for your radio.
Press the Config button and go to the Radios screen.
Then create a radio by specifying the general hardware type and give it a name of your choosing.
For a Hermes-Lite, specify "Hermes" as the hardware type and call it "HL2" (or some other name).
Press "Add" and a new tab for your radio will appear. Look through the various settings on the HL2 tab.
The parameters for the radios are stored in the file quisk_settings.json.
A special radio called "ConfigFileRadio" is always available.
It takes its parameters from a configuration file.
You can set almost everything with the screens, but you can have a configuration file if you want.
Most users will not need a configuration file.
For Linux, the default configuration file name is ".quisk_conf.py" in your home
directory; that is, "~/.quisk_conf.py". For Windows, the default
configuration file name is quisk_conf.py in your My Documents folder.
If you use a sound card for input, the quality of your sound card is
critical;
but you can start with the sound card you have. Check the Graph screen
with no input to see the noise floor. It should be as flat and as low
as
possible,
with no bump near zero Hertz. The 0dB line at the top of the Graph
screen
is the
maximum level, so if your noise floor is at -90 dB, you have that much
dynamic range. The IF (sound) input to the sound card should raise the
noise
floor only slightly to avoid losing dynamic range.
The sample rate determines how much of the band you can see on the
screen. My 96 kHz card shows a little over 80 kHz of bandwidth, from
-40 kHz to + 40 kHz centered at the VFO frequency. Generally you
would choose the
highest
rate available to get the most visible bandwidth. Be aware that a card
claiming to work at (say) 192 kHz may in fact play at that rate, but
only capture (record) audio at a lower rate. It is the capture rate
that matters.
Enter only the sample rate you know your raw hardware supports for
capture.
If you use the SDR-IQ or other hardware for input, you still need a
sound card for sound output. The quality of this card is not so
important, so try the one you have. Be aware that most sound
cards require the capture and playback rate to be the same when used
for both. Here are some sample configurations:
If you buy a new sound card, make sure you know the capture (recording) sample rates and the noise level. Sound cards are usually specified over the audio range up to 24 kHz or so. But we need low noise and distortion over the whole range.
Quisk can use PulseAudio, PortAudio or ALSA to access your sound card.
Names can be a fragment of text from the device description. It is
better to use this text search rather than an index number, because the
index number can change if you plug and unplug USB sound cards.
The ALSA drivers use different names for the same sound card
to provide different access. The names "hw:0" and "hw:1" refer
to the raw hardware devices of the first and second sound card.
You should use the raw hardware if possible. If the raw devices don't
work,
use the "plughw" name. The ALSA name can also be a string
name. Here are some ALSA names:
"hw:0" # First sound card "hw:1" # Second sound card, etc. "plughw" # plug device "default" # alsa default device "alsa:NVidia" # Search for the name in the alsa device description
Alsa names starting with "alsa:" are an extension to the normal alsa
names. They search for the text after the colon in the alsa
device
name. The alsa device names are shown on the config screen.
Or you
can start a terminal window and enter "aplay -l" for a list of play
devices, or "arecord -l" for a list of capture devices. See alsa_names for
more information.
The PortAudio interface is now optional. Many users are changing to PulseAudio.
You can run "python portaudio.py" in a terminal window to
see a list of available PortAudio names. Here are some PortAudio names:
"portaudio:(hw:0,0)" First sound card. "portaudio:(hw:1,0)" Second sound card, etc. "portaudio:NVidia" Search for the name in the portaudio device description. "portaudio#1" Directly specified index. "portaudiodefault" May give poor performance on capture.
Newer Linux systems are now shipping with PulseAudio enabled.
PulseAudio is a sound server, a program that takes control of your
sound cards, and controls usage by applications. The idea is that
your applications talk to PulseAudio, and PulseAudio talks to the sound
cards. Another example of a sound server is JACK.
You can control the
sound routing with the pavucontrol program. Remarkably, this is
not included with PulseAudio, and you will need to install the
pavucontrol package first.
Thanks to Philip G. Lee and Eric Thornton, KM4DSJ, Quisk now has native support for PulseAudio.
For PulseAudio devices, use the name "pulse:name" and connect the streams
to your hardware devices using a PulseAudio control program like pavucontrol. The name "pulse"
alone refers to the "default" device. The PulseAudio names are quite long;
for example "alsa_output.pci-0000_00_1b.0.analog-stereo". Look on the screen
Config/Sound to see the device names. There is a description, a PulseAudio name,
and for ALSA devices, the ALSA name.
Instead of the long PulseAudio name, you can enter a substring of any of these three strings.
An example is:
# As seen on the Config/Sound screen:
CM106 Like Sound Device Analog Stereo
alsa_output.usb-0d8c_USB_Sound_Device-00-Device.analog-stereo
USB Sound Device USB Audio (hw:1,0)
# Use the default pulse device for radio sound:
"pulse"
# Use a PulseAudio name for radio sound:
"pulse:alsa_output.usb-0d8c_USB_Sound_Device-00-Device.analog-stereo"
# Abbreviate the PulseAudio name:
"pulse:alsa_output.usb"
# Another abbreviation:
"pulse:CM106"
The PulseAudio code should not cause problems, but I am not sure what happens if PulseAudio is not installed, or if you replace it with JACK. This config file option will turn off all but directly entered "pulse:" names:
show_pulse_audio_devices = False
If Quisk appears to run but you get no sound input or output, you
may be having trouble
with your settings. Start Quisk and look at the graph. You should get a
moving
line display. Look at the Config screen. Interrupts should be
increasing and latencies
should fluctuate. If all this looks normal, but you get no sound
output, or you get only
white noise output, then you may need to change your settings with a
mixer program.
If you capture data with the sound card (no SDR-IQ) then you need
to set the "capture
device" to the line-in jack, and set the volume of the line-in to 100%.
To play sound,
you need to increase the volume of the playback device. Since a typical
sound card has
ten or twenty controls for all its analog and digital inputs and
outputs, it is a guessing
game to figure out which control to adjust.
Basically you start the alsamixer program (use "man alsamixer" first)
and adjust the volume
controls and capture device until Quisk works. It is wise to reduce or
mute unwanted inputs
to avoid adding extra noise.
Quisk does not do this for you. But once you have the controls set,
they will stay the same
and Quisk should keep working until you run another audio program that
changes them.
To make Quisk adjust the mixer controls when it starts, you need to
know the control id number.
Run the command "amixer -c 0 contents" (for card zero) and look at the
control ids, names
and values of all your controls. Figure out the control you need to
adjust. For a setable
option (on/off) the control value is one or zero. For a volume it is a
number from 0.0 to
1.0. Make a list of (device_name, numid, value) and add it to
mixer_settings in your
.quisk_conf.py file (see quisk_conf_defaults.py). I don't need to do
this on my computer
except for the microphone input on my second sound card.
If you really get stuck, try one of these commands (see the "man"
page):
And try to play an audio CD or run some other Linux audio program just
to see that you
have a working sound system.
If you can't get ALSA to work, you could try the PortAudio or PulseAudio interface by
just
changing the sound card names.
To see what sound cards you have, use the Control Panel item Sound
Devices. There is a separate list for capture (recording) and
playback devices, and a specified default device for each. The
name of the default device is "Primary". To specify your sound
card name, use either "Primary" or a substring of the device
name. The search is case sensitive.
SoftRock radios use an analog mixer to change the RF signal to stereo audio, and then use a sound card to digitize it.
A high quality sound card is advisable. The analog mixer is not perfect, and it will be necessary to adjust the I and Q
signals to equal amplitude and 90 degrees phase difference. Use the Config/Config screen buttons to
bring up an adjustment screen. Adjustments must be made for each band, and separately for transmit and receive.
The adjustment depends on both the VFO frequency and the tuning offset from the VFO. See my paper
http://james.ahlstrom.name/phase_corr.html for more information.
A good strategy is to pick a VFO near the band center, and record corrections at an Rx frequency of -15000, -1000, 1000 and 15000 Hertz.
If the corrections are sensitive to VFO, record the corrections for these same Rx frequencies at VFOs equal to
or slightly outside the upper and lower band edges.
To effectively adjust for multiple VFO frequencies, the VFOs must have the same table of Rx frequencies.
You can add as many correction points as desired. The corrections are saved in the file quisk_init.json. This file can be edited
by hand if you are a Python expert. Otherwise you can just read the values.
To create a Receive correction point for a given VFO and frequency, attach a signal generator to the SoftRock through an attenuator,
and look at the image on the graph screen. If the signal is 3500 Hertz above the VFO, the image is 3500 Hertz below it.
If you don't have a signal generator, find a strong station on the band and look at its image. Minimize the image by adjusting
the amplitude and phase sliders on the adjustment screen, and then press "Save".
To create a Transmit correction point for a given VFO and frequency, attach the SoftRock RF output to a spectrum analyzer through an attenuator,
and look at the image. If you don't have a spectrum analyzer use a second receiver tuned to the image. Minimize the image by adjusting
the amplitude and phase sliders on the adjustment screen, and then press "Save".
Quisk can use an SDR-IQ from RfSpace instead of a sound card as input. Set up a radio of type SdrIQ. The SDR-IQ uses a serial port to connect to Quisk. When you plug it in, it will create a USB serial port and connect to it.
On Linux the serial port has a name like /dev/ttyUSB0. Look in /dev or use "dmesg | tail" to figure out what port it is using. Then enter that port as the "Serial port" on the Config/radio/Hardware screen. The serial ports are part of the "dialout" group. Add yourself to the "dialout" group so you have permission to use the serial port. You also need a serial port USB driver for the ft245 chip in the SDR-IQ, but Linux generally comes with a suitable driver.
On Windows the "Serial port" name is not used, and Quisk will search for the port in use. On Windows 10, you should see a device "SDR-IQ" in Device Manager in the "View/Devices by Container" tab. In earlier versions of Windows, port names are COM1, COM2 etc. and use the "USB Serial Converter" driver. Windows should find this driver by itself.
Quisk can use an Perseus HF receiver from Microtelecom instead of a sound card as input. Set up a radio of type Perseus. The Perseus uses a native USB interface to connect to Quisk. The Quisk perseuspkg extension relies on libperseus-sdr open source library to manage Perseus hardware and receive the I/Q samples stream.
Follow the instruction into GitHub repository to compile and install the library. On Suse distribution the library is available as binary package. Next compile the perseuspkg using the command:
make perseus3
The several sample rates can be selected opening Config panel: in
the Config tab there is the Samples rates dropdown.
The input analog filter can be switched in using the button Wideband.
The input attenuator is operate via the button RF, that allows to select
the four attenuator steps.
The ADC commands for dithering and preamplifier are found on
left bottom corner as ADC Dither and ADC Preamp.
There are several configuration parameters devoted to tuning; read the
file quisk_conf_defaults.py for documentation. For most users, Quisk
should run fine with the default settings. But if you use Quisk as part
of a QSK CW transmitter, you should reduce latency_millisecs to as low
a
value as possible. This will reduce latency, but increase the
likelihood of clicks and pops due to sound buffer underruns.
Many radio devices are now controlled through a USB interface. In
many cases, the interface is actually a serial port, and an external or
internal USB to serial converter is used. In other cases, the USB
is native, but requires a custom device driver. In still other
cases, the USB device announces itself as a standard device such as a
sound device or human interface device, and uses a standard operating
system built-in driver.
Default USB permissions do not allow a non-root user to write to the
bus. You may find that Quisk will complain about lack of
permission to access the USB. You could test this by running
Quisk as root and seeing if that works; but this is not acceptable
except for testing. To change USB permissions, add a rule to
/etc/udev/rules.d/local.rules (for SoftRock on Debian and Ubuntu) like
this:
SUBSYSTEM=="usb", ATTR{idVendor}=="16c0" ,
ATTR{idProduct}=="05dc", MODE="0666", GROUP="dialout"
This changes the USB device permissions to read/write for all users,
and changes the group to the "dialout" group. Default group
permissions are read/write, so if you are in the "dialout" group, you
don't need "MODE"; modify as appropriate. To load the new rule, you can either reboot or on Ubuntu use
sudo udevadm control --reload-rules
Quisk comes with hardware files for many types of radio. See the various quisk_hardware_*.py files. But if you have a radio that Quisk does not support, or if you want to customize an included hardware file, you can write your own hardware file and enter the name on the Config/radio/Hardware screen. A model hardware file is included as quisk_hardware_model.py. It is useful as a starting point and as documentation. Hardware files use Python class inheritance. That is, all hardware files inherit methods from a parent file and then add their custom methods. Hardware files can control other hardware too. At my shack, I control an AT-200PC antenna tuner, my SDR-IQ, my filter boxes and my SSB transceiver (using Ethernet) all with Quisk. Take a look at my n2adr subdirectory.
The quisk_hardware_model.py file shows the basics of hardware control. There is an open() and close() function called once on startup and shutdown. The ChangeMode() and ChangeBand() functions are called when the user changes the mode or band with the corresponding buttons. The HeartBeat() function is called at about 10 Hz by Quisk. You can put code there to poll a serial port or to perform other housekeeping functions.
Here is the start of the SDR-IQ hardware file:
from quisk_hardware_model import Hardware as BaseHardware
class Hardware(BaseHardware):
def __init__(self, app, conf):
BaseHardware.__init__(self, app, conf)
# etc.
def ChangeBand(self, band):
# etc.
The file imports the Hardware from quisk_hardware_model and uses it as the basis of the SDR-IQ Hardware class. It calls the base init function and then adds its own methods for ChangeBand() and other methods. If it does not define a method, the method from quisk_hardware_model is used. Please refer to Python documentation if you are not familiar with inheritance.
If you want to write a hardware file from scratch, your file would start the same way. But if you have a radio like the SDR-IQ but want to customize it, your hardware file would look like this:
from quisk_hardware_sdriq import Hardware as BaseHardware
class Hardware(BaseHardware):
def __init__(self, app, conf):
BaseHardware.__init__(self, app, conf)
# etc.
def ChangeBand(self, band):
# etc.
This file uses all the methods from the SDR-IQ file except ones that are defined here. The HL2 hardware file is in the hermes subdirectory, so to create a custom file you would use:
from hermes.quisk_hardware import Hardware as BaseHardware
Alternatively, you can define a class named "Hardware" in your config
file,
and that class will be used instead of a hardware file. This is
recommended
only for simple hardware needs. The class should start like this:
from quisk_hardware_model import Hardware as BaseHardware
class Hardware(BaseHardware):
def __init__(self, app, conf):
BaseHardware.__init__(self, app, conf)
# Start your hardware control here.
# For ideas, see one of the other hardware modules.
Both the config file and your hardware file are written in the Python
language. Python is an easy to learn but powerful computer
language. Quisk can be adapted to different hardware because of
the power of Python.
Quisk calls the ChangeFrequency() function when the user changes the Tx
frequency with a mouse click on the graph or waterfall, with the entry
box, with the band Up/Down buttons, etc. The "source" is a string
giving the reason for the change:
| BtnBand | A band button was pressed (the string band is in the band argument) |
| BtnUpDown | The band Up/Down buttons were pressed |
| FreqEntry | The user entered a frequency in the box |
| MouseBtn1 | Left mouse button was pressed
(for the mouse, "event" is the handler event)
|
| MouseBtn3 | Right mouse button was pressed |
| MouseMotion | The user is dragging with the left button |
| MouseWheel | The mouse wheel up/down was used |
Most of the time you will not care about the "source". You just
need to react to the user's action, perhaps by changing the hardware
VFO frequency. It is not necessary to actually make the change
requested. Just
adjust your hardware as required, and return the actual (tune, vfo)
that you want. Quisk will ignore its requested values and use
your actual values instead.
For example, suppose you have a crystal controlled SoftRock. The
VFO frequency is fixed at (say) 7.025 MHz. Then when
ChangeFrequency() is called, return (tune, 7025000). This will
fix your VFO frequency to the only one available.
Suppose Quisk calls ChangeFrequency() with vfo=7050000 and
tune=7100000, so the tune is 50 kHz above the VFO. Suppose that
is unacceptable because of (say) bandwidth limitations, so you want the
VFO closer to the tune. Set your hardware VFO to 7090000 instead,
and return (tune, 7090000).
Suppose Quisk is just controlling a receiver and the audio is
demodulated by the receiver and not by Quisk. Then the center
frequency is a