/****************************************************************************
	The C Include file for the dissidents' samp.library. This library reads
	and writes SAMP files. Set your editor's TAB width to 3.

	Version 1.1		April 1990

	by Jim Fiore and Jeff Glatt

****************************************************************************/

#ifndef SAMP_H
#define SAMP_H

#ifdef AZTEC_C
#define NARGS
#endif

/* ============ SAMP.LIB ERROR CODES ============ */
#define SUCCESS			0	/* Operation successful */
#define LIBINUSE			1	/* Some other task is using samp.library */
#define NOOPENFILE		2	/* Cannot open the file */
#define NOTSAMP			3	/* Not a SAMP file */
#define BADSAMP			4	/* Bad SAMP file */
#define NOSUPPORT			5	/* SAMP file not supported */
#define OUTOFRANGE		6	/* Too few waves in the file */
#define OUTOFMEM			7	/* No mem to load the next wave */
#define NOMOREWAVES		8	/* No more waves in the file */
#define USERABORT			9	/* Application Abort */


#define MakeID(a,b,c,d) ( (LONG)(a)<<24L | (LONG)(b)<<16L | (LONG)(c)<<8L | (d) )

#define ID_SAMP MakeID('S','A','M','P')
#define ID_NAME MakeID('N','A','M','E')


/* ======================= The SAMP file MHDR chunk ===================== */

#define ID_MHDR MakeID('M','H','D','R')

	/* MHDR size is dependant on the size of the imbedded playMap. */

/* NUMCHANS is determined by your application. Redefine as needed */
#define NUMCHANS  4

struct MHDRChunk {
	UBYTE NumOfWaves,		/* The number of waves in this file */
		Format,				/* # of ORIGINAL significant bits from 8-28 */
		Flags,				/* Various bits indicate various functions */
		PlayMode,			/* determines play MODE of the playMap */
		NumOfChans,
		Pad,
		PlayMap[128][NUMCHANS];	/* a map of which wave numbers to use for
									each of 128 possible Midi Notes. Default to 4 */
   };

#define	INDEPENDENT		0
#define	MULTI				1
#define	STEREO			2
#define	PAN				3

#define CONTINUED_FILE  0x01
#define STEREO_FILE     0x02

/* ====================== The SAMP file BODY chunk ====================== */

#define ID_BODY MakeID('B','O','D','Y')

/* Every wave has an 80 byte waveHeader, followed by its data. The waveHeader
   structure is as follows:  */

struct waveHeader {
	ULONG  WaveSize;
	USHORT MidiSampNum;
	UBYTE  LoopType, InsType;
	ULONG  Period, Rate, LoopStart, LoopEnd;
	UBYTE  RootNote, VelStart;
	USHORT VelTable[16];
	ULONG  ATAKsize, RLSEsize, FATKsize, FRLSsize, USERsize;
	USHORT  USERtype;
	};

#define	SPECIFIC	0
#define	VOLMOD	1
#define	PERMOD	2
#define	LOOPING	3


/* ================ SAMPlib SampleHeader64 structure ============= */
/* Used by the lib to load SAMP files */

struct SampleHeader64 {
	BYTE		*OneShotAddr;
	UBYTE		Flags;			/* bit 7 on = no overlay */
	UBYTE		VelStart;
	USHORT	VelTable[16];
	BYTE		*OneShotEnd;	/* loop start, as well */
	ULONG		*TransTable;	/* points to ORIGINAL_PITCH */
	USHORT	RootNote;
	ULONG		LoopLength;		/* in words, bit 31 cannot be set */
	UBYTE		AttackRate;		/* 0 - 255 */
	UBYTE		AttackInc;		/* 1 - 64 */
	UBYTE		DecayRate;		/* 1 - 255 */
	UBYTE		DecayDec;		/* 1 - 64 */
	UBYTE		SustLevel;		/* 0 - 64 */
	UBYTE		ReleaseRate;	/* 1 - 255 */
	UBYTE		ReleaseDec;		/* 1 - 64 */
	UBYTE		ClipNote;
	ULONG		WaveSize;		/* in bytes */
	};

/* ====================== For the Transpose table ==================== */
/* For playback of the wave */

