Fichiers SONS
Format des fichiers snmci._, snmcf._ et snmcd._
Sur cette page vous seront exposés tous les algorithmes et les constantes nécessaires à la programmation de votre propre éditeur de sons.
Contenu des fichiers ._
Le fichier snmci._ contient une liste récapitulative des sons se trouvant dans les fichiers snmcf._ et snmcd._ ainsi que plusieurs informations les concernant permettant au client T4C de pouvoir les comprendre (comme par exemple à quel offset débute un son, sa taille, sa fréquence d’échantillonnage, etc...).
Le fichier snmcd._ contient les sons compressés au format .mp3, plus précisément; toutes les musiques du jeu (au nombre de 7 dans le client T4C 1.50 d'origine).
Le fichier snmcf._ contient les sons non-compressés au format .wav, plus précisément; tous les sons d'ambiance du jeu (coup d'épée, mort d'un monstre, etc...) (au nombre de 143 dans le client T4C 1.50 d'origine).
Format des fichiers
Structure du fichier snmci._
En C:
unsignef long nbsound;
typedef struct
{
unsigned char lg_name;
char name[];
unsigned long start;
unsigned long size;
unsigned short samplerate;
unsigned char bit_depth;
unsigned char format;
char * data;
} LISTINFO, *LPLISTINFO;
En C#:
public class SoundInfo
{
public byte length_name;
public string name;
public int start;
public int size;
public ushort sample_rate;
public byte bit_depth;
public byte format;
}
Structure du fichier snmcd._
Le fichier snmcd._ ne contient que les données des musiques du jeu juxtaposées les unes derrière les autres. Voici un exemple.
- Outdoors Music.mp3 débute à l'offset 0x00000000, dont la taille fait 0x0015f87d.
- Dungeons Music.mp3 débute à l'offset 0x0015f87d, dont la taille fait 0x00190829.
- Forest Music.mp3 débute à l'offset 0x002f00a6, dont la taille fait 0x00137fd6.
Il est très simple d'extraire ces fichiers mp3 et de les enregistrer directement sur fichier portant l'extension .mp3.
Structure du fichier snmcf._
Le fichier snmcf._ ne contient que les données des musiques d'ambiance du jeu juxtaposées les unes derrière les autres au format wave. Le format wave est un format propriétaire Windows très répandu possédant un header permettant d'être compris par un lecteur musical.
Explications sur le format Wave 1 Explications sur le format Wave 2 Explications sur le format Wave 3
Pour extraire les musiques d'ambiance, il faudra reconstruire l'header du fichier wave et lui coller les données sonores derrière. Voici la structure de l'header wave, dont la taille est de 44 octets.
En C:
typedef struct
{
unsigned char riff_tag[4];
unsigned long lg_chunkndata;
unsigned char wave_tag[4];
unsigned char fmt_tag[4];
unsigned long lg_fmt;
short wFormat_tag;
short wChannels;
unsigned long dwSamplesPerSec;
unsigned long dwAvgBytesPerSec;
short wBlockAlign;
short dwbitpersample;
unsigned char data_tag[4];
unsigned long lg_data;
} SOUNDHEADER, *LPSOUNDHEADER;
En C#:
public class SoundHeader
{
public char[] riff_tag = new char[4];
public int length_chunkndata;
public char[] wave_tag = new char[4];
public char[] fmt_tag = new char[4];
public int lg_fmt;
public short wFormat_tag;
public short wChannels;
public int dwSamplesPerSec;
public int dwAvgBytesPerSec;
public short wBlockAlign;
public short dwbitpersample;
public char[] data_tag = new char[4];
public int length_data;
public SoundHeader ()
{
riff_tag = "RIFF".ToCharArray();
wave_tag = "WAVE".ToCharArray();
fmt_tag = "fmt ".ToCharArray();
data_tag = "data".ToCharArray();
lg_fmt = 16;
wFormat_tag = 1;
wChannels = 1;
}
}
Exemple de chargement des sons
Exemple en pascal
procedure loadsound(); var lg_name : byte; begin blockread(ficlist, nbsound, 4); setlength(list, nbsound); for i := 0 to nbsound - 1 do begin blockread(ficlist, lg_name, 1); setlength(list[i].name, lg_name); blockread(ficlist, list[i].name[1], lg_name); blockread(ficlist, list[i].start, 4); blockread(ficlist, list[i].size, 4); blockread(ficlist, list[i].samplerate, 2); BlockRead(ficlist, list[i].bit_depth, 1); BlockRead(ficlist, list[i].format, 1); setlength(list[i].data, size); if (format = 1) then blockread(ficwave, list[i].data[0], size) else blockread(ficmp3, list[i].data[0], size); end; end;
Exemple en C#
byte[] snmci;
byte[] snmcd;
byte[] snmcf;
uint number_of_sounds;
List<SoundInfo> Sounds;
public void LoadSounds ()
{
int file_position = 0;
try
{
snmci = File.ReadAllBytes("snmci._");
snmcd = File.ReadAllBytes("snmcd._");
snmcf = File.ReadAllBytes("snmcf._");
}
catch
{
// error message
Environment.Exit(0);
}
number_of_sounds = BitConverter.ToUInt32(snmci, file_position); file_position += 4;
Sounds = new List<SoundInfo>();
for (int i = 0; i < number_of_sounds; i++)
{
SoundInfo sound = new SoundInfo();
sound.length_name = snmci[file_position]; file_position += 1;
sound.name = Encoding.Default.GetString(snmci, file_position, sound.length_name); file_position += sound.length_name;
sound.start = BitConverter.ToInt32(snmci, file_position); file_position += 4;
sound.size = BitConverter.ToInt32(snmci, file_position); file_position += 4;
sound.sample_rate = BitConverter.ToUInt16(snmci, file_position); file_position += 2;
sound.bit_depth = snmci[file_position]; file_position += 1;
sound.format = snmci[file_position]; file_position += 1;
Sounds.Add(sound);
}
}
Exemple d'extraction des sons
Exemple en pascal
procedure extract(numsound : integer); var f : file; begin if (list[numsound].format = 0) then begin soundheader.riff_tag := 'RIFF'; soundheader.lg_chunkndata := list[numsound].size + 36; soundheader.wave_tag := 'WAVE'; soundheader.fmt_tag := 'fmt'; soundheader.lg_fmt := 16; soundheader.wFormat_tag := 1; soundheader.wChannels := 1; soundheader.dwSamplesPerSec := list[numsound].samplerate; soundheader.dwAvgBytesPerSec := list[numsound].samplerate * (list[numsound].BitDepth div 8); soundheader.wBlockAlign := (list[numsound].bit_depth div 8) * soundheader.wChannels; soundheader.dwbitpersample := list[numsound].bit_depth; soundheader.data_tag := 'data'; soundheader.lg_data := list[numsound].size; assignfile(f, list[numsound].name + '.wav'); rewrite(f, 1); blockwrite(f, soundheader, sizeof(soundheader)); blockwrite(f, list[numsound].data[0], length(list[numsound].data)); closefile(f); end else begin assignfile(f, list[numsound].name + '.mp3'); rewrite(f,1); blockwrite(f, list[numsound].data[0], length(list[numsound].data)); closefile(f); end; end;
Comment créer votre propre éditeur de sons ?
Il est possible de programmer un éditeur de sons qui travaille exclusivement sur les fichiers snmci._, snmcf._ et snmcd._.
Exemples d'éditeurs de sons (plus puissants que ceux de Vircom ou de Dialsoft):
- T4C Editeur de Sons (auteur Mestoph)
- T4C Sound Editor (auteur ChaotikMind)
- T4C Gustaf Sound Editor (auteur Gustaf)
- ...
--Mestoph 12 mars 2008 à 08:31 (UTC)
--Gustaf 29 juillet 2008 à 16:49 (UTC) : Corrections et ajouts d'explications et de code en C#.