//==============================================================================================
//							FICHIER D'EN-TETE DU MODULE DE TRAITEMENT DE L'"ADPCM"
//
//		Créer	  :	30 / 12 / 97
//		Auteur	  :	Nicolas Meyer
//		Fichier	  :	ApmType.h
//
//		Descriptif:	Définitions des structures bas niveau (employées pour la génération des
//					fichiers "APM")
//
//==============================================================================================

#ifndef _APMTYPE_H_
#define _APMTYPE_H_

/*********************************************************************************************************
// DEFINITION DE MACROS

*/
// Codes de retour des différentes fonctions

#define		ADPCM_NOERROR				0x00000000L	// Aucune erreur
#define		ADPCM_INVALIDPARAM			0x00000001L	// Mauvais paramètres
#define		ADPCM_NOMEM					0x00000002L	// Pas assez de mémoire
#define		ADPCM_NOVOICELEFT			0x00000003L	// On ne peut pas charger d'autres voies
#define		ADPCM_BADFORMAT				0x00000004L	// Mauvais format de données
#define		ADPCM_BADVERSION			0x00000005L	// Mauvaise version( le poid fort retourne le numéro de version )
#define		ADPCM_BADFILE				0x00000006L	// Une erreur s'est produite durant la sauvegarde du fichier
#define		ADPCM_VOICEACTIVE			0x00000007L	// La voie reste active
#define		ADPCM_VOICEDELETE			0x00000008L	// La voie est détruite
#define		ADPCM_NOTHEMELEFT			0x00000009L	// Plus de voie theme active
#define		ADPCM_GENERATEFILE			0x0000000AL	// Pas de génération de fichier
#define		ADPCM_NONALLOCATEVOICE		0x0000000BL	// Voie "ADPCM" non allouée (inexistante)
#define		ADPCM_CONFLICT				0x0000000CL	// Conflit entre un fichier "APM" et un bloc ressource mem
#define		ADPCM_OPENFILEFAILED		0x0000000DL	// Le fichier "APM" n'a pas pu être ouvert
#define		ADPCM_INVALIDVOICE			0x0000000EL	// La voie demandée n'existe pas
#define		ADPCM_ENDREACH				0x0000000FL	// La voie a été totalement jouée
#define		ADPCM_NOTADPCMDATAS			0x00000010L	// Les données ne sont pas en ADPCM
#define		ADPCM_ALLOCMEMFAIL			0x00000011L	// Echec d'allocation mémoire
#define		ADPCM_NOVOICEACTIVE			0x00000012L	// Aucune voie à mixer

#define		SND_WAVE_FORMAT_ADPCM		0x00002000L	// Format ADPCM propre à Ubi soft
#define		SND_WAVE_FORMAT_PCM			0x00000001L	// Format PCM de Microsoft
#define		SND_SECURITY_PADD			4
#define		SND_ADPCM_NOLOOP			0xFFFFFFFFL	// Fait office de booléen
#define		SND_ADPCM_BUFFERFREQ		22050		// Fréquence du buffer client "ADPCM"
//#define		SND_ADPCM_BUFFERFREQ		44100		// Fréquence du buffer client "ADPCM"
/* Define the number of samples of for the Assynchronous buffer */
#define     M_SIZE_ASSYNCHRONE          17640 /*0.8 seconds*/


// Macros qui définie un code à partir de 4 caractères
#define SETCOMPRESSID( a, b, c, d )																	\
	( (unsigned long)(unsigned char)( a )         | ( (unsigned long)(unsigned char)( b ) << 8 ) |	\
	( (unsigned long)(unsigned char)( c ) << 16 ) | ( (unsigned long)(unsigned char)( d ) << 24 ) )

#define GETCOMPRESSID( a, b )										\
	*(char*)( b )			=	(char)( ( a ) & 0xff );				\
	*( (char*)( b ) + 1 )	=	(char)( ( ( a ) >> 8  ) & 0xff );	\
	*( (char*)( b ) + 2 )	=	(char)( ( ( a ) >> 16 ) & 0xff );	\
	*( (char*)( b ) + 3 )	=	(char)( ( ( a ) >> 24 ) & 0xff )