struct TransposeNode {
	struct TransposeNode	*Next;
	struct TransposeNode	*Prev;
	ULONG		Period;  /* in nanoseconds */
	ULONG		*Orig;
	ULONG		TSize;
	UBYTE		TPad, Hosts;
};

#define AUDIO_HARDWARE_FUDGE .279365


/* =================== the library's SAMPInfo structure ================ */

struct SAMPInfo {
		struct FileHandle *Handle;
 		UBYTE TypeID[4];	/* SAMP lib writes out waves as "FORM" */
		ULONG FileSize;
 		UBYTE SAMP[4];
		UBYTE MHDR[4];
		ULONG	MHDRsize;
		UBYTE NumOfWaves,
	      SampleFormat,
   	   Flags,
      	PlayMode,
      	NumOfChans,
      	Pad,
      	PlayMap[128][4];
		ULONG ANNOChunk,	/* DOS Seek() offset from beginning of file to ANNO chunk */
			BODYChunk,
			NAMEChunk,
			AUTHChunk,
			COPYChunk;
		APTR ATAK,
			RLSE,
			FATK,			/* Vector for the application's FATK routine */
			FRLS,
			USER,
			EXTRA;
		ULONG	SeekPos;
		ULONG	MemType;		/* AllocMem() attributes of mem where sample data is loaded */
		USHORT MaxChars,	/* Max # of chars in string buffer */
			LowPer,
			HighPer;
	};

/* ======================== Instrument types ========================= */
/* You can construct the InsType field by OR'ing the family with the
	class. For example,

	InsType = STRING | VIOLA_BOW;
*/

/* Instrument Families */
#define	STRING		0x10
#define	WOODWIND		0x20
#define	KEYBOARD		0x30
#define	GUITAR		0x40
#define	VOICE			0x50
#define	DRUM1			0x60
#define	DRUM2			0x70
#define	PERCUSSION1	0x80
#define	BRASS1		0x90
#define	BRASS2		0xA0
#define	CYMBAL		0xB0
#define	EFFECT1		0xC0
#define	EFFECT2		0xD0
#define	SYNTH			0xE0

/* Instrument Classes */

/* For the STRING family, the high nibble is as follows: */

#define	VIOLIN_BOW		0x1
#define	VIOLIN_PLUCK	0x2
#define	VIOLIN_GLIS		0x3
#define	VIOLIN_TREM		0x4
#define	VIOLA_BOW		0x5
#define	VIOLA_PLUCK		0x6
#define	VIOLA_GLIS		0x7
#define	VIOLA_TREM		0x8
#define	CELLO_BOW		0x9
#define	CELLO_PLUCK		0xA
#define	CELLO_GLIS		0xB
#define	CELLO_TREM		0xC
#define	BASS_BOW			0xD
#define	BASS_PLUCK		0xE
#define	BASS_TREM		0xF

/* For the BRASS1 family, the high nibble is as follows: */

#define	BARITONE_SAX	0x1
#define	BARI_GROWL		0x2
#define	TENOR_SAX		0x3
#define	TENOR_GROWL		0x4
#define	ALTO_SAX			0x5
#define	ALTO_GROWL		0x6
#define	SOPRANO_SAX		0x7
#define	SOPRANO_GROWL	0x8
#define	TRUMPET			0x9
#define	MUTED_TRUMPET	0xA
#define	TRUMPET_DROP	0xB
#define	TROMBONE			0xC
#define	TROMBONE_SLIDE	0xD
#define	TROMBONE_MUTE	0xE

/* For the BRASS2 family, the high nibble is as follows: */

#define	FRENCH_HORN		0x1
#define	TUBA				0x2
#define	FLUGAL_HORN		0x3
#define	ENGLISH_HORN	0x4

/* For the WOODWIND family, the high nibble is as follows: */

#define	CLARINET			0x1
#define	FLUTE				0x2
#define	PAN_FLUTE		0x3
#define	OBOE				0x4
#define	PICCOLO			0x5
#define	RECORDER			0x6
#define	BASSOON			0x7
#define	BASS_CLARINET	0x8
#define	HARMONICA		0x9

/* For the KEYBOARD family, the high nibble is as follows: */

