
                         The (Music) Weaver

So what is it?
The "Weaver" --- qualifier omitted  intentionally --- is a mechanism for
connecting small modules together graphically,  to work in concert
on common data.  Any kind of sequential data that needs to be processed
in a series of steps can be handled by the scheme --- provided suitable
modules for the purpose exist.  Crucially, data is tagged as to its nature,
so that modules will only conern themselves with data that they know
about; different kinds can thus be freely mixed, interacting only when 
-- and if -- necessary.-

Currently, the system is going to be targeted toward the real-time
processing of MIDI event streams --- hence "MusicWeaver" --, though
only a couple of modules exist for this initial demo.  To show its
potential versatility,  two other varieties of data module are in
this package:  two simple 'test data'  modules, and three that manipulate audio.  You can play with these latter on any BeOS system,  but of course
you will need MIDI  I/O (which currently means a BeBox) to do anything
with the MIDI set.

This is very much a demo version, as it is lacking some essential facilities
(such as Save and Load!).  [It isn't "crippled" --- just not "fully growed" yet...]
I probably will want to develop a few more more modules before I finish
the Weaver prograsm itself.  Stay tuned.   The module protocol will of
course be available so that others can write modules for their own needs;
I hope we can get a community of people working on a comprehensive
suite of stuff.

[Also please note that this documentation is very preliminary.  Apologies
for the lack of accompanying diagrams and the like.  An HTML version
will be along eventually.]


Requirements
This version needs BeOS AA:PR.  The main program and the test and
audio modules should work with any such system, but to use MIDI you
will need a BeBox.


A Walk Through
[...probably more of a quick trot through, but hopefully it'll give you
an idea.]

If you've successfully unzipped the package [and presumably you have,
as you're reading this] you should have a directory called "MusicWeaver"
containing a number of distinctive icons.  Of the entire bunch, only
"Weaver" is an executable program -- all the others (aside from this
README) are add-on modules that we will come to in a moment.
(As the package was archived with Chris H.'s 'zip', all the files should have
the right icons.  I haven't been able to check on a clean machine yet,
however.)

Although everything is in a single directory here, this is in no way
essential -- you can move things wherever you want.  It was just simpler
for a demo package, and makes for easier discussion, this way.

To start things up, just double click on the 'W' icon.  Two windows
should open up: a small one labelled "Weaver" at top left, and a larger
one marked "Diagram".  The former is for overall control; at the moment
it only has a menu ("Global") with two items: "New Diagram", and "QUIT".
The first opens a new window --- you can have as many separate diagrams
as you want ---, the other is obvious.  As you can see, the diagram itself
has no menu bar (in this version... undoubtedly it will be needed in the
future).

The diagram window is where most of the action takes place.  You place
elements you want in your configuration there simply by dragging the
module's icon from its home drawer (i.e. "MusicWeaver" here).  [I assime
all current readers are familiar with basic operations (:-)].   Mouse button
 one, by the way, is used for all 'arrangement' of the window.  For (my)
convenience I'll call this the 'left' one.  In what follows I'll have to talk
also about the 'right' button;   if you have one of those one-button
thingies, you can understand this to mean 'control' or 'shift' + mouse-
button.

Let's look around at the basics first.  Drag the icon labelled "PacketSource"
into the diagram window, and drop it somewhere toward the left.  You'll
notice as you drag it that a little square (in addition to the tracker's
outline) follows your cursor around.  The window is "tiled" with a grid,
and this square shows you where the centre of your placed element
will be.

Having placed the first element, now similarly drag and drop a copy of
"Counter" somewhere to the right of this.   If you don't like where you
actually dropped it, you can simply grab it again and move it somewhere
else.

