-
Notifications
You must be signed in to change notification settings - Fork 205
/
s3m.ksy
263 lines (261 loc) · 6.05 KB
/
s3m.ksy
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
meta:
id: s3m
title: Scream Tracker 3 module
file-extension: s3m
xref:
justsolve: Scream_Tracker_3_module
pronom: fmt/718
wikidata: Q1461901
license: CC0-1.0
endian: le
doc: |
Scream Tracker 3 module is a tracker music file format that, as all
tracker music, bundles both sound samples and instructions on which
notes to play. It originates from a Scream Tracker 3 music editor
(1994) by Future Crew, derived from original Scream Tracker 2 (.stm)
module format.
Instrument descriptions in S3M format allow to use either digital
samples or setup and control AdLib (OPL2) synth.
Music is organized in so called `patterns`. "Pattern" is a generally
a 64-row long table, which instructs which notes to play on which
time measure. "Patterns" are played one-by-one in a sequence
determined by `orders`, which is essentially an array of pattern IDs
- this way it's possible to reuse certain patterns more than once
for repetitive musical phrases.
doc-ref: http://hackipedia.org/browse.cgi/File%20formats/Music%20tracker/S3M%2c%20ScreamTracker%203/Scream%20Tracker%203.20%20by%20Future%20Crew.txt
seq:
- id: song_name
size: 28
terminator: 0
- id: magic1
contents: [0x1a]
- id: file_type
-orig-id: Typ
type: u1
- id: reserved1
size: 2
- id: num_orders
-orig-id: OrdNum
type: u2
doc: Number of orders in a song
- id: num_instruments
-orig-id: InsNum
type: u2
doc: Number of instruments in a song
- id: num_patterns
-orig-id: PatNum
type: u2
doc: Number of patterns in a song
- id: flags
-orig-id: Flags
type: u2
- id: version
-orig-id: Cwt/v
type: u2
doc: Scream Tracker version that was used to save this file
- id: samples_format
-orig-id: Ffi
type: u2
doc: '1 = signed samples, 2 = unsigned samples'
- id: magic2
contents: 'SCRM'
- id: global_volume
-orig-id: g.v
type: u1
- id: initial_speed
-orig-id: i.s
type: u1
- id: initial_tempo
-orig-id: i.t
type: u1
- id: is_stereo
type: b1
- id: master_volume
-orig-id: m.v
type: b7
- id: ultra_click_removal
-orig-id: u.c
type: u1
- id: has_custom_pan
-orig-id: d.p
type: u1
- id: reserved2
size: 8
- id: ofs_special
-orig-id: Special
type: u2
doc: Offset of special data, not used by Scream Tracker directly.
- id: channels
type: channel
repeat: expr
repeat-expr: 32
- id: orders
size: num_orders
- id: instruments
type: instrument_ptr
repeat: expr
repeat-expr: num_instruments
- id: patterns
type: pattern_ptr
repeat: expr
repeat-expr: num_patterns
- id: channel_pans
type: channel_pan
repeat: expr
repeat-expr: 32
if: has_custom_pan == 252
types:
channel:
seq:
- id: is_disabled
type: b1
- id: ch_type
type: b7
doc: Channel type (0..7 = left sample channels, 8..15 = right sample channels, 16..31 = AdLib synth channels)
instrument_ptr:
seq:
- id: paraptr
type: u2
instances:
body:
pos: paraptr * 0x10
type: instrument
instrument:
seq:
- id: type
type: u1
enum: inst_types
- id: filename
terminator: 0
size: 12
- id: body
type:
switch-on: type
cases:
'inst_types::sample': sampled
_: adlib
- id: tuning_hz
type: u4
- id: reserved2
size: 12
- id: sample_name
size: 28
terminator: 0
- id: magic
contents: 'SCRS'
enums:
inst_types:
1: sample
2: melodic
3: bass_drum
4: snare_drum
5: tom
6: cymbal
7: hihat
types:
sampled:
seq:
- id: paraptr_sample
-orig-id: MemSeg
type: swapped_u3
- id: len_sample
-orig-id: Length
type: u4
- id: loop_begin
-orig-id: LoopBeg
type: u4
- id: loop_end
-orig-id: LoopEnd
type: u4
- id: default_volume
-orig-id: Vol
type: u1
doc: Default volume
- id: reserved1
type: u1
- id: is_packed
-orig-id: '[P]'
type: u1
doc: 0 = unpacked, 1 = DP30ADPCM packing
- id: flags
-orig-id: '[F]'
type: u1
instances:
sample:
pos: paraptr_sample.value * 0x10
size: len_sample
adlib:
# TODO
seq:
- id: reserved1
contents: [0, 0, 0]
- size: 16
pattern_ptr:
seq:
- id: paraptr
type: u2
instances:
body:
pos: paraptr * 0x10
type: pattern
pattern:
seq:
- id: size
type: u2
- id: body
size: size - 2
type: pattern_cells
pattern_cells:
seq:
- id: cells
type: pattern_cell
repeat: eos
pattern_cell:
seq:
- id: has_fx
type: b1
- id: has_volume
type: b1
- id: has_note_and_instrument
type: b1
- id: channel_num
type: b5
- id: note
type: u1
if: has_note_and_instrument
- id: instrument
type: u1
if: has_note_and_instrument
- id: volume
type: u1
if: has_volume
- id: fx_type
type: u1
if: has_fx
- id: fx_value
type: u1
if: has_fx
swapped_u3:
doc: Custom 3-byte integer, stored in mixed endian manner.
seq:
- id: hi
type: u1
- id: lo
type: u2
instances:
value:
value: lo | (hi << 16)
channel_pan:
seq:
- id: reserved1
type: b2
- id: has_custom_pan
type: b1
doc: |
If true, then use a custom pan setting provided in the `pan`
field. If false, the channel would use the default setting
(0x7 for mono, 0x3 or 0xc for stereo).
- id: reserved2
type: b1
- id: pan
type: b4