GPS (NMEA) Decoder

For some special applications, there is a very basic 'GPS decoder' (actually an NMEA parser) implemented in Spectrum Lab since V2.76. The main purpose of this decoder is to store the geograpic position (latitude, longitude and meters above sea level) along with the current GPS time in data files. The GPS decoder can also be used to 'calibrate' the soundcard's sampling rate as explained in another document. In addition, GPS can provide highly accurate timestamps to sychronize audio streams sent over the internet.

This article describes how to configure and use the decoder inside Spectrum Lab.


  1. GPS Receiver Control Panel
    1. The 'position' tab
    2. The 'configuration' tab
    3. The 'Time Sync' tab
    4. The 'diagnostics' tab
  2. Using the GPS Receiver Control Panel in combination with the Sample Rate Calibration (per GPS, PPS+NMEA fed into the PC via soundcard)
  3. Exporting GPS data
    1. GPS logfile format
    2. Adding other data to the GPS logfile ("Info Strings")
  4. GPS receiver specific notes
    1. Garmin GPS18x
  5. Interpreter functions for the GPS 'decoder' (NMEA parser)
Related topics: Time Signal Decoders (DCF77, MSF), Sample rate calibration .

GPS Receiver Control Panel

To configure and test the decoder, select Options ... GPS Receiver from SL's main menu. This opens a small control panel for the receiver, with at least three tabsheets:

Screenshot of the GPS Receiver Control Panel      

The upper line shows the current position, for example
  54°11'18.0"N 007°52'18.4"E
 (Latitude, Longitude, with degrees, minutes, seconds, and tenths of a second).
Note: You can copy & paste this position into some well-known online mapping software..
If the position is invalid (because either the GPS receiver marked it as invalid, or no valid NMEA data have been received yet), the field will turn red.

The second line shows the GPS date and time (~UTC) for which the displayed position is valid.
The third line shows 'quality' information (number of satellites currently received, HDOP = horizontal dilution of precision), height in meters above mean sea level (" m ASL"), and the current velocity estimated by the GPS receiver (in kilometers/hour; no stoneage imperial units).

On this tabsheet, select the COM port to which the receiver is connected (or "Soundcard", see below), and the serial port speed (bits per second, 'Baudrate'). Usual values are 4800 or 9600 bit/sec, but some receivers (especially those which emit 4 or even 10 positions per second) use larger serial baudrates (*). The serial data format for the GPS data (NMEA-0183 standard) would be  4800 Baud, 8 data bits, no parity bit, one or more stop bits, and no handshake. Except COM port number and baudrate, the parameters are hard-coded in the program, there's no need to adjust them. Many GPS 'mice' use larger baudrates, for example 9600 or 19200 bits/second.

Alternatively the GPS receiver can be connected via the soundcard. Set the 'COM port' to 'Soundcard' (!). This is only possible if the soundcard runs in 'stereo', and the card has a true 'line-in' (not just a microphone input). Add a 100 : 1 resistive voltage divider, and a 100 nF coupling capacitor between the receiver's serial output and the soundcard's line input, to reduce the peak-to-peak voltage to a few hundred mV. The advantage of feeding the NMEA signal through the soundcard is the better timing accuracy, because the NMEA signal (and, possibly, a superimposed 1-pps-signal) travels through the same 'signal path' inside the PC, and the software, like the analysed signal. The soundcard's channel to which the GPS is connected ("L1" or "R1") can be configured on the 'Sampling Rate Detector' tab (!), because this was the main purpose of a GPS receiver connected to the soundcard : Using a combined NMEA- and 1-pps-signal connected to the soundcard as a reference signal for the sampling rate, to improve the accuracy and stability of phase- and frequency measurements.

Click 'Apply' when finished to make changes to the serial port settings effective (this closes the serial port, an re-opens it with the new settings).
The settings below will be 'applied' immediately, without clicking the 'Apply'-button, and thus without stopping and re-starting the acquisition.

'DispFrm': Position Display Format. At the moment, only a few formats like dd°mm'ss.s" (degrees, minutes, seconds) are supported.

'emit pos every NN seconds' : This is the interval at which the GPS position (including altitude, date, and time) is emitted into the audio logfile, or audio stream. Note that this is only possible with certain file- or data stream times. Even if the GPS receiver sends an updated position via NMEA (say once every second), you may only want to emit a new data block every 10 seconds - depending on the vehicle's maximum speed, and the required position accuracy.
If the output is logged to a wave file (audio file), and the GPS output interval is non-zero, the GPS data are periodically written into an auxiliary file (same name as the wave file, but different extension: *.aux instead of *.wav) .

