/************************************************
 *												*
 *	 		 Music.h - A music driver			*
 *												*
 *	  Started 27-Jan-89 by Ken Jordan for		*
 *												*
 *				  //  /   / / /					*
 *			 	 MicroIllusions					*
 *				/  / /   / //  tm				*
 *												*
 *	  Copyright 1990 MicroIllusions, Inc.		*
 ************************************************/

/* header file for music.c music driver */

short OpenMusic(void);
short InitMusic(void);
void FreeMusic(void);
short PlaySample(int samplenum, int channel);
void EndSample(int channel);
short StopSample(int channel);
struct event *PlaySong(short which);
void LoopSong(short which);
void ContinueSong(void);
void SetTempo(ULONG tempo);
void SyncMusic(struct Task *task, UBYTE sigbit);
void StopMusic(void);
void SuspendMusic(void);
BOOL LoadPlayXSong(char *name, LONG options);
void FreePlayXSong(void);
void FreePlayXSamp(void);
void FreePlayXSeq(void);
struct sample *AllocSample(struct sample *prev_sample, long attacksize, long sustainsize);
void FreeSample(long number);

typedef struct FileHandle *FILE;

/************************** IFF 8SVX Structures *******************************/

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

#define ID_FORM MakeID('F', 'O', 'R', 'M')
#define ID_8SVX MakeID('8', 'S', 'V', 'X')
#define ID_VHDR MakeID('V', 'H', 'D', 'R')
#define ID_NAME MakeID('N', 'A', 'M', 'E')
#define ID_Copyright MakeID('(', 'c', ')', ' ')
#define ID_AUTH MakeID('A', 'U', 'T', 'H')
#define ID_ANNO MakeID('A', 'N', 'N', 'O')
#define ID_ATAK MakeID('A', 'T', 'A', 'K')
#define ID_RLSE MakeID('R', 'L', 'S', 'E')
#define ID_BODY MakeID('B', 'O', 'D', 'Y')

typedef LONG Fixed;
	/* A fixed-point value, 16 bits to the left of the point and 16
	 * to the right. A Fixed is a number of 216ths, i.e. 65536ths. */

#define Unity 0x10000L  /* Unity = Fixed 1.0 = maximum volume */

/* sCompression: Choice of compression algorithm applied to the samples. */

#define sCmpNone		0       /* not compressed */
#define sCmpFibDelta    1       /* Fibonacci-delta encoding (Appendix C) */

typedef struct {
	ULONG oneShotHiSamples, /* # samples in the high octave 1-shot part */
	repeatHiSamples,		/* # samples in the high octave repeat part */
	samplesPerHiCycle;      	/* # samples/cycle in high octave, else 0   */
	UWORD samplesPerSec;    /* data sampling rate   */
	UBYTE ctOctave, 		/* # octaves of waveforms       */
	sCompression;   		/* data compression technique used      */
	Fixed volume;   		/* playback volume from 0 to Unity (full
							 * volume). Map this value into the output
							 * hardware's dynamic range.    */
} Voice8Header;

	/* this structure identifies a sample */

typedef struct {
	Voice8Header    vhdr;   	/* see structure definition above */
	UBYTE   *sample_data;   	/* where the sample is stored */
	LONG    sample_bytes;   	/* size of allocated memory */
	SHORT   per_delta,      		/* period table offset from std wave */
			ppref_upper,    	/* upper limit (index) of preferred octave */
			ppref_lower;    	/* lower limit (index) of preferred octave */
} IFFSample;

typedef struct {
	UWORD   duration;
	Fixed   dest;
	} EGPoint;

/* ==== structure definitions =====     */

struct envseg   	/* segment of an envelope       		*/
{
	LONG    		delta;  	/* $xxxx.xxxx fixed point delta */
	UWORD   		duration;       /* ticks to achieve target vol. */
	UBYTE   		volume; 	/* target volume level  		*/
	UBYTE   		flags;  	/* flags for this segment       	*/
};

struct envelope 	/* envelope data for channel    	*/
{
	struct envseg   *env_data;      /* ptr to envelope data 		*/
	ULONG   		value;  	/* current value ($xxxx.xxxx)   */
	LONG    		increment;      /* amount to add ($xxxx.xxxx)   */
	UWORD   		count;  	/* iterations left in segment   */
	UWORD   		targetvol;      /* target volume level  		*/
	UWORD   		status; 	/* SUSTAIN and END flags		*/
};

struct sample   	/* sample info structure			*/
{
	struct sample   *next_sample;   	/* pointer to next octave header	*/
	ULONG   		attack_size;    	/* size of initial attack portion        */
	ULONG   		sustain_size;   	/* size of looping portion      		*/
	WORD    		tune;   			/* period table offset from std wave*/
	struct envseg   envelope_data[16];      /* sixteen envelope segments    	*/
	UBYTE   		waveform_data[2];       /* sample data  					*/
};

struct channel  	/* data about each channel      		*/
{
	struct sample   *current_sample;	/* sample that was played       		*/
	struct envelope envelope;       	/* volume envelope data 			*/
	UWORD   		period_entry;   	/* entry in period table used   	*/
	UWORD   		stoptime;       	/* stop time for this voice     	*/
	UBYTE   		octave_shift;   	/* how many times to double period	*/
	UBYTE   		midi_note;      	/* pitch of note that was played	*/
	UBYTE   		midi_channel;   	/* midi channel note played on  	*/
	UBYTE   		priority;			/* priority of this note			*/
};

struct playmsg  	/* play message 					*/
{
	struct Message  message;			/* actual message       				*/
	struct sample   *sample;			/* ptr to sample to play			*/
	UBYTE   		midi_note;      	/* midi note to play    			*/
	UBYTE   		midi_channel;   	/* midi channel 					*/
	UBYTE   		audio_channel;  	/* channel to play it on (0-3)  	*/
	UBYTE   		priority;			/* priority of this note			*/
};

struct event    	/* music events 					*/
{
	UWORD   		starttime;
	UBYTE   		command;			/* see enum below       			*/
	UBYTE   		data;
	UWORD   		stoptime;
};

	/* can also be NOTE ( < 0x80 ) or PRGM ( & 0xf0 == 0xc0) */
enum    {TEMPO = 0x80, SYNC=0xA0, END = 0xFF};     	/* event commands		*/

/* SYNC actually includes a LOT of things...

	Note#		Effect			Vel Means		Also...
	0			Sync to Video	user #
	1			Begin Repeat	count
	2			End Repeat
	3			Song Label						Ignored during playback
*/

struct sequence 		/* sequence data				*/
{
	ULONG   		seqnum;
	UBYTE   		startmode;
	UBYTE   		clockmode;
	UWORD   		startmeasure;
	UWORD   		tempo;
	UWORD   		beatsperbar;
	UWORD   		beatsize;
	UWORD   		barsize;
	ULONG   		numevents;
	struct event    *events;
};

struct stopevent							/* stop event struct    			*/
{
	UBYTE   command;
	UBYTE   data;
	UWORD   stoptime;
};

/* EOF */
