Thursday, September 30, 2004

NAME

lab 8 - small update to treemap.

DESCRIPTION

Tmap is a small util that takes the output of du
and presents a treemap using algorithms from UMD
HCILab

To make it a bit more useful I want to zoom into
the treemap and zoom out again. Button one selects
a rectangle highlights it and it's path and
presents information about the path and file
sizes. Button two zooms one level into the
selected area, where the mouse clicked. Button
three zooms out one level.

This was easy to add using Tk. I bind a command to
the mouse events and send a message down a
channel. On receiving the message I change the
root of the tree, regenerate the layout and redraw
the rectangles.

CONCLUSION

I find this a useful tool to find patterns in disk
usage, such as large or duplicate files. Often the
file hierachies are very deep, and so drilling
down interactively is great.

I should re-implement this by drawing directly on
an image instead of using Tk. I seem to be running
out of memory using Tk because I am not keeping
track of the Tk tags when creating new rectangles,
and I'm creating so many of them. It may also be
faster, but I don't know.

There is a bug in the squarified view where the
directory is rendered as if it is a file, using
the totalsize of all sub elements. I haven't found
what causes this. The other views seem okay.

I think the treemap is a beautiful view of the
filesystem. I'd like to put it to more use.

In a collaborative environment the treemap of a
filesystem is a shared map of the system. The
rectangles, which represent files, are color coded
for the users who have them open. This could fit
in as an engine to spree, or collab. We'd need to
monitor all styx messages, similar to Styxmon.

The prog device shows all files open and process
activity. Processes might also be presented as a
treemap.

The treemap could then be made more interactive.
Files are plumbed, to open and edit them. The
files are annotated and new annotations are seen
by all users of the treemap.

This looks like a good excuse to play with spree.
I'm thinking along the lines of VisitorVille
and Plan9's faces.

FILES

REFERENCES

Tuesday, September 28, 2004

NAME

lab 7 - sequencer; create a simple sequencer that
can play back a subset of SKINI messages.

SETUP

Inferno 4th Edition release 20040830.

DESCRIPTION

2004/0928 20:37SKINI is the sequencing language from the STK. It
is a readable form of MIDI, and was designed to be
"extensable and hackable"; all of which make it
ideally suited to this application and Inferno.
Here is a brief example

There is one command per line. The line begins
with command name followed by parameters separated
by space or tabs. The second parameter is always
the time delta. For the NoteOn command, the third
argument is channel (or voice), fourth is midi
pitch, and fifth if velocity (I guess! I'm
ignoring it for now).

These SKINI messages are interpreted by sequencer,
which sends messages to one or more instruments
and reads back audio data.

I created a basic instrument module, which should
be used as a template for later instruments,
called simple. It uses the adsr and wave modules.

The wave module I have described previously. Adsr
is a standard Attack, Decay, Sustain, Release
envelope. I copied the implementation from the
STK.

Simple and sequencer use a new interface to assist
in using other signal sources.

The source signals are opened by init. I made a
small modification to signalfs.b moving the init
call from signalfs.b:/serve to
signalfs.b:/requestproc to avoid deadlock.

I created /mnt/dsp for mounting signalfs and
/mnt/dsp/raw because I am hardcoding the names of
some signal sources and raw sound files. The raw
files from the STK should be bound or copied to
/mnt/dsp/raw. Therefore start as

CONCLUSION

The SKINI language has more commands and features
than implemented here.

Again, it is slow. I should buffer writes to the
/dev/audio, maybe a few seconds worth, so the
audio sounds smooth. Otherwise, I need to write to
a file first then stream the file to /dev/audio.
However, It's enough for testing while creating
some of the more complex instruments from the STK.

The sequencer could be a module of signalfs like
any other. Reads of the data return the audio
data. The ctl file is a synthetic file which could
be edited within any editor. But this is a
slightly different interface than other signals.
An alternative is to use the skini file as a
source file just like the raw files for the wave
module. The sequencer module then represents
patterns, which can be combined, looped, and
sequenced just like any other signal.

