/****************************************************************************
   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.0		Dec 1989

	by Jim Fiore and Jeff Glatt

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

#ifndef SAMP_H
#define SAMP_H

/* ============ 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	equ	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 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. */

typedef struct {
	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][4];	/* a map of which wave numbers to use for
									each of 128 possible Midi Notes. Default to 4 */
   } MHDRChunk;

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


/* ====================== 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:  */

typedef struct {
   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;
   } waveHeader;

#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 */
	USHORT	*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		Rate;
	USHORT	*Orig;
	ULONG		TSize;
};

#define AUDIO_HARDWARE_FUDGE .279365


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

struct SAMPInfo
{		struct FileHandle *Handle;
 		UBYTE SAMP[4];
		ULONG FileSize;
		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 ========================= */

struct SAMPInfo *OpenSampWrite();
struct SAMPInfo *OpenSampRead();
BOOL  WriteWaves(), WriteNames(), WriteMHDR(), WriteSampChunk(), WriteSampData();
void  CloseSamp();
void  LoadPlaymap();
void  MixPlaymap();
SHORT ReadWaves();
USHORT *MakeTransTable();
UBYTE  *SAMPErrorMsg();

#endif
