The .SKS file format

Overview

A STarKos song has an SKS extension. A song is composed of Patterns, each composed of 3 Tracks, one per channel. A Pattern also posesses a Special Track. The Tracks pointed by the Pattern may be different, or the same. Thus you can have two channels playing the same notes at the same time, without requiring the space of two Tracks in memory, as only one Track is used. The Special Track is only used to change the Speed, as well as play Digidrums.

Each Pattern has its own height, from 0 to 127, regardless of the height of the Track it points to.

A SKS song is saved in ASCII on CPC. It is required because a SKS song can grow up to 55 kilobytes. The song is managed in the banks, linearly. The only possibility to save a file in these conditions with the Amsdos is to save the file byte per byte, which automatically creates an ASCII file.

DATA Structure

SONG HEADER
Offset Field Name Size Value Description
0 Format Tag 10 STK1.0SONG ASCII string indicating the SKS format version.
0 Author 10 ASCII string, padded with spaces.
0 Comments 32 ASCII string, padded with spaces.
0 DigiChannel 1 1, 2 or 3 Indicate on which channel Digidrum should be played.
0 EndPattern 1 >=0 Gives the number of the last Pattern.
0 LoopTo 1 >=0 Indicate where to loop when the song is over.
0 Transposition 1 -12 to 12 Song transpose value (add it to each note).
0 BegSpeed 1 1 to #1F Initial song speed.
0 ReplayFreq 1 0 to 5 0=13 Hz, 1=25hz, 2=50hz, 3=100hz, 4=150hz and 5=300hz.
PATTERNS
Offset Field Name Size Value Description
NBPatterns	1		0 to #FF	Gives the number of the last Pattern that is NON-EMPTY (see the note below).
						This information is non redundant to EndPattern, because the software must also
						save what is beyond the end of the song, the musician may have unused pattern written there.
Reserved	1		0		Unused.

{

Chan 1 Track	2		0 to #1FF	Encoded from bit 0 to 8.
Transposition	-		-#F to #F	Encoded from bit 9 to 13.

Chan 2 Track	2		0 to #1FF	Encoded from bit 0 to 8.
Transposition	-		-#F to #F	Encoded from bit 9 to 13.

Chan 2 Track	2		0 to #1FF	Encoded from bit 0 to 8.
Transposition	-		-#F to #F	Encoded from bit 9 to 13.

Pattern Height	1		0 to #7F
No SpecialTrack	1		0 to #FF

} * (NBPatterns + 1).


NOTE : a NON EMPTY Pattern here only means that the musician hasn't modified the default value in the Linker. By default, the three channels point on Track 0,1,2 respectively. The transpositions and the Special Tracks are 0, and the Pattern Height is #3F.

There is always at least one line encoded, even if it has the default values (which is logical, NBPatterns giving the last Pattern. 0 means that one Pattern is in the list).




Then are coded the INSTRUMENTS, the SPECIAL TRACKS, and the TRACKS. Only non-empty structures are coded, that's why all of them are identified by a 16 bits value (#FFFF marks the end of each list). If the list is empty (for example, no Special Tracks are used) then the Special Tracks list only contains a #FFFF.




INSTRUMENTS
-----------

