-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnotes.txt
300 lines (208 loc) · 6.73 KB
/
notes.txt
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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
Mute Groups
-----------
Menu to select which tracks are muted when pressing Mute Group key combo (need to think of one!)
Echo Speed for Each Voice?
--------------------------
Might be more flexible but needs more parameters/editing space
Multi-Automation
----------------
MLD - LFO Delay, ABC
MLS - LFO Delay, ABC
MLW - LFO Delay, ABC
MAV - AMP Volume, ABD
MAE - AMP Envelope, ABD
MAT - AMP Time, ABCD
Echo
----
Switch - 1 byte (ABD on, sync mode)
Level A - 1 byte
Level B - 1 byte
Level D - 1 byte
Decay - 1 byte
Speed - 1 byte
Song
----
Loop Start Table
Loop Length Table
Song Speed Table
Song Swing Table
00 - FF Song Steps
Modes
OFF = playback is current Pattern in a loop, nothing affects Song
PLY = playback is Song, changing Pattern in Grid not allowed, changing Pattern in Song not allowed
changing BAR will change playback position (FFW and RWD)
REC = changing Pattern in Song or Grid will change Pattern number on current BAR whether Song is playing
or not
Song loops unless LP LEN = 0 then it will play to end
If Stopped
If Song Mode = OFF
set plyrNextPattern to editor current pattern
set index to 0, set note counter to 0
If Song Mode = PLY or REC
set plyrNextPattern to pattern on current bar
set pattern index to 0, set note counter to 0
If playing
Stop
Pattern
-------
00 Speed
01 Groove
02 Drum for Track 1
03 Drum for Track 2
04 Drum for Track 3
05 Drum for Track 4
06 Drum for Track 5
07 Drum for Track 6
08 Phrase for Track 1
09 Phrase for Track 2
0A Phrase for Track 3
0B Phrase for Track 4
0C Phrase for Track 5
0D Phrase for Track 6
0E - padding -
0F - padding -
Phrases = 16 steps * 6 bytes per step = 80
COMPRESSION
-----------
480 byte editing buffer in RAM (and 6 bytes for drum allocation per track)
When pattern is selected, decompress selected pattern to editing buffer.
Temporarily replace bank/address pointer of pattern (pointer table would need to be in SRAM)
While editing, edit functions and playback is done on edit buffer
If pattern number changed:
recompress pattern in edit buffer
see if it will fit in old place (size compare)
if not, copy compressed pattern to end of memory, set free space pointer to address where patter used to be
(always have 480 bytes + 6 free)
initiate defrag task
If defrag task active, move all pattern date from end of free space to beginning of free space, update
pattern pointers as we go (all pointers will be valid if done one at a time). Do this X bytes per frame
until done. Stop defrag task.
Nice Compression Method
-----------------------
lda #<source
sta tmp0
lda #>source
sta tmp1
lda #<dest
sta tmp2
lda #>dest
sta tmp3
ldx #$60 ;96 blocks
: ldy #$00
lda (source),y
beq :+
sta (dest),y
iny
lda (source),y
sta (dest),y
iny
lda (source),y
sta (dest),y
iny
lda (source),y
sta (dest),y
iny
lda (source),y
: sta (dest),y
lda tmp2
clc
adc #$05
sta tmp2
bcc :+
inc tmp3
: lda tmp0
clc
adc #$05
sta tmp0
bcc :+
inc tmp1
: dex
bne :----
ldy #$00
lda tmp2
sta (tmp2),y
iny
lda tmp3
sta (tmp2),y
rts
IDEAS
-----
- Have a mod parameter SLD which is slide amount (instead of being a drum parameter). Only slide if new note
starts before last note finised (portamento). Only for A, B and C
- Retrigger has dual use - if > $10 then value is probability of note playing $10 = most likely, $FF = least
GATE 00
-------
Possible extra mode where sound generation only lasts for a single step of Pattern. Not sure how to implement could be useful.
ECHO
-----
Need to think about whether implementing Echo is possible. Would essentially have to check envelope phase of all 6 tracks to determine gaps. Needs to be tempo synced so "speed" would actually be number of pattern steps. How would this work with "groove"?
Bigger problem is figuring out how to set the echo for the song and have a setting (or multiple settings) to switch echo on or off.
ADSR
----
The 'curve' setting could also be used as a 'break point'. Envelope would go
1) 00->0F (attack speed)
2) decrease amplitude until it <= 'curve' value
3) continue holding at that level for gate time
4) release
VAPU
----
At time of new note, write voice select flag to tempoarary "active voices" flag, one for each track.
Before writing, check "active voice". If bit not set, don't write.
Write values.
For A, B & D, if envelope phase = 0, clear relevant bit in active voice flags. Write 0 to amp?
For C, if gate timeer finished, clear relevant bit in active voice flags. Write 0 to 'amp'?
Adding A Trigger To The Grid
----------------------------
Default should be: C4, RT 00 and P1-P3 copied from drum definition.
When note is modified, pitch is stored and becomes default.
When deleting a trigger (B+A), all 5 values copied to buffer. Then B+A on empty cell should paste those
values in.
-------------------------------------------------------------------------
Process all 6 tracks, writing output values to VAPU if voice is active
Copy VAPU settings to APU
Each Step
1) Read each drum definition (from RAM) and store in working RAM
2) Apply "patch" to working RAM using variables in that step
3) Initialise new note if required. Each cell has four states: nothing, note, tie note, kill note
Controls
--------
6 different "windows"
- Drum allocation for each track
- Grid editor
- Modulation editor
- Drum editor
- Global settings (speed/groove etc)
- Song editor
Tempo/Groove
-------------
Tempo determined by 2 numbers: 1st applied to even number steps, 2nd applied to odd numbered steps.
e.g. if tempo is 12, speeds are 06/06
02 = 01/01
03
04 = 02/02
05
06 = 03/03
07
08 = 04/04
09 = 03/03
10 = 05/05
Case example
Tempo of 06 = 03/03 straight. 25% swing = 04/02, 50% = 04/02, 75% = 05/01
Tempo of 07 = 04/03 straight. 25% swing = 05/02, 50% = 05/02, 75% = 06/01
Tempo of 08 = 04/04 straight. 25% swing = 05/03, 50% = 06/02, 75% = 07/01
Tempo of 09 = 05/04 straight. 25% swing = 06/03, 50% = 07/02, 75% = 08/01
Tempo of 10 = 05/05 straight. 25% swing = 06/04, 50% = 07/03, 75% = 08/02
Optimisation Cheat
------------------
- Don't process synth on first frame of note (when all the drum patches are copied to RAM)?
- open out synth stuff into one big routine (remove jsr/rtses)?
- move some frequently accessed vars into ZP?
Fetching Drum Patches!
----------------------
As you can't change the drum assigned to a track from within a pattern, only need to fetch
the whole drum patch when a) manually changing a drum assignment on a track or b) changing
the pattern manually in the editor or c) during song playback when a new pattern is
encountered.
Instead of fetching 6 drum patches every pattern step, instead you only need to look at what
parameters are assigned to the real-time controllers and first fetch those from the drum patch
then apply the real-time data to those parameters.