^0

cCompress -- compresses or expands input values according
to a ratio expressed by the other control inputs.

		│<---------- value to process
		│	│<------ numerator of ratio
		│	│	│<-- denominator of ratio (0 will be
		│	│	│	 converted to 1)
		│	│	│
	┌───┴───┴───┴───────────────────┐
	│	cCompress					│
	└───┬───────────────────────────┘
		│
		│<---------- processed value (compressed or expanded)

This mod simply multiplies input #1 by input #2, then
divides the result by input #3. {TN: Operations are carried
out in long (32 bit) arithmetic.} It is thus possible to
compress or expand the input value by fractional amounts.

^1

cConst -- delivers a constant value determined at edit
time

	┌───────────────────────────────┐
	│	cConst						│
	└───┬───────────────────────────┘
		│
		│<--- constant (established at edit time)

An unconnected control input will always deliver the
constant zero.	If any other unchanging value is desired,
use cConst instead.

^2

cDisp -- display the input value in the scrolling window
defined at edit time in decimal and hexadecimal form. The
input value is then delivered unchanged.

		│<--- value to display
		│
	┌───┴───────────────────────────┐
	│	cDisp						│
	└───┬───────────────────────────┘
		│
		│<--- value (unchanged)

^3

cGraph -- display the input value in the scrolling window
defined at edit time in graphic (piano roll) form. The
input value is then delivered unchanged.

		│<--- value to display
		│
	┌───┴───────────────────────────┐
	│	cGraph						│
	└───┬───────────────────────────┘
		│
		│<--- value (unchanged)

When creating the window at edit time, you specify the
minimum and maximum values that this window should display.
Those values then represent the extreme left and right
edges of the window, and all values to be displayed are
scaled accordingly.

^4

cNegate -- negates a control value

		│<--- value to negate
		│
	┌───┴───────────────────────────┐
	│	cNegate 					│
	└───┬───────────────────────────┘
		│
		│<--- negated value

Example: If control input #1 is 64, cNegate will deliver a
value of -64. Zero will be passed unchanged. Due to
limitations inherent in digital arithmetic, -32768 will
also be passed unchanged.

^5

cChange -- pulse when control value changes

		│<--- value to test
		│
	┌───┴───────────────────────────┐
	│	cChange 					│
	└───┬───────────────────────────┘
		│
		│<--- 1 if input has changed, else 0

This mod is useful in situations where a single, momentary
pulse is desired, such as for controlling gates or resetting
clocks.

^6

cKey -- allows you to define two computer keys with
associated values.	Whenever one of those keys is struck,
its associated value is added to the incoming control
value.

		│<--- value to modify
		│
	┌───┴───────────────────────────┐
	│	cKey						│
	└───┬───────────────────────────┘
		│
		│<--- modified value

Usually, the two computer keyboard keys are assigned to
complement each other -- such as (left arrow)/(right arrow)
being assigned -12/+12 respectively. Thus you can
accurately control the value being delivered to other mods,
such as dtranspose.

cKey allows you to have several degrees of control over a
control line, by chaining several cKey mods together. For
example, to drive a dtranspose mod, you could start with a
cKey mod assigned (up arrow -12)/(down arrow +12), with
the input left unconnected. The output could then be
modified by another cKey mod assigned (left arrow +1)/
(right arrow -1). Thus, every time you press (up arrow) or
(down arrow), the transposition would jump in octaves; (left
arrow) and (right arrow) would give you half step control
within the current octave.

^7

cLimit -- pass any values that fall between the specified
limits. Values that fall outside these limits will be
treated according to the limit mode selected

		│<---------- control value to process
		│	│<------ low and high limits (order
		│	│	│<-- is not important)
		│	│	│
	┌───┴───┴───┴───────────────────┐
	│	cLimit						│
	└───┬───────────────────────────┘
		│
		│<------ processed value

cLimit compares an input value to a high and a low limit.
If the input value falls between the high and low limits
(inclusive), it is passed unchanged. If the input value
does not fall within thise range, the action taken depends
upon the limit mode selected at initialization time.

There are three limit modes. "Hold" means hold the value to
the respective high or low limit it is exceeding. This is
similar to the "clipping" of an audio wave. "Reflect" and
"wrap" are more unusual.

In "reflect" mode, values that fall outside the limit range
are reflected back towards the permitted range. If the
reflection causes the value to exceed the other limit, it
will be reflected back again until it finally reaches a
position within the range.

In "wrap" mode, values that fall outside the limit range
are wrapped around to the opposite end of the permitted
range. If after wrapping the value still falls outside the
limit, it will be wrapped again until it finally reaches a
position within the range.

Notice that since control mods always return a value, it is
not possible to "throw away" an input value (that is, there
is no control counterpart to the "discard" mode in the
dLimit mod).

^8

dSwitch -- packet switcher

		│<---------- switch control
		│	║<------ packet to process
		│	║
	┌───┴───╨───────────────────────┐
	│	dSwitch 					│
	└───╥───╥───╥───╥───────────────┘
		║	║	║	║
		║	║	║	║<-- paths to take depending on control

This mod is a simple packet switcher, sending a packet down
one of its four outputs depending on the value of the
control input. The control value is expected to fall in the
range 0..3 (inclusive). A value less than zero will be
treated as zero; a value greater than three will be treated
as three.

Zero will select the leftmost path, three the rightmost.

^9

UnitInBlock -- connection block for inputs into a Unit

	┌───────────────────────────────────────┐
	│	UnitInBlock 						│
	└───┬───┬───┬───┬───╥───╥───╥───╥───────┘
		│	│	│	│	║	║	║	║
		│	│	│	│	║	║	║	║<--- data inputs
		│	│	│	│<------------------- control inputs

