Spectrum Lab's Interpreter

Contents of this chapter:

There is a simple command interpreter in the program, used to define periodic, scheduled, and conditional actions; macro buttons and other purposes. Multiple commands can be entered in a single line using the ':'-character as separator (like in the old BASIC programming language). An example:

capture:export.start("NewFile01.txt"):export.write(";-- new file segment --")

For testing purposes, you can enter and run commands in the periodic actions dialog, or you can enter them in the command window

Functions: A function is a subroutine which usually requires some kind of input (passed in an argument list), and it always returns a value to the caller. Function names are written in lower case to tell them from variable names (do not mix functions with procedures. A procedure does not return a value). Functions and numeric expressions can also be entered in the watch window where they will be periodically evaluated and displayed.

Note: Most (but not all) interpreter commands and -functions can be invoked from a remote PC through SpecLab's integrated HTTP server, using a piece of Java script which you can find in the examples in the "server_pages" directory.

See also: Spectrum Lab's main index .


Command and Function overview

Overview of procedures (a procedure does not return a value. The difference between "procedure" and "command" is academic, both are used here for the same thing) . Note: All these procedures can also be invoked by other programs(!) using a message-based protocol, or through the DOS command line (even if the program is already running).

Overview of interpreter functions (a function returns a value to the caller). Often used for the text-based export function.

See also:

back to top


Numeric expressions

The numeric interpreter described here is used to evaluate 'formulas' wherever needed in the program. The main usage is the versatile text file export function.

The basic function is similar to a programmable ("basic") pocket calculator, expressions are evaluated from left to right (with different operator priorities: multiply before add etc).

Operators:

The operands in a numeric expression can be simple numbers, variables, or function calls.

Numeric expressions can be used as argument for some other commands (they can be "nested"). Example:
1/(2*pi*sqrt(1.22e-3*1114e-12))

Some more examples can be found in the description of the print command.

Note for German users / Hinweis für deutsche Anwender: Spectrum Lab verwendet - wie die meisten Programmiersprachen - das Komma als Aufzählungszeichen. Als Dezimaltrenner dient immer der international übliche Dezimalpunkt, nicht das verfluchte Dezimalkomma ! Es ist daher nicht nötig, in irgendwelchen Windoze-Systemeinstellungen herumzuwühlen um die "deutschen Besonderheiten" wie das Dezimalkomma abzuschalten.

See also: overwiev , functions, procedures , string expressions .


Variables

An interpreter variable can accept a single numeric value, or a single string. It begins to exist by assigning a value to it, there is no need to declare a variable (in contrast to the "C" programming language). Variables were initially used to define conditional actions, etc, but they may be used in a script-like language one day too.

The name of a variable must begin with an upper- or lower case letter, the next characters may include decimals (0..9) and the underscore. Nothing else !
Furthermore, be careful not to use built-in keywords as variable names. This will usually result in a syntax error or similar.

Some examples for variables:

CurrentPeak = peak_a(300, 3000)
A=A+1

InfoString = "Oh, well"
InfoString = InfoString + " .. so what"

TimeString = str("hh:mm:ss",now)

Variables can help to reduce the CPU load. For example, if you need the result of a complicated function (or subroutine) in many different places, it is more efficient to calculate the function only once and store the result in a variable, instead of computing the same result over and over again. A good place to do this is in the conditional action table. Since all variables in SpecLab are "global" (up to now), you can read the value from the variable wherever you need it, for example in the watch window, on a programmable button, etc.

Note: You can even access those variables from a Java script running in your web browser ! The integrated HTTP server allows any application, even on a remote PC, to communicate with SpecLab - which includes read- and write access to the interpreter variables.


Functions

See also: Overview of interpreter functions, overview of interpreter procedures .

now, time (functions)

These functions return date- and time as a floating point value (which can be converted into a string if required)

 The format of the values returned by these functions is defined as:

"seconds elapsed since Jan 1 1970, 00:00:00 UTC".
(Note: because it is a floating point value, the resuliton is much higher than a second).

To display time and/or date, use the str-function which can turn numeric values into strings . Example:

print("Date="+str("DD-MM-YYYY",now), "Time="+str("hh:mm:ss",now) )

See also:  function overwiev , spectrum.time .


Spectrum Analyser / Channel Numbers for some numeric functions

Most of the calculation functions explained in the following chapters accept an options "spectrum analyser channel number".

Valid spectrum analyser/channel numbers are:
#1 = first channel of the first spectrum analyser ("main spectrum analyser / spectrogram")
#2 = second channel of the first spectrum analyser ("main spectrum analyser / spectrogram")
#3 = first channel of the second spectrum analyser ("second spectrogram window")
#4 = reserved for the second channel of the second spectrum analyser (future plan !)
#LTA1 = long-term average of the first channel in the first analyser (if enabled)

If specified at all, the spectrum analyser/channel number must be the first parameter in a function's argument list. If it is not specified (which will often be the case), the first channel of the first analyser will be used by default. This applies to the following interpreter functions:

See also: peak detection functions,  noise calculation functions, spectrum average functions,  interpreter function overwiev .


Peak detection functions

If no channel number is specified, the peak detecting functions operate on the 'latest' result from Spectrum Lab's main spectrum analyser, first channel (= "#1"). Optionally,  a spectrum analyser / channel number can be specified. Examples::

The relation between input voltage into the A/D-converter and the FFT output value in decibel (dB) is explained here.

back to the  interpreter function overwiev

Frequency interpolation (for peak-detecting functions and cursor display)

To increase the frequency-resolution of the peak detecting functions to a fraction of an FFT bin width, an interpolation algorithm is used as explained below. It is based on a recipe suggested by DF6NM.

First, the FFT bin with the strongest magnitude (dB) is searched in the frequency range of interest. Next, from the magnitude of the strongest FFT bin and it's strongest neighbour, the exact frequency and and amplitude of the bin can be interpolated. This is possible, because the curvature of the fourier-transform near the peak is known - it only depends on the windowing function which was applied to the samples in the time domain, before the FFT. This only works if the carrier is stable and quite strong, but under such circumstances the result (the frequency accuracy) can be stunning:

It is often possible to measure the frequency of a carrier with a resolution of a few milli-Hertz, though the FFT bin width is in the Hz-region ! This way, you can measure frequencies quickly and accurately, which would otherwise take an endless gate-time (consider this: a classic "frequency counter" needs a tate time of 1000 seconds to measure a signal with a 1-mHz-resolution, which doesn't mean accuracy).

The frequency-interpolation subroutine is internally used by the peak-detection functions and for the readout-cursor on the main spectrum display.


Average Functions

Syntax:

The avrg functions work like this (in detail):

  1. Add the values (converted into POWERs) from all FFT bins which belong to the specified frequency range.
  2. Divide the sum by the number of FFT bins.
  3. Convert the result back into decibels, it the FFT used logarithmic scales.
  4. (only for avrg_n)
    Add or subtract a few decibels, depending on the current FFT settings. The normalization procedure is explained here in detail.

The avrg function can be used to determine the relative strength of (relatively) broad-band signals with known modulation patterns. For example, there may be a digital emission on 137.0kHz with a bandwidth of 100Hz. Assuming you have an LF receiver tuned in USB to 135.0kHz, use an AF frequency range of 1950.0 to 2050.0 Hz for the avrg function. This will give an estimate for the signal strength of that particular station.

To measure the signal-to-noise ratio of broadband signals, use the avrg-function in combination with the noise-function. (Use a LARGER frequency range for the noise function, at least 5 times the bandwidth used for "avrg").

The relation between input voltage into the A/D-converter and the FFT output value in decibel (dB) is explained here.

Optionally,  a spectrum analyser / channel number can be specified if you don't want to use the 1st channel of the 1st spectrum analyser. Example: avrg(#2,200,1000)for the 2nd channel of the 1st spectrum analyser.

See also:  effective voltage, SINAD,   function overwiev


Calculation of an "effective" voltage

Syntax:
veff(freq1, freq2)

This function returns the effective voltage in a given frequency range, normalised to 1 Volt for 100% SINE WAVE at the ADC's input, based on the latest spectrum calculated in the main spectrum analyser.

Notes:

See also:  "average" functions,  SINAD,   function overwiev


Calculation of the standard deviation ("sigma") in a part of the spectrum

For some 'special' applications (or for debugging..), a function was implemented to calculate the standard deviation (greek lower case sigma; german: Standardabweichung).

Syntax:
sinad(#channel, frequ1, frequ2 )

The returned value is the standard deviation (sigma) in the spectrum of the specified channel, between freq1 and freq2.

The frequency range must be specified because a part of the spectrum will often be unusable, maybe due to filtering, 1/f-noise, or other reasons which only you (and not SL) will know.

See also: function overwiev 


SINAD calculation

The sinad function calculates the ratio betwen SIgnal, Noise And Distortion to noise and distortion as a logarithmic value. It provides a quantitative measurement for the quality of an audio signal.

Syntax:
sinad(#channel, center_freq, notch_width, filter_model)

where all these values are optional:

Examples:

sinad(#1,1000,30,1)
Calculates the SINAD value in dB using the C-MESSAGE filter.
Notch width = 30 Hz is OK for FM receivers, but may be a bit too narrow for SSB receivers with coarse tuning steps or drifting VFO's.
sinad(#1,1000,200,2)
Calculates the SINAD value in dB using the CCITT ("p53") filter.
Notch width = 200 Hz should be ok for VHF SSB receivers even if there is some VFO drift.

Notes:

See also:  more about SINAD measurements,  average functions,  effective voltage,   function overwiev


Noise calculation functions

The noise functions calculate the noise level in a specified frequency range.

 The definition of noise levels is not easy. Here is the basic algorithm of the 'noise' function:

  1. An array of amplitudes (usually dB values) from the last FFT calculation is sorted into order of increasing amplitude.
  2. The amplitude of the lower quartile value (for example bin number 256 in a sorted set of 1024 points) PLUS 3dB is then returned as an estimate of the mean noise level.

This technique automatically throws away very high values (strong signals) that would otherwise affect the result.

So the value returned by the noise()-function is very different from the average value for the same frequency range (there is one special case where both should be equal, see the notes below).

Optionally,  a spectrum analyser / channel number can be specified if you don't want to use the 1st channel of the 1st spectrum analyser. Example: noise_n(#2,200,1000) to retrieve the noise level from the 2nd channel of the 1st analyser, between 200 and 1000 Hz.

Notes:

The relation between input voltage into the A/D-converter and the FFT output value in decibel (dB) is explained here.

See also: average functions, sigma( ),  SINAD,  function overwiev


Noise normalised to 1Hz bandwidth

The 'noise' level (and average value of noisy signals) calculated from a spectrum with the "noise()"-function is influenced by some FFT settings (FFT size, window function) and the soundcards sampling rate. But for some applications it is desirable to have 'noise level' readings which do not depend on the FFT settings and the sample rate.

Spectrum Lab offers the possibility to 'normalize' the result of the noise() and avrg()-functions (then called noise_n and avrg_n) to make them independent from the current FFT settings. To be precise: make them independent from the effective FFT bin width, measured in Hz.

The noise (and average) value can be normalised for a receiver bandwidth of 1 Hz, no matter if the currently used FFT bin width is 6 Hz or 0.0001 Hz or whatever. You can consider an FFT bin as a single receiver for a very small frequency range, and all power in that frequency range is dumped into the bin. The bin actually will contains an ENERGY because it collects the power over a certain time, but don't care about that now. The FFT bin with is called "frequency resolution" somewhere else in this manual.

Due to the nature of noise, if the bin width is halved (for example by doubling the number of bins), the noise(-power) collected in every single bin is reduced by 3 dB. One may call this phenomenon "FFT gain".

The formula used by Spectrum Lab to "normalize" a noise value (in decibels) is this:

db_norm = db_calculated - 10 * log10( fft_bin_width_hz )

Example:
FFT bin width (~"RX bandwidth") = 0.5 Hz,
measured noise (db_calculated) = -80dB.

The noise measured with an RX-bandwidth of 0.5 Hz must be lower than it would be with 1.0 Hz bandwith. The normalised "noise" value is:

db_norm = -80[dB] - 10*log10( 0.5Hz / 1.0Hz)

= -76.99 dB -77 dB , which -as expected- is 3dB MORE than the non-normalized value noise.


Notes:

See also:   average-function ,   noise-function , veff-function , dB-function ,  function overwiev


Decibel conversions and the '0-dB-point'

Usually, values from the ADC (analog/digital converter) are fed into an FFT (fast fourier transform) which generates an amplitude spectrum at first. The next (optional) stage of processing turns the amplitudes into decibels.

This page contains some background information how the dB conversion works, and how it can be modified.

Logarithmic scales and the 'reference level'

If a pure sine wave A*sin(omega*t) is fed into the ADC's input, one of the FFT bins will contain the peak value which is proportional to the input voltage.

The values from all FFT bins are then converted into decibel value. One of them contains the peak value Pdb:

Pdb = 20 * log(A / R). (simplified, if the peak if in the "center" of an FFT bin)

The value R is an "internal Reference parameter". It depends on the soundcard and on the FFT size, but don't worry about it (the program cares for the FFT size). The maximum value of PdB is 0 dB. Above this point, the ADC gets overloaded by a single sine wave.

For this reason, all internally stored dB values (and those returned by some interpreter functions) are negative (they can go down to -90dB .. -140dB, depending on the FFT size and decimation).

For display, you can add an offset to the internally stored dB value. If you prefer to see positive dB values on the screen, or want to 'calibrate' the dB values to have absolute values on the screen, read the next chapter.

User-defineable 'dB-display-offset'

This 'offset' will be added to the result of the 'PdB' formula explained above. By default, the offset is 0.0 dB and you will only see negative dB values on the SpecLab screen. Set the offset to +90 if you like to see mostly positive values on the screen (and to be compatible with old versions of Spectrum Lab before V1.65). If you have a calibrated AF source, you can set the offset so that 1 Microvolt will be displayed as '0.0 dB'.

You may even enter a numeric expression ("formula") as the 'dB-offset'. This formula will be evaluated once per second (or less frequent), but only after the calculation of an FFT.

You can use this for a programmed AGC (etc..), using the noise- or avrg-function. Note that the functions "noise", "avrg", "peak" etc are not affected by the 'dB-display-offset', but they can be used to affect the 'dB-display-offset' !

An example: You want the noise level in the AF range from 500Hz to 2.5kHz to appear at the '0dB' line in the spectrum plot. Enter the following expression as "Offset" (Menu Options..Display Settings):

Set the range for the 'amplitude scale' to -10..+80dB for this example, because most of the displayed dB values will now be positive.

See also:  "dB"-function ,  function overwiev


String expressions

Some interpreter commands (like export.start or wave.record) require strings in the argument list. These strings can be simple constants, like

Note that a string constant should be embedded in double-quotes as shown, otherwise white spaces in a string would be impossible. You can also 'add' strings like this:

The second example is a bit tricky. The 'str'-function formats a numeric value (here: the value of 'time') into a string, using the specified format string (here: 'hh_mm'). The result of the str-function will be a string, for example 16:45 if the last spectrum was calculated at 16:45 o'clock. Three strings are added, the result is a filename containing the time, like:

More possibilities of the format-string are explained in the next chapter. Without the format string, the 'str'-function generates the shortest possible decimal representation for the numeric argument, truncated (to a few decimal places after the comma). Example: If N were 123.456, str(N) would return "123.5".

If you want to use an evaluated string expression (=the 'result' of the evaluation of a string expression) where the program expects a simple text string, use the '@' character before the string expression. Example: In the "watch window", you want to use the same format string as in the "export definition table". The program expects a string literal (a "simple text" there), so instead of typing:
export.format[1]  (in the "watch list", "format" column)
you must use
@export.format[1]
which forces the interpreter to evaluate this string expression. Complicated, isn't it ? Without this, the interpreter would think "export.format[1]" is the format string itself, instead of the evaluated result which may be "####0.0##" (as defined in the "export" table). However, these special cases are quite rare. Using the leading '@' character is -at the moment- only required in
if a cell does not contain the string itself but a reference to a string defined in another table or cell.

Backslash sequences (in string expressions)

The backslash character has a special function (like in the "C" programming language). The reason for this is manifold, so -for a start- here only some basic facts which you should observe when using strings with backslashed in them - like in filenames !

One of the reasons why we need backslash sequences in string expressions is this: Because the double quote is used as delimiter for string literals (in many programming languages), we must replace the double quote character with the backslash sequence \" (backslash-doublequote). So here are the basic rules for backslash-characters in string expressions. More info can be found in textbooks about the "C" programming language !

See also:   formatting options , numeric expressions , interpreter commands .


Format String for numeric values

The following formatting options are available:

Numerical Values
# = placeholder for an optional digit in a number
0 = placeholder for a non-optional digit in a number
. = placeholder for the decimal point in a number
(german users: please forget the decimal comma !)
Time+Date Values
YY = Year, two digits only
YYYY = Year, four digits
MM = Month, two digits
MMM = Month-NAME (Jan, Feb, Mar, Apr, ...)
DD = Day of month, two digits
hh = hour of day, two digits
mm = minute, two digits
ss = second, two digits
ss.s = seconds, three digits (two places before and one place after the comma)

Notes:

Examples for valid format strings:

###0.##

0000.00

hh:mm

DD.MM.YYYY hh:mm:ss

YYYY-MM-DD hh:mm:ss

 

back to the overwiev


print (procedure)

Prints some numeric or string values into one line of the interpreter's message window, or (one fine day) into a communication channel. Used for debugging.


Syntax:
print( Argument1, Argument2, ...)

The arguments can be either numeric or string expressions. All arguments must be separated by comma or semicolon (not colon.. the colon character is used to separate commands - remember the old BASIC programming language) . A comma between two arguments inserts an additional space, a semicolon does not.
Like in the "C"-programming language, the print function replaces certain backslash sequences into their equivalent ASCII control characters as explained here. These sequences are: /n = new line,  /r = carriage return, /t = tab, // = single backslash, /" = double quote character.

Examples:

  1. print("date="+str("DD-MM-YYYY",now), "time="+str("hh:mm:ss",now) )
  2. print(1/3):print("OK?")
  3. print(str("0.#################",1/3),".. 17 decimal places !")
  4. print("fo=",1/(2*pi*sqrt(1.22e-3*1114e-12)),"Hz")
  5. print(val("2001-11-05 22:00:00","YYYY-MM-DD hh:mm:ss"))

Resulting text for the above examples:

  1. date=17-09-2001 time=19:01:01.
  2. 0.333
    OK?
  3. 0.33333333333333332 .. 17 decimal places !
  4. fo= 136520.422 Hz
  5. 1004997600 (which is the number of seconds passed since Jan 1, 1970, 00:00:00)

Note: Very similar like print are the commands fprint and fwrite, which write lines of text into a file. See file commands.

See also: Numeric expressions, string expressions, command overwiev


str (function)

Turns a numeric value into a string.

Syntax:
str( <format-string>, <numeric expression> )

Examples:

  1. print("date="+str("DD-MM-YYYY",now), "time="+str("hh:mm:ss",now) )
  2. export.start(str("YYMMDDhhmm",now)+".txt")

See also: Numeric expressions, string expressions, backslash sequences, command overwiev, val-function, format string .


fopen, fwrite, fprint, fclose (file access routines)

fopen( <filename> [,<open-mode>] )

Opens or creates a disk file. The optional open-mode is  a single-letter-parameter with one of the following values:

r
Open for reading only. Does not make sense at the moment because there are no file-read-routines yet !
w
Create for writing. If a file by that name already exists, it will be overwritten.
a
Append; open for writing at end-of-file or create for writing if the file does not exist.

The default open-mode is "w". If only the filename is specified, an old (existing) file will be overwritten (truncated). Also the line printer can be opened for plain text output with this routine, use fopen("LPT1") for this purpose.

Since 2006-03, a third argument can be specified for shared files. The syntax is

fopen( <filename>, <open-mode>, <share-mode> ) then. The share mode is a combination of flags which are explained in the Win32 programmer's reference for the CreateFile function, parameter dwShareMode. According to that source, the share modes can be combined if necessary:

d
Subsequent open operations on the file will succeed only if delete access is requested (FILE_SHARE_DELETE).
r
Subsequent open operations on the file will succeed only if read access is requested (FILE_SHARE_READ).
w
Subsequent open operations on the file will succeed only if write access is requested (FILE_SHARE_WRITE).

Example for a file created for writing, granting read-access for other applications:

fopen("c:\\share_test.txt",w,r) : REM Write new file, share for Read-access
fprint("Try to open the file with a text editor now,")
fprint("BEFORE closing it here, to see the effect of the read-share flag")
fclose

Note: Like in the "C" programming language, special care must be taken with the backslash ! For example, a double backslash in the sourcecode will be replaced with a single backslash in the filename. More details in the chapter about backslash sequences .

fclose

Closes a file (a disk file, a printer, or something similar). Never forget !

fprint( Argument1, Argument2, ...) (abbreviated "fp")
fwrite( Argument1, Argument2, ...)
   (abbreviated "fw")

These commands do almost the same as "print", exept that they write into disk files instead of the command interpreter's output window.
The fprint command appends a carriage return and a new line character after the text, fwrite does not. Use fwrite if many values must be written into a single line of the output file. Control codes can be placed in the output as in the "C" programming language, like \r for carriage return and \n for new line (may be nice to have if you want to send a formfeed to the printer).

If you need more than one file opened at the same time, append digits (0..9) directly after the function names, like this:
fopen0("file_one.txt")
fopen1("file_two.txt")
fopen3("LPT1")
fp0("Hi, I am the first file.")
fp1("This is the second file!")
fp2("and this is the printer")
fclose0
fclose1
fclose2

An example for the file commands can be found under "screen capture extension macros" (which was the first application using file commands, but they can be used for many other purposes).

See also: command overwiev, str-function, print command  format string .


send (command)

Sends a text message (string) to another window. Internally, a WM_COPYDATA message is used for this purpose.

Syntax:
send(<recipient>,<message>)
Example:
send("RdfCalc","set brg1x="+str(azim(23350,23450)) )

Sends the measured azimuth angle of a signal near 23.4 kHz to a recipient called "RdfCalc" (which is a utility for radio-direction calculation).
The recipient is the so-called class name of the main window of another program running on the same computer. Sending a message to a program running on a remote computer is not possible with this command.

For programmers: This command sends a string to the module "CL" (=command line interpreter inside the receiving application), the command-ID is "EC" (execute command, don't send a response).

Note: Since version 2.7, it is possible to send messages between two instances of SpecLab running on the same PC. Use recipient "SpecLab1" for the first instance, and "SpecLab2" for the second instance, etc. The old class name "TSpectrumLab" remains for backward compatibility, but it only works for the first instance.

See also: Communication with external programs, command overwiev


val (function)

Converts a string into a numeric value.

Syntax:
val( <string>, <format-string> )
val( <string>, <format-string> )

Examples:

  1. val("1.2345")
  2. val("2001-11-05 22:00:00","YYYY-MM-DD hh:mm:ss")

The first example returns the value 1.2345 as a floating point value. Instead of the string constant (or literal), also string expressions can be used here (which makes more sense).
The second example returns the value 1004997600 (which is the number of seconds passed between Jan 1, 1970, 00:00:00 and Nov 5, 2001, 22:00:00).

See also: Numeric expressions, string expressions, command overwiev, str-function,  format string .


min, max  (functions)

These functions return the minimum or maximum value from a number of arguments. Examples:

min(3,2,1,4)
returns 1
max(3,2,1,4)
returns 4
max( peak_a(200,500),  peak_a(900,1000) )
returns the "highest peak amplitude" in the audio frequency ranges from 200..500 Hz and 900..1000 Hz.

See also: functions, numeric expressions .


click, sound (procedures)

Can both produce some kind of acoustic signal with the PC's internal speaker (not the soundcard!).
Syntax:

click  
with no parameters produces the standard "Message Beep" using a windows API routine (so chances are good this works on EVERY machine).
You can use this for debugging: Insert it whereever you like to check if the program does what you expect. For example, with this command you can *hear* if data is being written to a file from the export function, without having the PC's monitor on.
sound( <frequency> [,<duration>] )
Expects the frequency in Hertz as parameter. The tone will be generated until it is turned off by another sound-command or by "click". To turn the sound off, use "sound(0)". Because this procedure uses direct port accesses, it may cause problems under future Windows versions, but at the moment it runs properly under Win95 / Win98, Win NT, Win ME and Win 2000 (thanks to A.Weitzman's SmallPort utility). The sound command doesn't work if the SmallPort driver is disabled in the system settings !
The optional <duration> parameter may be used to turn the tone off after a certain time, <duration> is a value in seconds.
This command was intended for debugging, with the ability to distinguish between different "messages" (unlike the click-command).
Examples:
sound(1000)  -> 1 kHz tone from the PC speaker, lasting endless (until the next "sound" command)
sound(0)     -> turns the sound from the PC speaker off
sound(2000,3)-> 2kHz tone from the PC speaker for 3 seconds

back to the command verwiev


wave (procedure)

A group of commands for recording and playing audio streams as wave files.

See also : Wave file analysis (interactive)

back to the overwiev


cfg.xxx (configuration parameters, accessable like variables)

Offer some access to spectrum Lab's configuration data. Most of them are only implemented for "internal" use (fellow programmers will find them in a different file). You read the values from your own program using a simple message-based communication protocol.

back to the overwiev


water.xxx (waterfall display parameters, accessable like variables)

Control the waterfall display. Currently implemented functions and parameters are:

water.avrg_cnt, water.avrg_max
Returns the current / the maximum number of FFTs which were added to the average of a single waterfall line. Details about spectrum averaging can be found here.
water.f_min, water.f_max
Sets or retrieves the visible frequency range for the waterfall (and possibly the spectrum graph which uses the same range).
To modify these values (in Hertz), use a formal assignment like these:
water.f_min=600 : water.f_max=900
water.brt
Waterfall brightness value.
water.ctr
Waterfall contrast value.
water.clear
Command to clears the waterfall screen and the spectrogram buffer.
water.f_offset
Access the "frequency offset" for the spectrum display and the waterfall. Unlike the following function, this one does not affect f_min and f_max.
water.f_offset2
Almost the same as above, but write-access to this value changes the min- and max- frequencies too. In effect, the frequency scale will be redrawn, but a 1-kHz-AUDIO frequency will remain at the same position in the waterfall screen (and the spectrum graph, if visible).
On read, water.f_offset2 returns the same result as water.f_offset .
water.count
Returns the number of waterfall lines which have been calculated since the program was started. Can be used in the Conditional Actions to do something "special" as soon as a certain amount of waterfall lines (alias FFT's) have been calculated. Note: If the waterfall is turned off, its counter won't count ! (joking aside, FFTs may be calculated for the spectrum graph even if the waterfall display is turned off). See also: water.line_nr .
water.sweeps
Returns the number of completed waterfall sweeps (scans across the waterfall screen) since the program was started. Can be used in conditional actions, similar like the function 'water.count' . By comparing the value returned by this function with the previous value, you can -for example- upload a capture of the waterfall to a website whenever a new screen is finished.
Note: If the waterfall runs in multi-strip mode, the value of water.sweeps will be incremented whenever a new strip is finished. Doing a capture precisely at that time would contain an empty strip, because in the moment your application recognizes that 'water.sweeps' was incremented, the display routine has already scrolled the waterfall screen by one strip. To circumvent this, use the function 'water.line_nr' - see below.
water.line_nr
Returns the waterfall's current line number (within the current sweep or strip). This number counts DOWN from the maximum to zero. When water.line_nr reaches zero, a new sweep begins, and the line number wraps from zero to water.line_max (see below). You can use this function to test if a sweep of the waterfall is "almost" complete (in that case, water.line_nr will be very low. If the waterfall scrolls slowly, you may be able to catch the time when water.line_nr is exactly zero. Otherwise, don't expect to see every step in water.line_nr ... in fact, if the waterfall scroll interval is less than 50 ms, two or even more pixel lines are painted in a single over to speed things up.
water.lines
Returns the number of lines in one complete sweep of the waterfall. Depending on the orientation of the waterfall, this is the height (if the frequency scale is horizontal) , or the width (if the frequency scale is vertical) of the waterfall bitmap in pixels.

<there may be other interpreter commands to control the waterfall which are not mentioned here>

back to the overwiev


spa.xxx (commands and functions for "special" control of the spectrum analysers)

For some 'special' applications, some parameters of the spectrum analysers can be controlled "directly" through the interpreter, without affecting the configuration data. There are at least the following functions... some of them may be used as commands to assign new values to these parameters, but most are "read-only" (so their value cannot be changed by a formal assignment):

If no index in square brackets after the keyword "spa" is given, the above commands apply to the first channel of the first spectrum analyser. Otherwise, use...

Notes:

See also: spectrum.xxx, fft.xxx, overview of interpreter-commands and -functions .


spectrum.xxx (commands to process the current spectrum)

Procedures and Functions to control or export the latest calculated spectrum (= "Result of the latest FFT calculation for the spectrum analyser"). To control the spectrum analyser (which produces these spectra), use the spa-commands/functions. Some additional, FFT-related commands are described further below.

Implemented up to now:

spectrum.time
returns the time of the calculation of the lastest spectrum, using the UNIX time format (number of seconds passed since 1970-01-01 00:00:00). The result may be slightly different from "now". See notes below.
spectrum.pause
reads or sets the "pause"-flag of the spectrum analyzer. You can use this to pause/restart the analyzer on a programmable event, for example a button to toggle the pause flag. pause=0 means "not paused", pause=1 means "paused". Example for toggling the pause flag:
spectrum.pause = !spectrum.pause
spectrum.save(#<channel_nr>,  "filename.txt" )
saves the current spectrum ("FFT results") as a textfile. Includes a header and -after the header- one line of text for every FFT bin.
Example:
spectrum.save(#1, "my_spectrum.txt")
saves the latest spectrum for the first channel of the first spectrum analyser as a textfile.
Note: The file format is the same as for the spectrum reference curve. But there may be some command-options in future to leave some parts of the spectrum away to save disk space. In addition to this command, SpecLab allows to export the FFTs for the main spectrum analyser periodically, using the FFT export function described here.
spectrum.print( [#<channel_nr>,]  [f=<frequency of interest>,]  <string> )
Prints a label (or a small text message) into the spectrogram, which is scrolled together with the lines of the waterfall. Can be used to mark special "points of interest" in a waterfall, either manually or automated. If <channel_nr> is not specified, the command prints into both channels of the first spectrum analyzer, #1 prints into the first (left) channel, #2 prints into the second (right) channel. If f=<frequency_of_interest> is  not specified, the label will appear on the left (or lower) edge of the spectrogram, as close to "0 Hz" as possible.
Examples:
sp.print("Meteor Nr "+str(MsBurst)):MsBurst:=MsBurst+1
The example could be used in one of the programmable buttons, or in the automated spectrum alert function.

sp.print(f=peak_f(500,2000),"* Peak "+str("hh:mm:ss",sp.time))
This example prints a label into the spectrogram close to a certain frequency, here: near the "peak" between 500 and 2000 Hz.

Notes:

See also: command verwiev,   fft.xxx,   export functions, spa.xxx (spectrum analyser),  channel numbers for the spectrum analyser


fft.xxx (commands to export FFTs from the spectrum analyser, etc)

Functions to control the export of FFTs as text files (one FFT per line in the file), in addition to the options on the FFT export panel.

To control the


exec (procedure)

Formats:

This interpreter command is used to launch or run an other application. In its simplest form, you just have to supply the name of the program which shall be run. Example:

Usually, the interpreter will continue to operate while the operating system is still initializing the other program. Most windows applications will never terminate themselves, while many 'console' applications will be ready sooner or later.

(future plans: The numeric parameters <options> and <waitflags> can let the interpreter wait until the called program is ready.)

Many console applications (and DOS commands) need a list of arguments passed in a command line. These arguments follow as <argument1>, <argument2> after the name of the executable program. You may also pass all arguments in a single string. Example:

will do quite the same as

exec("cw.exe", "alarm", "alarm")

Notes on exec:

About space characters in file- or directory names:

Avoid spaces in directory- and filenames wherever possible ! They only leads to problems, because you need additional quotes to get the syntax for the command line arguments right. Because someone (!) once decided to allow spaces in filename, it gets terribly complicated now. If you don't use spaces in any of your data directories, skip this paragraphs. If you do, the punishment follows because you have to read on !
Because the double quote is used as delimiter for string literals (in many programming languages), we must replace the double quote character with the backslash sequence \" in into a double quote character. So here are the rules for embedding spaces in filenames (pathnames) without breaking up a single argument:

Phew ! Time to present an example to make this a bit clearer. Lets assume you have an executable file named "cw.exe" in the directory c:\test\ugly space\, which you want to launch via SpecLab's exec command, and passing the string "hello" to it in the command line. You may be tempted to write something like..

exec("c:\\test\\ugly space\\cw.exe hello") <<<< deliberately wrong

Thanks to Mr B.G. this is totally legal under windoze (it was not under pure DOS). But after parsing the string expression, we'll find THREE arguments (separated by space characters): c:\test\ugly, separation, space\cw.exe, separation, and hello . To concatenate the path+name of the executable into a single parameter for the command line, double quotes must be used. But double quotes are already used here as delimiters for the string constant in Spectrum Lab's primitive interpreter language. We cannot simply add more double-quote characters like this:

exec(""c:\\test\\ugly space\\cw.exe" hello") <<<< also deliberately wrong

because this doesn't make sense to the interpreter in Spectrum Lab. The interpreter would see an empty string enclosed with double-quotes, and something strange which is not a string constant after that. The correct way to achieve what we want is:

exec("\"c:\\test\\ugly space\\cw.exe\" hello")

Note that the very first and the very last double-quote character in the above example is the string limiter, which indicates a "string constant". The string expression in this interpreter-command-line will be translated to:

"c:\test\ugly space\cw.exe" hello

before passing it a windows API function named CreateProcess (all we need to know here is CreateProcess can be used to launch a program from another program, and that's what SpecLab's exec command is used for).

Note: Your browser may be irritated by all those backslashes and double-quotes above. You will find a few examples for the exec-function in the file testcmd.txt which was used for testing purposes when developing Spectrum Lab.

back to the overwiev


export (procedures and functions)

A group of commands for exporting data as text files. Intended to be used for monitoring applications, but can also be used elsewhere.
Note: The export file may contain whatever you like. It is very flexible but not easy to understand how it works for occasional use. For many applications, the settings "export control window" has all you need. 

Interpreter commands to control the user-defined text export function (not for the FFT-export) are:

The following export- functions return numeric or string values:

See also: saving a single spectrum in a textfile,  command overwiev , function overview, string expressions .


Accessing Configuration Parameters with the interpreter

Many components of the configuration data can be accessed from the interpreter. From a programmer's point of view, all configuration data are organized in a large structure (here: "cfg"), some of its components can be read and modified. Examples:

print( cfg.Wat1ClContrast )
shows the current "color contrast" setting for the first waterfall display
cfg.Wat1ClContrast = 127
sets the "color contrast" setting for the first waterfall display. Note: This is a formal assignment.

An overview of all accessable components of the configuration can be found here ("subject to change").


PTT Control Functions/Commands

When Spectrum Lab controls the PTT function of a transmitter (usually from the "digimode terminal"), there is no need to use the following interpreter commands. But in some cases, someone else (a human operator, or another program) controls the transmitter and SpecLab shall behave differently depending on the current transmitter status. The following functions can be used to sense the current transmitter status. They will often be used for event definitions in the conditional action table.

The following functions poll inputs on the serial port :

With the interpreter, you can also switch some of the output signals on the serial port. Be careful not to interfere with the signals controlled automatically from the digimode terminal. The following commands can be used to set output signals on the serial port. If <new_state> is zero (= "FALSE"), an output will be cleared (negative voltage on the serial port); if <new_value> is non-zero (="TRUE"), the output will be set (typically +10 to 12 V on the serial port).

The functions ptt_port.rts, ptt_port.dtr, and ptt_port.txd can also be used to retrieve the last state written to the port. For example, the following command line toggles the state of the RTS output ( "!" = negation ) :

ptt_port.rts = ! ptt_port.rts // toggle RTS

See also: command overwiev , function overview , numeric expressions ,  configuration of the PTT control port  .


Remote Control Functions/Commands

For some special application (shortwave propagation studies), it was necessary to control an HF receiver through the serial port. First, Icom's CI-V protocol was implemented (by the time you read this, other manufacturer's protocols may be supported too).

Please note that before using these interpreter functions and -commands, the serial port must be configured to match the settings of your receiver (like baudrate, serial data format, "address" of the radio, etc). This can be done in Spectrum Lab's main menu, select "Options".."System Settings".."Tx/Rx Interface settings".

The prefix "rct" means "remote control". The following functions / commands are implemented (possibly more) :

Hint: ICOM radios autonomously report the new frequency through the serial port when the VFO knob is turned. Spectrum Lab receives and parses such messages. So the frequency can be displayed without much overhead on one of the programmable buttons of the main window, using the following interpreter code ("string expression" for the  button text):

str("###0.000 kHz",1e-3*rct.freq)

A simple example for this can be found in the settings file "CI_V_tst.usr", and a more sophisticated example in the Conditional Action file "ncdxf_4u1un_tracker.txt" (which periodically switches the frequency of a receiver, like shortwave beacons operated by the Northern California DX Foundation).


The Command Window

The command window can be used to enter and execute any interpreter command.

Enter a few lines with interpreter commands in the upper part of the window. To execute a single command line, press the F2 key. The command in that line wil be executed, and after that the cursor jumps into the next line to be executed (kind of "single-step" operation).

Alternatively, press F9 to run the whole "batch" of commands.

The lower part of the window shows the output from the print command. Can be used for testing purposes, as a simple calculator, or as a logging display (if you use the print command in event-driven subroutines like periodic actions, scheduled actions, etc.

See also: command overwiev , function overview .


See also:  Spectrum Lab's main index .

Last changes (YYYY-MM-DD):

2005-10-26: Documented the new  "spa"-functions (spectrum analyser control functions)
2006-09-16: Added a few new commands, and the option to run multiple commands like a "batch" (in the command window)