#define SET16_16TO23_9( a )	( ( a ) >> 7 )
#define SET23_9TO16_16( a )	( ( a ) << 7 )

// Encodage et décodage 1.1
#define ADPCM_CODAGE_VER				SETCOMPRESSID( 'v', 's', '1', '2' )

/*********************************************************************************************************
// DEFINITION DE STRUCTURES

*/
// Evite les dépendances des "SndBool" (surtout pour la génération des en-tête "APM")
typedef unsigned long	ApmBool;

#ifndef TRUE
#define TRUE  1
#endif

#ifndef FALSE
#define FALSE 0
#endif

// ====================================================================
// Format de diverses données PCM
typedef struct _SampleMono {				// Format d'une donnée mono
	long						Sample;
} SAMPLEMONO;

typedef struct _SampleStereo {				// Format d'une donnée stéreo
	long						SampleR;
	long						SampleL;
} SAMPLESTEREO;

typedef union _DataFormat {
	SAMPLEMONO					stMono;
	SAMPLESTEREO				stStereo;
} tduSampleFormat;

// ====================================================================
// Structure définissant les envirronnements de décompression
typedef struct _AdpcmStateMono {
	ApmBool						bHighByte;	// Indique si il faut décompresser le poid fort ou poid
	long						lValPrev;	// Dernière valeur de sortie
	long						lIndex;		// Index au sein de la table des pas
	long						lLastValue;	// Dernière valeur
} ADPCMSTATEMONO;
typedef ADPCMSTATEMONO*	LPADPCMSTATEMONO;

typedef struct _AdpcmStateStereo {
	ApmBool						bHighByte;	// Indique si il faut décompresser le poid fort ou poid
    long						lValPrevR;	// Dernière valeur de sortie droite
    long						lIndexR;	// Index au sein de la table des pas
	long						lLastValueR;// Dernière valeur droite
    long						lValPrevL;	// Dernière valeur de sortie gauche
    long						lIndexL;	// Index au sein de la table des pas
	long						lLastValueL;// Dernière valeur gauche
} ADPCMSTATESTEREO;
typedef ADPCMSTATESTEREO* LPADPCMSTATESTEREO;

typedef union _tduState {
	ADPCMSTATEMONO				stStateMono;
	ADPCMSTATESTEREO			stStateStereo;
} tduState;
typedef tduState*				lptduState;

// ====================================================================
// Waveformatex ( évite les dépendance envers WINMM )
typedef struct	_SND_tdstWAVEFORMAT {
	unsigned short				unFormatTag;
	unsigned short				unChannels;
	unsigned long				ulSamplesPerSec;
	unsigned long				ulAvgBytesPerSec;
	unsigned short				unBlockAlign;
	unsigned short				unBitsPerSample;
	unsigned short				unSize;					// Reserved 0
} SND_tdstWAVEFORMAT;
typedef SND_tdstWAVEFORMAT* lpSND_tdstWAVEFORMAT;

typedef struct	_SND_tdstWAVEFORMATEX {
	unsigned short				unFormatTag;
	unsigned short				unChannels;
	unsigned long				ulSamplesPerSec;
	unsigned long				ulAvgBytesPerSec;
	unsigned short				unBlockAlign;
	unsigned short				unBitsPerSample;
	unsigned short				unSize;					// Something else
	unsigned long				ulCompressId;
	unsigned long				ulByteSize;				// Taille en octets du fichier
	unsigned long				ulNbSample;
// Données nécessaires au point de bouclage
	unsigned long				ulSampleLoop;			// Position en sample
	unsigned long				ulLengthLoop;			// Taille en octets de la boucle
	tduState					uInitial;				// Environnement de décompression initial
	tduState					uLoop;					// Environnement de décompression au point de loop
	unsigned char				chPadding[ SND_SECURITY_PADD ];	// Delimiteur de structure permet d'eviter les erreurs
} SND_tdstWAVEFORMATEX;
typedef SND_tdstWAVEFORMATEX* lpSND_tdstWAVEFORMATEX;

#endif	// _APMTYPE_H_