This block is used inside a unit to provide an attachment
point for control and data lines entering the unit. No more
than one is allowed in each Unit.

^10

cPulse -- compares the input value to a threshold; delivers
+32767 if the value has just risen to or over the threshold,
otherwise delivers 0.

		│<------ value to analyze
		│	│<-- threshold
		│	│
	┌───┴───┴───────────────────────┐
	│	cPulse						│
	└───┬───────────────────────────┘
		│
		│<------ 0 or +32767

This mod is most often used control other mods, such as
gates. It differs from cTrigger in that it delivers +32767
only when the threshold is crossed. If the input value
remains above the threshold, cPulse will deliver 0. The
effect is of a single pulse each time the threshold is
crossed.

^11

cAdd -- add two control values

		│<------ first value
		│	│<-- second value
		│	│
	┌───┴───┴───────────────────────┐
	│	cAdd						│
	└───┬───────────────────────────┘
		│
		│<------ sum of two inputs

If the sum overflows the limits of a control value (-32768
to +32767) the result will wrap to the other end of the
range. {TN: This is the natural result of overflow in 16
bit arithmetic.}

^12

cTrigger -- compares the input value to a threshold;
delivers 0 if the the value is less than the threshold,
otherwise delivers +32767.

		│<------ value to analyze
		│	│<-- threshold
		│	│
	┌───┴───┴───────────────────────┐
	│	cTrigger					│
	└───┬───────────────────────────┘
		│
		│<------ 0 or +32767

This mod is most often used to control other mods, such as
gates.

^13

dClass - allows selected "classes" of events to be
isolated and treated separately.

		║<--- packet to be processed
		║
	┌───╨───────────────────────────┐
	│	dClass						│
	└───╥───╥───────────────────────┘
		║	║
		║	║<--- all events that do not fall in selected
		║		  classes
		║<------- selected events

A "class" is most familiar if viewed in terms of note
values: All "C#"s are members of the "C#" note class,
regardless of the octave within which they occur. dClass
allows to specify at edit time one or more "classes", which
are then separated from the data stream and made available
at Data output #1. All other classes are available at data
output #2.

Although dClass was designed with note classes in mind, it
is quite possible to use it with any part of any packet,
provided the number of possible classes is not greater than
16. For example, one could select just events on channels
1,2,7, and 11 (number of possible classes (channels): 16).

^14

dCompress -- compresses or expands selected portion of
packet according to a ratio expressed by the control
inputs.

		│<---------- numerator of ratio
		│	│<------ denominator of ratio (if zero, will be
		│	│		 converted to one)
		│	│	║<-- packet to process
		│	│	║
	┌───┴───┴───╨───────────────────┐
	│	dCompress					│
	└───╥───╥───────────────────────┘
		║	║
		║	║<--- unchanged packet if processing
		║		  would have resulted in out of range value
		║<------- processed packet

This mod simply multiplies the selected portion of the data
packet by control input #1, then divides the result by
control input #2. It is thus possible to compress or expand
the input value by fractional amounts.

^15

dCounter -- delivers the number of MIDI data packets that
have passed through the mod. Data packet is unchanged.

        │<------- reset count to 0 if this line non-zero
		│   ║<--- packet to process
		│   ║
	┌───┴───╨───────────────────────┐
	│	dCounter					│
	└───┬───╥───────────────────────┘
		│	║
		│	║<--- data packet (unchanged)
		│<------- count of packets processed

dCounter can count up to 32767 packets, at which point
it will return to zero. Count can also be returned to
zero by setting the reset line momentarily to a non-zero
value.

^16

dDisp -- display the selected portion of the MIDI packet
in the scrolling window defined at edit time, in decimal
and hexadecimal form. The data packet is passed unchanged.

		║<--- packet to display
		║
	┌───╨───────────────────────────┐
	│	dDisp						│
	└───╥───────────────────────────┘
		║
		║<--- data packet (unchanged)

^17

dGate - blocks a data stream while control value is greater
than 0

		│<------ controls opening of gate. Gate is closed if
		│		 this value is greater than zero
		│	║<-- packet to process
		│	║
	┌───┴───╨───────────────────────┐
	│	dGate						│
	└───╥───────────────────────────┘
		║
		║<--- packets that have passed the gate (unchanged)

dGate allows precise control over the flow of a data
stream. As each packet arrives at the gate, the control
input is examined to decide whether the gate is open or
closed. If it is open, the packet is passed on its way. If
it is closed, the packet is placed in a holding area, where
it and any other waiting packets will be passed as the gate
opens. The gate is checked for each packet.

The size of the holding area (or "buffer") is set at edit
time to a value from zero to about 3000, depending on the
memory in your computer, which corresponds to the number of
packets that can be in the holding area at any one time. If
the holding area is full, any new packets will simply be
discarded. Thus, a buffer size of zero would allow you to
discard any packets that arrive while the gate is closed.

Remember that the amount of time between events can be
modified by the gate. If there are three packets waiting in
the holding area when the gate lifts, it does not matter if
they arrived together or minutes apart; they will be passed
through the gate as quickly as dGate can process them, as
long as the gate remains open.

^18

dGraph -- display the selected portion of the MIDI packet
in the scrolling window defined at edit time, in graphic
(piano roll) form. The data packet is passed unchanged.

		║<--- packet to display
		║
	┌───╨───────────────────────────┐
	│	dGraph						│
	└───╥───────────────────────────┘
		║
		║<--- data packet (unchanged)

When creating the window at edit time, you specify the
minimum and maximum values that this window should display.
Those values then represent the extreme left and right
edges of the window, and all values to be displayed are
scaled accordingly.

The graphic display is an event display rather than a true
piano roll. The difference is note on and note off events
will be shown as single, unconnected marks, rather than as
a continuous bar representing the sustained note.

^19