Field Name	Size in Bytes	Value		Remark
----------      -------------	-----		------
{
Instrument ID	2		1 to #FF/#FFFF	#FFFF marks the end of the list.
Size		2		>=2		The size includes itself.
Loop Address	2				The value is RELATIVE to THIS address.
Speed		1		>=0		Frames spend on each line.
IsRetrig	1		0 or 1
Instrument End	1		0 to #FF	Last line of the Instrument.
LoopTo		1		0 to #FF	<= Instrument End.
IsLoop		1		0 or 1
Name		8				Instrument Name, padded with spaces (32).

Instruments Data				See below.
} * Nb Instruments (information not given. Read data till you find an ID equal to #FFFF).

NOTE : Don't forget there is ALWAYS #FFFF written at the end of the list, even if the song is empty !!


Instrument Data 
***************

One Instrument Line Data follows this scheme :

{
Byte1 : Check the 7th bit. If 1, go to HARD SOUND below:

NON HARD SOUND :
****************
Byte1 :

76543210
0panvvvv

p=Pitch ?
a=Arpeggio ?
n=Noise ?
v=Volume

If Volume=0, Noise?=0, Byte2 below is not coded (but it also means Sound?=1 and Manual Frequency=0). Other bytes may be coded, however.

Byte2 :

76543210
-dsnnnnn

d=Manual Frequency ? If Yes, Arpeggio and Pitch not coded.
s=Sound?
n=Noise, if any.

If Manual Frequency? = 1 : read Manual Frequency WORD (0 to #FFF).

If Arpeggio? = 1 : read Arpeggio BYTE (-#5F to #5F).

If Pitch? = 1 : read Pitch WORD (-#FFF to #FFF).



HARD SOUND
**********
Byte1 :

76543210
1rednpas

r=retrig ?
e=Manual HardFrequency ? If 1, Shift and HardSync not coded.
d=Manual Frequency ? If 1, Arpeggio and Pitch not coded.
n=Noise ?
p=Pitch ?
a=Arpeggio ?
s=Sound ? (0=yes 1=no)

Byte2 :

76543210
hf ssscc

h=Hardsync ?
f=Finetune ?
sss=Shift value (0-7). Inverted value.
cc=Hard curve (0=R13 à 8, 1=9 2=10 3=11)

If Noise? is 1 : read Noise Byte (0 to #1F).

If Finetune? is 1 : read Finetune BYTE (0 to #FF).

If Arpeggio? is 1 : read Arpeggio BYTE (-#5F to #5F).

If Pitch? = 1 : read Pitch WORD (-#FFF to #FFF).

If Manual Frequency? = 1 : read Manual Frequency WORD (0 to #FFF).

If Manual HardFrequency? = 1 : read Manual HardFrequency WORD (0 to #FFFF).

} * (Instrument End + 1)







SPECIAL TRACKS
--------------

Field Name	Size in Bytes	Value		Remark
----------      -------------	-----		------
{
SpecialTrack ID	2		0 to #FF/#FFFF	#FFFF marks the end of the list.
Size		1		>=2		The biggest Special Tracks is always < 256 bytes, so a byte is enough to encode its size. The size includes the Size value.
Special Track Data 				See below.
} * Nb Special Tracks (information not given. Read data till you find an ID equal to #FFFF).

Special Tracks Data
*******************
Data Byte :

76543210
wddddddd

If w = 1 : Wait for (b6-b0) lines. #FF marks an end of the Special Track (no test needed).

If w = 0 :
76543210
0e-vvvvv
e=Effect (0=Speed 1=Digidrum)
v=Value (0 to #1F)




TRACKS
------
Field Name	Size in Bytes	Value		Remark
----------      -------------	-----		------
{
Track ID	2		0 to #FF/#FFFF	#FFFF marks the end of the list.
Size		1		>=2		The size includes the Size value.
Track Data 					See below.
} * Nb Tracks (information not given. Read data till you find an ID equal to #FFFF).

Tracks Data
***********
Byte1:
76543210
wddddddd

If w = 1 : Wait for (b6-b0) lines. #FF marks an end of the Track (no test needed).

If w = 0 :
76543210
0nnnnnnn

n = Value :
0 to 95 = Note. Volume and Pitch may be present.
96=Volume only (no Note/Pitch/Instrument)
97=Pitch only (no Note/Volume/Instrument)
98=Volume+Pitch only (no Note/Instrument)
99=Reset. Nothing else to read for this line.
100=Digidrum. Read next byte to get Digidrum value. Nothing read more for this line.

If no Reset and no Digidrum found :
Byte2 :
76543210
-vipoooo

v=Volume? 0=Yes 1=No.
i=Same Instrument than before ? (0=Yes 1=No) Always 0 on a first Note found on a Track.
p=Pitch?
o=Inverted Volume value (0=max 15=min). Only significant if v=0.

If New Instrument : read Instrument BYTE (1-#FF)

If Pitch : read Pitch BYTE (-#7F to #7F)


documentations/software/starkos/dev.fileformat.sks.txt · Last modified: 2009/07/15 19:08 by grim