shithub: neindaw

ref: 8dee36f6f544958eb8430b1d0760f9ecce7e3873
dir: /README.md/

View raw version
# faust9p

Tools to compile [Faust](https://faust.grame.fr) DSP code to a 9p
server, provide UI to control DSP, etc.

## Testing

Since Faust isn't(?) ported to Plan 9 (yet?), first you need to
generate some code on some other OS that supports it, by running
`./gen.sh`.

So far only one instrument provided, which is a kick drum.

```
% ./6.out -m /n/kick
% cd /n/kick

# allocate one instance
% cd `{cat clone}

# check the A oscillator frequency
# the order is: type key value initial min max step
# it's different for different UI elements
% cat K*/a/frequency/ctl
vslider	0	100.000000	100.000000	10.000000	200.000000	5.000000

# raise frequency to 160Hz
% echo 160 > K*/a/f*/ctl

# toggle the gate, we need to compute once in between for it to actually be processed
# then listen to the sound
% echo 0 > 'Kick Drum/control/gate/ctl' && \
	dd -if data -of /dev/null -count 1 -quiet 1 && \
	echo 1 > 'Kick Drum/control/gate/ctl' && \
	audio/pcmconv -i f32c2r44100 -l 128000 < data > /dev/audio

# increase the delay of A oscillator
% echo 0.2 > 'Kick Drum/a/delay/ctl' # make it

# now you can repeat the listen command to hear the difference
```

## Description

A DSP fs presents an interface to create instances of a DSP class by
reading the `clone` file.  In the resulting directory `ctl` is used to
read general info about the dsp, `data` is used to supply input to the
DSP (if it has any inputs) by writing to it, and output can be read
from it.  The format is raw stream of `float`.

Each DSP instance, in addition to the mentioned files, provides a file
tree that reflects the UI elements.  UI elements may provide `ctl`
file to read initial and current, maximum and minimum, step, and may
be used to write a new value to it.  File `value` is for watching the
value of the UI element change: first read gives current value and a
number of samples processed before the change, next read is blocked
until the value is changed.

Several DSPs may be connected by chaining their `data` interfaces
together.  If some parameters need to be changed dynamically during
processing with frame accuracy, it can be achieved by running the
chain for a chunk of data, changing the parameters, then continuing
processing.