Now we have to connect the two.  You'll see a little 'pip' on the right side
of the PacketSource element in the diagram.   Drag from this point to
one of the sides of the Counter (one without the pip); you should see
a 'rubber-band' line following you, plus the target square as before.
(I believe that some graphics cards have trouble with single-pixel-wide
diagonals, so you may only get partial rubberbanding; this won't affect
other operations.  I'd be glad of any feedback on this, though.)  When
you release the mouse-button you should see a link between the two
elements.  Data is now flowing, though this is not apparent as yet.

The Counter has a Display Panel that can be brought up to show the
count.  To do this,  move the cursor over the centre of the element and
press the right mouse-button.  A short menu will pop up -- as well as a
(blue) panel of information about the element.  Select the "Panel" item
from the menu and the Counter's display will open up: it should be
clicking away merrily.  (All that PacketSource does is to generate a
stream of incrementing values -- one every millisecond.) Observe that
the element is outlined in red while its panel exists (iconized or not).

You'll have noticed two other items on the menu.  "Remove" is probably
again obvious, but you may not want to do that at this moment... Play
around some more first.  "Name", when selected, opens up an edit window
where you can supply a suitable descriptive label if you wish.  Every
element must have a unique name (to label its panel if it has one, but
more importantly for the sake of yet-to-come saving and loading);
it will be given a default one -- like "FLT0' etc -- if you don't wish to.
Notice too that the menu for the source element doesn't have a "Panel"
item -- simply because there's nothing to see or control for this particular
module.

You can also use the right button on a link.  The menu here has only
one item at the moment -- "Cut".  There is a potential for (optionally)
labelling links too, but it's not implemented yet.

Working with the trivial diagram --- and with data still flowing --- we can
explore some of the other basic capabilities.   First, drag another copy of
the Counter, but this time drop it straight onto the existing link,
somewhere between the other two.  (Make sure the targetting square
is directly over the link line.)  The new copy will be inserted into the
existing path.  If you pop open the panels for each, you'll see them
counting along together.

Oh yes. the inserted element's menu has that extra "Elide" item.  If you don't know that word (:-))... just try it out...  You'll only see that item when
the element can be removed from a path, leaving the path itself intact;
"Remove"  in contrast also deletes any links that may be attached.

Drag yet another counter onto the diagram, but not onto an existing
path this time.  Then drag from some intermediate point on the path
that does exist, and drop on one of the counter's input sides.  You have
a branch!  Data is duplicated on both forks.

Similarly, as each basic "filter" (like the Counter) has three possible input
sides, you can merge up to three paths onto one element.  You can try
adding another source and connecting it to a free side of one of the
existing counters.  You'll probably see some flickering of the displayed
numbers, as the two data streams are running from different starting
points.  (Unlike some systems, which allow forests of branches to and
from connection points, the Weaver is strictly regulated.  This is partly
because of the tiled structure, which makes for much more readable
diagrams, and because the efficient data transmission mechanism ---
designed to minimize copying --- works well with linear chains of filters
and identifiable branch points.)

For merging data streams where there happens to be no convenient
filter, the "JoinPaths" module is provided;  it is simply a null element
that passes on all its inputs through its single output, and doesn't care
what kind of data is flowing.

You've probably  got it  pretty well figured out by now, so I'll mostly
leave you to play with the other modules yourself.   A few necessary
words, though.

'
Audio
AudioSource'  and 'AudioOut' subscribe to the respective  audio streams
of the MediaKit.  You should be able to use them if you have audio
connections to your system.  

To avoid confusion from other signal paths, you should set the BeOS Sound Preferences to have no direct audio from the CD --- or whatever
source you are using --- and to have no Loopback.  Then you can
connect AudioSource to AudioOut to hear the signal.

If you do bring up the direct sound as well, you'll notice a short delay
in the MusicWeaver's version.  This is inevitable, because it's passing
complete buffers of data from the input stream to the output, and
the buffer must be filled before it is available.  This latency could be
reduced to --- probably --- unnoticeable levels by using smaller buffers
(the system default is 4K), but the current modules have no way of
changing this.

Another consequence of this continuous -- fixed rate -- stream of
buffers is that you probably don't want to connect more than one
path to an AudioOut element!  To do so is not harmful, but I doubt
you'll be pleased with the results (unless you're looking for gross...)
On the other hand, it is quite all right to insert a second AudioOut
in an existing path between an AudioSource and AudioOut: being
a proper subscriber, it will smoothly add the data it receives into the
output stream.  You can similarly branch the path to a second AudioOut
-- possibly with different processing (if such was available!) in each fork.

