-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdigit_sum_study.dc
223 lines (195 loc) · 4.99 KB
/
digit_sum_study.dc
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
############################################################################
# This module was written so that I could have a clearer understanding #
# of the musical implications of the various variable settings involved #
# in the midi_digit_sum* examples. #
# #
# There are 2 public words: `run_sample` and `range_sample` #
# #
# `run_sample` will show `end - start` (default 1024) iterations of #
# the output of `digit_sum`, given the variables set by the user. #
# These variables are defined below, but can be changed so various #
# behaviors can be studied, and a new run kicked off with `run_sample`. #
# Some documention of these variables is inline below, as comments. #
# #
# `mul_study` will vary the `mul` from 2 to `study_end` and do a #
# `run_sample` on each iteration. It will output lines that represent: #
# #
# <current_mul> <min_count> <max_count> <max_count / min_count> #
# #
# ....where <min_count> is the digit_sum __least hit__ during the run, #
# and <max_count> represents the digit_sum __most hit__ during the run. #
# This allow one to understand the "meta-features" of a given run of #
# `digit_sum` given a certain `base`, `wrap`, `shift`, and `slots`, #
# while the `mul` changes. Using the MIDI examples, this will have musical #
# implications. #
############################################################################
"math.dc" import
"string.dc" import
"redis_midi.dc" import
32 const FIGURE_STORAGE_SIZE
var figures FIGURE_STORAGE_SIZE allot
var start
0 start !
var end
1024 end !
var study_end
129 study_end !
# used by the `draw_sample_infinite` routines as a global index
var x
0 x !
# `mul` and `base` are the core args consumed by `digit_sum`
var mul
1 mul !
var base
2 base !
# `wrap` is the largest digit sum (prior to shifting) that you
# want to "wrap" (AKA do a modulus operation) around.
var wrap
32 wrap !
# `scale` is an experimental scaling extension
var scale
1 scale !
# `shift` offsets the resulting digit_sum by the assigned amount.
# If in a musical scale/gamut situation, this would be a "mode".
var shift
0 shift !
# `slots` would, for example, represent the largest digit_sum
# _after shifting_ that you'd want to "wrap" (AKA do an `absmod` modulus wrap)
# around. If you set/keep `wrap` and `slots` to 32, and `shift` to 0,
# the "natural behavior" of `digit_sum` is shown, which can be useful for
# understanding.
var slots
32 slots !
var drawchars
"0123456789abcdefghijklmnopqrstuvwxyz" drawchars !
: _clear_figures
FIGURE_STORAGE_SIZE times
0 figures i + !
again
;
: _show_figures
slots @ times
i 2 0 .pz "\b: " print
figures i + @ 5 0 .pz cr
again
;
: _run_sample_inner
end @ start @ 1
for
mul @ i * base @ digit_sum
wrap @ absmod shift @ + slots @ absmod
figures + dup @ 1 + swap !
next
;
: _draw_row
dup
0 >
if
dup
times
" " print
again
endif
drawchars @ swap dup 1 + strslice print cr
;
: _draw_sample_inner
end @ start @ 1
for
mul @ i * base @ digit_sum
scale @
* round
wrap @ absmod
shift @
+
slots @ absmod
_draw_row
next
;
: _draw_sample_infinite
redis_midi.get_mul x @ * redis_midi.get_base digit_sum
redis_midi.get_wrap absmod
redis_midi.get_mode
+
14 absmod
_draw_row
redis_midi.get_on_gate sleep
x dup @ 1 + swap !
_draw_sample_infinite
;
: _get_non_zero_size
slots @ 1 -
-1 over -1
for
figures i + @
0 <>
if
i min
endif
next
slots @ swap -
;
: _get_lowest_figure
slots @
_get_non_zero_size
-
figures
+
@
;
: _get_highest_figure
figures
slots @ 1 -
+
@
;
################
# The main API #
################
: run_sample
_clear_figures
_run_sample_inner
_show_figures
;
: draw_sample
_clear_figures
_draw_sample_inner
;
: draw_sample_infinite
0 x !
_clear_figures
_draw_sample_infinite
;
: mul_study
"mul num_nz_slots min_cnt max_cnt max_cnt/min_cnt" print cr
study_end @ 1 1
for
i mul !
_clear_figures
_run_sample_inner
figures slots @ sortnums
i 3 0 .pz
_get_non_zero_size 2 0 .pz
_get_highest_figure _get_lowest_figure
2dup
4 0 .pz
4 0 .pz
/ . cr
next
;
: wrap_study
"wrap num_nz_slots min_cnt max_cnt max_cnt/min_cnt" print cr
slots @ 1 + 5 1
for
i wrap !
_clear_figures
_run_sample_inner
figures slots @ sortnums
i 3 0 .pz
_get_non_zero_size 2 0 .pz
_get_highest_figure _get_lowest_figure
2dup
4 0 .pz
4 0 .pz
/ . cr
next
;