#define	GRAND_PIANO		0x1
#define	ELEC_PIANO		0x2
#define	HONKYTONK		0x3
#define	TOY_PIANO		0x4
#define	HARPSICHORD		0x5
#define	CLAVINET			0x6
#define	PIPE_ORGAN		0x7
#define	HAMMOND_B3		0x8
#define	FARFISA_ORGAN	0x9
#define	HARP				0xA

/* For the DRUM1 family, the high nibble is as follows: */

#define	KICK			0x1
#define	SNARE			0x2
#define	TOM			0x3
#define	TIMBALES		0x4
#define	CONGA_HIT	0x5
#define	CONGA_SLAP	0x6
#define	BRUSH_SNARE	0x7
#define	ELEC_SNARE	0x8
#define	ELEC_KICK	0x9
#define	ELEC_TOM		0xA
#define	RIMSHOT		0xB
#define	CROSS_STICK	0xC
#define	BONGO			0xD
#define	STEEL_DRUM	0xE
#define	DOUBLE_TOM	0xF

/* For the DRUM2 family, the high nibble is as follows: */

#define	TIMPANI			0x1
#define	TIMPANI_ROLL	0x2
#define	LOG_DRUM			0x3

/* For the PERCUSSION1 family, the high nibble is as follows: */

#define	BLOCK				0x1
#define	COWBELL			0x2
#define	TRIANGLE			0x3
#define	TAMBOURINE		0x4
#define	WHISTLE			0x5
#define	MARACAS			0x6
#define	BELL				0x7
#define	VIBES				0x8
#define	MARIMBA			0x9
#define	XYLOPHONE		0xA
#define	TUBULAR_BELLS	0xB
#define	GLOCKENSPEIL	0xC

/* For the CYMBAL family, the high nibble is as follows: */

#define	CLOSED_HIHAT	0x1
#define	OPEN_HIHAT		0x2
#define	STEP_HIHAT		0x3
#define	RIDE				0x4
#define	BELL_CYMBAL		0x5
#define	CRASH				0x6
#define	CHOKE_CRASH		0x7
#define	GONG				0x8
#define	BELL_TREE		0x9
#define	CYMBAL_ROLL		0xA

/* For the GUITAR family, the high nibble is as follows: */

#define	ELECTRIC			0x1
#define	MUTED_ELEC		0x2
#define	DISTORTED		0x3
#define	ACOUSTIC			0x4
#define	STRING_12		0x5
#define	NYLON_STRING	0x6
#define	POWER_CHORD		0x7
#define	HARMONICS		0x8
#define	CHORD_STRUM		0x9
#define	BANJO				0xA
#define	ELEC_BASS		0xB
#define	SLAPPED_BASS	0xC
#define	POPPED_BASS		0xD
#define	SITAR				0xE
#define	MANDOLIN			0xF

/* For the VOICE family, the high nibble is as follows: */

#define	MALE_AHH		0x1
#define	FEMALE_AHH	0x2
#define	MALE_OOO		0x3
#define	FEMALE_OOO	0x4
#define	FEMALE		0x5
#define	BREATHY		0x6
#define	LAUGH			0x7
#define	WHISTLER		0x8

/* For the EFFECTS1 family, the high nibble is as follows: */

#define	EXPLOSION		0x1
#define	GUNSHOT			0x2
#define	CREAKING_DOOR	0x3
#define	DOOR_SLAM		0x4
#define	DOOR_CLOSE		0x5
#define	SPACEGUN			0x6
#define	JET_ENGINE		0x7
#define	PROPELLER		0x8
#define	HELOCOPTER		0x9
#define	BROKEN_GLASS	0xA
#define	THUNDER			0xB
#define	RAIN				0xC
#define	BIRDS				0xD
#define	JUNGLE_NOISES	0xE
#define	FOOTSTEP			0xF

/* For the EFFECTS2 family, the high nibble is as follows: */

#define	MACHINE_GUN		0x1
#define	TELEPHONE		0x2
#define	DOG_BARK			0x3
#define	DOG_GROWL		0x4
#define	BOAT_WHISTLE	0x5
#define	OCEAN				0x6
#define	WIND				0x7
#define	CROWD_BOOS		0x8
#define	APPLAUSE			0x9
#define	ROARING_CROWDS	0xA
#define	SCREAM			0xB
#define	SWORD_CLASH		0xC
#define	AVALANCE			0xD
#define	BOUNCING_BALL	0xE
#define	BALL_ON_BAT		0xF	/* OR CLUB */