The only audio-processing module in this demo is "LaserBreath" ---
directly, umm, borrowed from Marc Ferguson's example code that
he described in a past Be Newsletter (#61, I think).  Insert it between
an AudioSource and an AudioSource, and its effects are obvious.  
(The reduction in volume is normal --- an overall gain control might
have been nice, but another time...)  There is a (large) control panel
for the module, again using exactly Marc's original code; you can play
with the sliders on this to change the effect. 

As a diversion, you can try connecting a Counter element to a path
originating at an AudioSource.  It will count any kind of data packet,
but it changes the colour of its display if it's not the test data.  (You will
also probably hear stuttering of the sound if you move windows around
while that panel is open and counting.  This is completely the fault of
the simple Counter, which updates the window directly from the data
stream thread; if the window happens to be locked, that data may get
delayed unacceptably.  Heck, it's only a hack...) 
 

MIDI
There are just four modules devoted to MIDI so far -- one for each
MIDI Port on the BeBox, one for channel selection, and a note
transposer.

When you place  the Port modules ("Midi 1" and "Midi 2") in the diagram,
 you will observe  that they are a bit different from all the others 
--- they're a bit bigger, and they have two output connector pips.
These are the only examples in this demo of "multiconnector elements".
which combine more than a single "source" or "filter" function into
a single element.  In the present case, each element provides connections
to both the 'MIDI In' and 'Midi Out' functions of its associated port;
it is hence both a 'source' and a 'filter'.   Any input that arrives at the element will drive whatever MIDI device the port is wired to. 
One of the output connectors (either one) can be accessed to get
the MIDI events coming in; the other will then just pass on the events
arriving at the element (not Port) input, just like any other filter.

How do you select which output is which?  Well by default, the first
one you link from is 'Midi In', and the other will then be the pass-
through.  If this is not what you want, you have the option of switching
a connection you have already made.  Use the right mouse button again,
on the connector you wish to modify;  you will get a pop-up menu of
the possibilities: select the one you want (the currently selected option
is checked).

You can use just these elements to build a "MIDI Through" connection.
To pass MIDI In 1 to MIDI Out 1. connect the output of the element
directly back to its own input.  To link MIDI In 1 to MIDI Out 2, or
vice versa, cross connect between the two elements.  You'll notice, by
the way, that you can't place more than one of each element in the
diagrsam.  This prevents the horrible results of having two BMidiPort
objects on the same port -- at least as far as the MusicWeaver is concerned:
it doesn't stop you loading another MIDI application that also uses the
ports!  [I consider this a bug in the MidiKit --- especially as it doesn't
square with the documentation!]

Unlike audio, it is of course perfectly normal to have multiple MIDI
streams converging on a single output port.  Just one problem.  You
can't do it directly!   In general, a multiconnector element can have
several inputs, each with a different function, so --- to avoid confusion ---
each input must be singular.   This applies to the MIDI element too,
even though it in fact only has a single input.  All you need to do,
though, is merge on a 'JoinPaths' element that in turn feeds the MIDI
element.

The two MIDI filter modules are st5raightforward.  Each has a control
panel to adjust the parameter it controls.  And it controls only that
parameter:  'MidiChannel' sets the channel of all channel messages that
pass through it (it doesn't affect system messsages, naturally), nothing
else in the message is affected; 'Transpose' shifts only note-on and
note-off messages by the desired amount.  Chain them together for
combined effects.

You can't actually do much useful with those two, but they are just
a start.  Still to come are all sorts of goodies: key filters, keyboard
range-splits, delays, message generators, certainly record and playback,
so on and so forth.  I am unlikely to write a Sequencer module to plug in,
because I know others can do it much better.  And I'm hoping they will,
and the same for other functions that I haven't thought of.

                                                  *   *   *

Bugs
I've found only one crashworthy bug at this point.  The 'Elide' option
in the element menu is not inhibited (as it should be) when an element
is connected directly to itself; if you use this option under those
circumstances, the program will crash.


What Next?
The first priority is to get a BeOS-Preview-Release version of this
available.   Then I intend to expand the range of MIDI modules
drastically.   After that I'll complete a full-featured edition of the
Weaver, with saving and loading of diagrams, non-default routing
of paths etc.

When I have things organized, I'll make the protocol -- both for MIDI
and the general module mechanism -- available for others to write
their own  bits and pieces.  I'm leaving commercial niggles aside for
now, but I expect to ask some small licence fee --- nothing up front,
but some small proportion of sales or shareware fees,  I'd guess.

As I stressed at the start, the Weaver should be suitable for a lot more
than MIDI.  The data being passed around might be bitmaps, for instance.
Depending on the complexity of the operations you wanted to perform,
it might not be possible to process bitmaps in real-time, but this probably
wouldn't matter for that sort of application, where you would be
performing the same sequence of transformations on a large set of
images for later presentation.

Another attractive possibility is real-time control.  A MIDI track, or
some other master sequence could be linked to controller modules
that would drive special-purpose hardware, synchronize animation,
and so on.

Then there is Scientific Data Acquisition and Analysis.   An important
application area, if anyone gets around to doing it under BeOS...

So, there are interesting possibilities.  Watch this space.


Author:

				Pete Goodeve
				Berkeley, California

		e-mail:	pete@jwgibbs.cchem.Berkeley.EDU
