-- Basic components for OAK. #USE "snglmath.lib" #INCLUDE "mathvals.inc" #INCLUDE "oak.inc" --{{{ SIGNAL FUNCTION signal (VAL [BLOCK.SIZE]REAL32 in) --* Yuck -- this is a workaround for not being able to use array constructors to build SIGNALs. SIGNAL FUNCTION signal (VAL [BLOCK.SIZE]REAL32 in) SIGNAL r: VALOF SEQ i = 0 FOR BLOCK.SIZE r[i] := in[i] RESULT r : --}}} --{{{ PROC join (CHAN SIGNAL in, CHAN SIGNAL out) PROC join (CHAN SIGNAL in, CHAN SIGNAL out) WHILE TRUE SIGNAL s: SEQ in ? s out ! s : --}}} --{{{ PROC sink (CHAN SIGNAL in) PROC sink (CHAN SIGNAL in) WHILE TRUE SIGNAL s: in ? s : --}}} --{{{ PROC constant (VAL REAL32 value, CHAN SIGNAL out) PROC constant (VAL REAL32 value, CHAN SIGNAL out) WHILE TRUE out ! signal ([i = 0 FOR BLOCK.SIZE | value]) : --}}} --{{{ PROC da (CHAN SIGNAL in, []CHAN SIGNAL out) PROC da (CHAN SIGNAL in, []CHAN SIGNAL out!) WHILE TRUE SIGNAL s: SEQ in ? s PAR i = 0 FOR SIZE out out[i] ! s : --}}} --{{{ PROC mixer ([]CHAN SIGNAL in, VAL []REAL32 level, CHAN SIGNAL out) PROC mixer ([]CHAN SIGNAL in?, VAL []REAL32 level, CHAN SIGNAL out) WHILE TRUE INITIAL SIGNAL sum IS signal ([i = 0 FOR BLOCK.SIZE | 0.0]): SEQ SEQ i = 0 FOR SIZE in SIGNAL s: SEQ in[i] ? s SEQ j = 0 FOR BLOCK.SIZE sum[j] := sum[j] + (s[j] * level[i]) out ! sum : --}}} --{{{ PROC amp (CHAN SIGNAL in, VAL REAL32 factor, CHAN SIGNAL out) PROC amp (CHAN SIGNAL in, VAL REAL32 factor, CHAN SIGNAL out) WHILE TRUE SIGNAL s: SEQ in ? s out ! signal ([i = 0 FOR BLOCK.SIZE | s[i] * factor]) : --}}} --{{{ PROC sqrt (CHAN SIGNAL in?, CHAN SIGNAL out!) PROC sqrt (CHAN SIGNAL in?, CHAN SIGNAL out!) WHILE TRUE SIGNAL s: SEQ in ? s out ! signal ([i = 0 FOR BLOCK.SIZE | SQRT (s[i] + 0.001)]) : --}}} --{{{ PROC gate (CHAN SIGNAL in, CHAN SIGNAL gate, CHAN SIGNAL out) PROC gate (CHAN SIGNAL in, CHAN SIGNAL gate, CHAN SIGNAL out) WHILE TRUE SIGNAL a, b: SEQ in ? a gate ? b out ! signal ([i = 0 FOR BLOCK.SIZE | a[i] * b[i]]) : --}}} --{{{ PROC transpose (CHAN SIGNAL in?, out!, VAL INT steps) -- To be used on a frequency stream... PROC transpose (CHAN SIGNAL in?, out!, VAL INT steps) amp (in?, POWER (FREQ.FACTOR, REAL32 ROUND steps), out!) : --}}} --{{{ PROC pitchbend (CHAN SIGNAL in?, bend?, out!, VAL REAL32 range) --* Apply pitchbend to a frequency stream. PROC pitchbend (CHAN SIGNAL in?, bend?, out!, VAL REAL32 range) WHILE TRUE SIGNAL f, b: SEQ PAR in ? f bend ? b out ! signal ([i = 0 FOR BLOCK.SIZE | f[i] * POWER (FREQ.FACTOR, range * b[i])]) : --}}} --{{{ PROC limiter (CHAN SIGNAL in?, out!) -- A proper compressor/limiter would be much better... PROC limiter (CHAN SIGNAL in?, out!) WHILE TRUE SIGNAL s: SEQ in ? s SEQ i = 0 FOR BLOCK.SIZE REAL32 v IS s[i]: IF v > 0.999 v := 0.999 v < (-0.999) v := (-0.999) TRUE SKIP out ! s : --}}} --{{{ Support for manipulating individual samples --{{{ PROC to.single (CHAN SIGNAL in?, CHAN REAL32 out!) PROC to.single (CHAN SIGNAL in?, CHAN REAL32 out!) WHILE TRUE SIGNAL s: SEQ in ? s SEQ i = 0 FOR BLOCK.SIZE out ! s[i] : --}}} --{{{ PROC from.single (CHAN REAL32 in?, CHAN SIGNAL out!) PROC from.single (CHAN REAL32 in?, CHAN SIGNAL out!) WHILE TRUE SIGNAL s: SEQ SEQ i = 0 FOR BLOCK.SIZE in ? s[i] out ! s : --}}} --{{{ BUFFER FUNCTION new.buf () BUFFER FUNCTION new.buf () IS [(-1), signal ([i = 0 FOR BLOCK.SIZE | 0.0])]: --}}} --{{{ PROC buf.input (BUFFER buf, CHAN SIGNAL in?, REAL32 val) PROC buf.input (BUFFER buf, CHAN SIGNAL in?, REAL32 val) SEQ IF (buf[count] = BLOCK.SIZE) OR (buf[count] = (-1)) SEQ in ? buf[data] buf[count] := 0 TRUE SKIP val := buf[data][buf[count]] buf[count] := buf[count] + 1 : --}}} --{{{ PROC buf.output (BUFFER buf, CHAN SIGNAL out!, VAL REAL32 val) PROC buf.output (BUFFER buf, CHAN SIGNAL out!, VAL REAL32 val) SEQ IF buf[count] = (-1) buf[count] := 0 TRUE SKIP buf[data][buf[count]] := val buf[count] := buf[count] + 1 IF buf[count] = BLOCK.SIZE SEQ out ! buf[data] buf[count] := 0 TRUE SKIP : --}}} --}}}