ProTracker Studio Module
The ProTracker Studio Module (PSM) file format is used for the music in Jazz Jackrabbit, Epic Pinball, Extreme Pinball, Silverball, Sinaria and One Must Fall. The file format is named after ProTracker, an Amiga program, though this program was probably actually not used to write PSM files. One Must Fall's music was written in Multitracker, and the music for Jazz Jackrabbit, Epic Pinball and Extreme Pinball probably in Scream Tracker.
There are currently two file types that use the extension .PSM; they seem to be related to a certain extent, though how is currently unknown. The two formats are:
- PSM New Format: Used by Jazz Jackrabbit, Epic Pinball, Extreme Pinball, One Must Fall, Sinaria (in this game with slight differences, see below), newest PSM format
- PSM 16: Used by Silverball, an older version of the format which is closer to ProTracker-style modules.
The most common of the two PSM formats is the new format, and most programs that try to run PSM files will be expecting this. For example, ModPlug Player cannot open Silverball files as these are in the PSM 16 format.
PSM New Format
This format is used by Epic games in Jazz Jackrabbit, Epic Pinball, Extreme Pinball, Silverball, Sinaria and One Must Fall. It is notable for consisting of a number of segments (chunks) and sub segments. It bears the 4-byte signature 'PSM ' at the file start.
File structure: Header Pattern segment Song segment Samples
The file header is 12 bytes long:
File header: 0 4 ID 'PSM '; indicates file is PSM format 4 4 Size Filesize - 12 8 4 ID2 'FILE'; indicates start of file info
After the header, some chunks follow in IFF-style. You should not expect chunks to come up in the same order as they are described here. A good way to handle chunks is to read the 4-Byte ID and the 4-Byte size field first, then evaluate the ID and decide what to do next based on this ID. Note that the size field does not include the ID and itself; it only holds the size of the chunk content.
This segment is optional, and one of the few segments that can be absent when playing PSM files in most programs. (Most programs expect all other segments to exist, even if they are not vital.) Most PSM songs have no title.
0 4 ID 'TITL'; indicates a title follows 4 4 Size Size of title as dword after this dword 8 ? Title Song title
Song info segment
This segment seems to indicate the beginning of the song data and is not really relevant when parsing.
12 4 ID 'SDFT'; indicates start of format info 16 4 Size Size of next header as dword, (8) 20 8 Song 'MAINSONG'; indicates song type. No other song types are known.
Each pattern is stored in its own PBOD chunk. Note that there are two possible formats for this chunk; one is used in the "old" format (as used in Epic Pinball, Extreme Pinball, Jazz Jackrabbit, One Must Fall) and the other in the "new" format (as used in Sinaria)
Pattern segment: 0 4 ID 'PBOD'; indicates a pattern follows (Pattern BODy) 4 4 Size Length of pattern data as dword, after this dword 4 4 Size Same value again.
Pattern: 0 4/8 Number Pattern ID. See note below. 4 2 Row n Number of rows in ALL channels in pattern (64 usually, but can differ.) as word. 6 ? Data Contains pattern data as a number of rows of interlaced channels (12341234...) Usual settings is 64 rows of 4 channels. Epic Pinball has shorter patterns for example, but they also include a "break to row" command at the end of the pattern.
Note: In the old format, this starts with a 'P' and is followed by an integer number which is the pattern number, padded to 4 bytes with spaces. Caution: This number might or might not be zero-padded; In some files, the ID of the first pattern could be 'P0 ', but there are also files where it is 'P00 '!. In C/C++, you could use atoi() to parse this value. In the new format (Sinaria), This field is 8 bytes long instead of 4 bytes, and the first 4 bytes read "PATT", so the first pattern could be for example 'PATT0 '.
Pattern row channel entry: ? 1 Fill Convert this byte value into binary; (240 -> 11110000), the first four values +1 1 chan What channel this belongs to, 0-255, each filled only once per tick, this is what, by absence, identifies empty channels. It is possible that actual PSM implementations will support less channels and crash if a file contains too many channels. +2 1 Note Pitch, $01 is C-1, etc... The octaves are aligned by 16, i.e. B-1 is $0C but the next note, C-2, is $10. +3 1 Ins Instrument used, 0-31 +4 1 Vol Volume change to, 0-63 = 0-127; optional +5 1 Effect Effect to use, volume slide, Portamanto... +6 1 Eff Am Strength of effect, e.g amount of slide
Each row consists of a word giving the size of the row (Including the word) followed by the channel data. A channel is only included if it has data in it, but a totally empty row is still included. So an 'empty' row (Where none of the channels have data.) thus consists of just a word of value 2.
Each channel entry consists of between 3-7 bytes. The first byte is a flag that shows what data follows. (The first four bits indicate whether there are bytes for the following four variables; Note ($80), Instrument ($40), Volume ($20), Effect AND Effect magnitude ($10). Thus 5 bytes are represented by a combination of 4 possibilities.) The next byte identifies the channel (Since each channel may or may not be present.) starting at 0 for channel 1. The remaining 5 bytes may or may not be present and contain data for Note, Instrument(Sample) used, Volume change for channel, Effect and Effect magnitude.
There are several things to note about this; Effect and Effect magnitude MUST occur together. Sample numbers, like channels are numbered starting at 0, not 1. Magnitudes (For effect AND volume) are from 0-127, not 0-64 as in other formats.
Note that this table is guaranteed to be correct; Most effects seem to be converted correctly, though. Note that these values are not correct for the PSM files that can be found in the game Sinaria. Leave out all divisions and it will be correct again.
PSM Command Param length S3M Command Volume commands 1 1 Byte DxF - fine volside up 2 1 Byte Dx0 - volslide up 3 1 Byte DFx - fine volslide down 4 1 Byte D0x - volslide down Portamento commands B 1 Byte FFx - fine porta up (divide x by 4) C 1 Byte Fxx - porta up (if x < 4, use FFx, else divide x by 4) D 1 Byte EFx - fine porta down (divide x by 4) E 1 Byte Exx - porta down (if x < 4, use EFx, else divide x by 4) F 1 Byte Gxx - portamento (divide x by 4) 10 1 Byte S1x - glissando control 11 1 Byte Lx0 - tone porta + volslide up 12 1 Byte L0x - tone porta + volslide down Vibrato 15 1 Byte Hxy - vibrato 16 1 Byte S3x - vibrato waveform 17 1 Byte K0x - vibrato + volslide up 18 1 Byte Kx0 - vibrato + volslide down Tremolo 1F 1 Byte Rxy - tremolo 20 1 Byte S4x - tremolo waveform Sample commands 29 3 Bytes Oxx - offset (only take the 2nd byte) 2A 1 Byte Q0x - retrigger 2B 1 Byte SCx - note cut 2C 1 Byte SDx - note delay Position change 33 2 Bytes(?) Bxx - position jump (divide by 2) 34 1 Byte Cxx - break to row (divide by 2) 35 1 Byte SBx - pattern loop 36 1 Byte SEx - pattern delay Speed change 3D 1 Byte Axx - set speed 3E 1 Byte Txx - set tempo Misc. commands 47 1 Byte Jxy - arpeggio 48 1 Byte S2x - set finetune 49 1 Byte S8x - set balance
Effect interpretation is different in Sinaria's new format.
This segment contains most of the important data used to play the song, as well as a lot of unimportant data that is no longer used. It contains several sub-segments, each of the same format as a normal segment, but contained in the song segment. Note that there might be more than one song segment and thus, more than one order list, default speed, default tempo, etc...
Segment structure: 0 4 ID 'SONG' indicates start of song structure 4 4 Size Size of song structure, including all sub-segments 8 9 Type Type of song this is for; This is 'MAINSONG ' in almost all PSM files. Extreme Pinball has several SONG items with different types! 17 1 Comp Compression, for PSM = 1 (Uncompressed) 18 1 Chan Number of channels, usually, but not always, 4
This dates the file and is used by some programs. It is usually the first sub-segment.
0 4 ID 'DATE' indicates date data 4 4 Size Size of date segment (6) 8 6 Date Date as text, YYMMDD
Orders are how patterns are arranged in the song. This allows the same pattern of instruments to be played more than once in a song (E.g. a chorus.) without the pattern having to be repeated. There is usually only one order. This section also contains basic song information. It usually follows the date sub-segment.
0 4 ID 'OPLH' indicates start of pattern placement order 4 4 Size Size of order segment 8 2 Cnt. Number of following chunks
Now, the following chunks may follow until the end of the "OPLH" chunk is reached. Every chunk is identified by the first byte:
- $00 (1 Byte): End (Nothing follows)
- $01 (5/9 Bytes): Order list item follows (e.g. "P0 ", "P12 " in old format or "PATT0 " in new format, see above) - join those to get the complete order list.
- $04 (3 Bytes): This 16-bit value indicates the "restart chunk". If the end of the subsong is reached, it will jump back to this chunk. In many cases, this would be 4th chunk (no 3rd chunk, as the chunk index is starting at 0!), which is a panning index in most PSMs - So you would just go to the nearest order list item that's following this chunk. However, this can also point to a valid order list chunk.
- $07 (2 Bytes): Next byte is default speed for this subtune
- $08 (2 Bytes): Next byte is default tempo for this subtune
- $0C (7 Bytes): Sample map table(?): This chunk is always $0C $00 $FF $00 $00 $01 $00.
- $0D (4 Bytes): Channel panning index. Next byte is channel number (Start at 0), then initial pan ($00 ... $FF) and a byte follow. The byte seems to tell what to do with the previous pan position (0 - use it, 2 - ignore it, make this channel surround, 4 - set to center).
- $0E (3 Bytes): Channel volume index. Next byte is channel number (Start at 0), then volume ($00 ... $FF). $FF in most (all?) cases.
This is simply a list of all the patterns used in the file. You do not really need to parse this, it seems to be a purely informational chunk.
0 4 ID 'PATT' indicates start of pattern list 4 4 Size Size of pattern list after this 8 4 Size Same as above 12 4x Pat An ordered list 'P0 ', 'P1 '... for all patterns in the file, each entry 4 bytes
Sample list sub-segment
Similar to the above, this is a list of all the samples used in the file. It is usually the last sub-segment in the song segment and you do not really need to parse this.
0 4 ID 'DSAM'; indicates start of sample list, used to say what samples are 'full' Any samples not on this list will be ignored, even if they have data 4 4 Size Size of list after this 8 4 Size Same value as above 12 15x Entry Sample entries, one for each sample in the file, each entry 15 bytes
Sample entry: 0 8 Format Sample format, padded with spaces (END, RAG2...) This is important to some programs 8 4 ID 'I0 ', 'I1 '... the sample ID ('I' means 'Instrument'). Again, be sure to accept both 'I0 ' and 'I00 '! 12 2 Num The sample number, 0,1,2... for the sample
Samples are the raw sound data that makes up the instruments on the song. The actual format depends on the sample format. Samples have information in their headers which allows data to be played at different pitches (Speeds.) and to loop from and to various points in the data. This is by far the largest part of the file, since the raw data takes up so much space.
0 4 ID 'DSMP' indicates start of sample 4 4 Size Size of following sample as 'DSMP' + dword from end of word 8 9 Flags If highest bit is set, then sample is looped 9 8 Songn. Filename of the original module (without extension) 17 4 INSx Last digit of sample (Instrument) number, 0-9; with 31 instruments possible Only last digit is shown. E.g 1st, 11th, 21st and 31st sample is 'INS0' 21 33 Name Defines the instrument name or file, usually a .st or line of text 54 51 Header Sample parameters (Can also 58 bytes long, padded with nuls) Byte 1-6 are unknown ($00 $00 $00 $00 $00 $FF) Bytes 7-8 is instrument number Bytes 9-12 are sample length Bytes 13-16 are loop start Bytes 17-20 are loop end (all $FF means at end of sample) Bytes 21-22 are unknown (second byte could be default pan, but seems to be unused) Byte 23 is default volume Bytes 24-27 are unknwon Bytes 28-29 is frequency (Sample rate) 21 $00-bytes follow 105 ? Data Music data in 8-bit mono format
The sample header is slightly different in Sinaria's new format: INSx is 8 bytes long (like the PATT IDs), and the last 21 $00-bytes are just 16 bytes.
The PSM new format, along with the PSM 16 format use delta-encoded samples, something to make the file smaller when zipped. 'Deltas', convert a string of bytes into another by storing the DIFFERENCE between a byte and the previous byte. It has the effect that if a single byte in the sample is changed, the entire sample will be degraded. This use of deltas varies slightly from that of the PSM 16. The 'start value' of the string is assumed to be $80 (128) and the first byte will thus turn this into the first desired value, the second delta converts the first value to the second, and so on.) All deltas are signed, 1-byte values, but loop (Thus 10 - 20 = -10 can also be considered as 10 + 236 = 246). An example of this is as follows:
RAW: (128) 64 66 67 68 69 70 71 73 75 77 76 DELTAS: -64 0 2 1 1 1 1 1 2 2 2 -1
This is the format used in Silverball, early versions of Epic Pinball and possibly other games. The designation 'Protracker Studio 16 format' was given to it by the only reliable source of information on this format, and may not be the official designation.
The format bears many similarities to the S3M format; the file is set out roughly the same, patterns and samples are similar, indeed, near identical and the functionality is similar. It also shows many similarities to the ProTracker MOD format and retains vestiges of Amiga compatibility.
This format can be identified by its signature 'PSMþ', though files may lack this and still function.
File structure: Header Order Pan segment Pattern segment Sample data Sample headers
0 4 Sig Signature, 'PSMþ' 4 59 Title Song title, padded with nulls. Unlike other formats, this must also be terminated with a null byte. (It sometimes is not terminated, though.) 62 1 This must be $1A to end the song name, like in S3M format. 64 1 Type Song type, First bit: 0 - Module (w/samp.), 1 - Song (w/o samples) Second bit: 0 - 3 octave Protracker, 1 - 5 octave; remaining bits reserved. 65 1 PSM v PSM format version, $10 for this format (Hence the name PSM 16) = 'v1.00'. Sometimes, this is also $01, but there's no difference in the format itself. 66 1 Patt v Pattern version, 0 or 1. 0 means the pattern is stored in the module are in the 32 channel file format. A 1 signifies the patterns as being stored as a 255 channel format. (I have not found any PSM16 modules that have this format.) 67 1 Speed Song speed 68 1 BPM Beats per minute, the default Amiga BPM value. (The only reason that the Amiga BPM format is still followed here is that it allows more control over the final hz value.) Range: 32 to 255. 69 1 Vol Master volume of song, 0-255 70 2 Len Song length, 0-255. The number of patterns to play in the song, in total. 72 2 Ordlen The number of orders actually stored at the order offset. It was hoped that the PSM 16 format would allow multiple orders, so this would be the length of the first order. This doesn't appea to ahve happened, and is usually the same as the previous value. 74 2 Patnum Number of patterns in the song. 1-255 76 2 Sampnum Number of samples and 'sample structures' in song, 1-255 78 2 NCIS Number of channels in song to PLAY. 1-32. 80 2 NCP Number of Channels to Process; describes the MAXIMUM number of channels to process. As an example, when converting 669 files, NCP = 9 because some track information is in Channel 8, but the Number of Channels to Play was set to 8, (Channel numbers to play from 0 to 7.) 1-32 82 4 Ordoff Location of order in header 86 4 Panoff Location of pan positions in header 90 4 Patoff Location of patterns in header 94 4 Sampoff Location of sample headers in header 98 4 Commoff Location of comments in header 102 4 Patsiz Total pattern size; the total size of all the patterns loaded from the pattern offset. 106 40 Fillers 10 fillers, to be used for any possible expansions.
It is important to notice that the offsets point to the first byte after the chunk ID, i.e. "Ordoff" points to the first byte after "PORD".
Order and Pan positions
These are two separate segments, pointed to in the header. They may be anywhere, but usually follow the header sometimes after an amount of blank space. They are often padded with blank space. They are basically lists.
Order: This segment is pointed to in the header, and sets the PSM 16 format apart. The PSM 16 format was designed to be much more like the MOD format, allowing game designers to set flags to switch from one set of patterns to another, in effect allowing one file to contain more than one song. (For example a boss flag might make the music switch from a clam patterns 1-4 to a racy and dangerous patterns 5-7.)
0 4 Sig Signature, not needed, 'PORD' 4 ? Ords Pattern numbers and order. There will be [Ordlen] bytes of patterns ? 2 Lang Order language, not implemented, so left blank.
0 4 Sig 'PPAN' 4 12 Pan Pan positions; empty positions left blank.
0 2 Size Size of pattern, including these bytes 2 1 Len Length of pattern, in rows. Max length is 64 rows. 3 1 Chan Number of channels in pattern, 1-32 4 ? Data Pattern data
This is similar to the previous two segments, except actual pattern data is stored here. Patterns are very similar to the S3M format, and consist of y rows of x channels. Each row contains a number of channels and ends with a byte of value 0. Each channel is between 2-6+ bytes long. A totally empty channel is represented by a single byte of value 0.
Each channel starts with a flag byte, abcddddd, where a,b and c indicate whether there is a note and instrument, volume or special effect and effect magnitude in the following data, and dddd is the channel number (0-31, used since a given channel may or may not be present in a row.)
The usual maximum length of a channel entry is 6 bytes (1 flag byte, 2 Note AND instrument bytes, 1 volume byte and two Effect and Effect magnitude bytes.) Thus Note&ins\Eff&Eff mag must always occur together.
Like S3M, volume range is 0-64, as is special magnitude. However, special effects range from 0-255, like PSM New Format.
### Co MOD Description Arguments --- -- --- ----------- --------- Volume Commands 1 A1 EA Fine Volume Slide Up B xx xx=speed 2 A2 A Volume Slide Up B xx xx=speed 3 A3 EB Fine Volume Slide Down B xx xx=speed 4 A4 A Volume Slide Down B xx xx=speed Portamento Commands 10 B0 E1 Fine Porta Up B xx xx=speed 11 B1 1 Portamento Up B xx xx=speed 12 B2 E2 Fine Porta Down B xx xx=speed 13 B3 2 Portamento Down B xx xx=speed 14 B4 3 Tone Portamento B xx xx=speed 15 B5 E3 Set Glissando Control B xx xx=0 - Off, 1 - On 16 B6 5 Tone Port+Vol Slide Up B xx xx=speed 17 B7 5 Tone Port+Vol Slide Down B xx xx=speed Vibrato Commands 20 C0 4 Vibrato B xy x=speed, y=depth 21 C1 E4 Set Vibrato Waveform B x x=Waveform 21 C2 6 Vibrato+Vol Slide Up B xx xx=speed 22 C3 6 Vibrato+Vol Slide Down B xx xx=speed Tremolo Commands 30 D0 7 Tremolo B xy x=speed, y=depth 31 D1 E7 Set Tremolo Control B x x=Waveform Sample Commands 40 E0 9 Sample Offset 3B Position for offset change (0-1,048,575) 41 E1 E9 Retrig Note B xx xx=tick to retrigger sample 42 E2 EC Note Cut B xx xx=tick to cut note 43 E3 ED Note Delay B xx xx=ticks to delay note Pos. Change Commands 50 F0 B Position Jump B xx xx=order position 51 F1 D Pattern Break B xx Skip to line xx in next pattern 52 F2 E6 Jump Loop B xx xx=number of loops 0 Set 53 F3 EE Pattern Delay B xx xx=notes to delay pattern Speed Change Cmds 60 G0 F Set Regular Speed B xx xx=speed 61 G1 F Set BPM B xx xx=BPM (32-255) Misc. Commands 70 H0 0 Arpeggio B xy x=semitone #1, y=semitone #2 71 H1 E5 Set Finetune B xx xx=finetune 72 H2 Set Balance B xx xx=Balance (0-15)
Sample segment 0 4 ID 'PSAM' (Psm SAMple) 4 ? Data Sample data
Sample header segment 0 4 ID 'PSAH' (Psm SAmple Header) 4 ? Data Sample headers
Sample header 0 13 Name Sample filename, terminated with a null. 13 24 Desc Sample description or comments. 37 4 Offs Location of raw sample data in file 43 4 Mem This is the physical offset in RAM/DRAM of the sample. (Often blank.) 45 2 Num Sample number, 1-255 47 1 Type Sample type: (In some games left blank; if this is the case then the sample format is END, as used in most PSM New Format files) Bit 0: 0 - Digital, 1 - Synthesized Bit 2: 0 - 8-bit, 1 - 16-bit Bit 3: 0 - Signed, 1 - Unsigned Bit 4: 0 - Deltas, 1 - Raw Bit 5: 0 - Loop normally, 1 - Bidirectional Bit 6: 1 - Gravis patch (unsupported) Bit 7: 0 - No loop, 1 - Loop sample 48 4 Len Sample length, in bytes. 52 4 Rep st Sample repeat start; if sample loops, the loop starts here. 56 4 Rep fn Sample repeat end, if sample loops, it ends here. If this is less than the sample repeat start, the sample loops backwards. 60 1 Tune Fine tune; range 0-15, Tune 0-7 = 0-7; tune -1 - -8 = 8-15 61 1 Vol Sample volume, 0-64 62 2 Freq This is the frequency for the sample at a C of Octave 2. Typical values are 8,000 hz to 8,448 hz.
Like S3M, sample headers are stored separately from the raw sample data. Unlike S3M, the number of sample headers doesn't have to be 31, but rather is the number of samples in the header. Sample headers are usually stored at then end of the file, after the raw sample data.
A type of sample compression used often, like in the PSM New Format is 'Deltas', which converts a string of bytes into another by storing the DIFFERENCE between a byte and the previous byte. Thus:
RAW: 64 66 67 68 69 70 71 73 75 77 76 DELTAS: 11 64 2 1 1 1 1 1 2 2 2 -1
This is done to make files more compressible, but doesn't seem to be used much.
It is unknown which of the two PSM formats the following utilities support, unless stated otherwise.
- Download psm2scrm.zip - DOS program to convert .PSM songs into ScreamTracker .S3M format, suitable for playing in your favourite tracker/module player. Works only with PSM New Format and is not nearly as accurate as OpenMPT.
- ModPlug Tracker and OpenMPT 1.17 can play the files and save them as S3M. More complex songs don't load correctly though. Works only with new format.
- OpenMPT 1.18 and newer can load all PSM and PSM16 files.
- foo_dumb is a plugin for various module formats for the Foobar2k media player. It supports both PSM16 and PSM and is similar to OpenMPT in playback quality.
- EPICTEST is a demonstration of the Epic Megagames MASI. It contains CONVERT.EXE which can be used to convert modules to the PSM format.
-  JJ1MOD can convert S3M files to PSM, though often with errors (Though these are usually only detectable with older programs such as game executables.) It is currently the only utility able to do this, and works only with New Format.
The New PSM format was reverse engineered by Levellord and tidied up by Levellass. It is possible there may be minor errors in the sample format information, especially since this is poorly documented. Some format definitions have been updated and corrected by Johannes Schultz of the OpenMPT development team.
The PSM16 format was reverse engineered by Wotsit and written up by Levellass. More info is needed.
In all formats the following table shows how note bytes are converted into actual notes: (PSM new format has the widest range, 0-255)
+---------+---------+---------+---------+---------+ | C-0 0 | C-1 12 | C-2 24 | C-3 36 | C-4 48 | | C#0 1 | C#1 13 | C#2 25 | C#3 37 | C#4 49 | | D-0 2 | D-1 14 | D-2 26 | D-3 38 | D-4 50 | | D#0 3 | D#1 15 | D#2 27 | D#3 39 | D#4 51 | | E-0 4 | E-1 16 | E-2 28 | E-3 40 | E-4 52 | | F-0 5 | F-1 17 | F-2 29 | F-3 41 | F-4 53 | | F#0 6 | F#1 18 | F#2 30 | F#3 42 | F#4 54 | | G-0 7 | G-1 19 | G-2 31 | G-3 43 | G-4 55 | | G#0 8 | G#1 20 | G#2 32 | G#3 44 | G#4 56 | | A-0 9 | A-1 21 | A-2 33 | A-3 45 | A-4 57 | | A#0 10 | A#1 22 | A#2 34 | A#3 46 | A#4 58 | | B-0 11 | B-1 23 | B-2 35 | B-3 47 | B-4 59 | +---------+---------+---------+---------+---------+