1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# Sequencer/tracker based on a string pattern
β¨
SetOpts # Set global options
MakeTrack # Build entire track
Sequence # Build a single instrument
AdvanceState # Advance state object π© past pattern π¨
ReadPattern # Read pattern for a track from lf-separated string
β©β
"tracker.bqn takes a single option namespace, or no arguments" ! 1β₯β β’args
op β β βΆβ¨β’Importβ"options.bqn", ββ© β’args
β¨Addβ©βΏβ¨Lp2,Hp2β© β op β’ImportΒ¨ "mix.bqn"βΏ"filter.bqn"
# Sequencing options
Opts β {
shifts β {π©.shifts}β("><]["βΓ·8βΏΒ―8βΏ3βΏΒ―3) π©
gains β {π©.gains} β("-+"β1.2βΒ―1βΏ1) π©
noop β {π©.noop} β"." π©
control β noopβΎshiftsβΎββgains # Non-sample characters
GetShiftβΏGetVol β 0βΏ1 {{π©βΛπ¨βΈβ}β(βΎβπ¨)Λπ©}Β¨ shiftsβΏgains
beat β {π©.beat} β(!Λ) π© # Starting samples/beat (optional with :BEAT:)
swing β {π©.swing}ββ¨1β© π© # Modifier for length of each beat
empty β {π©.empty}β(2βΏ0β₯0) π©
pink β {π©.pink} β2 π© # Level of pink noise "humanization"
end β {π©.end} β0 π© # Number of additional beats at the end
}
o β Opts{β}
SetOpts β { o β© Opts π© }
# Build a multi-track pattern
MakeTrack β { ππ©:
patternβΏsample β π© β pattern<Λβ(1<=)β© # Template, and sample function
state β patternβ’Β¨{β¨vβstateβ©:v;{β}}π© # Starting state for each track
overlap β {β¨vβoverlapβ©:v;0Β¨ pattern}π© # Whether adjacent samples overlap
post β {β¨vβpost β©:v;β’ΛΒ¨pattern}π© # Post-processing for each channel
postgroup β {β¨vβpostgroupβ©:v; ββ post}π© # Group equal values: add before post-processing
arg β β[pattern,sample,state,overlap]
_sum β { π½_π£β¨xβ©: π½x ; o.empty π½βΈAddΒ΄ π© }
{ (postβΛβπ©){ππ©} (Sequence ββarg)_sum π© } _sum βpostgroup
}
# String handling
Ex β +`βΈΓβΒ¬-β’
Cut β ExΛβ=ββ’
ReadPattern β { βΎΛβ> 1βΈΒ»βΈ<βΈExβ(0=β Β¨)βΈβ (@+10) Cut π© }
# :BEAT: indication handling
Getb β β’BQN
Avgb β (+´÷β )ββ₯
# Sound utilities
Con β βΎβ
# Pink noise with no normalization
Rand β -βΒ¬ {op.RandFloatsπ©}
PinkDiff β {π© β β₯ββββΒ΄β½ -βΒ«βRandΒ¨ (1ββββ)βΎ(2ββΌβ’)2βπ©}
# Output is β¨list of lengths, list of characters, average lengthsβ©
ParseBeats β {
m β "Initial beat length unknown"
s β ':' Cut ' 'βΈβ βΈ/ π©
g β (β1βs) {π©.beat}βπ¨βΈββΈβΎβ(0<β ββ£) GetbΒ¨βΎ(ββ) ββΏ2β₯1βs
<ββΎΛ β (β ββ’ β₯Β¨ ββΎAvgbββ£)Β΄Λ g
}
AdvanceState β { b π st:
offset β ({π©.offset}β0π¨) + β0.5 +Β΄ β st ParseBeats b
beat β {β':'βb ? Avgb Getb 1β (1-Λβ’Β΄)βΈ=β(+`':'βΈ=)βΈ/ b ; st.beat}
}
Sequence β { πpβΏsβΏt:ππ©βΎ0 ; π patternβΏGetSamplesβΏstateβΏoverlap:
# Beat length, character, average length
bβΏcβΏa β state ParseBeats pattern
# Compute lengths
b +β© (β₯β(o.swing-1) + (o.pinkΓ·100){(0β π)βΆβ¨0,πΓPinkDiffβ©})ββ βΈΓ a
ge β (mβΎ0) (Β¬βΈΓ-β£) g β +`0βΎΛ m β Β¬ cβo.control
sh β +´¨ ge β 0βΎΛb Γ o.GetShift c
len β β0.5+ (-βΒ»sh) + +´¨ g β bβΎo.endΓΒ―1βb
# Samples
vol β Γ´¨ Β―1β ge β 1βΎΛo.GetVol c
d β β¨o.emptyβ© βΎ vol Γ GetSamples m/c
# Construct output from samples and lengths
{ overlap ?
LβΏH β Lp2βΏHp2 {π©βΈπβ2}Β¨ 1000
Overlap β {
tail β o.empty
Next β {lππ©:
xt β π©βΏtail
f β lβ₯Β―1ββ’π©
tail β© fβΆAddβΏβ l ββ1Β¨ fβxt
+Β΄ l ββ1Β¨ xt
}
Con π¨ NextΒ¨ π©
}
len (Overlapβ(HΒ¨) Add Β·Con(Lββ1)Β¨) d
;
Con len ββ1Β¨ d
}
}
|