DAY DREAMING

I can have a grid generating the sounds. What is
possible with unlimited cpu power? Using a grid we
should be able to create, in realtime, a very
complex syntesized soundscape. Could we use the
plan9 grid for this? Run emu on each node, serve a
signalfs, bind them all into a local namespace,
then generate the patterns. 8 channel, 24 bit,
unlimited voice and polyphony.

Wednesday, September 22, 2004

NAME

SETUP

DESCRIPTION

2004/0922 21:24
Changed filter.b to use the clone interface. The
ctl file accepts a source command which takes a
filename or another signal source which may be
served by the same signalfs

% echo source /usr/caerwyn/lab/6/mnt/wave > mnt/filter/2/ctl

The filter module then opens ctl reads the number
of the conversation directory and then opens data.
The filter is then responsible for setup of the
signal source. It should probably pass through
commands written to ctl that it does not
understand, so the wave can be controlled through
the filter ctl.

I made a small change to signalfs.b to not fork
the namespace so the mount of the server affects
the current process and the filter module is able
to access the wave

176c178
< pidc pctl(0, nil);
---
> pidc pctl(Sys->FORKNS, nil);

CONCLUSION

The recursion (if that's the right term) works.
Filter reads data from wave served by the same
file server; or it could be a different file
server running remotely.

This was a quick lab session to resolve my doubts
about signalfs. Need to really start implementing
all the filters. Especially those that combine
multiple sources.

The module itself uses the ctl message to
determine whether it should open a connection to
clone and read the Fibonacci number for the number
- 1. If the ctl number is 0 it returns 1, ending
the recursion.

The module is a single function. The parameters
are controlled by the ctl file, and the result is
read from data.

The fileserver framework manages the clone and
naming and loading of modules. I used wmexport.b
as the starting point for building a framework.

2004/0918 21:28
The ip(3) device comes close to what I want. A
directory for each proto (module); a clone below
that, and a numbered directory for each instance.
The numbered directory has ctl and data. The
numbered directories aren't removed but keep state
variable tracking whether in use.

What if we get a read on the data file from a
process other than the opening process? We want to
deny this.

2004/0919 16:51
Writing and debugging.

2004/0919 20:08
Is this something like spree, where the loaded
module is an engine?

2004/0919 22:41
Given the layout of signalfs a filter is given the
directory for the source module. The filter opens
the clone file to get a connection. It then has
exclusive access to that module. The filter
exposes the same interface, so I could create
multiple connections to that filter. But what if I
want to alter the sinewave that the filter is
reading from? Do I want shared write access to the
sine ctl file? I'd need to know the connection the
filter was reading from. No. The filter is in
complete control of it's source.

2004/0921 22:01
Writeup and debugging.

Signalfs now knows nothing of the format of the
signal. The signal is responsible for converting
arrays of real to bytes. The signal interface has
changed

CONCLUSION

Once this is debugged, I've reached the point
where I can write all the signal modules. I still
have no real plan for a sequencer. It may end up
being shell script. I haven't tested the
recursiveness yet.

I could have implemented signals using file2chan(2) except I am supporting the more complicated
interface of clone, ctl and data. I hope it will
be worth it having all the modules organized
together under one server.

Tickfs might be better adapted to this interface.
The ctl message for lookup are written to the ctl
file, and I can control permission on the data
file.

REFERENCES

Thursday, September 16, 2004

NAME

lab 4 - signalfs; generalize wavefs to a family of
file servers that support a variety of sound
sources and filters.

SETUP

Inferno 4th edition release 20040830. Using wavefs
and the Synthesis Toolkit in C++.

DESCRIPTION

I started with the wavefs source and abstracted
out an interface for modules that the fileserver
can call. The signal processor implements this
interface. The compiled dis module that implements
a specific dsp is passed as parameter to the
signalfs which exports the standard files

Messages written to /signalctl are passed to
config, and reads return the contents of
Signal.configstr. Reads from /signal, which is
readonly, are sent data generated by tickFrame. I
rewrote the wave loop module using this interface.
wave.b
The server is now mounted as

DESCRIPTION

I've been looking for tools to experiment with
DSP. The synthesis toolkit has a good all round
collection of DSP routines and the code is easy
enough to read. I wanted this "sound workbench"
well integrated with inferno. Where possible make
the resources files or file2chans.

The first step was to make a sound source; an
oscillator. For this I created a file server that
serves two files

/ctl
/data

I started with the sample code from
styxservers-nametree(2). The server is given a raw
audio file to loop. I took the example raw files
included in the STK distribution. These are 16bit
mono, big-endian two's complement.

The data file served is an unlimited stream of
data in 16bit mono, little-endian, two's
complement suitable for streaming to /dev/audio

CONCLUSION

These are the final versions: pcm.bgr.bwavefs.bffts.bseq.b
And here is the sinewave from the STK package.
sinwave.raw
Given the above I have a model to build a family
of fileservers. Each serves a ctl and data file.
Reading from data always reads the sound samples
in a format suitable for /dev/audio and writing to
ctl controls the effect, filter, or oscillator.

The filesystems can be layered. So a filter is
started by giving it as parameter the wave file

The size of the file is always 0. I checked the
/appl/cmd/disk/kfs.b for calls it makes to the
file. All reads and writes are blocks; blocksize
can be given as a parameter. It calls fstat in one
place to get the file size. I changed it to take
the size of the file as a parameter.

CONCLUSION

Layering of filesystems is fascinating. There is
very clear separation between programs, a well
defined interface, and reuse of code to accomplish
something new. In this example we have the kfs on
top of cryptfile on top of the host file system.
And of course other file systems can be run on top
of the files within kfs, such as tarfs.

I haven't looked into the security of this
solution. ECB itself is not as secure as CBC, but
only ECB is usable for random access to blocks.
There is likely to be known plaintext within the
kfs.file such as the magic word at the start.
Also, decrypted data is stored in memory and might
be swapped to disk by the host system.

A small enhancements would be to prompt twice for
password, or passphrase, without echo.

SETUP

DESCRIPTION

Sh has command blocks which can be passed as
params to commands, and executed. I want to
exploit this to see if I can implement much of the
flavor of Postdate in the shell. I already have
tickfs in Inferno which supports bi-temporal
binary relations. So the value for a tickfs entry
could be the sh command block.

I can now call the function add; the code comes
from a lookup in tickfs

% ${pd add} 1 1
2

I'll create a function I want to vary along the
timeline. I can also define variables using the
same method. I'll create a substition function
that uses rng to give the date in epoch format.
And then use that in ${pd} to select the effective
fuction or variable

I have to redefine pdfn and pd to use ${hd $pdstk}
instead of hardcoded /n/tick/sh.bt.

The usual mode of processing tickfs result sets is
in a pipeline. If I define a temporal package as a
tickfs file with a main sh command block, the
pdpkg command will call main on one triad at a
time from stdin. It doesn't need to convert from
YYYYMMDD format to epoch because triads always
come in epoch format. We'll get around that by
just defining another pd function, say epd, that
takes seconds since the epoch.

CONCLUSION

I have created shell functions and variables that
can vary along the valid time line. I created
packages, blocks of temporal shell code, that can
be applied to tickfs result set. It is more
featureful that Postdate, since we have the whole
shell and inferno at our disposal. It is slow. I'm
not concerned with the perfomance now. I want to
find out if there's some interesting functions
that I can implement that can vary along the
timeline.

Postdate also has the effective valid time stack.
We could implement the stack in the same way as
pdstk but really the effective time is in the
callstack since it is passed as a param to every
call of pd.