'show pos in spectrogram' : When checked, the GPS position is shown in the main spectrogram, along with the time-'ticks'. The GPS position, using the format specified above, will be appended to the time marker format specified under 'Display Settings' / 'Waterfall Time Grid'.

'use GPS time, not local' : If this option is selected, most places where otherwise the PC's local time aka 'PC clock' is used, the program will use the last (valid) GPS time instead. If the NMEA stream stops, the time value will continue to increase in a more or less 'free running' mode (less accurate than the GPS time).

'add to track in RDF-Calc' : With this option it's possible to send each new GPS position to DL4YHF's RDF-Calculator. The RDF-Calculator is an external program which can show the current track in a simple map. Internally, both programs (Spectrum Lab and the RDF Calculator) communicate with each other through WM_COPYDATA messages.
Note: The RDF Calculator can also load Spectrum Lab's GPS logfiles (*.aux) directly. The 'add to track in RDF-Calc' option has the advantage to show the current track in real time.

'Date Correction' (in days): This field was added in 2020 when certain old GPS receivers like the author's Garmin GPS18LVC delivered a wrong UTC date in the NMEA output ($GPGGA, $GPRMC). If your receiver also delivers a date that is approximately 20 years ago, enter 7168 into this field. Technical background: The current GPS navigation message (from satellite to receiver) only contains the ten least significant bits of the week. After 2^10 = 1024 weeks = 7168 days, the week number rolls over from 1023 to zero. Most GPS receivers handle this properly (they can determine the full year number by some other means), some (like the Garmin GPS18) don't.

