Refactoring in faustexp.ml.
[Faustine.git] / interpretor / faust-0.9.47mr3 / tools / faust2pd / examples / seqdemo / sequencer.pure
1
2 /* A basic pd-pure pattern sequencing example. This Pure script generates the
3 sequences played by the seqdemo.pd patch. */
4
5 using math;
6
7 /* Simple (monophonic) musical patterns with aleatoric elements represented as
8 streams. */
9
10 rand m::int = int (uint random/0x100000000*(m+1));
11 rand (n::int,m::int)
12 = rand (m-n) + n;
13
14 /* Choose an element at random. */
15
16 choose xs = (xs!rand (#xs-1));
17
18 /* Concatenate a recursive pattern to a flat sequence. */
19
20 mkseq [] = [];
21 mkseq (x:xs) = catmap mkseq (x:xs);
22 mkseq x = [x] otherwise;
23
24 /* Sample patterns. pat1 is shamelessly pilfered from the SuperCollider
25 documentation, pat2 is a finite section of pat1, and pat3 is a simple
26 random C minor arpeggio. */
27
28 pat1 = [[24, 31, 36, 43, 48, 55,
29 [[60, choose [63, 65], 67, choose [70, 72, 74]] |
30 i = 1..rand (2,5)],
31 [choose [74, 75, 77, 79, 81] |
32 i = 1..rand (3,8)]] |
33 i = 1..inf];
34
35 pat2 = [[24, 31, 36, 43, 48, 55,
36 [[60, choose [63, 65], 67, choose [70, 72, 74]] |
37 i = 1..rand (2,5)],
38 [choose [74, 75, 77, 79, 81] |
39 i = 1..rand (3,8)]] |
40 i = 1..rand (2,5)];
41
42 pat3 = [[60,60,choose [63,67]] | i = 1..inf];
43
44 /* The sequencer object. */
45
46 nonfix bang reset; // we respond to these
47 nonfix stop note pan wet; // we generate these
48
49 sequencer = process
50
51 with
52
53 /* Process events. Respond to the messages 'bang' (produce the next stream
54 member), 'reset' (rewind the stream to the beginning), numbers (change
55 the note duration a.k.a. delta time value) and a pattern (to switch
56 patterns on the fly). Last but not least we also send back a 'stop'
57 message when the stream ends (of course this will only happen if the
58 sequence is finite). */
59
60 process x::double
61 = () when put dur x end;
62 process pat@(_:_)
63 = ()
64 when pat = mkseq pat;
65 put time 0; put ctr 0;
66 put seq pat; put seq0 pat;
67 end;
68 process reset = () when put seq (get seq0); put time 0; end;
69 process bang = case get seq of
70 n:seq1 = event n when
71 put seq seq1; put time (get dur);
72 end;
73 _ = stop;
74 end;
75 process _ = stop;
76
77 /* Turn a stream member (a note number in this case) into a sequence of
78 events (a.k.a. Pd messages). The sample event function below illustrates
79 how to carry around some state (a running counter in this case) in order
80 to implement some dynamic effects, and how to do random pitch, velocity
81 and onset variations on the fly. Also note that here we return an entire
82 "bundle" (i.e., list) of Pd messages for each pattern element. */
83
84 event n = {// play a note on voice #2:
85 t 2 note n 1 d,
86 // vary the pan and wet controls of voice #2 in a periodic
87 // fashion to simulate a sound source walking around in
88 // circles:
89 t 2 pan (0.4+0.3*u),
90 t 2 wet (0.35+0.1*w),
91 // play the same note, delayed by a small amount of time,
92 // transposed down an octave and slightly detuned,
93 // alternating between voice #1 and voice #3:
94 (t+dt) (2*k+1) note (n-12+dn) v d}
95 when i = getctr ctr; k = i mod 2;
96 x = i mod 100/100*2*pi; u = cos x; w = sin x;
97 t = get time; d = get dur; dt = rand (0,10);
98 dn = rand (-20,20)/1000;
99 v = rand (90,120)/100;
100 end;
101 getctr c = k when k = get c; put c (k+1) end;
102
103 end
104
105 when
106 // initialize
107 dur = ref 500; time = ref 0; ctr = ref 0;
108 pat = mkseq pat1;
109 seq = ref pat; seq0 = ref pat;
110 end;