xpsk31 is an X/GTK+ Linux application for Amateur Radio communications in the PSK31 digital mode. xpsk31 detects the carrier phase changes that make a PSK31-encoded character by reading audio samples from the DSP in the computer's sound card, connected to the output of a receiver. The audio signal is processed by a software phase detector which, for BPSK, detects '1' or '0' states ('0' signaled by a 180 deg phase reversal) and the resulting stream of BPSK31-coded bits is decoded into ASCII characters for printing to the Receive window of xpsk31. In QPSK the carrier phase changes are processed by a soft-decision Viterbi decoder which provides error correction in bad receiving conditions. A FFT-based "Waterfall" display is available to help tune in signals.
Transmission of PSK31-encoded characters is realized by writing pre-computed audio samples to the sound card's DSP and feeding the resultant audio signal to the transmitter's input. The transmitter must be in the SSB mode during transmission but for reception a narrow-bandwidth mode like CW-Narrow is preferable since PSK31 theoretically only occupies about 32 Hz of bandwidth. xpsk31 has built-in CAT control capability for the Yaesu FT-847 or FT857 Transceiver which, when enabled, can change the operating mode automatically. xpsk31 now also has serial port RTS control to allow transceiver PTT-On/PTT-Off control.
Usage: xpsk31 [-hv]
-h: Print usage information and exit.
-v: Print version number and exit.
xpsk31 automatically prepares the sound card and sets the mixer Capture level to the value specified in the ~/xpsk31/xpsk31rc configuration file. For proper operation, the level of the input signal must be adjusted from the receiver, if volume control is available, or by changing the value of the Capture level in the ~/xpsk31/xpsk31rc configuration file, if audio is taken from a fixed-volume source, such as the "data" i/o port. The output audio level is also set to the Playback level specified in ~/xpsk31/xpsk31rc, although again this will need to be set-up properly for low-distortion transmission. Please see the Operation section for details on how to set-up the sound card.
xpsk31 was designed from the beginning to be simple and efficient, decoding PSK31 signals using only integer arithmetic and simple processing methods. It uses the computer's sound card to read the '1' and '0' elements that make the PSK31-coded characters by implementing a software detector of the received audio signal's phase shift. This software phase detector is centered on a nominal frequency of 500 Hz and it operates by integrating the output from an in-phase and a quadrature detector over the period of a PSK31 element (32 msec). The carrier phase is then calculated by an integer arctan function implemented using tables to calculate the arc tan (in degrees) of the (quadrature/in-phase) signal ratio. Phase changes are calculated by comparing consecutive values of the carrier's phase after every PSK31 element.
xpsk31 has a simple visual aid for tuning the receiver accurately and displaying the carrier's phase changes. At the lower left corner of the main window there is an indicator for the carrier magnitude and phase (Receive Magniphase), in which which a line emanating from the center of the circular dial indicates the magnitude of the PSK31 carrier by its length and the phase by its direction. For a BPSK signal, the line should be seen to change direction by 180 deg at each carrier reversal, and additionally for QPSK, it should also change direction by +/- 90 deg. Any error in the receiver's frequency results in the Magniphase line rotating either clockwise or anti-clockwise, and so it can be used for tuning the receiver accurately to the incoming signal's frequency. A second line from the Magniphase center shows the tuning error as calculated by the AFC function, if activated. More on this in the Operation section.
"Waterfall" display with
xpsk31 has a "Waterfall" (audio spectrum) display derived from a FFT of the receiver's audio output. The Waterfall display appears in place of the Magniphase when the right mouse button is clicked in the Magniphase window. A vertical red line indicates the center frequency of the tone detector. When tuning a signal manually, its trace should be centered on this line for best results. Clicking with the center button on the display reverses the background/foreground colors of the display.
xpsk31 has built-in CAT capability but only for the Yaesu FT847 or FT857, the only rigs I have. This is an unfortunate limitation but an attempt to convert xpsk31 to using the "hamlib" library was unsuccessful for various reasons. However xpsk31 now also has serial port RTS control to allow transceiver PTT-On/PTT-Off control. The Waterfall display can be used to tune in a signal by clicking with the left mouse button near its trace. xpsk31 will scan a small section of the display either side of the mouse pointer, looking for the strongest trace and then tune the receiver so that the signal is centered on the red line. Since the FT847/FT857 has only a 10 Hz resolution when tuned by the CAT, there can be an error of +-5 Hz in the tuning of a signal. Other errors resulting from the finite resolution of the FFT can increase the tuning discrepancy and since PSK31 requires tuning to within +-4Hz, it may be necessary to fine-tune the receiver manually before the AFC can lock on the signal.
Macros in Transmit
xpsk31 allows 9 prepared Macros to be sent by clicking on one of the nine buttons in the 'Prepared Macros' frame for easy transmission of repeated messages like call-sign exchanges, station info, BTU, sign-off etc. Theses Macros are stored in the 'xpsk31rc' run time configuration file (in ~/xpsk31/) and are invoked by clicking on the relevant Macro button. Short labels for these Macros are also stored in xpsk31rc and are displayed in the button labels. For even more operating convenience xpsk31 allows the use of 'tags' embedded in the Macros for automatic insertion of certain basic strings in the transmitted message: call-sign, RST, name, QTH and QTH locator for both the operator and the remote station, the current UTC date and time and the operating frequency. The program's version string is also available as a tag so that it can be included in a macro, e.g. there are 13 tags altogether in this version. More on this in the Operation section.
QSO Recording and
xpsk31 can save details of activity during its operation in three separate files on the disk:
1. In ~/xpsk31/record.txt all characters printed in the Transmit or Receive window including Macros are recorded 'raw' e.g. in real time and unedited. This makes it possible to check everything transmitted or received during operation if something goes wrong.
2. In ~/xpsk31/log.txt all details of a QSO entered in the QSO Record form (under the Receive window) are saved in text form with the addition of date and time to form a standard station log.
3. In ~/xpsk31/log.adif an ADIF-formatted version of the QSO Record is saved for direct uploading to eQSL.cc or other sites that can accept ADIF formatted logs.
Recognized characters The alphabetic characters, punctuation marks and special codes that xpsk31 can currently recognize are in the header file xpsk31.h. The table of characters has the ASCII symbol on the left, the Varicode bit pattern in the middle and the equivalent HEX code on the right.
Before compiling xpsk31, it is possible to customize some entries in the header file pskcodec.h. A list of all characters, punctuation marks and special signals recognized by xpsk31 are listed in this file. Different characters can be entered in the table in the pskcodec.h header file before compilation, following the instructions in there.
Please note that I use Arch Linux which is a "bleeding edge" type distribution, so there may be compilation and/or run time difficulties if you are using a relatively old distro. This is mostly true of the basic dependencies like GTK+ 2 and Glade 2, and there can also be sound card incompatibility problems at run time.
To compile the package, it may be preferable to first run the included "autogen.sh" script in the package's top directory, to produce a fresh build environment. Then the "configure" script can be run with optional parameters to override the default settings and compiler flags, e.g: ./configure --prefix=/usr CFLAGS="-g -O2" will override the default /usr/local installation prefix and the "-Wall -O2" compiler flags.
Running "make" in the package's top directory should produce the executable binary in src/. Running "make install" will install the binary into /usr/local/bin by default or under the specified prefix. It will also install the xpsk31 working directory and default configuration file into the user's home directory. This will have to be edited by the user as required. There is also this hypertext documentation file which you can copy to a location of your choice.
xpsk31 requires a directory named xpsk31 in the user's Home
directory, where the default/xpsk31rc run time configuration file
is placed after suitable editing. Additionally, xpsk31 places three
files in this directory, created during operation:
1. record.txt is a complete character-by-character record of everything that has been received or sent during a session.
2. log.adif is an 'ADIF' formatted record of the main QSO data e.g. call-sign, signal report, mode, frequency and date-time.
3. log.txt is a more detailed record of conducted QSO's in text format.
4. Command line
xpsk31 can be invoked with the following options:
-h: Print this usage information and exit.
-v: Print version number and exit.
xpsk31 is an X/GTK+ application for Linux. The main application window has the following widgets:
1. The Transmit window: Any text typed during transmission appears in this window. When it is filled, it scrolls automatically so that the last line is always visible. It can be cleared by right-clicking in the window and activating the 'Clear Window' item in the pop-up menu. Clicking the middle button toggles xpsk31 between the Transmit and Receive modes. Next to the Transmit button there is a spinbutton which can be used to change the Playback volume, thereby adjusting the Transmitter's power output.
2. The Receive window: Displays characters decoded from a PSK31 signal. When it is filled, it scrolls automatically so that the last line is always visible. It can be cleared by right-clicking in the window and activating the 'Clear Window' item in the pop-up menu. Clicking the middle button toggles xpsk31 between the Receive mode and Standby. If xpsk31 is in Transmit mode it is changed over to Receive, but if a Macro is being transmitted, then it is interrupted and xpsk31 remains in Transmit mode until another middle-click on either window. Next to the Transmit button there is a spinbutton which can be used to change the Capture volume, thereby adjusting the audio input level to the DSP.
3. Receive Magniphase/Waterfall and Squelch: The Magniphase/Waterfall widget is an aid to tuning the receiver accurately to an incoming PSK31 signal. It displays a simple round 'dial' in which a line emanating from the center indicates the magnitude of the PSK31 signal by its length and the phase by its direction. Another line from the center indicates by its inclination, the frequency error as measured by the AFC function of xpsk31.
The "Waterfall" audio spectrum display appears in place of the Magniphase when the right button is clicked in the window. There is a CAT function associated with the Waterfall but only for the Yaesu FT847 or FT857 transceivers, as there were problems adapting xpsk31 to work with the Hamlib library.
The Squelch slider sets a threshold on the detected PSK31 carrier below which decoding is suppressed. This is useful in limiting gibberish printing in the Receive window under poor signal conditions.
4. The QSO Record frame: In this frame there are seven entry fields in which basic QSO data are entered for saving in the text-format station log file and the ADIF-format log file in the ~/xpsk31/ directory. The minimum requirement for a valid record is the DX station's call-sign, signal report and operating frequency. The mode and date are entered automatically by xpsk31 each time a new record is opened. If the transceiver in use is an FT847 and CAT is enabled, xpsk31 will read the Transceiver status and enter the signal report and operating frequency automatically each time a new record is opened.
The buttons below the QSO Record fields have the following
Open New Record: This button clears all but the 'Band' field and enters the mode (BPSK, QPSK-USB or QPSK-LSB) and date and time to the QSO record buffer in memory. If there is a previous valid record then this is saved to the log files in ~/xpsk31/ before a new record is opened. Key F10 also opens a new Record.
Save Record: Opens a pop-up save dialog box. If the QSO Record is valid (call-sign, RST-out and Band have been entered) then a confirmation request for saving is shown, otherwise if not, a warning is given to that effect. Key F11 also has the same function.
Clear All Fields: This button clears all entry fields. NOTE: This will clear the QSO Record buffer in memory, resulting in lost data if the record has not been saved first!.
Clear Windows: Clears the Transmit and Receive windows of all text.
5. The Macro buttons frame: In this frame there are nine buttons that initiate the transmission of prepared macros, e.g. standard messages saved in the run time config file xpsk31 (in the ~/xpsk31/ directory). Clicking on a button puts xpsk31 in Transmit mode and starts transmission of the macro, clicking again on any of these buttons interrupts the macro but leaves xpsk31 in transmit mode.
6. The pop-up menu: This opens on a right-click on the
Receive or Transmit window. It has the following items:
PSK31 mode: Select the PSK31 mode: BPSK, QPSK-USB or QPSK-LSB.
Enable CAT: Enable/disable CAT control of the FT847 or FT857 transceivers.
Record QSO's: Enable/disable recording of everything printed in the Receive or Transmit windows to the record.txt file.
Capitalize letters: Enable/disable capitalization of letters in the Receive and Transmit windows.
Clear Window: Clears all characters of the underlying window.
Identify in CW: Sends sends the station call-sign in CW/Morse code.
Quit: Quits xpsk31.
After compilation and installation, the ~/xpsk31/xpsk31rc run time configuration file MUST be edited for proper operation! To do this, load ~/xpsk31/xpsk31rc into your favorite editor and make sure that you review ALL the configuration fields in the file and that you properly edit all the ones that must be edited. There are four sections, Sound card, xpsk31 Run time, Operator/QTH info and Macros fields. Please review ALL and EDIT as needed!! There are more detailed instructions in the file itself so please follow them for a proper set-up. In particular, station details like Call-sign, operator's name and QTH etc must be edited for Macros to be usable.
Next, the sound card must be set up. For this to be done, the receiver's audio output should be connected to the computer's sound card (usually to the 'line' input) and the receiver tuned to some stable carrier signal with no am modulation. Modern HF transceivers have general coverage receivers with DSP audio filters down to 25 or 50 Hz bandwidth and this makes it possible to use a local broadcast station as a signal source.
With the narrowest bandwidth selected, start xpsk31 and fine-tune the receiver for a 500 Hz beat frequency output, using the Magniphase indicator as a guide, e.g. tune for a maximum length of the Magniphase line and a minimum phase slip rate, e.g. for a minimum rate or rotation of the Magniphase line. For the correct level of audio input, the Magniphase line must extend to just inside the dial's rim. If the audio level is to high, then the line will extend beyond the dial and it will leave its mark around the outside, since this area is not re-drawn by xpsk31. If this happens then reduce the receiver's volume level or if the audio output is taken from a fixed-level outlet (like the 'data' port), set the correct input level by editing the Capture level value in the ~/xpsk31/xpsk31rc file. This can be done by using the spinbutton next to the Receive button to adjust Capture level as above and then setting this value as the Capture level in xpsk31rc.
For PSK31 transmission, the DSP output level needs to be set up for minimum distortion in the transmitter. The Playback volume setting in ~/xpsk31/xpsk31rc can be edited to set the right audio output level by using the spinbutton next to the Transmit button. Adjust the Playback volume till the Transmitter's output is about 50% or less. The spinbutton setting can then be used in xpsk31rc as the Playback volume level. If the setting needs to be below approximately 10% then a simple resistive attenuator will be needed ahead of the transmitter's audio input. In each case the best way to set the sound card output level would be to have the transmitter's settings (Mic gain, ALC or other appropriate control) at an average or 'normal' level and adjust the sound-card audio level so that the RF output power is about 50% or less of the rated maximum power. This will ensure that distortion is kept to a minimum and the dissipation of the final stage within its ratings.
PSK31 is a narrow-band mode and it requires accurate tuning, to within less than +-3 Hz for reliable operation. For manual tuning this requires the receiver to have a tuning step of 1 Hz but if this is not available, the "Rx Freq +-" slider can be used to fine-tune the tone detector's frequency. The AFC function when enabled can also fine-tune the detector to about +-5 Hz and it is very helpful in locking an incoming PSK31 signal. If the transceiver in use is an FT847 or FT857 then the Waterfall display can be used to tune in a signal by clicking near its trace. xpsk31 will adjust the main dial frequency so that that the signal is tuned in closely, but since tuning resolution under CAT is 10 Hz for both rigs an error of at least +-5 Hz is possible so manual fine tuning may be needed.
Receiving QPSK signals is similar to BPSK but requires even more accurate tuning of the receiver. Please note that the operating mode of the Transceiver (USB or LSB) during transmit and receive, must match that of xpsk31 as selected from the pop-up menu.
Conducting a QSO
As usual to make a QSO with another station using PSK31 you may call CQ or reply to a CQ. Calling CQ would normally be done using a prepared Macro by clicking on the relevant Macro button and during the course of a QSO, other Macros can be started as needed to send some of the standard messages that are usually exchanged. When the Macro is finished, xpsk31 will revert to Receive mode unless a tilde '~' is the last character in the Macro, in which case it remains in Transmit so that a manually typed message can follow the Macro. Reversion to Receive would then be done by middle-clicking on the Receive or Transmit window.
Please note that Macro transmission can be interrupted by middle-clicking on the Receive or Transmit window or left-clicking on any of the Macro buttons.
When a station replies to a CQ it would normally be netted closely and characters transmitted will appear in the Receive window. If there is a significant frequency offset, it will cause errors in decoding but correcting this from the main dial may cause the remote station to miss reception. Using the RIT control may be advisable as this will help to avoid 'crawling' along the band as stations tune in to each other during the QSO.
Once two-way contact is established, at least the station's call-sign, RST, and the QSO frequency must be entered in the QSO Record's fields before it can be saved to ~/xpsk31/log.adif and ~/xpsk31/log.txt. BUT PLEASE NOTE: Always remember to 'Open New Record' before entering any data otherwise the mode and date/time will not be entered to the record buffer by xpsk31.
Any information entered in the fields is available to any relevant 'tag' in the Macros but please note that if any fields are not filled, xpsk31 enters blanks in place of tags! Please note that during transmission no entries should be made to the QSO Record fields since these will reflect in whatever tags are embedded in Macros.
To reply to a CQ, tune in the station accurately and type its
call-sign, signal report and frequency in the QSO Record fields.
Then prepared Macros can be used to reply to the call and conduct a
QSO. Have a look in ~/xpsk31/xpsk31rc for some typical prepared
NOTE: You will need to edit at least some of these!!
6. Bugs and deficiencies
I have fixed whatever bugs I came across testing xpsk31, but there may be some hiding, waiting for the right conditions to appear.
The PSK31 phase detector algorithm may need further improvements to make it more tolerant to fading and noise. The biggest problem seems to be adjacent strong signals raising the AGC and reducing the level of the PSK signal being decoded.
The use of a simple integer-only DSP decoding process makes it necessary to run the software phase decoder/synthesizer at a 500 Hz center frequency. This also makes it necessary to run the receiver with a CW pitch setting of 500 Hz. This well below the usual 700-800 BFO pitch setting and will probably make it necessary to change BFO settings for CW work.
Version 0.1 First beta release of the basic xpsk31 application.
Version 0.2 Fixed the omission of initializing the Viterbi decoder when switching to QPSK.
Version 0.3 Modified the QSO record so that the RST-out is before the RST-in field. Also changed the format of the 'log.txt' file that is used for logging QSO's to make it more printable.
Version 0.4 Added +- 5.0 Hz fine tuning to the receive audio frequency, e.g. it can now be tuned from 495 to 505 Hz to help with rigs that only have 10 Hz tuning steps.
Version 0.5 Added a simple FFT-based "Waterfall" (audio spectrum) display with CAT functions for the Yaesu FT847/FT857 transceivers. This allows tuning in a signal by clicking on its trace in the Waterfall.
Version 0.6 Added a very useful AFC function that can lock in a signal and also indicate the frequency error in the Magniphase window.
Version 0.7 Changed the signal detection scheme to a Goertzel tone detector. Changed sampling frequency to 48 KHz to avoid an apparent bug in ALSA's resampling code.
Version 0.8 After a bug report from Juha Vierinen regarding seg faulting of xnec2c, my graphical adaptation of NEC2, I changed all "sprintf" commands to "snprintf" to avoid buffer overruns. Following on the above changes, I revised all similar situations in xpsk31 source code and changed all "sprintf" commands to "snprintf" just in case. While going through the xpsk31 source code, I also fixed some minor bugs like typos and tidied error messages and other aspects of the GUI.
Version 0.9 After a bug report from Pino Zollo ZP4KFX, I modified the waterfall display function to avoid a divide by zero condition that caused a SIGFPE crash.
Version 1.0 After a bug report from Pino Zollo ZP4KFX, I modified the program to hopefully correct GUI problems caused by glitches (race conditions) on start up, which caused incorrect initialization of the GDK pixbuf used to draw the Waterfall.
Version 1.1 After a bug report from Pino Zollo ZP4KFX, regarding failure of "xdemorse" to start the Morse decoding loop after reading its configuration file, I have modified the functions that read this file so that more detailed error messages are printed if entries are malformed.
Version 1.2 After a feature request by Pino Zollo ZP4KFX, I added serial port RTS line control to enable PTT-On/PTT-Off of transceivers other than FT847/FT857. But please note that no CAT functions will be available, e.g. clicking on the waterfall trace will not tune in the receiver and frequency/S-meter readings will not be available in the QSO records.
Version 2.0-beta After many reports of difficulties and/or failure to set up and run xpsk31, due to poor or non-existent support for some sound cards in ALSA's OSS compatibility layer, I carried out major changes in xpsk31 to use the ALSA sound API instead of the original OSS API. Because of very sparse or lacking documentation for the ALSA sound API, I had great difficulty getting xpsk31 to work under ALSA, especially the Mixer interface. I am releasing xpsk31 as version 2.0-beta for public testing, hoping it will be more successful with modern sound cards. Please don't blame me if it is not, even simple sound card programming with ALSA can be very difficult and/or tricky and buggy, since there are few if any tutorials available, especially for the Mixer interface.
I have also made several changes to the transceiver CAT code to deal with error conditions better and to be enabled by the "Receive" or "Transmit" buttons, so that CAT is enabled only when xpsk31 is actually receiving or transmitting PSK31 signals. Please note that all the above changes inevitably resulted in regression bugs which I fixed, together with a few that were already there from the previous version. However, it is unlikely that I was able to catch all the bugs, so please do not hold me responsible for any problems xpsk31 may create while in use on your system.
Version 2.1-beta I changed the way xpsk31 decodes BPSK31 signals. Instead of identifying one bit of a Varicode character at a time, where a 180 deg phase change is taken as a '0' and no phase change as a '1', xpsk31 now identifies sequences of 3 consecutive bits. The algorithm used is to some extend 'fuzzy', e.g. instead of setting a 'hard' range of phase shifts that identify a '0' or '1' bit (90-270 deg phase shift is a '0' and the rest is a '1'), xpsk31 now stores the value of three consecutive phase shifts in a ring buffer, and calculates their sum for each of the 8 combinations of '0' and '1' that a 3-bit field in a Varicode character can have (including the '00' inter character space). For a '0' bit, 180 is subtracted from the appropriate ring buffer location, and for a '1' bit nothing is done. Then the 3-bit combination that produces the lowest sum is then taken as the one that was received.
For example, if a string of '0's is transmitted during a preamble, then there can be a sequence of 3 '0' bits which will result in three 180 deg phase shifts stored in the ring buffer. When xpsk31 tries to find which of the 8 combinations of a 3-bit field matches 3 180 deg phase shifts, the '000' combination will result in 180 being subtracted for each buffer location and so their sum will be zero. Other combinations will result in a higher sum and they will be rejected, e.g '101' will result in 180 + (180-180) + 180 = 360. The advantage of this algorithm seems to be higher tolerance to phase detector errors (due to noise etc) since effectively 3 consecutive phase changes are averaged.
Version 2.2 I modified the DSP_Write() function in
sound.c to write Tx data to the DSP in chunks equal to the Period
Size of the codec, to avoid occasional "Broken pipe" errors (and
resultant xrun recoveries).
Also fixed some "Variable defined but not used" warnings from GCC (due to some variables "left over" during development).
Version 2.3 I fixed an error in the modified DSP_Write() function in sound.c
Version 2.4 I added CAT support for the Elecraft K3
transceiver, which may also work with the K2 but I cannot verify
this. It was necessary to make many changes to the CAT functions to
do this, so that the CAT functions for the FT847/FT857 also had to
be modified. I have tested the new code on my FT857 but I no longer
have my FT847 so I cannot verify that the new CAT code works well
with it, although I expect it will.
I replaced the GDK drawing primitives (gdk_draw_line() etc) with similar functions from the Cairo library. This has resulted in improved anti-aliased drawing of the waterfall and signal scope images. I have also changed the appearance of the signal scope to have a dark green backround and bright green plots, and the waterfall to have a black background with color coded spectrum display.
Version 2.5 I made extensive modifications to the source code to silence a large number of warnings generated by the LLVM clang compiler when used with the -Weverything option. These were mostly cases of implicit conversions between variable types, like int to char or uint to int etc. I have also updated the basic files of the GNU Autotools build system, to be compatible with the current version of these tools at the time of writing (February 2013).
8. Copying This software package is released under the GNU Public License. Please see the COPYING file for more details.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
Last modified: Sat Mar 8 07:38:59 EET 2003