'column separator' : Allows you to select the character which is used as separator (delimiter) between the data columns in the audio logfile. Possible separators are the space character (author's favourite for 'human-readable data files'), comma, semicolon, or tab.

'Time Sync' tab
On this tabsheet, the optional synchronisation of the PC's system date and time from the received GPS (NMEA) data can be configured and checked.
Note: Under most Windows versions, Spectrum Lab must be run 'as admin' to sychronize the system time. Also, any other time-synchronizing software or services must be disabled before the option
    ☑ periodically synchronize PC's system date/time with data from GPS
is enabled.

GPS 'Time Sync' panel with 'good' settings for a Garmin GPS18LVC,
with a significant latency (700 ms) between the PC's system time
and the reception / decoding of NMEA data with date and time.

On this tab, since 2020-12-08, the difference between the system time (in UTC) and the time and date decoded from NMEA (also combined into UTC) is even displayed if the 'periodically synchronize'-option is disabled.
This is done on purpose so you can check the correctness (*) of the GPS receiver's NMEA output before turning on the 'Time Sync' option.
Use a trustable "system time synchronizer" like DL4YHF's rsNTP (Ridiculously Simple NTP Client) as a reference. For example, while the system time was synchronized by rsNTP to a 'nearby' NTP server, and manual re-synchronisations indicated residual errors below 50 ms (again, from rsNTP, not from the GPS/NMEA), the difference measured by Spectrum Lab between
"System time" and ("minus") GPS date and time
was often about 700 milliseconds - in other words, much worse than even the worst NTP client (like the 'Internet Time' service in older Windows versions) could achieve.
Fortunately, these delays only occurr if you DON'T connect your GPS receiver's sync pulse output to the soundcard. Also, these delays appeared to be fairly constant. They are mostly caused by the GPS receiver itself, which sends out the NMEA string at unpredictable times, plus delays caused by buffering in the Windows "COM port" (serial port) API and/or the serial port / USB driver.
When tested with the old Garmin GPS18LVC connected via RS-232 to USB adapter, using 9600 bits/second for the NMEA data, the time decoded from received NMEA strings was always late by approximately 0.7 seconds (measured by rsNTP). This could be 'compensated' by entering that offset on the 'Time Sync' tab in the field labelled
  'Add ___ seconds to GPS time before setting the PC's system time'.
The above offset can NOT be measured by Spectrum Lab itself, unless you have the GPS receiver's sync output ("PPS") connected to the soundcard as described here.
See also: Oscillogram of NMEA traffic and GPS sync pulse, from a Garmin GPS which starts outputting NMEA 600 milliseconds after the sync pulse ("PPS"). Another 100 milliseconds may have passed before completion of the the first NMEA sentence.
Thus, don't expect a high accuracy if you only connect the GPSes serial data, but not the sync pulse output to the PC.

(*) About the 'correctness' of date and time decoded from the NMEA output:
When tested in 2020-12, the author's trusty old Garmin GPS18LVC was "wrong" (off) by 7168 days, because the Garmin firmware did not correctly handle the 1024-week GPS date roll-over. More on that annoyance, and a possible work-around, is here (enter 7168 [days] in the 'Date Correction' field if your poor old GPS is also late by approximately 20 years).
Being a few hundred extra milliseconds late isn't the GPS'es fault; this systematic delay is caused by the NMEA sentences being sent over a stoneage serial interface (here with an amazing speed of 9600 bits per second).
The 'Time Sync' option described in this chapter will not modify your PC's system time if the (corrected) date-and-time from the GPSes NMEA output differs from the PC's system time (converted to UTC) by more than 10 minutes. Thus, if your receiver also suffers from the 2^10 week 'rollover' problem like the old Garmin GPS18LVC, you will not get the system time synchronized without the appropriate 'Date Correction' value (7168 days in this case, but your mileage may vary ... modern receivers shouldn't need this).
See also: SetSystemTime (interpreter command), interaction with rsNTP (DL4YHF's NTP client).

Shows the most recent received NMEA sentences with types ($GP-)RMC, GGA, and GLL. Your GPS receiver should be able to send at least one of these (it may send all of them). Any 'unknown' sequence -at least from SL's NMEA parser's point of view- is dumped to the line labelled 'unknown', along with the counter of such messages.
For example, when tested with one of the common cheap 'GPS mice' (u-blox), this field occasionally showed
when the receiver's antenna didn't have sufficient sky view.

On this tab, you can copy and paste NMEA sentences through the windows clipboard. Click on the Decode button to feed the lines from the text editor into the NMEA decoder. The previous position, date, time, and counters on the Diagnostics tab are cleared before this, so after clicking 'Decode' the other tabs show only the result from the NMEA data entered here for testing.
For normal operation, you will hardly ever need this function. Its main purpose was during software development (testing the NMEA parser, and adding support for less frequently used sentences like $GPZDA).


back to contents

Using the GPS Receiver Control Panel in combination with the Sample Rate Calibration

Since V2.76 (2011-04), GPS receiver with NMEA- and PPS-output can be used to  continuously "calibrate" the soundcard's drifting sample rate. For this purpose, the PPS-signal must, and the NMEA output may be connected to the soundcard. So a 'real' serial port, or an USB-to-serial adapter is not required anymore - only a simple passive combiner like the one shown below.

Passive combiner circuit for GPS-PPS and NMEA

Details about using a GPS receiver to "calibrate" the soundcard's sampling rate can be found in an extra document about GPS receivers with one-pulse-per-second output .

Exporting GPS data

GPS data can be saved to a disk file, usually along with the 'raw data' (which are usually saved in wave audio files). To avoid breaking the WAVE file structure (by splitting up the 'data' chunks), the GPS data are written into a separate file, using the same path and filename, but a different file extension. This simplifies post-processing, and makes it easy to extract the GPS data for a 'mapping application'. Future audio files may allow embedding the GPS data directly in the audio file, but the principle explained below will remain the same. To save the most important GPS data along with the audio-logfiles,

If the GPS receiver is connected to the PC via soundcard, additional settings must be made on the 'Sampling Rate Detector' panel (which includes the source channel selection, the serial bitrate ("NMEA bits/sec"):

GPS positions are traditionally logged in 'GPS Track Files', but unfortunately there is no simple and space-efficient standard file format for this (GPX is widespread now, but due to its XML-based nature, it wastes a lot of disk space if you need to save throusands of track points). So the file format to log GPS data within Spectrum Lab now uses its own, simple structure (see next chapter), which allows an EASY link between any audio sample position (in the wave file) and the geographic position (in the GPS logfile). If necessary, SL's own GPS logfile format can easily be converted into GPX (or, maybe, KML), but not vice versa because GPX doesn't store the 'audio sample index into the wave file'.

GPS log file format ( in "aux files")

The logfile is a simple ASCII text file, one line per GPS position, no structure, no XML, no whistles and bells. Data columns are separated by spaces. The data columns are:

  1. Audio sample index in the audio logfile (with the same name of the logfile, but different extension).
    This value starts counting at zero(!) for the first sample in the audio file.
  2. GPS timestamp in UNIX format (number of seconds elapsed since January 1st, 1970).
    It marks the time for which the GPS position (below) is valid. For most GPS receivers, the timestamp will only step by one (second), but there are receivers which send four or even ten position reports per second, thus the two fractional digits.
  3. GPS latitude in degrees (positive = north, negative = south,  - 90 .. + 90 °,  0 ° = Equator) .
    If the GPS position is not value, this value will be -99.99999 (degrees).
  4. GPS longitude in degrees (positive = east, negative = west,  - 180 .. + 180 °,  0 ° = Greenwich meridian).
    If the GPS position is not value, this value will be -999.99999 (degrees).
  5. GPS altitude in meters above mean sea level, as returned by the GPS receiver.
    If the GPS position is not value, this value will be -9999.9 (meters).
  6. GPS velocity in km/h ( kilometers per hour, not knots ! ).
    If the GPS position is not value, or the GPS receiver doesn't provide it, this value will be -999.9 (km/hour).
  7. 'Info String' from the user application. Can be set anytime with the 'wave.wr_info' pseudo variable (see next chapter).
    Spectrum Lab makes no assumption about the contents of this string.

Only at the begin of the file, there may be a few comment lines, beginning with a semicolon. The second comment line describes the file structure. Comments in between to 'data lines' are not allowed. Below is a sample of such a GPS logfile, with some user-defined contents set through wave.wr_info (explained in the next chapter) :

; Spectrum Lab auxiliary data file for "gpstest1.wav"
;sample_nr unix_date_sec latitude_d longitude_d h_m_asl sp_kmh ...
0000000000 1278604831.00 +52.130111 +008.440111 +0098.4 +000.0 pk37=-94.8
0000004096 1278604832.00 +52.130222 +008.440222 +0098.5 +000.1 pk37=-87.5
0000014336 1278604833.00 +52.130333 +008.440333 +0098.6 +000.1 pk37=-94.7

Adding other data to the GPS logfile ("Info Strings")

Along with the GPS data as specified in the previous chapter, other data can be added into the logfile (audio log, or GPS log with the same name as the audio log but different extension).

To write such 'extra data' to the recorded file(s), put those data into the pseudo-variable wave.wr_info, for example in the periodic events or conditional events:

wave.wr_info="pk37="+str("##0.0",peak_a(36000,38000)) : REM update write-info with the peak amplitude between 36 and 38 kHz

Note: wave.wr_info can only be set to a string value ! Numeric values must be formatted into a string as in the example above. There is no way to tell exactly (in advance) when the string will be flushed / merged into the output stream. It also depends on the GPS receiver's output interval, which is typically once per second.

To retrieve these info strings during audio file analysis (or 'playback'), use the function wave.rd_info . This function works like a string variable, it contains the most recent info string read from the file during file analysis.

To append a matching 'headline' for the user-defined part (wave.wr_info), use the wave.wr_info_header variable. You will find an example for this function in the sample application '37kHz_Pingers.usr' . The contents of wave.wr_info_header variable must be set before starting a logfile. This can be achieved, for example, but executing a command like the following in the 'Conditional Actions', called when 'initialising' :
wave.wr_info_header=",ampl_1,ampl_2" : REM headline for two user def'd columns

Note: You should use the same column separators as defined in the GPS configuration tab.

Details about other interpreter commands to control 'wave' file in- and output are here .

back to contents

See also: Spectrum Lab's main index

GPS receiver specific notes

This chapter contains a few notes about certain GPS receivers; mostly how to configure them.

Garmin GPS 18x

Note that not all of the GPS18x devices by Garmin have a 1-pps output ! For details, search the web for "GPS18X Technical Specifications - Garmin" . With some luck, this will take you to a document which covers different receivers. The 1-pps output (which, btw, Garmin calls "Measurement Pulse Output) only exists in the GPS 18x LVC, not in the GPS18x "USB", and not in the GPS18x "PC" ! The "GPS 18x-5Hz" has a 5-pps output, which, as the paper says "One of the five pulses will align with the UTC second boundary" - which makes it a bit difficult to use.

For these reasons, the author only tried the GPS 18x LVC (with a "true" 1-pps-output), and the passive combiner shown earlier in this document, to route both the NMEA signal, and the 1-pps-signal, into the PC's soundcard.

The first problem was that with the default configuration (i.e. GPS receiver shipped from the factory) had so many different NMEA messages enabled, that the NMEA packet overlaps with the 1-pps-signal. This made the simultaneous decoding using only one input into the soundcard impossible.

To turn off all 'unnecessary' NMEA messages, a program called "SNSRCFG_320.exe", which used to be somewhere at the Garmin site, must be used. For the GPS 18x LVC, you will need a serial port (or USB to serial port adapter) connected to your PC. Here is a short walk-through of how the author of Spectrum Lab configured "his" GPS 18x LVC:

  1. Find, download, and install the "SNSRCFG software version 3.20". It used to be at .
    If you're lucky, it's still there, along with the instruction about how to install and use it.
  2. When the program asks "Which Garmin sensor are you connecting to ?", select "GPS 18 PC / LVC".
  3. In the main menu, select "Comm" .. "Setup". Select the COM port to which your GPS is connected (Note: The program also lists interfaces which don't exist at all. If you use an USB-to-RS232 adapter, use the windows system control to find out which COM port number has been assigned to your interface today. Windows will happily assign a NEW (different) COM port number each time you plug the interface into a different USB port on your PC. Sigh.. try to plug the damned RS-232 adapter into the same USB port each time you need it. Set the "Baud Rate" to "Auto" in Garmin's "Comm Setup". Click "OK" to close that box.
  4. In the main menu, select "Comm".."Connect" (or click the funny little icon which is supposed to do the same). After a few attempts to find the right baudrate, the program will hopefully show
    Auto Baud Rate Detection
    Connection Success. Baud rate detected at XYZ bps.

  5. Select "Config" in Garmin's main menu. If the item "Switch to NMEA mode" is enabled, select it.
    This will switch the receiver's output from Garmin's proprietary format (which Spectrum Lab doesn't support, and never will) to the standard NMEA format.
  6. Select "Config" .. "NMEA Sentence Selection". Only select GPGGA, GPGSA, and GPRMC. You don't need all the rest !
    After this step, the Garmin main window should look similar as below:
    Configuration file:    SNSRCFG.cfg
    GPS Base Model:        GPS 18 PC / LVC
    Selected Sentences:
    Latitude, Longitude:   (yours!)
    Altitude:              (approximately yours!)
    Fix mode:              Automatic
    Filter mode:           Automatic
    Baud rate:             9600 bps
    Dead Reckon Time:      30.0 sec
    NMEA Output Time:      1 sec
    Position Averaging:    On
    NMEA 2.30 Mode:        Off
    Power Save Mode:       Off (Normal Mode)
    PPS mode:              1 Hz
    PPS Length:            100 msec
    PPS Auto Off:          Off
    Phase Output Data:     Off
    Mask Low Speeds:       On
    DGPS Mode:             None
    Differential mode:     Automatic
    Earth datum index:     WGS84             

  7. In Garmin's main menu, select "Config" .. "Send Configuration to GPS (F9)" .
  8. Because the receiver seems to "forget" the configuration when not in use for a long time (this is at least what happened to mine), save the configuration as "SNSRCFG.cfg" in the directory where you installed the sensor configuration software.
  9. Exit Garmin's sensor configuration software.

With the sensor configuration listed above, the NMEA data burst will be short enough, and never collide with the PPS output (neither with the falling nor the rising edge). On the sample rate calibrator's "scope" window, the combined NMEA+PPS signal should look similar as the waveform below:

It should not look like this (with NMEA-burst and PPS-signal critically close, this was with a GPS 18 LVC firmware V3.30):

PPS and NMEA signal from GPS 18 LVC, old firmware (V3.30)

After turning off the 'GPGSA' sentence, and upgrading the device firmware to V3.70 (*), the time required to send the NMEA sequence was short enough, and (which is more important) the NMEA data burst was nicely centered between two sync pulses:

PPS and NMEA signal from GPS 18 LVC, newer firmware (V3.70)

(*) About the GPS 18 firmware update:
This was done using Garmin's SNSRCFG program, and firmware  from GPS18xPC_LVC_370.exe, as described on the Garmin website. The firmware's change history carried the note "Improved NMEA output timing stability" for V 3.70, which may explain the difference of the oscillograms shown above.

Interpreter functions for the GPS 'decoder' (NMEA parser)

The following functions in SL's command interpreter can be used to access the GPS decoder output:

Returns the last decoded date and time in Unix format (seconds since 1970-01-01 00:00:00 UTC).
Takes the 'age' of the decode into account, thus there is a fractional part (from 0 to 0.999 seconds).

Last modified (besides fixing a few typos) : 2020-12-09

Benötigen Sie eine deutsche Übersetzung ? Vielleicht hilft dieser Übersetzer - auch wenn das Resultat z.T. recht "drollig" ausfällt !

Avez-vous besoin d'une traduction en français ? Peut-être que ce traducteur vous aidera !