Fichiers SONS

De T4C Tech
Révision datée du 25 février 2016 à 21:54 par FunJp (discussion | contributions) (Page créée avec « == 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 ... »)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à la navigation Aller à la recherche

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#.