/* For the SYNTH family, the high nibble is as follows: */

#define	SYNTH_STRINGS	0x1
#define	SQUARE_WAVE		0x2
#define	SAWTOOTH_WAVE	0x3
#define	TRI_WAVE			0x4
#define	SINE_WAVE		0x5
#define	NOISE				0x6

/* ======================== SAMP.LIB ROUTINES ========================= */


#ifndef __ARGS
#ifdef NARGS
#define __ARGS(a) ()
#else
#define __ARGS(a) a
#endif
#endif

extern struct SAMPInfo *OpenSampWrite __ARGS(( char * ));
extern struct SAMPInfo *OpenSampRead __ARGS(( char *, unsigned long ));
extern BOOL	WriteWaves __ARGS(( unsigned long, unsigned long, struct SampleHeader64 *, struct TransposeNode ** ));
extern BOOL	WriteNames __ARGS(( unsigned long, char * ));
extern BOOL	WriteMHDR __ARGS(( unsigned long, unsigned char * ));
extern BOOL	WriteSampChunk __ARGS(( unsigned long, unsigned long, char * )); 
extern BOOL	WriteSampData __ARGS(( unsigned long, char * ));

extern void  CloseSamp __ARGS(( void ));
extern void  LoadPlaymap __ARGS(( ULONG, ULONG, ULONG, ULONG, UBYTE * ));
extern void  MixPlaymap __ARGS(( ULONG, ULONG, ULONG, ULONG, UBYTE * ));
extern SHORT ReadWaves __ARGS(( ULONG, ULONG, UBYTE *, struct Sampleheader64 * ));
extern ULONG *MakeTransTable __ARGS(( ULONG, ULONG, ULONG, struct TransposeNode ** ));
extern ULONG *CusMakeTransTable __ARGS(( ULONG, ULONG, ULONG, struct TransposeNode ** ));
extern ULONG *FindTNode __ARGS(( ULONG *, struct TransposeNode * ));
extern void	RemoveTTable __ARGS(( struct SampleHeader64 *, struct TransposeNode * ));
extern void	FreeTTables __ARGS(( struct TransposeNode * ));
extern UBYTE *SAMPErrorMsg __ARGS(( unsigned long ));


/* *************************************************************************** 
	WARNING: it is advised that you do not use these pragmas, since
   SampInterface.asm maintains the SAMPError variable. If you are really
   interested in efficiency, it is possible to edit the Interface for
   only the functions you need - and pragmas may be used for functions which
   don't fiddle with SAMPError. DON'T include the entire SampInterface AND
   all pragmas, as your code will be larger than if you just used
   SampInterface, AND you will have problems with SAMPError.

#ifndef NO_PRAGMAS

#pragma libcall SAMPBase WriteWaves 			24  981004
#pragma libcall SAMPBase WriteNames 			2a  8002
#pragma libcall SAMPBase WriteMHDR 				30  8002
#pragma libcall SAMPBase WriteSampChunk 		36  81003
#pragma libcall SAMPBase WriteSampData 		3c  8302
#pragma libcall SAMPBase CloseSamp  			42  0
#pragma libcall SAMPBase LoadPlayMap  			4e  8761005
#pragma libcall SAMPBase MixPlayMap  			54  8761005
#pragma libcall SAMPBase MakeTransTable 		60  a76504
#pragma libcall SAMPBase SAMPErrorMsg 			66  101
#pragma libcall SAMPBase CusMakeTransTable 	6c  a976505
#pragma libcall SAMPBase RemoveTable 			72  9802
#pragma libcall SAMPBase FreeTTables 			78  901
#pragma libcall SAMPBase FindTNode 				7e  9002

The three guys below set SAMPError, so these pragmas should NEVER be used...
#pragma libcall SAMPBase OpenSampWrite 		1e  101
#pragma libcall SAMPBase OpenSampRead  		48  8102
#pragma libcall SAMPBase ReadWaves 				5a  ba7604

#endif
************************************************************************* */

#endif

