APRL commands
Contents
Introduction
This is a complete list of the Tcl commands defined by APRL
to create signal processing objects. They all take the form:
opcode name [-opt val [-opt2 val ...]]
where opcode is the object-creating command, name is
the name of the new signal processing object, and opt and
val are pairs of configuration options.
Creating an object has several effects. Firstly, a new signal processing
module is created and added to the global scheduler (which must have been
created already with the scheduler command). Secondly, if that
module generates a signal output (i.e. unless it is a `sink' object),
it registers that output stream against name in the source
lookup table. It also updates a global record of the most-recently
created stream source which is used for default inputs to modules for
which no explicit input is specified.
Thirdly, it creates a new Tcl command, name which can be
used for further interaction with that object. (This is modeled
after the `object-oriented' approach recommended by Dr. Ousterhout in
his book on Tcl). The new command can be used to change the configuration
options, for instance:
name config -input source
will change the input stream to the object name to come from the
object source. In further keeping with the Tk style of object-
orientation, the "cget" command is also specified. Thus, to query
the name of the current input source for a particular object,
one enters:
name cget -input
.. which would be expected to return source if the
preceding command had been executed.
Sources
Source objects introduce a new signal stream, thus, every chain of
signal processing objects must start with a source object. Currently,
this stream may originate from the live audio input (e.g. a microphone),
from a sound file stored on disk, or from a spontaneous noise source.
Source objects
- audiosrc name [-sampleRate rate] [-bufferTime time] [-scale k]
Creates a new source called name, reading from the
live audio input. rate specifies the sampling rate, in Hz,
at which to configure the analogue-to-digital converters (for the
SGIs, this must be one of 8000, 11025, 16000, 22050, 24000, 32000
44100 or 48000. The default is 8000).
time specifies the buffer size to allocate
for input sound. This must be at least as large as the
scheduler step time, but can be
larger to allow the processing temporarily to fall behind real-time
without losing samples. Output samples are scaled by factor k
(default: 1.0).
Special commands
- name filled
Returns the number of filled locations in the input audio
buffer. This can be between zero (if the buffer has just
been read and no new samples have been clocked in) to
time x rate, the total buffer size,
which indicates any new incoming samples are being lost
(dropped). This can be a useful parameter to monitor
to see when the processing network is overloading the
real-time capabilities of the machine.
- soundfsrc name [-filename file] [-bufferTime time] [-loop loopit] [-scale k]
Creates a new source called name, fetching data from
a soundfile called file. At the moment, only AIFF/C
soundfiles are supported (the default format on SGIs).
time is the size (in seconds) of the internal buffer which
must be as large as the largest scheduler step to be used
(default: 0.5 s). If loopit is nonzero, the sound
will read in continuously, seeking back to the beginning
each time the end is reached. Output samples are scaled by
factor k (default: 1.0).
[Note to DAn and Eric : sources cannot query their antecedants to
get a buffersize, which is why we have to specify it. But really
all objects should be querying the scheduler, not their inputs.
When we fix this, there will be no point in -bufferTime for
soundfsrc. It's still valuable for latency control in audiosrc,
though.]
- randsrc name [-sampleRate rate] [-bufferTime time] [-scale k]
Creates a new source whose output is unit-magnitude normally-
distributed white noise. rate and time as for
audiosrc, except that rate can take any value.
Output samples are scaled by factor k (default: 1.0).
[DevNote: per eric's suggestion, we should add more controls,
such as distribution type and gain. In fact, we need to
add more gain controls - maybe it should be a common option
for all sources, though probably not all objects.]
Common source commands
All source objects accept the following commands.
- name more
Returns 1 if there is more data to be had from this source, or
0 if the source has run out of data. At present, the only
situation when it returns zero is when a soundfsrc
reaches the end of its input file.
- name sampleRate
Returns the sample rate (in Hz) for that source. Normally this
will have been specified when the object was created, but not
for soundfsrcs.
- name time
Returns the time in seconds corresponding to the most recent
sample emitted by the source. Useful for synchronizing time
scale labels etc.
- name value
Returns the most recent output value of the source. Note that
this will just be the final value in the most recently computed
block (whose size is determined by the scheduler's
timestep parameter); it is not possible to read arbitrary values
of the output stream using this command.
Sinks
Sinks are processing objects that take a single input stream.
A pure sink does not generate any output stream, thus its name
does not refer to any data source (and cannot be used as an input).
Processing chains, being data-flow, can end anywhere, but a
chain that leads to a sink isn't going any further (although other
objects may connect to the same stream that the sink is using as
input, and take it somewhere else). Currently sinks take a stream
and write it to real-time output, save it to a soundfile, or
display it on the screen.
Sink objects
- audiosink name
Create an object that will feed its input to the digital-to-analogue
converters of the machine for real-time sound output. The sampling
rate of its input must match one of the supported system rates
(see audiosrc).
Special commands
- name filled
Returns the number of filled locations in the input audio
buffer. This can be between zero (if the buffer has just
been read and no new samples have been clocked in) to
time x rate, the total buffer size,
which indicates any new incoming samples are being lost
(dropped). This can be a useful parameter to monitor
to see when the processing network is overloading the
real-time capabilities of the machine.
- soundfsink name -filename file
Create a soundfile called file (which is required -
there is no default) and write whatever data comes in
the input out to that file. Note: In order to write a
valid header, the soundfile writing module must know when
the sound is 'finished'. This happens at the moment
when the object is destroyed, which I think you can only
do by defining a new command with the same name.
Special commands
- name close
Close the output file. You must do this
before exiting; unfortunately, tcl does not go round
destroying all the created commands before exiting,
so unless you close, the header never gets updated and
you have an invalid output soundfile. Hopefully, we'll
find a way to fix this (a la 'atexit') in the future.
- wavesink name [-offset ofs] [-scale k] [-buflen buf] [-linewidth w]
This command is a little different from the other signal processing
objects because it actually creates a Tk widget in which it
displays the waveform of the stream it accepts. As such, its
name must conform to the dot-separated window path
conventions of Tk etc. buf specifies how many samples
of the past are displayed (default: 200). k and
ofs control the scaling of the data : each sample is
first multiplied by the scale, then has the offset added;
the display's vertical axis is from -1 to +1, so the scaling
must bring the samples within that range to be visible.
w is the size in pixels of the pen used to draw the
lines, for a `chunkier' display.
Common sink configuration options
Pipe objects
A pipe is, both notionally and in terms of its implementation, the combination
of a sink (input) and a source (output), presumably with some processing
inbetween. As such, they inherit the configuration options and commands
of sources and sinks as described above.
Objects
- bpfilter name [-centerFreq freq] [-Qfactor Q]
Create a band-pass filter centered at freq (default: 1000 Hz)
with a center-frequency-to-bandwidth ratio of Q (default:
4.0). Thus a high-Q
filter has a rather narrow bandwidth, a more strongly `resonant'
filter. The filters are implemented as two coincident pairs of poles,
plus zeros at dc and the Nyquist rate. The gain is normalized to
be unity at the center frequency.
Special commands
- name config -centerFreq freq
This construct allows you to change the filter characteristics
dynamically.
This actually generates a new set of coefficients while leaving the
state vector as it is, so there may be glitches as the filter
changes, but otherwise it's safe. You can change the Q too.
- lpfilter name [-cutoffFreq freq] [-Qfactor Q]
Create a low-pass filter. Currently this is a very simple
affair with two real poles. This gives a rather smooth low-pass
characteristic, but doesn't actually eliminate any components;
they are just progessively attenuated at higher frequencies.
The smoothness is notionally related to freq (default:
100 Hz), which
can be changed dynamically as for bpfilter.
The Q parameter (default: 4.0) doesn't do anything at
the moment.
- hpfilter name [-cutoffFreq freq] [-Qfactor Q]
Create a high-pass filter. Currently this is a crude arrangement
of one zero at d.c. and a pair of conjugate poles at the specified
center frequency freq (default: 100 Hz), whose modulus
is approximately set to counteract the pole at d.c.
The cutoff can be changed dynamically as for
bpfilter.
The Q parameter (default: 4.0) doesn't do anything at
the moment.
- thresh name [-reference val]
Apply a simple hard threshold to the input. Incoming samples
greater than val (default: 1.0) cause an output of
1.0, otherwise the output is 0.
- nthresh name [-reference val]
As thresh, except the output is 0.0 if the
input exceeds val, and 1.0 otherwise, i.e. it is the
logical `not' of thresh.
- dB name [-reference val]
Convert the input linear intensity value to deciBels, i.e.
20 log10(input). The input is scaled so that an input of
val (default: 1.0) gives an output of 0 dB.
- rms name [-sampleRate rate]
Converts the input signal to a new signal with a new sampling
rate of rate by finding the rms value of the input
over windows large enough to make sure no samples are missed
in the resampling. This is intended to convert from
audio-sampling-rate signals such as filter outputs into
slower, energy contours which contain all the necessary
information for subsequent processing. The rms (root-mean-square)
calculation is actually done over a window twice the length of
the output sample period, scaled by a Hanning (raised cosine)
weighting window. Thus rms includes a certain amount of
smoothing too.
- delay name [-delayTime time]
The output of the delay element is the same as its input time
seconds earlier (default: 0.0). We might provide a different
way to get this directly from the data streams (since they all
incorporate a fair chunk of history), but this is an elegant way
to get the same thing.
- eventer name [-holdoffTime htime] [-pulseTime ptime] [-command cmd]
This is a very important command. It is basically like a thresholder,
in that its output is zero if the input is less than or equal to
zero, but changes to 1.0 when the input goes above zero. However,
this transition causes a 'triggering' which has two effects.
Firstly, the output will remain at 1.0 for a fixed period of time,
ptime (default: 0.0). Moreover, if there are more
positive-going zero-crossings in the interim, the output will
stay at 1.0 until there has not been a recognized zero-crossing
for ptime. However, a trigger edge that occurs within
htime (default: 0) of a recognized edge is ignored.
Setting htime larger than ptime guarantees that
each output pulse will be exactly ptime long.
Finally, when the output changes from 0 to 1, it also executes
the Tcl command formed by cmd time,
where cmd is specified by the user (default: none) and
time is the time in seconds of that edge. This mechanism
provides the critical interface between continuous, data-flow
signal processing, and discrete, event-driven operations.
The remaining pipes are not yet implemented. The underlying C++ is
written and tested, however.
- decimer name [-factor n]
Reduce the sampling rate of the input to be a factor of n
lower (default: 1, i.e. no change) by discarding extra samples.
n must be an integer.
- linterper name [-factor n]
Increase the sampling rate of the input by a factor n,
(default: 1) using linear interpolation to generate the new in-between
samples. Currently, n must be an integer, although
this should be fixed to allow any factor.
- ptrack name [-sampleRate srate]
Bill Gardner's pitch tracker - takes an audio signal in
one side and returns an estimate of the fundamental pitch
(in Hz) out the other. The latest estimate of the fundamental
frequency is sampled at srate (default: 0, which
copies the input rate as a special case).
ptrack has several obscure undocumented
configuration controls which are liable to change,
so I won't describe them.
Common pipe configuration options
- name config -input source
As for sinks.
Common pipe commands
The other commands accepted by pipe objects all refer to the output part
of the pipe, which behaves like any other data stream source.
Combiners
Combiners take two inputs to generate a single output. (The
second input is specified by the -in2 option, see configuration
options below). Common
examples are the dyadic functions of algebra. Since there are so many
of these, it was worth making them into a separate type, rather than
trying to generalize pipes to multiple inputs.
Although not currently supported, the intention is to allow both inputs
to a combiner to be data sources, literal constants or Tcl variables.
It would even be feasible to allow combiners to combine inputs with
different sampling rates - probably by linearly interpolating the slower
of the two. At the moment, APRL bails unceremoniously if you try to
connect inputs of different sampling rates to the same combiner.
Combiner objects
- adder name [-scale1 k1] [-scale2 k2]
The output is the sum of the two inputs, where the data from the
primary input is multiplied by k1 and the second input is
scaled by k2 (both default to 1.0).
- multer name [-scale1 k1] [-scale2 k2]
The output is the product of the two inputs, where the data from the
primary input is multiplied by k1 and the second input is
scaled by k2 (both default to 1.0).
Common combiner configuration options
- name config -input source
As for sinks.
- name config -in2 source
Specifies the second input to the dyadic function.
[DevNote: we want eventually to be able to accept constant
expressions and tcl expressions in this field or an equivalent.
At present, the underlying DataCombiner class does not know how
to combine a stream with a constant, though it shouldn't be too
hard. It would also be nice to be able to combine streams of
different sampling rates by silently interpolating the slower.]
Common combiner commands
The other commands accepted by combiner objects all refer to the output part
of the pipe, which behaves like any other data stream source.
Display commands
See also the wavesink object.
Objects
- needle name [-damping d] [-clipcolor ccol]
[-scale k] [-offset ofs] [-value val]
[-clipval clip]
This is a Tk display object which imitates a VU meter. It would
be called 'vumeter', but DAn got there with his row of LEDs first.
The value val, after being scaled by k and then
having ofs added to it, is treated as a force applied
to the needle of the meter; that is, if val is greater than
the current position, the needle accelerates upward at a rate
proportional to the difference. The needle's velocity is damped
by d every iteration: config -damping 1 means
no damping; config -damping 0 means the needle won't
move. There is a colored light to
indicate a value greater than the value of clipval;
the color of this light can be changed with clipcolor.
The needle 'pegs' at the extrema, 0 and 1.
- timeline name [-minVal min] [-maxVal max] [-isLog log]
This isn't a signal processing object at all, it's just a regular
Tk widget that displays a graticule and labels it with numbers.
It's useful for creating time axis labels, however, which is
why we provide it. In your main scheduler step loop, you can
update the timeline widgets to display up to the very latest
time, as read from a source time command. The timeline
will extend from min to max times. Setting the
log flag will make it a logarithmic axis, less obviously
useful.
- vumeter name [-orient HorV] [-value val] [-scale k] [-offset ofs] [-cells nc] [-ngreen ng] [-nyellow ny] [-greencolor gcol] [-yellowcolor ycol] [-redcolor rcol] [-framewidth fw]
This is a simple scalar value display that imitates the array of
LEDs often used to indicate the level on a hi-fi unit. The array
of nc elements will be arranged in a horizontal or vertical
line, according to the value of HorV (default: "horizontal").
The value val, after being scaled by k then having
ofs added to it, determines the proportion of the cells
that are visible - when the result of this calculation is 1.0, all
the cells are drawn. The first ng cells are drawn in
gcol (default: "green"), the next ny in ycol
(default: "yellow") and the remainder in rcol (default:
"red"). The spacing between the elements is fw pixels
wide, drawn in the -foreground color.
Other commands
The scheduler
Before definining any signal processing objects, it is necessary to
define a scheduler object. All the signal processing objects are
registered with the scheduler, which then arranges to call them in
the right order.
The scheduler is also created as a new Tcl `object' command, so it
is possible to have more than one scheduler in existence; however,
we haven't thought of any good uses for this, so it is not fully
supported (you can't specify to which scheduler a given object belongs).
The scheduler object is created by the following command:
scheduler sched [-timestep step] [-nowtime time] [-command cmd] [-docmd do]
The new scheduler sched will attempt to compute step
second's worth of data at each invocation (default 0.1). It will start at
time time, in case there are sources (such as perhaps a future
version of soundfsrc) that respond to the absolute value of the
current time.
If cmd is set to a string and do is non-zero (it is zero
by default), then
cmd will be evaluated by the tcl interpreter after each
update of the signal processing network in response to a step
command. The default value is:
after 10 { %s step }
which causes the scheduler to run autonomously once do is set.
In the command string, %s is replaced by the name of the
scheduler (as in the default string), and %t is replaced by
the time in seconds up to which the signal processing network has
just been completed. Other
commands (such as updating timelines or other screen elements) can
be usefully included in the command string.
Specific commands
sched step
causes the scheduler to calculate another block of time, update its
idea of nowtime, and execute the command string if
the docmd option is set.
Go on to the C Code Page .
Go back to the APRL Page .
DAn Ellis <dpwe@media.mit.edu>
MIT Media Lab Perceptual Computing
$Header: /ti/http/projects/aprl/RCS/commands.html,v 1.8 1996/02/07 00:17:55 dpwe Exp $