dInvert -- invert a portion of the data packet around a selected axis

		│<------- axis to invert around
		│	║<--- packet to process
		│	║
	┌───┴───╨───────────────────────┐
	│	dInvert 					│
	└───╥───╥───────────────────────┘
		║	║
		║	║<--- unchanged packet if processing would
		║			have resulted in out of range value
		║<------- processed packet

^20

dLimit -- pass any packets whose selected data value fall within
the specified limits. Values that fall outside these limits will be
treated according to the limit mode selected.

		│<---------- low and high limits (order
		│	│<------ is not important)
		│	│	║<-- packet to process
		│	│	║
	┌───┴───┴───╨───────────────────┐
	│	dLimit						│
	└───╥───╥───────────────────────┘
		║	║
		║	║<--- rejected packets (see below)
		║<------- correctly processed packets

dLimit extracts a portion of a data packet (such as note
value), and compares it to a high and a low limit. If the
value falls between the high and low limits (inclusive), it
is passed unchanged. If the input value does not fall
within this range, the action taken depends upon the limit
mode selected at initialization time.

There are four limit modes. In "Discard" mode, packets that
fall outside the range are "rejected" (passed down data
output #2).

In "hold" mode, the value is held to the respective high or
low limit it is exceeding. This is similar to the
"clipping" of an audio wave.

"Reflect" and "wrap" are more unusual. In "reflect" mode,
values that fall outside the limit range are reflected back
towards the permitted range. If the reflection causes the
value to exceed the other limit, it will be reflected back
again until it finally reaches a position within the range.

In "wrap" mode, values that fall outside the limit range are
wrapped around to the opposite end of the permitted range.
If after wrapping the value still falls outside the limit,
it will be wrapped again until it finally reaches a
position within the range.

In all modes, if the limits imposed by the control values
are not appropriate for the part of the packet being
processed, the packet will be "rejected" (sent down data
output #2). Thus, if one is processing note values, and the
limits are -200 to -100, all packets will be rejected,
since note values can never be negative.

^21

dTrackIn -- entry module for note tracking system

		║<--- packet to process
		║
	┌───╨───────────────────────────┐
	│	dTrackIn					│
	└───┬───╥───────────────────────┘
		│	║
		│	║<--- processed packets (unchanged)
		│<------- direct connection to dTrackOut mod

The note tracking system is designed to solve "stuck note"
problems. It consists of two mods, dTrackIn and dTrackOut,
which are always used as a pair. The basic idea is to take
a "snapshot" of the data stream both before (using
dTrackIn) and after (using dTrackOut) the processing that
causes the stuck note.	dTrackOut can then ensure that
"note off"s (and "aftertouch") match up with their
respective "note on"s.

dTrackIn has a single control connection, which must always
connect DIRECTLY to its matching dTrackOut. This is not a
normal control connection -- it may not be connected to any
other mod (not even cSplit).

You may have as many note tracking pairs as you need in a
single patch.

(see also dTrackOut)

^22

dTrackOut -- exit module for note tracking system

		│<------- direct connection to dTrackIn mod
		│	║<--- packet to process
		│	║
	┌───┴───╨───────────────────────┐
	│	dTrackOut					│
	└───╥───────────────────────────┘
		║
		║<--- processed packets. Note off and aftertouch
			  events will be transposed (pitch or channel)
			  as necessary to match Note on. Time reversed
			  Note on/Aftertouch/Note off combinations will
			  be filtered out.

The note tracking system is designed to solve "stuck note"
problems. It consists of two mods, dTrackIn and dTrackOut,
which are always used as a pair. The basic idea is to take
a "snapshot" of the data stream both before (using
dTrackIn) and after (using dTrackOut) the processing that
causes the stuck note.	dTrackOut can then ensure that
"note off"s (and "aftertouch") match up with their
respective "note on"s.

dTrackOut has a single control connection, which must always
connect DIRECTLY to its matching dTrackIn. This is not a
normal control connection -- it may not be connected to any
other mod (not even cSplit).

You may have as many note tracking pairs as you need in a
single patch.

(see also dTrackIn)

^23

UnitOutBlock -- connection block for outputs from a Unit

		│	│	│	│<------------------- control outputs
		│	│	│	│	║	║	║	║<--- data outputs
		│	│	│	│	║	║	║	║
	┌───┴───┴───┴───┴───╨───╨───╨───╨───────┐
	│	UnitOutBlock						│
	└───────────────────────────────────────┘

This block is used inside a unit to provide an attachment
point for control and data lines leaving the unit. No more
than one is allowed in each Unit.

^24

dMerge -- merge several data streams

		║	║	║	║<--- streams to merge
		║	║	║	║
	┌───╨───╨───╨───╨───────────────┐
	│	dMerge						│
	└───╥───────────────────────────┘
		║
		║<--- merged stream

This mod will merge several data streams into a single data
stream. It does no processing on the stream at all. In
particular, it makes no attempt to remove duplicate
packets.

^25

dSelect -- select specified data type

		║<--- incoming packets
		║
	┌───╨───────────────────────────┐
	│	dSelect 					│
	└───╥───╥───────────────────────┘
		║	║
		║	║<--- all other packets
		║<------- packets that match the type desired

This mod is used to route packets according to type. At
edit time, the desired packets type is selected (such as
"notes" or "pitch bend"). Then at run time, the desired
packets will appear at the first output; all others will be
directed to the second output. Quite commonly, this second
output may enter another dSelect mod for further splitting
of the data stream.

^26

dSplit -- split a data stream

		║<--- stream to split
		║
	┌───╨───────────────────────────┐
	│	dSplit						│
	└───╥───╥───╥───╥───────────────┘
		║	║	║	║
		║	║	║	║<--- copies of the input stream

This mod splits a data stream into four parallel identical
streams. Each stream may be processed in a different way,
without affecting the other streams. Parallel streams may
then be merged with dMerge.

If fewer than four streams are needed, the unneeded outputs
may be left unconnected.

^27

dToC -- data to control converter. The selected portion of
the data packet is converted to a control value, which is
then available at the control output. The original data
packet is passed unchanged.

		║<--- packet to process
		║
	┌───╨───────────────────────────┐
	│	dToC						│
	└───┬───╥───────────────────────┘
		│	║
		│	║<--- data packet (unchanged)
		│<------- control value extracted from data packet

There are all sorts of uses for this mod. You could convert
the velocity from "note on" packets to a control value,
then use this information to control other things, such as
transposing the channel. Or use dSet to set another
portion of the same packet to the same value. You could,
for example, extract the note value from a "note on" packet
and set the velocity to match.

^28

dTranspose -- transpose the selected portion of the packet
by a given amount.

		│<------- amount to transpose (positive to transpose up,
		│		  negative to transpose down)
		│	║<--- packet to process
		│	║
	┌───┴───╨───────────────────────┐
	│	dTranspose					│
	└───╥───╥───────────────────────┘
		║	║
		║	║<--- packets for which which transposition was
		║	║	  not possible. Packet is unchanged.
		║<------- successfully transposed packets

If the transpose cannot be accomplished, the packet is
REJECTed, and sent down output #2. This would occur if the
requested transposition would cause an overflow or
underflow. These rejected packets can then be processed
separately, merged unchanged into the data stream, or
simply discarded.

Like most mods, dTranspose can operate on any portion of
the data packet. Thus you can transpose note values,
channel number, velocity, pitch bend, or any other part.

^29

dMidiIn -- this is where the MIDI data stream enters the
computer

	┌───────────────────────────────┐
	│	dMidiIn 					│
	└───╥───────────────────────────┘
		║
		║<--- the MIDI data stream

This is the incoming MIDI data stream as it appears at the
MIDI port. System exclusive data and active sense are
stripped and sent directly to MIDI Out; they cannot be
edited by TAB.

^30

dMidiOut -- sends the data stream to the MIDI Out port.

		║<--- MIDI stream to send
		║
	┌───╨───────────────────────────┐
	│	dMidiOut					│
	└───────────────────────────────┘

^31

dSet - sets the selected part of the packet to the value
of the control input

		│<------- value to set packet to
		│	║<--- packet to process
		│	║
	┌───┴───╨───────────────────────┐
	│	dSet						│
	└───╥───╥───────────────────────┘
		║	║
		║	║<--- packets for which which control value
		║	║	  was out of range. Packet is unchanged.
		║<------- successfully set packets

This mod can be used to set a part of each packet to a known
value (such as velocity to 64). It can also be used (in
conjunction with dToC (data to control) to copy a value
from one part of a packet to another.

More subtle use of this basic idea allows various forms of
"keyboard scaling", where velocity is modified differently
depending on the note value.

^32

cRandom -- deliver a random integer value between the
limits defined.

		│<------- low and high limits (order
		│	│<--- is not important)
		│	│
	┌───┴───┴───────────────────────┐
	│	cRandom 					│
	└───┬───────────────────────────┘
		│
		│<------ random value between those limits
				 (inclusive)

^33

cKeyTog -- this is a "toggle switch" which changes its
state from zero to a value specified at initialization and
back again, whenever the assigned key from the computer
keyboard is struck.

	┌───────────────────────────────┐
	│	cKeyTog 					│
	└───┬───────────────────────────┘
		│
		│<--- 0 or predefined value, depending on the
			  state of the toggle (initially zero).

This mod is useful for controlling other mods such as
gates.

^34

cClock -- variable frequency clock.

		│<---------- clock rate (frequency) in ticks
		│	│<------ number of seconds
		│	│	│<-- reset clock if greater than 0
		│	│	│
	┌───┴───┴───┴───────────────────┐
	│	cClock						│
	└───┬───────────────────────────┘
		│
		│<--- current clock value (number of ticks since
			  start)

Frequency is specified by control inputs #1 and #2. Control
input #1 specifies the number of ticks, and control input
#2 specifies the time period in seconds that those ticks
should occur over. Thus the highest clock frequency is
32767 ticks in one second. The slowest frequency is one
tick every 32767 seconds.

As with all mods, it is possible to have several different
clocks running at different frequencies to serve different
purposes.

All clocks start from zero when the patch is run. The clock
may be reset by momentarily setting control input #3 to a
value greater than 0. In this situation, the clock will not
start running again until control input #3 returns to a
value less than or equal to 0; therefore, it is most common
to pulse this input with a mod such as cPulse or
cChange.

The highest possible frequency with full resolution is 4648
ticks/second, which is the frequency of the system clock.
Higher frequencies (up to 32767 ticks/second) are possible,
but the clock will tick several steps at a time. This is
due to the fact that all clocks derive their value from the
system clock.

If the number of ticks (control input #1) drops below one,
the clock is effectively frozen. Thus, leaving control
input #1 unattached will freeze the clock.

If control input #2 (seconds) is less than one, it will be
treated as one. Thus, the smallest number of seconds that
can be specified is one, and leaving this input unattached
will be interpreted as one second.

For more detailed discussion, see the manual.

^35

cDec -- decrement control value

		│<------- control value to process
		│
	┌───┴───────────────────────────┐
	│	cDec     					│
	└───┬───────────────────────────┘
		│
		│<------ decremented control value

Subtracts one from control value

^36

dMidiClock -- MIDI clock mod

		║<----------- stream to process
		║
	┌───╨───────────────────────────┐
	│	dMidiClock					│
	└───┬───╥───╥───────────────────┘
		│	║	║
		│	║	║<--- all other packets
		│	║<------- clock packets from input stream
		│<----------- MIDI clock value

This mod allows synchronization to an external MIDI clock.
It simply counts the MIDI clock packets that pass through;
the resulting control output may be used just like any
other clock value.

For detailed discussion of clock mods, see cClock.

^37

cSplit -- allows a single control line to be accessed by
more than one line

		│<--- control line to be accessed
		│
	┌───┴───────────────────────────┐
	│	cSplit						│
	└───┬───┬───┬───┬───────────────┘
		│	│	│	│
		│	│	│	│<--- control value from input #1
						  (unchanged)

Although this mod might appear always to deliver the same
value to each output, that is often not the case. It is
important to realize that cSplit cannot deliver more than
one value to one output at a time. In the time between
delivering a value to one output and delivering a value to
another, the value of the control input may have changed
unpredictably. Nevertheless, this mod is very useful both
for reducing the complexity of a patch, and for under
limited conditions providing a certain uniformity of
response to multiple inputs.

^38

dDelay -- delay a data stream a specified length of time

		│<----------- reference clock (if not connected,
		│			  system clock will be used)
		│	│<------- delay time in clock ticks. If <= 0,
		│	│		  packet will be passed without delay
		│	│	║<--- data stream to process
		│	│	║
	┌───┴───┴───╨───────────────────┐
	│	dDelay						│
	└───╥───────────────────────────┘
		║
		║<------- delayed data stream.
				  Contents of packets unchanged.

Data packets are stored in a holding area until their delay
time is up and it is time to move them on again. Multiple
dDelays can be chained together, each contributing a
portion of the total delay time.

The reference clock can be of any type: "absolute" clocks
like system clock and cClock, or "relative" like dMidiClock.
A relative clock would be sensitive to changes in tempo,
which means delayed events would always stay in sync
regardless of tempo changes.

A packet's delay time is established at the time of its
arrival at the dDelay mod. At that time it is placed in the
holding area with information on when it is to be released.
Notice that the delay time can be varied in real time (as
can all control inputs), but this does not affect packets
already in the holding area.

Notice also that ANY MIDI packet can be delayed, not just
notes.	If employing a variable delay time on notes, be
sure that "note on" packets are not delayed so much they
emerge after their corresponding "note off" packet --
otherwise you could get a "stuck note" problem. See
manual on "stuck notes"; also see "Note tracking".

(See also dEcho)

^39

cLfo -- low frequency oscillator. Wave form is selected at
edit time; frequency and reference clock are all determined
by control inputs.

		│<---------- reference clock (if unconnected,
		│			 system clock will be used)
		│	│<------ frequency in clock ticks per cycle
		│	│	│<-- reset (if greater than zero, waveform
		│	│	│	 is restarted at the beginning of the
		│	│	│	 cycle)
	┌───┴───┴───┴───────────────────┐
	│	cLfo						│
	└───┬───────────────────────────┘
		│
		│<------ oscillator wave

Four wave forms are selectable at edit time: ascending
sawtooth, triangle, square, and sine. Other wave forms can
be derived by further processing. For example, a descending
sawtooth can be achieved by inverting the output of an
ascending sawtooth (with cNegate). A variable width pulse
wave can be had by producing a triangle wave, then using
either cTrigger or cLimit in "Hold" mode to process the
result.

Notice that frequency is expressed in clock ticks per cycle,
rather than the more common Herz, or cycles per second.
This is because clock ticks per cycle is much easier to
handle when dealing with very slow waves. Thus, the slowest
possible wave would have a frequency of 32767, the fastest
would depend on the resolution desired -- a square wave
could theoretically be produced with a frequency of 2. Using
the system clock (4648 Hz) the maximum cycle length works
out to about 7 seconds, and can go as far up as 2324 Hz.
Using a cClock with a frequency of 1000 ticks/second, the
maximum cycle length is almost 33 seconds.

In practice, very high frequencies should be used with
caution, since the oscillator produces just one sample for
every clock tick. Thus, a frequency of just three
ticks/cycle would produce only three samples per cycle, and
the resulting waveform may bear little resemblance to the
wave actually desired (this is known as "alias distortion").
For all practical purposes, a frequency of several hundred
ticks/cycle should be considered the maximum. Using the
system clock and a frequency of 256, a respectable waveform
can be generated at 18.2 Hz, not too bad for a low
frequency oscillator.

The system clock is the fastest possible clock; using a
slower one could lengthen the wave considerably. For
example, using a cClock running at one tick per second as a
reference, a cLfo could produce a wave with a period as
long as 9 hours.

^40

cFreeze -- freeze the entire system

		│<------ any control value
		│	│<-- freeze control
		│	│
	┌───┴───┴───────────────────────┐
	│	cFreeze 					│
	└───┬───────────────────────────┘
		│
		│<------ control input #1 (unchanged)

If freeze control is greater than zero, entire run time
system will freeze until the value falls to or below zero
again.

This mod is designed primarily for debugging a new patch.
It is useful to halt the system temporarily so that
scrolling windows can be examined, etc. The system clock is
not frozen. If MIDI data continues to arrive while the
system is frozen, it will be stored until the MIDI input
buffer overflows, at which point any further data will be
discarded. Thus cFreeze should only be used for short
periods of time. Also, because the system clock continues to
run, cFreeze acts like a dam on the data stream. Data
will pile up, then rush by all at once when the freeze is
lifted.

It is convenient to attach a mod like cKeyTog to control
input #2. Then the system can be frozen and unfrozen with
a simple computer keystroke such as pressing the space bar.

^41

dFileIn -- a TAB data file (produced by dFileOut) is used as
an input stream. The file is in standard MIDI file format.

		│<---- reference clock (if not connected,
		│	   system clock will be used)
		│
	┌───┴───────────────────────────┐
	│	dFileIn 					│
	└───╥───────────────────────────┘
		║
		║<---- MIDI data stream from file

You will specify the file name at edit time. A default data
path is available on the System Control Panel (Alt-F1).

The clock at control input #1 is used to interpret the
timing data in the input data file. If unconnected, the
system clock will be used.

For accurate reproduction of the data file, the same clock
rate should be used as was used when the file was saved
(with dFileOut). Obviously, a different clock can be used
for a different effect.

You can have multiple files open for input at one time. See
the "Files" section of the manual for details.

^42

dFileOut -- saves the data stream to a TAB data file. The
file is in standard MIDI file format.

		│<------- reference clock (if not connected,
		│		  system clock will be used)
		│	║<--- MIDI data stream
		│	║
	┌───┴───╨───────────────────────┐
	│	dFileOut					│
	└───────────────────────────────┘

You will specify the file name at edit time. A default data
path and extension is available on the System Control Panel
(Alt-F1).

The clock at control input #1 is used to record timing data
in the data file. If unconnected, the system clock will be
used.

You can have multiple files open for output at one time. See
the "Files" section of the manual for details.

^43

dArpegg -- arpeggiates notes that are held down according to
a selected pattern

		│<----------- control wave for arpeggiator
		│	│<------- pattern (see below)
		│	│	║<--- data stream to process
		│	│	║
	┌───┴───┴───╨───────────────────┐
	│	dArpegg 					│
	└───╥───╥───────────────────────┘
		║	║
		║	║<------- arpeggiated notes
		║<----------- original data stream (unarpeggiated)

The selectable patterns are:
		0: ascending
		1: descending
		2: ascending/descending
		3: order of play
		4: reverse order of play
		5: order of play/reverse order of play
		6: random

The arpeggiator will only arpeggiate note on and off events.
The original data stream will appear (unarpeggiated) at
data output #1.

The actual arpeggiator output appears at data output #2. A
note will be arpeggiated for as long as it is held down.
Once the note off event for that note arrives, it will be
removed from the arpeggiator. If the note off arrives
while that note is sounding in the arpeggiation sequence,
it will be allowed to finish before it is removed.

The playing of the arpeggiated notes is controlled by
control input #1. Whenever this control input rises above
zero, the next note in the sequence is played. When the
input drops down to or below zero, the note off is sent.

The simplest input to use here is a low frequency
oscillator (cLfo) producing a square wave at the rate you
want the arpeggiation to occur. This will give notes with
equally spaced silences in between. You can of course, use
any other control input you wish.

^44

cGreater -- transmit the greater of two control inputs

		│<------ value to be examined
		│	│<-- value to be examined
		│	│
	┌───┴───┴───────────────────────┐
	│	cGreater					│
	└───┬───────────────────────────┘
		│
		│<------ first or second value, whichever
				 is larger

This mod allows one control line to override another. For
example, perhaps you want to have a sine wave entering
input #1, but discard the negative portion. Leaving input
#2 unconnected will force it to always supply zero -- thus,
whenever the sine wave goes negative, the maximum of the
two inputs will be zero, until the sine wave rises above
zero again.

See also cLesser

^45

cLesser -- transmit the lesser of two control inputs

		│<------ value to be examined
		│	│<-- value to be examined
		│	│
	┌───┴───┴───────────────────────┐
	│	cLesser 					│
	└───┬───────────────────────────┘
		│
		│<------ first or second value, whichever
				 is smaller

See cGreater

^46

cScale -- convert an input value from one range to another

		│<--- value to convert
		│
	┌───┴───────────────────────────┐
	│	cScale						│
	└───┬───────────────────────────┘
		│
		│<--- converted value

This mod will convert dissimilar control values so they can
be used interchangably. For example, if you want to convert
a pitch bend value (with a range of 0 - 16383) to a MIDI
note (range 0 - 127), you could setup a cScale mod at edit
time to convert from a range of 0 - 16383 to a range of 0 -
127. Thus, an input value of 8192 (about the center of the
old range) would be converted to a value of 64 (about the
center of the new range).

cScale is a combination of cCompress and cAdd. Although its
operation can be simulated with those mods, it is much
faster and much more convenient for those situations where
the compression/expansion ratios and relocation do not need
to be controlled in real time.

^47

dEcho -- echoes the data stream

		│<--------------- reference clock (if not connected,
		│				  system clock will be used)
		│	│<----------- time between echoes in clock ticks.
		│	│			  Values < 0 are treated as zero.
		│	│	│<------- number of times to echo
		│	│	│		  (if <= 0, no echo will occur)
		│	│	│	║<--- data stream to process
		│	│	│	║
	┌───┴───┴───┴───╨───────────────┐
	│	dEcho						│
	└───┬───╥───────────────────────┘
		│	║
		│	║<------- data stream with echoes.
		│			  Contents of packets unchanged.
		│<----------- echo number of current packet

dEcho is really a specialized dDelay mod. See notes on
dDelay for generalities on delaying.

The differences between dEcho and dDelay are (1) dEcho
allows you to specify the number of echoes, (2) dEcho
passes the packet undelayed when it first arrives, and (3)
dEcho provides an echo count at its control output, useful
for further processing of echoed packets.

Notice that by specifying (via control input #2) zero time
between echoes, you can create a set of virtually
simultaneous "clones" of a given packet.

Many people expect an echo mod to "fade" (i.e. reduce the
velocity) with every repetition. This is quite possible
with TAB, but is not built into dEcho itself. This was done
to provide more flexibility for processing the echoed
packets, and for allowing dEcho to be used by packets other
than notes.

Instead, dEcho provides an "echo count" at the control
output, which can be modified and used to drive another
module. When dEcho releases an echoed packet, it places the
"echo count" for that packet on the control output. For
example, if the packet being released is the fourth echo of
a particular event, four is placed on the control output.
The echo count of the original, unechoed packet will always
be zero.

Assuming you are echoing notes, if you wanted to "fade" each
echo by reducing the velocity of each echo, you could take
the data output of dEcho and feed it to dTranspose, which
is set to transpose velocity. The control output from dEcho
should be modified to make it more useful: you could
multiply it (with cMult) by 12 then negate it (with
cNegate) before attaching it to dTranspose. Then, every
echo would have its velocity reduced by 12.

(See dDelay)

^48

cMult -- multiply two control inputs

		│<------ multiplicand (first value to multiply)
		│	│<-- multiplier (second value to multiply)
		│	│
	┌───┴───┴───────────────────────┐
	│	cMult						│
	└───┬───────────────────────────┘
		│
		│<------ product of two inputs

If the product overflows the limits of a control value
(-32768 to +32767) the results are unpredictable. No
attempt is made to prevent overflow.

^49

cDivide -- divide one control value by another

		│<------ dividend (value to divide)
		│	│<-- divisor (value to divide by)
		│	│
	┌───┴───┴───────────────────────┐
	│	cDivide 					│
	└───┬───────────────────────────┘
		│
		│<------ quotient (truncated to integer value)

A divisor of zero will be internally converted to one. The
result of any division will be truncated to the integer
value closest to zero.	That is, any fractional part will
simply be discarded (this is NOT the same as rounding).

^50

cSubtrct -- subtract two control inputs

		│<------ first value
		│	│<-- second value
		│	│
	┌───┴───┴───────────────────────┐
	│	cSubtrct					│
	└───┬───────────────────────────┘
		│
		│<------ difference of two inputs (first - second)

If the difference overflows the limits of a control value
(-32768 to +32767) the result will wrap to the other end of
the range.

^51

dDispPak -- display an entire data packet in the scrolling
window defined at edit time, in hexadecimal. The data
packet is passed unchanged.

		║<--- packet to display
		║
	┌───╨───────────────────────────┐
	│	dDispPak					│
	└───╥───────────────────────────┘
		║
		║<--- data packet (unchanged)

If the defined window is not wide enough to accommodate the
entire display line, it will be truncated to fit. Portions
of the packet may not be meaningful. A given status byte
may have zero, one, or two data bytes, although both will
always be displayed. Any unused data bytes may be ignored.

		(sample output - in hexadecimal)

				 			 s: 90 d1: 40 d2: 35
				 			 	   	  
		status byte ─────────┘	   │	  │
		first data byte ───────────┘	  │
		second data byte ─────────────────┘

^52

Unit -- an entire subassembly of mods

		│	│	│	│<------------------- control inputs
		│	│	│	│	║	║	║	║<--- data inputs
		│	│	│	│	║	║	║	║
	┌───┴───┴───┴───┴───╨───╨───╨───╨───────┐
	│	Unit								│
	└───┬───┬───┬───┬───╥───╥───╥───╥───────┘
		│	│	│	│	║	║	║	║
		│	│	│	│	║	║	║	║<--- data outputs
		│	│	│	│<------------------- control outputs

TAB provides a very powerful means to extend its editing
area beyond the primary editing space of 128 columns by 64
rows. This is done through a special mod called a Unit.

From the outside, a Unit looks like any other mod.	But you
can open the lid on a Unit, and build your OWN mod inside
to do whatever you want. A Unit, in fact, contains nothing
at all except a completely new editing space and a couple
of connection blocks that communicate with the outside
world.

^53

cFilter -- lowpass filter for a control input

		│<------ control value to process
		│	│<-- cutoff adjustment
		│	│
	┌───┴───┴───────────────────────┐
	│	cFilter 					│
	└───┬───────────────────────────┘
		│
		│<------ filtered control value

If you view the control input as representing a wave
comprised of discrete digital "samples", it becomes clear
that it can be processed like a wave -- and that includes
filtering. cFilter is useful for smoothing out "spiky"
waves. For example, if fed by a purely random input
(cRandom), cFilter could smooth out the resulting "white
noise" into something more resembling "pink noise"; that is,
a random wave with fewer spikes and a gentler contour.

^54

dClock -- insert MIDI clock in data stream

		│<------ reference clock (if not connected,
		│		 system clock will be used)
		│	║<-- incoming data stream
		│	║
	┌───┴───╨───────────────────────┐
	│	dClock						│
	└───╥───────────────────────────┘
		║
		║<--- incoming stream (unchanged), plus inserted MIDI
			  clock packet generated each clock tick

For detailed discussion of clock mods, see cClock.

^55

cBuffer -- return the control value from the PREVIOUS
check of the control input

		│<--- control value
		│
	┌───┴───────────────────────────┐
	│	cBuffer 					│
	└───┬───────────────────────────┘
		│
		│<--- control value from previous call

Whenever a mod needs a control value, it INQUIRES the mods
connected to the control inputs. If they in turn require
control inputs, they inquire the mods connected to their
control inputs, and so on. Only when a control mod has
received replies from all inquiries of its inputs does it
return a control value. cBuffer acts the same way, but
instead of delivering the value just delivered by the mod
connected to the control input, it delivers the value
delivered THE LAST TIME it checked its input. The value
just delivered is stored, and is delivered on the NEXT call
to cBuffer.

This action gives you a form of control value delay. The
important difference between cBuffer and dDelay (the data
delay mod) is that cBuffer is not time based. That is,
cBuffer has no way of knowing WHEN the stored control value
was delivered. Thus, it does not tell you what the control
value was two seconds ago; it tells you what the value was
THE LAST TIME A VALUE WAS REQUESTED, which may have been
two seconds ago or two hours.

^56

cClockRate -- delivers the system clock rate in
ticks/second (constant: 4648)

	┌───────────────────────────────┐
	│	cClockRate					│
	└───┬───────────────────────────┘
		│
		│<--- constant (4648)

This may be useful for some computations.

^57

cMaxVal --	delivers the largest possible control value
(constant:	+32767)

	┌───────────────────────────────┐
	│	cMaxVal 					│
	└───┬───────────────────────────┘
		│
		│<--- +32767

This may be useful for some computations.

^58

cMinVal --	delivers the smallest possible control value
(constant:	-32768)

	┌───────────────────────────────┐
	│	cMinVal 					│
	└───┬───────────────────────────┘
		│
		│<--- -32768

This may be useful for some computations.

^59

cAbsVal -- deliver absolute value of the control input

		│<--- control value
		│
	┌───┴───────────────────────────┐
	│	cAbsVal 					│
	└───┬───────────────────────────┘
		│
		│<--- absolute value of input

The absolute value of a number is derived by stripping the
minus sign off if it exists. That is, negative numbers are
converted to their positive equivalent; positive numbers
are unchanged. Thus the absolute value of -37 is 37. The
absolute value of 56 is 56. Due to limitations inherent in
digital arithmetic, the absolute value of -32768 is -32768.

^60

cModulo -- divide two control inputs, returning the
remainder

		│<------ dividend (value to divide)
		│	│<-- divisor (value to divide by)
		│	│
	┌───┴───┴───────────────────────┐
	│	cModulo 					│
	└───┬───────────────────────────┘
		│
		│<------ remainder

A divisor of zero will be internally converted to one.

Modular division is very useful for insuring that a control
value stays below a certain level. In this sense it is like
cLimWrap -- the remainder will always be less that the
divisor, and greater than or equal to zero. A simple rising
control input with a small divisor such as 12 would "wrap"
numerous times (see response graph). Thus, driving input
#1 with a cClock could give you a simple low frequency
oscillator. (cLfo is actually better suited to the task,
though -- see cLfo, and also cClock for limitations in the
use of clock outputs.)

^61

cSysClock -- system clock module

	┌───────────────────────────────┐
	│	cSysClock					│
	└───┬───────────────────────────┘
		│
		│<--- current clock value
			  (number of ticks since start)

The system clock runs at a fixed frequency of 4648 ticks
per second. This is the fundamental clock used by all of
TAB: any unconnected clock inputs will use the system clock
by default, and all variable frequency clocks (cClock)
compute their values from the system clock.

See cClock for more detailed discussion of clocks.

^62

cLatch -- hold (lock) a control value

		│<------ control value
		│	│<-- latch control (latch when > 0)
		│	│
	┌───┴───┴───────────────────────┐
	│	cLatch						│
	└───┬───────────────────────────┘
		│
		│<------ control value or latched value,
				 depending on latch control

This module holds a control stream at a particular value as
long as the latch control (input #2) is greater than 0.

^63

dBuffer -- buffer the most recent four packets and pass them
to outputs one through four, with the most recent going to
output #1.

		║<--- data stream
		║
	┌───╨───────────────────────────┐
	│	dBuffer 					│
	└───╥───╥───╥───╥───────────────┘
		║	║	║	║
		║	║	║	║<--- the four most recent packets

Whenever a packet arrives at dBuffer, it sends that packet
on through output #1, followed immediately by the three
previous packets through outputs #2-4. Thus, a path
connected to output #2 will get the packet that was passed
down output #1 the LAST time dBuffer received something.

This action gives you a form of data packet delay. The
important difference between dBuffer and dDelay (the data
delay mod) is that dBuffer is not time based. That is,
dBuffer has no way of knowing WHEN the data packets in its
list were delivered. Thus, it does not give you the packet
that arrived two seconds ago; it gives you the packets that
arrived THE LAST FOUR TIMES dBuffer was activated, which
may have been two seconds ago or two hours.

^64

cInc -- increment control value

		│<------- control value to process
		│
	┌───┴───────────────────────────┐
	│	cInc     					│
	└───┬───────────────────────────┘
		│
		│<------ incremented control value

Adds one to control value

^65

cNot -- logically inverts control value

		│<------- control value to process
		│
	┌───┴───────────────────────────┐
	│	cNot     					│
	└───┬───────────────────────────┘
		│
		│<------ inverted control value

If control value is not zero, cNot delivers zero.
If control value is zero, cNot delivers one.

^66

dRecord -- record and loop buffer

		│<--------------- reference clock (if not connected,
		│				  system clock will be used)
		│	│<----------- <= 0: record
		│	│			   > 0: playback
		│	│	│<------- speed of playback
		│	│	│		       0: freeze
		│	│	│		    1,-1: normal
		│	│	│		     > 1: faster
		│	│	│		    < -1: slower
		│	│	│   │<--- zero: forward
		│	│	│   │     non zero: reverse
		│	│	│   │	║<--- data stream to process
		│	│	│   │	║
	┌───┴───┴───┴───┴───╨───────────┐
	│	dRecord						│
	└───┬───╥───────────────────────┘
		│	║
		│	║<------- original data stream plus playback
		│<----------- loop counter

dRecord is a sophisticated recording and playback buffer.
Playback speed can be altered in two ways: controlling the
clock attached to input one, and increasing or decreasing
input three. The first method yields smooth variations in
speed; the second increases or decreases in direct integer
multiples of the basic clock speed (2X, 3X, 1/2X, etc.).

The reverse input will reverse the playback of the recorded
buffer (retrograde).  This is currently implemented in a
limited way. A more sophisticated version will be released
soon.

The loop counter may be used to control the number of loops
executed.

^999 (part numbers start at 1000)
^1005

Note value

^1999 (type numbers start at 2000)
^2015

notes -- note on, note off, and after touch (polyphonic key 
		 pressure) will be selected

^2999 (misc help screens start at 3000)

