-- OAK sequencing support. #USE "snglmath.lib" #INCLUDE "mathvals.inc" #INCLUDE "oak.inc" #USE "basic" --{{{ INT FUNCTION nn -- Turn a note name and octave into a (MIDI-ish) note number. INT FUNCTION nn (VAL INT note, octave) IS note + (12 * octave): --}}} --{{{ REAL32 FUNCTION note.freq REAL32 FUNCTION note.freq (VAL INT note) IS FREQ.C * POWER (FREQ.FACTOR, REAL32 ROUND note): --}}} --{{{ REAL32 FUNCTION midi.freq -- Workaround for now -- we should really use MIDI note numbers all over. REAL32 FUNCTION midi.freq (VAL INT note) IS 440.0 * POWER (FREQ.FACTOR, REAL32 ROUND (note - 69)): --}}} --{{{ PROC note.to.freq PROC note.to.freq (CHAN NOTE in?, CHAN SIGNAL out.f!, out.g!) INITIAL BUFFER f.buf IS new.buf (): INITIAL BUFFER g.buf IS new.buf (): INITIAL BOOL running IS TRUE: WHILE running in ? CASE INT n, l: note ; n ; l VAL REAL32 freq IS note.freq (n): INITIAL REAL32 t IS 1.0: SEQ i = 0 FOR (SAMPLES.PER.HDSQ * l) SEQ buf.output (f.buf, out.f!, freq) buf.output (g.buf, out.g!, t) t := 0.0 INT l: rest ; l SEQ i = 0 FOR (SAMPLES.PER.HDSQ * l) SEQ buf.output (f.buf, out.f!, 440.0) buf.output (g.buf, out.g!, 0.0) end running := FALSE : --}}} --{{{ [7]INT FUNCTION make.scale [7]INT FUNCTION make.scale (VAL [7]INT scale, VAL INT base) IS [i = 0 FOR SIZE scale | scale[i] + base]: --}}} --{{{ PROC use.scale -- Convert a CHAN NOTE using notes in the scale to real notes PROC use.scale (CHAN NOTE in?, out!, VAL []INT scale, VAL INT root.octave) INITIAL BOOL running IS TRUE: WHILE running in ? CASE INT n, l: note ; n ; l VAL INT note IS n \ (SIZE scale): VAL INT octave IS (n / (SIZE scale)) + root.octave: out ! note ; scale[note] + (12 * octave) ; l INT l: rest ; l out ! rest ; l end running := FALSE : --}}}