Three Node Markov Chain Jacob Joaquin July 5, 2010 jacobjoaquin@gmail.com csoundblog.com sr = 44100 kr = 44100 ksmps = 1 nchnls = 1 0dbfs = 1 ; Instruments # define Start # 1 # # define Stop # 2 # # define State_0 # 3 # # define State_1 # 4 # # define State_2 # 5 # # define TriPunch # 6 # ; Tables ; Waveforms # define t_tri # 1 # ; State Odds # define S_0 # 2 # # define S_1 # 3 # # define S_2 # 4 # ; Dependencies # define WeightedRandomFn # 5 # ; Table gi_tri ftgen $t_tri, 0, 2 ^ 16, -7, 0, 2 ^ 14, 1, 2 ^ 15, -1, 2 ^ 14, 0 ; Connect state nodes gitemp ftgen $S_0, 0, -6, -2, $State_0, 1, $State_1, 1, $State_2, 1 gitemp ftgen $S_1, 0, -6, -2, $State_0, 2, $State_1, 2, $State_2, 1 gitemp ftgen $S_2, 0, -6, -2, $State_0, 1, $State_1, 2, $State_2, 7 ; Different every time ;seed -1 opcode WeightedRandom, i, i ifn xin ; Table of ordered (element, weight) pairs isize = ftlen(ifn) isize_2 = int(isize / 2) iweight_fn ftgen $WeightedRandomFn, 0, isize_2 * -1, -2, 0 iweight_total init 0 ; Get elements and weights i_index init 0 start_loop: iweight tab_i i_index * 2 + 1, ifn iweight_total = iweight_total + iweight tabw_i iweight_total, i_index, iweight_fn loop_lt i_index, 1, isize_2, start_loop ; Choose element based on weighted values i_index = 0 irandom random 0, iweight_total start_loop_2: ival tab_i i_index, iweight_fn if irandom < ival igoto end i_index = i_index + 1 igoto start_loop_2 end: ielement tab_i i_index * 2, ifn xout ielement endop opcode SelectState, i, iiiiS istate_fn, \ ; Table storing weighted odds inext, \ ; Time until next note itempo, \ ; Tempo ratio iamp, \ ; Amplitude Sid xin itime_left chnget Sid itime_left = itime_left - inext if itime_left >= 0 then chnset itime_left, Sid istate WeightedRandom istate_fn Sevent sprintf {{i %d %f %f %f "%s"}}, istate, inext * itempo, \ itempo, iamp, Sid scoreline_i Sevent endif xout 1 endop instr $Start itempo = p3 ; Tempo idur = p4 ; Duration in beats iamp = p5 ; Amplitude Sid = p6 ; String identifier of running Markov chain p3 = idur * itempo ; Duration in seconds ; Begin Markov chain Sevent sprintf {{i %d 0 %f %f "%s"}}, $State_0, itempo, iamp, Sid scoreline_i Sevent ; Create a bus to track remaining time istatus = 1 chn_k Sid, 3 chnset idur, Sid turnoff endin instr $State_0 itempo = p3 ; Tempo in seconds per beat iamp = p4 ; Amplitude Sid = p5 ; Markov process ID inext = 0.5 ; Duration of of note ifreq = cpspch(8.03) ; Frequency ;Trigger note event "i", $TriPunch, 0, itempo, inext, iamp, ifreq ; Select next state itemp SelectState $S_0, inext, itempo, iamp, Sid turnoff endin instr $State_1 itempo = p3 ; Tempo in seconds per beat iamp = p4 ; Amplitude Sid = p5 ; Markov process ID inext = 1 ; Duration of of note ifreq = cpspch(8.00) ; Frequency ;Trigger note event "i", $TriPunch, 0, itempo, inext, iamp, ifreq ; Select next state itemp SelectState $S_1, inext, itempo, iamp, Sid turnoff endin instr $State_2 itempo = p3 ; Tempo in seconds per beat iamp = p4 ; Amplitude Sid = p5 ; Markov process ID inext = 0.25 ; Duration of of note ifreq = cpspch(7.07) ; Frequency ;Trigger note event "i", $TriPunch, 0, itempo, inext, iamp, ifreq ; Select next state itemp SelectState $S_2, inext, itempo, iamp, Sid turnoff endin instr $TriPunch itempo = p3 ; Tempo in seconds per beat idur = p4 * itempo ; Duration in seconds iamp = p5 ; Amplitude ifreq = p6 ; Frequency p3 = idur ; Modify play time from beats to seconds iattack = 0.06 irandom random 0.995, 1.005 a1 oscil iamp, ifreq * irandom, gi_tri a2 linseg 1, iattack, 0.1, idur - iattack, 0 out a1 * a2 endin ; Instruments # define Start # 1 # # define Stop # 2 # # define State_0 # 3 # # define State_1 # 4 # # define State_2 # 5 # # define TriPunch # 6 # t 0 96 i $Start 0 1 64 0.7 "process_1" i $Start 48 1 16 0.2 "process_2" ; Play the chain concurrently e 64