PT2

Introduction

This is the original module of Pro Tracker v2.x, an AY music editor for ZX Spectrum, author is Nikolay Khudentsov (Nick).

The story began with Pro Tracker 1.1 (see the description of the PT1-format). The format became a development of his ideas: glisses, portamento, noise control from the tracks (and not just from the samples), looping of ornaments independent of samples were added. And together with the capabilities inherited from PT1, it turned out to be a powerful instrument recognized by most musicians of the second half of the 90s.

The PT2-format was well described by VfNG in the Echo #2 e-paper (given at the end; study to understand some notation further).

Features of Pro Tracker 2.4 Phantom Family modules

The modules of this editor do not differ in structure from other versions of Pro Tracker v2.x, but the module is bound to the compilation address, namely, the module loading address in RAM is added to the PAT, SAMP_A and ORN_A offsets.

Such modules can be loaded and used in Ay_Emul as usual, and, if necessary, saved as regular PT2 (without binding to the address).

Module format

The following is a slightly edited excerpt from the VfNG article in Echo #2 e-paper (with notes by the Ay_Emul author).

---------------------------cut here-------------------

Terminology:

QUARK: the elements that make up SAMPLES, ORNAMENTS.

QUANT: the number of QUARKS in each element of the PATTERN. In fact, the playback speed.

PATTERN: couplet.

POSITION LIST: the order in which PATTERNS are played.

POSITION: position in the POSITION LIST.

Compiled module format:

+0
DELAY – the number of QUARKS for which 1 QUANT is played;
+1
MUS_LEN – the number of positions in the melody;
+2
LOOP TO POSITION – the number of the position to which looping will be performed when the entire melody is played (0–#FF);
+3,64
SAMP_A – offsets from +0 to each of the 32 SAMPLES. SAMPLE with number 0 is not described. Its number is used to mute the channel.
+67,32
ORN_A – similar to SAMP_A for 16 ornaments. Ornament number 0 means "no ornament".
+99,2
PAT_OFFSET – offset from +0 to the first descriptor PAT of PATTERNs.
+101,30
NAME – the name of the music in ASCII.
+131
POSITION LIST – a list of positions: PATTERN numbers for each position. The end of the table is #FF.
+?
PAT – descriptors of PATTERNs. Each PATTERN consists of 3 channels. This table shows the offsets from +0 to the channel descriptors of each PATTERN. Thus, 6 bytes/PATTERN. The end of the table is #0000.
+?
CHAN – channel descriptors. The channel is represented as a list of bytes, which are analyzed as follows:
LOOP   LD A,(DE)
       INC DE
       ADD A,#20
       JR C,L1
       ADD A,#60
       JR C,L2
       ADD A,#10
       JR C,L3
       ADD A,#10
       JR C,L4
       ADD A,#40
       JR C,L5
       ADD A,#10
       JR C,L6
       INC A
       JR Z,L7
       INC A
       JR Z,L8
       INC A
       JR Z,L9
       INC A
       JR NZ,L10
L11

Turn off commands (Sergey Bulba's note: namely, GLISSADE or PORT) and jump to LOOP.

L10

Extract the next byte, it contains the value for adding to NOISE frequency. Then to LOOP.

L9

Extract three bytes. In the 1st one is the PORT value, i.e. the number that will be added to the current frequency of the note. It should be noted that the frequency value of the highest note is the smallest, and the lowest is the largest, which means: posit. 128-255, negat. 0-127. In the 2nd and 3rd bytes (Sergey Bulba's note: they are ignored in Ay_Emul, because it is impossible to accurately calculate at the compilation stage if alternating different patterns) is the difference in the frequency values of the new (the one on which PORT is called) and the previous note. There is a compiler error that incorrectly determines this value if a new note is at the beginning of the PATTERN (Sergey Bulba's note: this is not a compiler error, but a miscalculation in the format itself; if the frequency difference is calculated right during playback, then there is no error). The command should be turned off when the sum of additions from +1 exceeds the value of +2,+3. Jump to LOOP.

L8

Extract 1 byte. It has the GLISSADE value. Signs are similar to PORT. Then jump to LOOP.

L7

Extract 1 byte. It has a value for DELAY (playback speed). Then jump to LOOP.

L6

In A is volume (0–F). This value is multiplied by 16 and added to the beginning of the TABL1 table (Sergey Bulba's note: see in the e-paper or in the source codes of Ay_Emul). The resulting value should be treated as the beginning of a 16-byte table, which contains values for the amplitude registers of the sound chip for each value extracted from SAMPLE. Then jump to LOOP.

L5

In A is how many QUANTS it is not necessary to analyze the channel, i.e. the distance in QUANTS between the next changes in channel parameters. Then to the LOOP.

L4

In A is the number of the ornament. If it is equal to 0, then there is no ornament. Jump to LOOP.

L3

If A=0 then exit. If 0<À<F then setting the envelope type, then extracting the next 2 bytes with the envelope period, jump to LOOP. If A=F then disabling envelopes, jump to LOOP.

L2

In A is the note number. There are 8 octaves of 12 notes, a total of 96 notes. The frequency values for each of the notes in the TABL2 table (2 bytes/each, Sergey Bulba's note: see in the e-paper or in the source codes of Ay_Emul). Jump to LOOP.

L1

In A is the SAMPLE number. If=0 then turn off channel, exit. Otherwise, setting the SAMPLE number and jump to LOOP.

+?
SAMPLES – SAMPLES descriptors. Each SAMPLE consists of:
 ++0 The number of QUARKS in the SAMPLE.
 ++1 The QUARK number in SAMPLE to which looping is performed at the end of SAMPLE.
 ++2 QUARKS descriptors of 3 bytes each:
  +++0
   Bits 7–3 – NOISE frequency (0–31);
   Bit 2 – vibrato sign (1="-", 0="+");
   Bit 1 – TONE mask;
   Bit 0 – NOISE mask.
  +++1
   Bits 7–4 – amplitude (0–15);
   Bits 3–0 – high part of the frequency vibrato value.
  +++2
   Bits 7–0 – low part of the frequency vibrato value.
+?
ORNAMENTS – descriptors of ornaments. They consist of:
 ++0 – The length of the ornament in QUARKS;
 ++1 – The QUARK number in the ornament, which you need to switch to at the end of the ORNAMENT;
 ++2 – Deviations from the current note value in semitones. Values 0–63. The highest bit is signed: 0='+', 1='-'.

There may be some inaccuracies in the description that are not difficult to detect and correct.

Now about how music is played in general. The value of DELAY is taken and written to a special variable. Each time the player is called, this value decreases by 1. If it is greater than 2, the channel parameters do not change. If 2, then it is checked for the end of the channel. If it is the end, then the next position is processed, new values are set in variables indicating the current positions in the channels. Channel A is being processed. If 1, then channel B is being processed. If 0, then channel C is processed and the data obtained as a result of processing all three channels (SAMPLES, ORNAMENTS, etc...) are set to playback, the variable again gets the value DELAY (Sergey Bulba's note: this approach to speed optimization, which was then repeated in other projects, created a problem for musicians: the inability to set the playback speed to less than 3; this restriction has been removed in Ay_Emul and PTxTools players).

---------------------------cut here-------------------