-- Demo tune for OAK: "Popcorn" by Hot Butter. #INCLUDE "oak.inc" #USE "basic" #USE "delay" #USE "osc" #USE "env" #USE "organ" #USE "seq" #USE "alsaout" --{{{ Sample sequenced tune PROC popcorn.seq (CHAN NOTE tune!, bass!) --{{{ PROC popcorn.tune VAL []INT notes.1 IS [nn (C, 3), nn (B.B, 2), nn (G, 2), nn (E.B, 2), nn (C, 2), nn (D, 3), nn (E.B, 3), nn (D, 3), nn (E.B, 3), nn (A.B, 2), nn (C, 3)]: VAL []INT notes.2 IS [nn (G, 3), nn (F, 3), nn (E.B, 3), nn (B.B, 2), nn (G, 2), nn (A, 3), nn (B.B, 3), nn (F, 3), nn (G, 3), nn (E.B, 3), nn (D, 3)]: PROC popcorn.tune (CHAN NOTE out!, VAL BOOL second.time, altered, VAL []INT notes) PROC bit (VAL INT n.1, n.2, n.3, n.4, VAL BOOL last) SEQ out ! note ; n.1 ; SQ IF altered SEQ out ! note ; n.2 ; DSQ out ! note ; n.4 ; SQ IF last SEQ out ! note ; n.4 ; DSQ out ! note ; n.3 ; SQ TRUE SEQ out ! note ; n.4 ; SQ out ! note ; n.3 ; DSQ TRUE SEQ out ! note ; n.2 ; SQ out ! note ; n.4 ; SQ out ! note ; n.3 ; SQ : INT adjust: SEQ IF altered adjust := DSQ TRUE adjust := 0 SEQ i = 0 FOR 2 SEQ out ! note ; notes[0] ; SQ out ! note ; notes[1] ; SQ out ! note ; notes[0] ; SQ out ! note ; notes[2] ; SQ out ! note ; notes[3] ; SQ - adjust out ! note ; notes[2] ; SQ out ! note ; notes[4] ; SQ out ! rest ; SQ + adjust out ! note ; notes[0] ; SQ out ! note ; notes[5] ; SQ bit (notes[6], notes[5], notes[0], notes[6], FALSE) bit (notes[5], notes[0], notes[1], notes[5], FALSE) IF second.time SEQ bit (notes[0], notes[1], notes[7], notes[10], TRUE) out ! note ; notes[8] ; SQ TRUE SEQ bit (notes[0], notes[1], notes[9], notes[0], FALSE) out ! note ; notes[0] ; SQ out ! rest ; SQ : --}}} --{{{ PROC popcorn.bass PROC popcorn.bass (CHAN NOTE out!) PROC part1 (CHAN NOTE out!) SEQ out ! note ; 0 ; SQ out ! note ; 7 ; DSQ out ! note ; 4 ; DSQ : PROC part2 (CHAN NOTE out!) SEQ out ! note ; 0 ; DSQ out ! note ; 2 ; DSQ out ! note ; 4 ; DSQ out ! note ; 7 ; DSQ : PROC parts (CHAN NOTE out!, VAL [7]INT scale.1, scale.2, VAL BOOL second.time) CHAN NOTE ts: SEQ PAR SEQ part1 (ts!) IF second.time part2 (ts!) TRUE part1 (ts!) ts ! end use.scale (ts?, out!, scale.1, -1) PAR SEQ part1 (ts!) part2 (ts!) ts ! end use.scale (ts?, out!, scale.2, -1) : PROC bass (VAL [7]INT scale.1, scale.2, scale.3, scale.4, scale.5) SEQ parts (out!, scale.1, scale.1, FALSE) parts (out!, scale.1, scale.1, FALSE) parts (out!, scale.2, scale.3, TRUE) parts (out!, scale.4, scale.5, TRUE) : VAL []INT c.minor IS make.scale (MINOR, nn (C, 0)): VAL []INT g.minor IS make.scale (MINOR, nn (G, 0)): VAL []INT f.major IS make.scale (MAJOR, nn (F, 0)): VAL []INT bb.major IS make.scale (MAJOR, nn (B.B, 0)): VAL []INT ab.major IS make.scale (MAJOR, nn (A.B, 0)): VAL []INT eb.major IS make.scale (MAJOR, nn (E.B, 0)): SEQ bass (c.minor, c.minor, bb.major, ab.major, c.minor) bass (c.minor, c.minor, bb.major, ab.major, c.minor) bass (eb.major, g.minor, f.major, eb.major, eb.major) bass (eb.major, g.minor, f.major, eb.major, c.minor) : --}}} PAR SEQ tune ! rest ; CR tune ! rest ; Q WHILE TRUE SEQ popcorn.tune (tune!, FALSE, FALSE, notes.1) popcorn.tune (tune!, TRUE, FALSE, notes.1) popcorn.tune (tune!, FALSE, FALSE, notes.2) popcorn.tune (tune!, TRUE, FALSE, notes.2) popcorn.tune (tune!, FALSE, TRUE, notes.1) popcorn.tune (tune!, TRUE, TRUE, notes.1) popcorn.tune (tune!, FALSE, TRUE, notes.2) popcorn.tune (tune!, TRUE, TRUE, notes.2) SEQ bass ! rest ; M WHILE TRUE popcorn.bass (bass!) : --}}} --{{{ PROC popcorn PROC popcorn (CHAN BYTE keyboard, screen, error) CHAN NOTE notes.0, notes.1: CHAN SIGNAL freq.0, freq.1, gate.0, gate.1, inst.0, inst.1: CHAN SIGNAL master, reverbed, limited, out.l, out.r: PAR popcorn.seq (notes.0!, notes.1!) note.to.freq (notes.0?, freq.0!, gate.0!) CHAN SIGNAL a, b, c: VAL []INT length IS [200, 1000, 2000, 200]: VAL []REAL32 level IS [0.0, 1.0, 0.5, 0.5, 0.0]: PAR vibrato (freq.0?, c!, 20.0, 0.0) generate.organ (c?, 5, a!) envelope (gate.0?, length, level, b!) gate (a?, b?, inst.0!) note.to.freq (notes.1?, freq.1!, gate.1!) #IF FALSE -- siren noise! CHAN SIGNAL a, b, c, d: PAR constant (2.0, a!) generate.sine (a?, b!) constant (1100.0, c!) mixer ([b?, c?], [1000.0, 1.0], freq.1!) #ENDIF CHAN SIGNAL a, b: VAL []INT length IS [200, 1500, 5000]: VAL []REAL32 level IS [0.0, 1.0, 0.5, 0.0]: PAR generate.organ (freq.1?, 3, a!) envelope (gate.1?, length, level, b!) gate (a?, b?, inst.1!) mixer ([inst.0?, inst.1?], [0.5, 0.5], master!) reverb (master?, reverbed!, 4000, 0.05) limiter (reverbed?, limited!) --scope (limited?, screen!) da (limited?, [out.l!, out.r!]) alsa.out (out.l?, out.r?) : --}}}