~amaurycarvalho/midi2pt3/trunk

1 by Amaury Carvalho
Commit on 06/06/2020 05:32:36 -03 by amaury
1
How to decode a Vortex Tracker II "PT3" File
2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
4
	by Vince "Deater" Weaver, <vince@deater.net>
5
	http://www.deater.net/weave/vmwprod/pt3_player/
6
	10 September 2019
7
8
Background:
9
~~~~~~~~~~~
10
	Vortex Tracker II ( https://bulba.untergrund.net/vortex_e.htm )
11
	is a music tracker (tool for writing music) that targets systems
12
	with the AY-3-8910 sound chip.  The music made is most popular
13
	on various ZX Spectrum (z80) and Atari ST systems.
14
15
	I wanted to make a decoder for a 6502-based Apple II with a
16
	AY-3-8910 based Mockingboard sound card.  The challenge was
17
	all the low-level Vortex Tracker documentation is in Russian,
18
	and the source code available is either uncommented z80 assembly
19
	language or Russian-commented Pascal source code.
20
21
	This document is based at least partly on the writeup here:
22
		http://karoshi.auic.es/index.php?topic=397.msg4641#msg4641
23
	as well as the AY_emul source code, and lastly just from reverse
24
	engineering things while trying to get my code to match the output
25
	of AY_emul exactly.
26
27
28
The PT3 Format
29
~~~~~~~~~~~~~~
30
31
32
* File Header
33
34
	Note: 16-bit values are little-endian
35
36
	Offset    : Size     : Description  : Contents
37
	---------- ---------- -------------- ----------------
38
	$00 - $0C : 13 bytes : Magic        : "ProTracker 3."
39
	$0D       :  1 byte  : Version      : '5' for Vortex Tracker II
40
	$0E - $1D : 16 bytes : String       : " compilation of "
41
	$1E - $3E : 32 bytes : Name         : Name of the module
42
	$3E - $41 :  4 bytes : String       : " by "
43
	$42 - $62 : 32 bytes : Author       : Author of the module.
44
	$63       :  1 byte  : Frequency table (from 0 to 3)
45
	$64       :  1 byte  : Speed/Delay
46
	$65       :  1 byte  : Number of patterns+1  (Max Patterns)
47
	$66       :  1 byte  : LPosPtr      : Pattern Loop Pointer
48
	$67 - $68 :  2 bytes : PatsPtrs     : Pointers to the patterns
49
	$69 - $A8 : 64 bytes : SamPtrs[32]  : Pointers to the samples
50
	$A9 - $C8 : 32 bytes : OrnPtrs[16]  : Pointers to the ornaments
51
	$C9 - ??? :          : Patterns[]   : $FF terminated, More on this below
52
53
	Version: is at offset $0D, which is just the ASCII value of
54
		the version number from the magic.  Usually you
55
		subtract off '0' to get the proper value.
56
		If the value is not a valid number, '6' is assumed.
57
58
* Pattern list
59
60
	The pattern list starts at $C9 and is terminated by $FF
61
62
	The pattern is multiplied by 3.
63
64
	A sample pattern list might look like
65
		$03, $06, $09, $FF
66
	which corresponds to playing in order patterns
67
		1, 2, 3
68
69
70
* Samples
71
72
	The pt3 file allows for 32 samples.  These samples contain
73
	values that are applied to the music notes as they are playing.
74
75
	The 16-bit address of a sample X can be found by getting the
76
		16-bit little-endian address at offsets
77
		$6A+(X*2) and $6B+(X*2) in the header.
78
79
	Byte 0:	 LOOP VALUE -- sample offset to return to once hit the end
80
	Byte 1:  LENGTH     -- number of 32-bit sample values
81
	Byte 2+: VALUES     -- list of 4-byte (32-bit samples)
82
83
	* Sample format
84
85
		+ Byte 0 --- 7 6 5 4321 0
86
				Bit 7 - Amplitude sliding
87
				Bit 6 - 1/0 amplitude slide up/down
88
				Bit 5 - 1/0 envelope slide up/down
89
				Bits 4321 - sign extend, envelope slide value
90
				Bit 0 - Sample has envelope
91
92
		+ Byte 1 --- 7 6 5 4 3210
93
				Bit 7     - Envelope sliding
94
				Bit 6     - Accumulate Tone
95
				Bit 5     - parameter to envelope sliding?
96
				Bit 4     - Bit 6+4 used to set Noise/Channel
97
					    mixer value
98
				Bits 3210 - Amplitude
99
100
		+ Byte 2 --- Freq Low -\
101
		+ Byte 3 --- Freq High----- Used as base tone
102
103
* Ornaments
104
105
	The PT3 file format has 16 ornaments, which are patterns applied
106
	to the note.  This can be used for ?? effects.
107
108
	The 16-bit address of an ornament X can be found by getting the
109
		16-bit little-endian address at offsets
110
		$A9+(X*2) and $AA+(X*2) in the header.
111
112
	Byte 0:	 LOOP VALUE -- ornament offset to return to once hit the end
113
	Byte 1:  LENGTH     -- number of ornament values
114
	Byte 2+: VALUES     -- list of single-byte values applied to the notes
115
116
117
* Pattern data
118
119
	For each of three channels (A,B,C) there is a nul-terminated
120
	stream of bytes that gives the pattern data.
121
122
	To find the pattern data for a pattern, look it up in 
123
124
	A 6-byte chunk with the 16-bit addresses for A,B,C for pattern
125
	X can be found by
126
		a_addr_l = [address in ($68/$67)] + (X*6)+0
127
		a_addr_h = [address in ($68/$67)] + (X*6)+1
128
		b_addr_l = [address in ($68/$67)] + (X*6)+2
129
		b_addr_h = [address in ($68/$67)] + (X*6)+3
130
		c_addr_l = [address in ($68/$67)] + (X*6)+4
131
		c_addr_h = [address in ($68/$67)] + (X*6)+5
132
133
	Follow that address to find the nul-terminated pattern data.
134
135
	The data can be interpreted this way:
136
137
	+ $00         - NUL termination, end of pattern
138
	+ $01-$0f     - effects, see later.
139
			Note that parameters to the effect appear in the
140
			bytestream *after* the note to play
141
	+ $10-$1f     - set envelope type
142
			+ $10 means disable envelope
143
				- sample number is next byte
144
			+ $11-$1F 
145
				- envelope type is bottom 4 bits
146
				- envelope period is next 2 bytes (big endian)
147
				- envelope delay is next 1 byte
148
				- sample number is next byte
149
150
	+ $20-$3f     - set noise
151
				- Noise set to the ($20...$3F) value - $20
152
	+ $40-$4f     - set ornament
153
				- ornament sent to bottom 4 bits
154
				- possibly setting 0 counts as disabling
155
	+ $50-$af     - play note
156
157
                0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
158
          50: C-1 C#1 D-1 D#1 E-1 F-1 F#1 G-1 G#1 A-1 A#1 B-1 C-2 C#2 D-2 D#2
159
          60: E-2 F-2 F#2 G-2 G#2 A-2 A#2 B-2 C-3 C#3 D-3 D#3 E-3 F-3 F#3 G-3
160
          70: G#3 A-3 A#3 B-3 C-4 C#4 D-4 D#4 E-4 F-2 F#4 G-4 G#4 A-4 A#4 B-4
161
          80: C-5 C#5 D-5 D#5 E-5 F-5 F#5 G-5 G#5 A-5 A#5 B-5 C-6 C#6 D-6 D#6
162
          90: E-6 F-6 F#6 G-6 G#6 A-6 A#6 B-6 C-7 C#7 D-7 D#7 E-7 F-7 F#7 G-7
163
          a0: G#7 A-7 A#7 B-7 C-8 C#8 D-8 D#8 E-8 F-8 F#8 G-8 G#8 A-8 A#8 B-8
164
165
	+ $b0         - disable envelope, reset ornament position
166
	+ $b1         - set skip value
167
				- next byte is how many lines to skip for
168
				  this note
169
	+ $b2-$bf     - set envelope
170
				- envelope type to (bottom 4 bits - 1)
171
				- envelope period next 2 bytes (big endian)
172
173
174
	+ $c0         - turn off note (volume=0 and disable everything)
175
	+ $c1-$cf     - set volume
176
				- volume set to bottom 4 bits
177
178
	+ $d0         - done processing this note (end note)
179
	+ $d1-$ef     - set sample
180
				- sample set to value-$d0.
181
	+ f0-$ff      - initialize ornament/sample.  Envelope is disabled
182
				- ornament is bottom 4 bits
183
				- next byte is sample*2
184
185
	Note when parsing if you reach a note, a $D0 or a $C0 then you
186
	are done parsing the note for this line and should move on
187
	to parsing the effects.
188
189
	Effects
190
	~~~~~~~
191
192
	AY_emul supports having up to one of each effect for each line, and
193
	tracks the order in which to apply them.  However in the wild
194
	I have not seen more than one effect applied per line/channel
195
	(I don't think Vortex Tracker lets you add multiple?)
196
197
	The bytes for the effects follow after the byte that ended the note.
198
199
	The effect value on disk is not the same as that displayed when
200
	viewed in the tracker.
201
202
	On	In
203
	Disk  Tracker
204
	~~~~  ~~~~~~~
205
206
	$01     $01:	Glissando (slide through discrete notes) / Tone Down
207
208
			First byte: delay
209
			Next 2 bytes: frequency to add (is negative)
210
211
	$01     $02:	Glissando (slide) / Tone Up
212
213
			This appears differently in tracker, but is just
214
			the same as above but with a positive frequency.
215
216
	$02     $03:	Tone portamento (continuous slide)
217
218
			First byte: delay
219
			Next 2 bytes: ignored?
220
			Next 2 bytes: slide step (little-endian)
221
			
222
	$03     $04:	Sample Offset
223
			First byte: value to set the sample position offset
224
225
	$04     $05:	Ornament offset
226
			First byte: value to set the ornament offset
227
228
	$05     $06:	Vibrato
229
			Periodic sound off/on in that channel
230
			First byte: OffOn delay (frames to stay off)
231
			Second byte: OnOff delay (frames to stay on)
232
233
	$08	$09:	Envelope Glissando -- Frequency decreasing
234
			First byte: delay
235
			Next two bytes: Slide add (little-endian)
236
237
	$08     $0A:	Envelope Glissando -- Frequency increasing.
238
			Like previous but with sign switched?
239
240
	$09	$0B:	Set playing speed (new Delay).
241
			First byte: new delay (global number of frames per line)
242
243
244
* Frequency Tables
245
246
	Various versions of the tracker use different frequency tables.
247
	Players lookup notes in these tables to get the proper frequency.
248
249
	The value in the frequency table field specifies up to 4 (0...3)
250
	tables, but there is an alternate set of tables if the tracker version
251
	PT3_VERSION is 3 or less.
252
253
	Presumably for space reasons, some players only support tables 
254
	one and two from the newer set.
255
256
	These tables in theory can be calculated at runtime, but usually
257
	they aren't unless you are extremely space constrained.
258
	The z80 player has code to do this in z80 assembly.
259
260
	The tables are a set of 96 16-bit values (8 octaves of 12 notes)
261
262
	The frequency tables supported by Ay_Emul:
263
264
		PT3Version#	Table#		Frequency Table
265
		-----------	------		======================
266
		<=3.3		0		PT3NoteTable_PT_33_34r
267
		all		1		PT3NoteTable_ST
268
		<=3.3		2		PT3NoteTable_ASM_34r
269
		<=3.3		3		PT3NoteTable_REAL_34r
270
271
		3.4+		0		PT3NoteTable_PT_34_35
272
		all		1		PT3NoteTable_ST
273
		3.4+		2		PT3NoteTable_ASM_34_35
274
		3.4+		3		PT3NoteTable_REAL_34_35
275
276
* Volume Tables
277
278
	There are multiple 256-byte amplitude/volume lookup tables
279
	These seem to have changed with different versions of Vortex Tracker
280
	so to be complete you need to contain them all and use the proper
281
	one at run time
282
283
284
* Corner cases seen in the wild:
285
	+ What to do if the delay on an effect is set to zero?
286
287
288
* 6-channel PT3 Files
289
290
	In the Protracker 3.7 format you can look for a turbosound header
291
	at the very end of the file.
292
293
	Type1 (4 bytes), Size (16-bits, little-endian)
294
	Type2 (4 bytes), Size (16-bits, little endian)
295
	TSID: (4 bytes) 02TS
296
297
	If the type of these files is PT3! then these are describing
298
	PT3 subfiles, and can be read as two 3-channel files which can
299
	be interpreted together as one 6-channel file.
300
301
302
============================================================================
303
304
Example 1*
305
306
So if we have this in the module: $D2,$CF,$B1,$05,$50 we will have this in the
307
tracker:
308
309
C-1     2..F   ....
310
---     ....    ....
311
---     ....    ....
312
---     ....    ....
313
---     ....    ....
314
315
$D2: Sample 2    ($Dx samples)
316
$CF: Volume 15   ($Cx volume)
317
$B1: No envelope ($Bx envelope)
318
$05,$50: Play note $50 (C1) during five tracker lines.
319
320
*Example 2*
321
322
If we have this in the module: $D1,$CE,$09,$B1,$08,$50,$07
323
324
$D1: Sample 1.
325
$CE: Volume 14.
326
$09: New delay will be set. See after note is set.
327
$B1: No envelope.
328
$08,$50: Play note $50 (C1) during eight tracker lines.
329
$07: New Delay.
330
331
332
333