XPlot
Contents
- 1 XPlot : CObjEx
XPlot : CObjEx
A general class for plotting multiple graphs.
XPlot Construction
Initialize a new XPlot-instance to display 1 or more graphs. Returns the new object or an empty string. Information and error messages are written to the BSCRIPT CON
console.
XPlot rows=1 ; columns=1 ; title ; profile ; window ; owner
- rows
- The number of rows (default=
1
).
- columns
- The number of columns for each row (inrow0 inrow1 ...). The default is one column per row.
- title
- The display window title.
- profile
- The name of the graphics profile to use. A graphics profile is also known as a colour scheme.
- window
- The window position and size (in the format '
x y width height
').
- owner
- The id of an existing display item which should own this new window. See
NEW DISPLAY
for details.
A new XPlot
object if successful or an empty string.
The simplest way to create an XPlot
instance with one graph is as follows:
#xplot := xplot if '$#xplot[?]' != 'instance' em -1 ; Failed to create the xplot instance
XPlot Member Functions
The XPLOT
class has the following member functions. See CObjEx Member Functions for a list of functions implemented in the parent class.
AddPlot
The XPLOT
function AddPlot
is identical to the PLOT
function, except that it adds to an existing graph (in addition to or on top of the original plot). If no graph exists at the specified adr, then the call is passed to Plot
. It supports the following plot types: XYPLOT
, FUNCTION
and PARAMETER
. The parameters are identical to the PLOT
function.
Dialog
The function Dialog
can be used to show and hide a dialog in the XPlot
display.
inst Dialog cmd ; args
- cmd
- The following commands are available: New|Delete|Msg|On|Enabled|Off|Hidden. See below for details.
- args
- See below for details.
The ID of the current or new dialog item or an empty string.
New
Creates a new dialog item (deleting the old one first).
inst Dialog New ; pos
- pos
- Sets the position of the dialog within the display. The following values are supported:
ABOVE
|BELOW
|LEFT
|RIGHT
Delete
Removes the dialog from the display and deletes the dialog item.
inst Dialog Delete
Msg
Posts a message to the macro message queue. The format of the message is:
MENU
dialogItem msgId msgPar
Note that when the display is closed, this function is called to post the message MENU dialogItem CLOSE
to the dialog item.
inst Dialog Msg ; msgid msgpar
- msgid
- The message ID.
- msgpar
- The message parameters.
On|Off|Enabled|Disabled
Show the dialog and set it's position.
inst Dialog mode; pos
- mode
- Turns the dialog on or off and enables or disables it if it is on. The following keywords are supported:
ON|OFF|ENABLED|DISABLED
- pos
- Sets the position of the dialog within the display. The following values are supported:
ABOVE
|BELOW
|LEFT
|RIGHT
Display
Returns the ID of the display object associated with this XPLOT
instance.
inst display
Returns the display object of the XPLOT
instance.
End
Enters the message loop, waits until the user closes the plot display and then destroys itself.
Get
Retrieve an attribute from a specific graph.
xplot Get adr ; attribute
- adr
- The address of the display splitter (see member function
Graph
for detail).
- attribute
- The id of the requested attribute. The following values are supported:
CURSORPOSITION
- Returns the current cursor positions in the following format:i1 x1 y1 i2 x2 y2
- Note that
x1 <= x2
YDATA
- Returns the y data item.
XDATA
- Returns the x data item.
RANGE
- Returns the x axis and y axis range in the following format:xmin xmax ymin ymax
TYPE
- Returns the plot type (seePlot
for a list of available plot types).
GetFColors
The GetFColors
function returns a blank separated list of the function colors defined in the selected graphics profile.
xplot GetFColors
Returns a blank separated list of color keywords.
Graph
Returns the requested attribute attr of the graph identified by adr.
xplot Graph adr [; attr=GRAPH ]
- adr
- The id of a graph item, an
XGRAPH
instance or the 'row column
' address of a splitter in the display. Note that therow
andcolumn
indices are zero-based.
- attr
- The attribute to returned. The following values are allowed:
INSTANCE
- Return the id of theXGRAPH
instance associated with adr.
GRAPH
- Return the id of the graph object associated with adr. This is the default attribute.
ROW
- Return the row index of the splitter associated with adr.
COLUMN
- Return the column index of the splitter associated with adr.
Return values are selected by the argument attr. See the description of attr for details. If the address argument adr do not refer to a graph, XGRAPH
or splitter of the display, an empty string is returned.
Get the graph item id for the top left graph.
#graph := $#xplot graph 0 0
Legend
Display a graph legend. Use $#xplot LEGEND $#graph
to clear the legend.
xplot Legend graph ; unit ; x ; y ; w ; h ; color ; info ; text1 ; text2 ; textX
- graph
- The graph address (e.g. row and column index. See PLOT for detail).
- unit
- The unit for size and position values. The following values are supported:
real
- The real x/y values.
%
orpercent
- The percent of the graph's plot area.
- x, y
- The position of the upper right corner of the first legend line.
- w, h
- The width and height of one legend line.
- color
- The legend text color.
- info
- This flag selects the line attributes to be displayed. The following values are supported:
color
- The color.
all
- The color, style, width and symbol.
- textX
- The text for the legend for function X. If no text is supplied, the legend line is removed.This parameter can be either a string, or a simple table.
void
Plot
The XPlot
function Plot
can be used to plot a function in a graph. Currently, STx supports waveform , x/y (aka function and more specifically parameter), spectrogram and waterfall plots.
XYPLOT
Plot an x/y function graph.
xplot Plot adr ; XYPLOT ; y ; x ; title ; xr ; xu ; xt ; yr ; yu ; yt ; fstyles ; xlabtab ; ylabtab
- adr
- The address of the display splitter (see the member function GRAPH for details).
- y
- The y axis data (a vector or an array).
- x
- The data to be used for the x axis. This can be one of the following:
- A data vector with
y[!nrow]
values and 1 column.
*
- An asterisk. This is the default and means that the x axis uses the values0
through toy[!nrow]-1
.
- A blank separated list of values ('x1 x2' -> x[i] = x1+(x2-x1)/(y[!nrow]-1), i = 0..
y[!nrow]-1
).
- title
- The title to be displayed in this plot.
- xr
- The x axis display range. This can be one of the following values:
*
- An asterisk - an automatic scale is generated.
xmin xmax
- Two numerical values - the minimum and maximum values.
- xu
- The text describing the x axis unit (e.g.
seconds
). The default is an empty string.
- The
WAVEFORM
plot only allows the following values:SAMPLES
|MS
|S
. The default isS
.
- xt
- The title to be used for the x axis. The default is an empty string.
- yr
- The y axis display range. This can be one of the following:
*
- An asterisk - an automatic scale is generated.
ymin ymax
- Two numerical values - the minimum and maximum values.
- yu
- The text describing the y axis unit (e.g.
dB
).
- yt
- The title to be used for the y axis. The default is an empty string.
- fstyles
- An
fstyle
argument (seefstyle
for details) or a zero-based function line index as specified in a color scheme (see Color Schemes in the User Guide).
- xlabtab, ylabtab, zlabtab
- Extended tables containing the scale, grid and label definitions. For a description of the table format, please see the scale definition table for details.
Return 0
if successful.
Plot a simple x/y function.
#xplot := XPLOT 1 ; 1 ; XPLOT ; Default ; 0 0 400 400 $#xplot plot 0 ; XYPLOT; $(eval fill(10, 0, 1)) ; * ; xyplot ; * ; ; x-axis ; * ; ; y-axis
FUNCTION
Plot a function graph. Note that this is identical to an XYPLOT
.
xplot Plot adr ; FUNCTION ; y ; x ; title ; xr ; xu ; xt ; yr ; yu ; yt ; fstyles ; xlabtab ; ylabtab
See XYPLOT
for parameter descriptions.
Return 0
if successful.
PARAMETER
Plot a parameter graph. A parameter graph differs from a function graph because a parameter plot can have missing values - it does not necessarily have values for every point on the x axis.
xplot Plot adr ; parameter ; y ; title ; xr ; xu ; xt ; yr ; yu ; yt ; fstyles ; xlabtab ; ylabtab
See the xyplot
for parameter details.
Return 0
if successful.
SPECTROGRAM
Plot a spectrogram graph.
xplot plot adr ; spectrogram ; d ; y ; title ; xr ; xu ; xt ; yr ; yu ; yt ; zr ; xlabtab ; ylabtab
- d
- A data array containing one spectrum or function line per y row. Note that this parameter is specific to the
SPECTROGRAM
andWATERFALL
plots.
- y
- The y-scale data (frequency). This can be one of the following:
- 1)
vData
- A data vector withy[!ncol]
values and 1 column.
- 2) * - An asterisk:
y[i] = i
,i = 0..d[!ncol]-1
. This is the default.
- 3)
y1 y2
- Two blank separated values:y[i] = y1+i*(y2-y1)/(d[!ncol]-1)
,i = 0..d[!ncol]-1
.
- zr
- The z scale is a color scale. The following values are supported:
*
- An asterisk. The range is automatically generated.
zmin zmax
- Two numerical values specifying the minimum and maximum z axis values.
zdown
- A numerical value. The maximum z value is chosen automatically and the minimum value is calculated as follows:zmax-zdown
.
For all other parameters, see xyplot
for descriptions.
WATERFALL
Plot a waterfall graph.
xplot PLOT adr ; WATERFALL ; d ; x ; title ; xr ; xu ; xt ; yr ; yu ; yt ; zr ; zu ; zt ; xw ; yw ; n ; xlabtab ; ylabtab ; zlabtab
- d
- The data array (one spectrum or function-line / row).
- zr
- The z axis display range. The following values are supported:
*
- An asterisk. The range is automatically generated.
zmin zmax
- Two numerical values specifying the minimum and maximum z axis values.
- zu
- The text describing the z axis unit (e.g.
s
).
- zt
- The title to be used for the z axis. The default is an empty string.
- xw
- The relative width of the x scale. A value between
-1
and1
. The default is0.8
.
- yw
- The relative width of the y scale. A value between
-1
and1
. The default is0.8
.
- n
- The number of lines to be plotted. The default is
150
.
For all other parameters, see XYPLOT
for descriptions.
WAVEFORM
Plot a waveform graph. Note that the displayed wave item is automatically attached to the graph. This means, no explicit call to SetWave
is necessary.
xplot PLOT adr ; WAVEFORM ; wave ; title ; xu ; xt ; ymax ; yr ; yt ; fill
- wave
- A wave item id or an
XWAVE
instance
- xu
- The unit to use on the x axis. The following values:
SAMPLES
|MS
|S
. The default isS
.
- ymax
- The maximum waveform amplitude. This can be a value between 0 and ...
- yr
- The y axis display range. This can be any positive number. The default is
1
.
- fill
1
if the waveform envelope should be filled or0
.
For all other parameters, see XYPLOT
for descriptions.
TEXTBOX
Plot a graph containing text.
xplot PLOT adr ; TEXTBOX ; title ; color ; halign ; valign ; text
- title
- The graph title.
- color
- The text color. This can be an of the STx color arguments.
- halign
- The horizontal text alignment. This can be one of the following values:
CENTER
|LEFT
|RIGHT
- valign
- The vertical text alignment. This can be one of the following values:
CENTER
|TOP
|BOTTOM
- text
- The text to be displayed. This can be a simple table with an entry per line of text or a semi-colon separated list of text lines.
For all other parameters, see XYPLOT
for descriptions.
fstyle
The fstyle argument passed to the XPlot
functions Plot
and AddPlot
has the following syntax and components:
linestyle:
linecol:
printcol:
linewidth:
drawstyle:
drawsym:
ymiss
- linestyle
- Determines whether the function line is solid (
SOLID
), dotted (DOT
) or dashed (DASH
). The default value is taken from theXPLOT
color profile.
- linecol
- The colour to use for the function line on screen. This can be any STx colour keyword or RGB value. The default value is taken from the
XPLOT
color profile.
- printcol
- The colour to use for the function line when printing. See linecol for details. The default value is taken from the
XPLOT
color profile.
- linewidth
- The width of the function line. Possible values are
0
through to4
for lines with theSOLID
linestyle and0
or1
for lines with theDOT
orDASH
linestyle. The default value is taken from theXPLOT
color profile.
- drawstyle
- The style to use to draw the function. Each function point can be plotted separately (
POINTS
), a line can be drawn between each function point (LINES
), the area below the function can be filled with the linecol (AREA
), the function points can be joined by steps (STEPS
- note that this is only available for thePARAMETER
plot) or no points are plotted (NONE
- this is best used when a drawing symbol (drawsym) is defined). The default style isLINES
.
- drawsym
- The symbol to draw at each point. This can be used in conjunction with a drawing style (see drawstyle). The following keywords are supported:
NONE
|SQUARE
|TRIANGLE|CIRCLE|CROSS|DIAMOND
- The default style is
NONE
.
- ymiss
- The value to use for missing y values. If ymiss is not specified (empty) all values are displayed, otherwise all points where
y=
ymiss are not displayed. If ymiss is not empty and is not a number then ymiss is set to0
. If no ymiss is defined, no ymiss is used (this is the default).
Redraw
Redraw the selected graph. This is currently only implemented for the FUNCTION
(XYPLOT
) and PARAMETER
plots.
xplot REDRAW adr
- adr
- The address of the display splitter (see member function
Graph
for details).
Return 0 if successful.
ScaleOctave
Generate a logarithmic scale table for use with the Plot
or AddPlot
functions. This function can also be called statically.
xplot ScaleOctave df count ; fmax ; fmin
xplot ScaleOctave df count ; fmax ; fmin
xplot ScaleOctave vector ; fmax ; fmin
xplot ScaleOctave vector ; fmax ; fmin
- df
- The frequency resolution in Hz.
- count
- The number of frequency points.
- fmax
- The maximum frequency to be displayed.
- fmin
- The minimum frequency to be displayed.
- vector
- The scale range as a data vector.
The following string is returned:
xmin xmax xlabTab xdata
Where xmin
and xmax
are is the minimum and maximum of the logarithmic scale, xlabTab
is the scale definition table which you can then pass to a Plot
function and xdata
is the logarithmic frequency values vector. See the scale definition table description in the Command Reference for details of the table syntax.
Create a scale definition table for a logarithmic frequency axis with 2000 points at 10 Hz intervals and a maximum frequency of 10000 Hz.
readstr '$(xplot scaleOctave 10 2000; 10000)' #xmin #xmax #xlab #x
See also ScaleSteps.
ScaleLog10
Generate a logarithmic scale table for use with the Plot
or AddPlot
functions. This function can also be called statically.
xplot ScaleLog10 df count ; fmax ; fmin
xplot ScaleLog10 df count ; fmax ; fmin
xplot ScaleLog10 vector ; fmax ; fmin
xplot ScaleLog10 vector ; fmax ; fmin
- df
- The frequency resolution in Hz.
- count
- The number of frequency points.
- fmax
- The maximum frequency to be displayed.
- fmin
- The minimum frequency to be displayed.
- vector
- The scale range as a data vector.
The following string is returned:
xmin xmax xlabTab xdata
Where xmin
and xmax
are is the minimum and maximum of the logarithmic scale, xlabTab
is the scale definition table which you can then pass to a Plot
function and xdata
is the logarithmic frequency values vector. See the scale definition table description in the Command Reference for details of the table syntax.
See also ScaleSteps
and ScaleOctave
.
ScaleSteps
Generate a linear scale table for use with the Plot
or AddPlot
functions. This function can also be called statically, e.g. 'xplot ScaleSteps -70 -10 ; 10 ; 5 ; 5 ; 1 ; 1
'.
inst ScaleSteps min max ; labelDist ; majorGridDist ; majorTickDist ; minorGridDist ; minorTickDist
xplot ScaleSteps min max ; labelDist; majorGridDist; majorTickDist ; minorGridDist ; minorTickDist
inst ScaleSteps vector ; labelDist; majorGridDist; majorTickDist ; minorGridDist ; minorTickDist
xplot ScaleSteps vector ; labelDist; majorGridDist; majorTickDist ; minorGridDist ; minorTickDist
- min, max
- The scale range.
- vector
- The scale range as a data vector.
- labelDist
- The label distance in scale units.
- majorGridDist
- The distance of the major grid lines in scale units.
- majorTickDist
- The distance between major ticks in scale units.
- minorGridDist
- The distance of the minor grid lines in scale units.
- minorTickDist
- The distance between minor ticks in scale units.
The following string is returned:
min max labTab
Where min
and max
are is the computed or corrected scale range and labTab
is the scale definition table which you can then pass to a Plot
function. See the scale definition table description in the Command Reference for details of the table syntax.
Calculate the linear scale, grid and labels for an amplitude axis between -70 and -10 dB with labels every 10 dB, major grid lines and ticks every 5dB and minor grid lines and ticks every dB.
readstr '$($#xplot ScaleSteps -70 -10 ; 10 ; 5 ; 5 ; 1 ; 1)' #ymin #ymax #ylab
See also ScaleOctave
and ScaleLog10
.
Set
The Set
function sets the cursor mode and text attributes.
xplot Set [ graph|* ; ] attr args
- xgraph
- An xgraph instance on which to call the
Set
command. If no graph is specified or an asterisk, then theSet
command is carried out on all graphs.
- attr
- One of the following values:
cursormode
- turn cursors on and off and change the way they look.
xunit
- the name of the x-axis unit
yunit
- the name of the y-axis unit
xtext
- the description of the x-axis
ytext
- the description of the y-axis
title
- the graph's title
- args
- The value of args depends on attr.
- If attr is
cursormode
, then args is as follows:
mode|* type|* line|*
- Where mode is one of the following values:
on
- show the cursor
off
- hide the cursor
- Where type is one of the following values:
cross
|crosshair
|vbarcross
|harmonic
- And
line
is one of the following values:
off
|on
- If attr is not
cursormode
, then args is used as the text, unit or title.
No return value.
SetCallback
The callback function is called by the message handlers to process popup and context menu messages and hotkeys which are not used by XPLOT
or XGRAPH
. The following commands are used to call the callback function:
If called from an XGRAPH
message handler:
cbfunction xgraphinstance irow icol msgid msgpar
If called from the XPLOT
message handler:
cbfunction xplotinstance * * msgid msgpar
xplot SetCallback [ cbfunction ]
- cbfunction
- The name of the callback function or an empty string to remove a previous association.
No return value.
SetWave
Attach a signal to one graph or all graphs (see adr). If a wave item is attached to a graph, it can not be deleted before it is detached or the graph or XPLOT
instance is deleted.
xplot SetWave [ waveitem ]
xplot SetWave adr ; [ waveitem ]
- adr
- The address of the display splitter (see member function Graph for details). If this parameter is omitted, then the wave item is set for all graphs.
- waveitem
- A wave item id or an
XWAVE
instance (or empty to remove attachment).
Return 0
if successful.
Note that wave items can only be attached to graphs of type FUNCTION
, XYPLOT
, PARAMETER
, SPECTROGRAM
and WAVEFORM
.====XPlot Hotkeys====
The following hotkeys are implemented in the XPLOT
class:
C | Turn the cursors on and off. |
S | Change to the next cursor style. |
B | Turn cursor binding on and off. |
Ctrl+N | Bind the cursor to the next function. |
Ctrl+P | Bind the cursor to the previous function. |
R | Turn the cursor rubberline on and off. |
T | Turn the title on and off. |
X | Change to the next x-scale mode. |
Y | Change to the next y-scale mode. |
Z | Change to the next z-scale mode. |
Space | Open the setup dialog. |
P | Play the attached wave (between the cursors). |
Q | Play the attached wave (the whole signal). |
ESC | Stop playback. |
Ins | Show the selected metasegment's settings in a dialog or, if no metasegment is selected, show a dialog to create a new metasegment. |
Del | Delete the selected metasegments. |
Ctrl+Left Click | Move the legend to the clicked position. |
Shift+Left Click | Create a metasegment at the clicked position (show the 'Insert Metasegment' dialog). |
XPlot Examples
Simple XPLOT Example
The following example demonstrates simple XPLOT
usage.
[macro xplot_example_1] // // create display (and graph) // #xplot := xplot 2 ; 1 ; xplot ; default ; 100 100 800 800 if '$#xplot[?]' != 'instance' em -1 ; xplot creation failed ($emsg) // // plot graphs (including data generation) // #nValues := 100 $#xplot Plot 0 0 ; XYPLOT ; $(eval fill($#nValues,1,1)) ; * ; Graph Title ; * ; x unit ; x title ; * ; y unit ; y title ; solid:green::1 $#xplot Plot 1 0 ; SPECTROGRAM ; $(eval rand(1,100,100)) ; * ; Graph Title ; * ; x unit ; x title ; * ; y unit ; y title ; solid:green::1 // // clean up // // the clean up takes place automatically // when the plot window is closed exit
Plot rows of a matrix using XPLOT
The following example demonstrates how to plot the rows of a matrix using the XPLOT
class.
//{{3.9 6473}{2009.01.29 16.44.04} - automatically created version information - do not change or delete this line} [macro xplot_example_2] // // This row demonstrates how to plot each row of a matrix // // C.G. 29.1.2009 // // // create display (and graph) // #xplot := xplot 1 ; 1 ; xplot ; default ; 100 100 800 800 if '$#xplot[?]' != 'instance' em -1 ; xplot creation failed ($emsg) // // create a matrix and fill it with some meaningless data // #mat := new table * /Parameter * number:X:100 if '$#mat[?]' != table em -1 ; cannot create table ($emsg) for #i := 0 to $#i < 10 step #i := int $#i + 1 $#mat[$#i,*] := eval fill( 100, $#i+1, $#i+1 ) end // // plot each row of the matrix // for #i := int 0 to $#i < $#mat[!nrow] step #i := int $#i + 1 #x := eval $#mat[$#i,*] $#xplot AddPlot 0 0 ; XYPLOT ; $#x ; * ; row-by-row plot ; * ; x unit ; x title ; * ; y unit ; y title ; solid:green::1 end exit 1 int 0
Advanced XPLOT Example
This example not only demonstrates the use of the XPLOT
class, but also signal processing using the EVAL
function.
//================================================================================================= // // DSP Examples // // last update: Nov 17, 2007 (AN) // {{STX}} version: {{STX}} 3.8 Beta // // The examples in this file demonstrates how to ... // ... use the EVAL command for signal processing // ... use the class XWAVE to read a signal frame by frame // ... display spectrograms, waveforms and functions in XPLOT graphs // ... enable XPLOT to play signals // ... use the XPLOT callback function to implement simple user controls // ... set and get cursor attritbutes and positions of XPLOT graphs // ... add a legend to a XPLOT graph // ... use BUTIL MSGBOX for simple dialogs // ... use the CON object (class BScript) to display log. messages // ... use the CON object to save numeric tables to textfiles // ... simulate item messages using the message queue macro MSGQUEUE // ... implement and call local subroutines // //================================================================================================= //------------------------------------------------------------------------------------------------- // // DSPExAvrSpectrum Create a plot containing the average spectra of all segments selected // in the DataSet view. // //------------------------------------------------------------------------------------------------- [Macro DSPExAvrSpectrum #lfrm=100ms';'#sfrm=50%';'#wtyp=hamming';'#ascale=dB';'#fscale=Hz';'#amax=1';'#aref=1';'#] // arguments: #lfrm frame length, absolute time expression // #sfrm frame shift, relative time expression // #wtyp window type, {Hanning, Hamming, ...) // #fscale spectrogram frequency scale unit (Hz, kHz, Bark, Mel, ERB) // #amax calibration factor or CALSET to use a calibration set // #aref reference amplitude, ignored if #amax equals CALSET // set mode to macro name (see macro DSPExCallback) DSPExMode := set '$#mac' // get segments selected in the DataSet view #segments := dspexlib getsegments // create the result table (one spectrum per row) #asp := new table * * num:x:$#segments[] /p // segment analysis loop #nok := 0 // number of computed average spectra for #i := 0 to $#i < $#segments[] step #i := int $#i+1 // get next segment from segment list readtab $#segments $#i #aset';'#aseg';'#ach';'# con log process segment "set=$#aset, id=$#aseg, ch=$#ach" ($(int $#i+1) of $#segments[]) // create the wave object and initialize frame settings (mode "centered") // usage: XWAVE setref ; segmentid ; channel ; mode ; framelength ; frameshift ; ampmax ; ampref if $(#wave := xwave '$#aset;$#aseg;$#ach;1;$#lfrm;$#sfrm;$#amax;$#aref')[?] != instance then butil 'msgbox msg; create wave object for segment "$#aset/$#aseg,$#ach" failed; Error!' continue // set / check sampling rate else if '$#srate' == '' then #srate := $($#wave srate) else if $($#wave srate) != $#srate then butil 'msgbox msg; segment "$#aset/$#aseg,$#ach" - sampling rate mismatch; Error!' $#wave destroy // delete wave object continue end // compute the average spectrum if $(#tmp := dspexlib averagespectrum $#wave ; $#wtyp ; $#ascale)[?] != table then butil 'msgbox msg; compute average spectrum of segment "$#aset/$#aseg,$#ach" failed; Error!' $#wave destroy // delete wave object continue end $#asp[*,$#nok] := $#tmp // save the spectrum delete $#tmp // delete temp. buffer #legend := '$#legend $($#wave title);' // add segment to legend string $#wave destroy // delete wave object #nok := int $#nok+1 // increment result vector counter end // exit if no results are computed if $#nok < 1 exit // compute frequency scale vector, unit and frequency resolution readstr '$(dspexlib frequencyscale $#srate ; $#asp[!nrow] ; $#fscale)' #frq #funit #df // create and configure the plot object // usage: XPLOT rows ; cols0 cols1 .. ; windowtitle ; graphicprofile ; wx wy wwidth wheight #plot := xplot 1; 1; Average Spectrum; Rainbow; 0 0 1024 800 // plot all spectra and display the legend #title := format 'lfrm=%s, sfrm=%s, wtyp=%s, df=%.3fHz' '$#lfrm' '$#sfrm' '$#wtyp' $#df readstr '$(dspexlib amplitudescale $#ascale)' #ytext #yunit // usage: xplot PLOT row col; FUNCTION; ydata; xdata; title; xrange; xunit; xtext; yrange; yunit; yrange $#plot plot 0; function; $#asp; $#frq; $#title; ; $#funit; frequency; ; $#yunit ; $#ytext $#plot legend 0; %; 50; 95; 45; 5; black; color; $#legend $#plot set cursormode on crosshair // set cursor mode and style $#plot setcallback dspexcallback // assign callback function // wait until plot window is closed $#plot end // the xplot object is destroyed automatically when the window is closed // finished - cleanup and and exit delete $#asp $#frq $#segments // delete data items showLogOnExit := 0 // close the bscript log-window automatically exit //------------------------------------------------------------------------------------------------- // // DSPExSpectrogram Plot a spectrogram of all segments selected in the DataSet view. // For each segment one spectrogram window is displayed. The window // must be closed before the next segment is analysed. // //------------------------------------------------------------------------------------------------- [Macro DSPExSpectrogram #lfrm=40ms';'#sfrm=10%';'#wtyp=hamming';'#arange=50';'#fscale=Hz';'#amax=1';'#aref=1';'#] // arguments: #lfrm frame length, absolute time expression // #sfrm frame shift, relative time expression // #wtyp window type, {Hanning, Hamming) // #arange spectrogram display range in dB (max .. max-range) // #fscale spectrogram frequency scale unit (Hz, kHz, Bark, Mel, ERB) // #amax calibration factor or CALSET to use a calibration set // #aref reference amplitude, ignored if #amax equals CALSET // set mode variable to macro name (see macro DSPExCallback) DSPExMode := set '$#mac' // get segments selected in the DataSet view #segments := dspexlib getsegments // segment analysis loop for #i := 0 to $#i < $#segments[] && '$DSPExMode' != '' step #i := int $#i+1 // get next segment from segment list readtab $#segments $#i #aset';'#aseg';'#ach';'# // create the wave object and initialize frame settings (mode "centered") if $(#wave := xwave '$#aset;$#aseg;$#ach;1;$#lfrm;$#sfrm;$#amax;$#aref')[?] != instance then butil 'msgbox msg; create wave object for segment "$#aset ; $#aseg ; $#ach" failed; Error!' continue end // compute the spectrogram if $(#asp := dspexlib spectrogram $#wave ; $#wtyp ; log)[?] != table then butil 'msgbox msg; compute spectrogram of segment "$#aset ; $#aseg ; $#ach" failed; Error!' $#wave destroy continue end // compute frequency scale vector, unit and frequency resolution readstr '$(dspexlib frequencyscale $($#wave srate) ; $#asp[!ncol] ; $#fscale)' #frq #funit #df // create and configure the plot object #plot := xplot 2; 1 1; $($#wave title) quit = c-q, next = c-n; Rainbow; 0 0 1024 800 $($#plot display) height 3 1 /apply // set height of graphs // plot spectrogram and waveform #title := format 'lfrm=%s, sfrm=%s, wtyp=%s, arange=%s, amax=%.1fdB, df=%.3fHz' '$#lfrm' '$#sfrm' '$#wtyp' '$#arange' $(eval max($#asp)) $#df $#plot plot 0; spectrogram; $#asp; $#frq; $#title; $($#wave tbegin) $($#wave tend); s; time; ; $#funit; frequency; $#arange $#plot plot 1; waveform; $#wave; ; s; time; $($#wave amax); $($#wave amax); amplitude; 1 $#plot set cursormode on crosshair // set cursor mode and style $#plot setcallback dspexcallback // assign callback function // assign wave object to xplot graphs (for playback) $#plot setwave $#wave // wait until plot window is closed $#plot end // the xplot object is destroyed automatically when the window is closed // cleanup delete $#asp $#frq // delete data items $#wave destroy // delete wave object end // finished - cleanup and exit delete $#segments // delete segment table showLogOnExit := 0 // close the bscript log-window automatically exit //------------------------------------------------------------------------------------------------- // // DSPExCallback Callback function for XPLOT. // // arguments: // if called from xplotobject message handler -> 'CALLBACK xplotobject * * msgid msgpar' // if called from xgraphobject message handler -> 'CALLBACK xgraphobject row col msgid msgpar' // // Note: This macro uses the shell variable DSPEXMODE to check which macro has installed the // callback and to set return values. // //------------------------------------------------------------------------------------------------- [Macro DSPExCallback #obj #row #col #msgid #msgpar] // get xplot-object if called from a xgraph-object if '$#obj[!class]' == xgraph #obj := $#obj get xplot // message filter for keystroke messages // process Control-Q (QUIT) key if '$#msgid$#msgpar' == keyCQ then if $(butil msgbox yesno; Quit ?; $DSPExMode) == yes then // place the display-close message in the message queue to end the xplot message loop msgqueue 'display $($#obj display) close' // set mode variable to empty-string if C-Q key was pressed DSPExMode := '' end // process Control-C (COPY) and Control-S (SAVE) keys else if $(#i := keyword '$#msgid$#msgpar' keyCC keyCS) >= 0 then // get xgraph-object displayed in row 0 (later used to retrieve data) #obj := $#obj graph 0; instance // select the data to be saved and the save format #todo := butil msgbox userdefined Amp Frq+Amp Cancel;; $DSPExMode - $(word $#i 'Copy to Clipboard' 'Save to CSV-File') if $#todo == Amp then #table := eval $($#obj get ydata) // use eval to get a copy of y-data else if $#todo == Frq+Amp then if '$DSPExMode' == DSPExAvrSpectrum then #table := eval vmcol( $($#obj get xdata) , $($#obj get ydata) ) // merge x- and y-data into one table else #table := eval vmcol( $($#obj get xdata) , trn($($#obj get ydata)) ) // merge x- and transposed y-data into one table end end // copy / save if table exists if $#table[?] == table then // select target if $#i == 0 then #file := set clipboard // set target to "clipboard" for all copy_xxx functions else #file := butil filedialog save; Select Output File; ; CSV=CSV-File; TXT=Textfile // use filedialog to select the output file end // use the CON-object to copy/save table if '$#file' != '' con savedata text; $#table; $#file; 0; comma; dot delete $#table end // process Control-I (INFO) || Control-M (MAX-MEAN) keys else if $(#i := keyword '$#msgid$#msgpar' keyCI keyCM) >= 0 then // get xgraph-object displayed in row 0 #obj := $#obj graph 0;inst // save original graph title if '$GraphTitle' == '' GraphTitle := $#obj get title if $#i == 0 then // get and display cursor positions readstr '$($#obj get cursorposition)' #i1 #x1 #y1 #i2 #x2 #y2 # #text := format 'Index = %d .. %d, X = %g ... %g (%g), Y = %g ... %g (%g)' $#i1 $#i2 $#x1 $#x2 abs($#x1-$#x2) $#y1 $#y2 abs($#y1-$#y2) else // set cursor mode (on), style (crosshair), rubberline (off), bind-mode (off), bind-functionindex (0) $#obj set cursormode on crosshair off off 0 // get x- and y-data #x := $#obj get xdata #y := $#obj get ydata // find index of maximum y value #imax := eval imax($#y[*,0]) // compute mean of x and y #xavr := eval avr($#x) #yavr := eval avr($#y) // set cursor 1 to maximum and cursor 2 to mean $#obj set cursorpos 1 $#x[$#imax] $#y[$#imax] deselect $#obj set cursorpos 2 $#xavr $#yavr deselect // show maximum and mean in xgraph title #text := format 'Maximum( %g , %g ), Average( %g , %g )' $#x[$#imax] $#y[$#imax] $#xavr $#yavr end // show info in graph title $#obj set title $GraphTitle -- $#text end // note: the return value of the callback function is not used by the xplot/xgraph message handler exit //------------------------------------------------------------------------------------------------- // // DSPExLib Implements a set of signal processing functions which can be called with // "DSPLIBEXAMPLE functionname functionarguments". This call style is often // used to reduce the number of macros of a script or application. // // Functions: // // DSPEXLIB GETSEGMENTS // result: a list of all segments selected in the DataSet view stored in a simple // table (per line: 'setReference ; segmentId ; channelIndex') // note: this function shows an error message and terminates the caller if no segments // are selected // // DSPEXLIB AVERAGESPECTRUM wave ; wtyp ; atyp // wave prepared xwave object // wtyp type of window function: HANNING, HAMMING, KAISER, ... // atyp type of output spectrum: LOGARITHMIC (=DB), POWER, LINEAR (=AMPLITUDE) // result: an averaged fft spectrum in the selected format // // DSPEXLIB SPECTROGRAM wave ; wtyp ; atyp // wave prepared xwave object // wtyp type of window function: HANNING, HAMMING, KAISER, ... // atyp type of output spectrum: LOGARITHMIC (=DB), POWER, LINEAR (=AMPLITUDE) // or COMPLEX // result: a matrix of fft spectra in the selected format, one spectrum per line // // DSPEXLIB FREQUENCYSCALE sr ; n ; type // sr sampling rate in Hz // n number of spectrum bins (equally spaced in the Hz domain) // type type of frequency scale: HZ, KHZ, BARK, MEL, ERB // result: 'frq unit df'; frq is the frequency scale vector, unit is the frequency unit // name and df is the frequency scale step in Hz // // DSPEXLIB AMPLITUDESCALE type // type type of amplitude scale: LOGARITHMIC (=DB), POWER, LINEAR (=AMPLITUDE) // result: 'name unit df'; name and unit of amplitude scale // //------------------------------------------------------------------------------------------------- [Macro DSPExLib] // function call dispatching readvar #argv #fun #argv /d goto fun$#fun noFun noFun: // function not implemented // result: empty string // show an error message and exit con log '$#mac function "$#fun" not implemented' exit 1 set '' //------------------------------------------------------------------------------------------------- funGetSegments: // in: // out: segment_list_table //------------------------------------------------------------------------------------------------- // retrieve list of selected segments from the DataSet application #segments := datasetcmd getselected segments if '$#segments[?]' == table && '$#segments[]' > 0 exit 1 set $#segments butil msgbox msg ; no segments selected - select and try again; Error! if '$#segments[?]' == table delete $#segments exit 2 set '' // terminate this and the calling macro! //------------------------------------------------------------------------------------------------- funAverageSpectrum: // in: xwaveobject ; windowtype ; amplitudescale // out: averagespectrum_vector //------------------------------------------------------------------------------------------------- // parse arguments readvar #argv #wave';'#wtyp';'#atyp';'# // show init message con log $#mac $(upper '$#fun') - initializing // create window #w := gosub makewindow $($#wave framelength) $#wtyp // create result table #spg := new table * // compute averaged amplitude spectrum #n := $($#wave framecount) $#spg := eval cr2len ( fft ( $($#wave read) ?* $#w ) ) for #i := 1 to $#i < $#n step #i := int $#i+1 if $#i%10 == 0 con logext 0; $#mac $(upper '$#fun') - $#i of $#n frames processed $#spg := eval cr2len ( fft ( $($#wave read) ?* $#w ) ) + $#spg end $#spg := eval $#spg / $#n // convert to selected output spectrum type if $(#atyp := keyword '$#atyp' dB logarithmic power amplitude linear) < 2 then $#spg := eval lin2log($#spg , $($#wave aref), 20) else if $#atyp == 2 then $#spg := eval $#spg ?^ 2 end // show end message con logext 0; $#mac $(upper '$#fun') - finished ($#n spectra computed) // return averaged spectrum exit 1 set $#spg //------------------------------------------------------------------------------------------------- funSpectrogram: // in: xwaveobject ; windowtype ; amplitudescale // out: spectrogram_matrix //------------------------------------------------------------------------------------------------- // parse arguments readvar #argv #wave';'#wtyp';'#atyp';'# // show init message con log $#mac $(upper '$#fun') - initializing // create window #w := gosub makewindow $($#wave framelength) $#wtyp // check selected output spectrum type if $(#atyp := keyword '$#wtyp' dB logarithmic power amplitude linear complex) < 5 then // compute amplitude or power spectra // create result table (one spectrum per line) #spg := new table * * num:x:$(int $($#wave fftlength)/2 + 1) /p // compute amplitude spectra #n := $($#wave framecount) for #i := 0 to $#i < $#n step #i := int $#i+1 if $#i%10 == 0 con logext 0; $#mac $(upper '$#fun') - $#i of $#n frames processed $#spg[$#i,*] := eval cr2len ( fft ( $($#wave read) ?* $#w ) ) end // convert to selected output spectrum type if $(#atyp := keyword '$#atyp' dB logarithmic power amplitude linear) < 2 then $#spg := eval lin2log($#spg , $($#wave aref), 20) else if $#atyp == 2 then $#spg := eval $#spg ?^ 2 end else // compute complex spectra // create result table (one spectrum per line) #spg := new table * * num:x:$(int $($#wave fftlength) + 2) /p // compute complex spectra for #i := int $($#wave framecount) to $#i > 0 step #i := int $#i-1 if $#i%50 == 0 con logext 0; $#mac $(upper '$#fun') - $#i of $#n frames processed $#spg[$#i,*] := eval fft ( $($#wave read) ?* $#w ) end end // show end message con logext 0; $#mac $(upper '$#fun') - finished ($#n spectra computed) // return spectrogram matrix exit 1 set $#spg //------------------------------------------------------------------------------------------------- funFrequencyScale: // in: samplingrate ; spectrumbins ; frequencyscale // out: frequencyscale_vector frequencyscale_unit frequency_resolution_Hz //------------------------------------------------------------------------------------------------- // parse arguments readvar #argv #sr';'#n';'#unit';'# // generate frequency scale equally spaced in Hz #frq := new table * // dummy table to make frq-scale permanent $#frq := eval fill($#n, 0, $(#df := eval $#sr / 2 / ($#n - 1)) ) // convert to selected scale if $(#unit := keyword '$#unit' Hz kHz Bark Mel ERB) < 0 #unit := 0 if $(#unit := word $#unit Hz kHz Bark Mel ERB) == kHz then $#frq := eval $#frq / 1000 else if $#unit != Hz then $#frq := eval hz2$#unit($#frq) end // return scale settings exit 1 set '$#frq $#unit $#df' //------------------------------------------------------------------------------------------------- funAmplitudeScale: // in: amplitudescale // out: amplitudescale_text amplitudescale_unit //------------------------------------------------------------------------------------------------- // parse arguments readvar #argv #unit';'# // get text and unit of amplitude scale if $(#i := keyword '$#unit' dB logarithmic power amplitude linear) < 2 #i := 0 #unit := word $#i dB dB - - - #text := word $#i amplitude amplitude power amplitude amplitude exit 1 set '$#text $#unit' // // local subroutines // makeWindow: // GOSUB MAKEWINDOW windowlength windowtype -> windowvector readvar #argv #wlen #wtyp # #list := hanning hamming blackman kaiser bartlett taprect nuttall flattop gauss if $(#wtyp := keyword '$#wtyp' $#list) < 0 #wtyp := 0 exit 1 eval window($#wtyp, $#wlen, 1) * 2 / $#wlen