/*==========================================================================*
 * audio.c - Play audio sample for Discovery                                *
 * Copyright (c) 1985 by David Joiner (Talin)                               *
 *==========================================================================*/

#include "welcome.h"

#define STEREO

#define K128	(1L << 17)

#ifdef STEREO

struct SampleBuf {
	void	*sample;
	long	length;
	WORD	volume;
	WORD	period;
	struct	MsgPort *replyPort;
	struct	IOAudio *audioIOB[2];
	struct	IOAudio *moreIOB[2];
};

	/* channel allocation map (try left channel; if unavailable try right) */
static UBYTE allocationMap[] = { 1, 8, 2, 4 };
	/* stereo allocation */
static UBYTE stereoMap[] = { 3, 5, 10, 12 };

void play_sample(struct SampleBuf *sb)
{	struct	IOAudio *audioIOB, *audioIOB2, *firstIOB=NULL, *firstIOB2;
	long	signals, units;

	sb->audioIOB[0] = sb->audioIOB[1] =
		sb->moreIOB[0] = sb->moreIOB[1] = NULL;

	SetSignal(0L,SIGBREAKF_CTRL_C);

	if (sb->replyPort = CreatePort(NULL,0))
	{
			/* create audio I/O block */
		sb->audioIOB[0] = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio));
		sb->audioIOB[1] = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio));
		if (sb->audioIOB[0] && sb->audioIOB[1])
		{
			if (sb->length > K128)
			{
				sb->moreIOB[0] = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio));
				sb->moreIOB[1] = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio));
				if (sb->moreIOB[0] == NULL || sb->moreIOB[1] == NULL) goto bad;
			}

			audioIOB = sb->audioIOB[0];
			audioIOB->ioa_Request.io_Message.mn_Node.ln_Pri = 85;
			audioIOB->ioa_Data = stereoMap;
			audioIOB->ioa_Length = sizeof(stereoMap);

				/* open the audio device */
			if (OpenDevice(AUDIONAME, 0L, &audioIOB->ioa_Request, 0L) == 0)
			{
				units = (LONG)audioIOB->ioa_Request.io_Unit;

				audioIOB->ioa_Request.io_Command = CMD_WRITE;
				audioIOB->ioa_Request.io_Flags = ADIOF_PERVOL;
				audioIOB->ioa_Data = sb->sample;
				audioIOB->ioa_Length = (sb->length > K128 ? K128 : sb->length);
				audioIOB->ioa_Period = sb->period;
				audioIOB->ioa_Volume = sb->volume;
				audioIOB->ioa_Cycles = 1;

				audioIOB2 = sb->audioIOB[1];
				*audioIOB2 = *audioIOB;
				if (sb->length > K128)
				{	*sb->moreIOB[0] = *audioIOB;
					*sb->moreIOB[1] = *audioIOB;
				}

				audioIOB->ioa_Request.io_Unit = (void *)(units & 9);
				BeginIO(&audioIOB->ioa_Request);
				audioIOB2->ioa_Request.io_Unit = (void *)(units & 6);
				BeginIO(&audioIOB2->ioa_Request);

				if (sb->length > K128)
				{	firstIOB = audioIOB;
					firstIOB2 = audioIOB2;
					audioIOB = sb->moreIOB[0];
					audioIOB2 = sb->moreIOB[1];
					audioIOB->ioa_Data = audioIOB2->ioa_Data =
						(void *)((char *)sb->sample + K128);
					audioIOB->ioa_Length = audioIOB2->ioa_Length =
						sb->length - K128;
					audioIOB->ioa_Request.io_Unit = (void *)(units & 9);
					BeginIO(&audioIOB->ioa_Request);
					audioIOB2->ioa_Request.io_Unit = (void *)(units & 6);
					BeginIO(&audioIOB2->ioa_Request);
				}

				for (;;)
				{	signals = Wait((1<<sb->replyPort->mp_SigBit)|SIGBREAKF_CTRL_C);

					if (signals & SIGBREAKF_CTRL_C)
					{		/* abort only or second request */
						if (CheckIO(&audioIOB->ioa_Request) == FALSE)
							AbortIO(&audioIOB->ioa_Request);
						if (CheckIO(&audioIOB2->ioa_Request) == FALSE)
							AbortIO(&audioIOB2->ioa_Request);

						if (firstIOB)
						{	if (CheckIO(&firstIOB->ioa_Request) == FALSE)
							{	AbortIO(&firstIOB->ioa_Request);
								WaitIO(&firstIOB->ioa_Request);
							}
							if (CheckIO(&firstIOB2->ioa_Request) == FALSE)
							{	AbortIO(&firstIOB2->ioa_Request);
								WaitIO(&firstIOB2->ioa_Request);
							}
						}

						if (CheckIO(&audioIOB->ioa_Request) == FALSE)
							WaitIO(&audioIOB->ioa_Request);
						if (CheckIO(&audioIOB2->ioa_Request) == FALSE)
							WaitIO(&audioIOB2->ioa_Request);

						break;
					}

					if (CheckIO(&audioIOB->ioa_Request) &&
						CheckIO(&audioIOB2->ioa_Request)) break;
				}
				/* normally we would Get the message, but we're deleting the port
					anyway...
				*/

				CloseDevice(&sb->audioIOB[0]->ioa_Request);
			}

bad:		if (sb->length > K128)
			{
				if (sb->moreIOB[0]) DeleteExtIO(&sb->moreIOB[0]->ioa_Request);
				if (sb->moreIOB[1]) DeleteExtIO(&sb->moreIOB[1]->ioa_Request);
			}
		}

		if (sb->audioIOB[0]) DeleteExtIO(&sb->audioIOB[0]->ioa_Request);
		if (sb->audioIOB[1]) DeleteExtIO(&sb->audioIOB[1]->ioa_Request);
		sb->audioIOB[0] = sb->audioIOB[1] =
			sb->moreIOB[0] = sb->moreIOB[1] = NULL;

		DeletePort(sb->replyPort);
		sb->replyPort = NULL;
	}
}

void play_async(struct SampleBuf *sb)
{	struct	IOAudio *audioIOB, *audioIOB2, *firstIOB=NULL, *firstIOB2;
	long	signals, units;

	sb->audioIOB[0] = sb->audioIOB[1] =
		sb->moreIOB[0] = sb->moreIOB[1] = NULL;

	if (sb->replyPort = CreatePort(NULL,0))
	{
			/* create audio I/O block */
		sb->audioIOB[0] = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio));
		sb->audioIOB[1] = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio));
		if (sb->audioIOB[0] && sb->audioIOB[1])
		{
			if (sb->length > K128)
			{
				sb->moreIOB[0] = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio));
				sb->moreIOB[1] = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio));
				if (sb->moreIOB[0] == NULL || sb->moreIOB[1] == NULL) goto bad;
			}

			audioIOB = sb->audioIOB[0];
			audioIOB->ioa_Request.io_Message.mn_Node.ln_Pri = 85;
			audioIOB->ioa_Data = stereoMap;
			audioIOB->ioa_Length = sizeof(stereoMap);

				/* open the audio device */
			if (OpenDevice(AUDIONAME, 0L, &audioIOB->ioa_Request, 0L) == 0)
			{
				units = (LONG)audioIOB->ioa_Request.io_Unit;

				audioIOB->ioa_Request.io_Command = CMD_WRITE;
				audioIOB->ioa_Request.io_Flags = ADIOF_PERVOL;
				audioIOB->ioa_Data = sb->sample;
				audioIOB->ioa_Length = (sb->length > K128 ? K128 : sb->length);
				audioIOB->ioa_Period = sb->period;
				audioIOB->ioa_Volume = sb->volume;
				audioIOB->ioa_Cycles = 1;

				audioIOB2 = sb->audioIOB[1];
				*audioIOB2 = *audioIOB;
				if (sb->length > K128)
				{	*sb->moreIOB[0] = *audioIOB;
					*sb->moreIOB[1] = *audioIOB;
				}

				audioIOB->ioa_Request.io_Unit = (void *)(units & 9);
				BeginIO(&audioIOB->ioa_Request);
				audioIOB2->ioa_Request.io_Unit = (void *)(units & 6);
				BeginIO(&audioIOB2->ioa_Request);

				if (sb->length > K128)
				{	firstIOB = audioIOB;
					firstIOB2 = audioIOB2;
					audioIOB = sb->moreIOB[0];
					audioIOB2 = sb->moreIOB[1];
					audioIOB->ioa_Data = audioIOB2->ioa_Data =
						(void *)((char *)sb->sample + K128);
					audioIOB->ioa_Length = audioIOB2->ioa_Length =
						sb->length - K128;
					audioIOB->ioa_Request.io_Unit = (void *)(units & 9);
					BeginIO(&audioIOB->ioa_Request);
					audioIOB2->ioa_Request.io_Unit = (void *)(units & 6);
					BeginIO(&audioIOB2->ioa_Request);
				}

				return;
			}

bad:		if (sb->length > K128)
			{
				if (sb->moreIOB[0]) DeleteExtIO(&sb->moreIOB[0]->ioa_Request);
				if (sb->moreIOB[1]) DeleteExtIO(&sb->moreIOB[1]->ioa_Request);
			}
		}

		if (sb->audioIOB[0]) DeleteExtIO(&sb->audioIOB[0]->ioa_Request);
		if (sb->audioIOB[1]) DeleteExtIO(&sb->audioIOB[1]->ioa_Request);
		sb->audioIOB[0] = sb->audioIOB[1] = NULL;

		DeletePort(sb->replyPort);
		sb->replyPort = NULL;
	}
}

void stop_async(struct SampleBuf *sb);

void wait_async(struct SampleBuf *sb)
{	struct	IOAudio *audioIOB = sb->audioIOB[0],
					*audioIOB2 = sb->audioIOB[1];
	extern WORD skipped;

	if (audioIOB)
	{	
		if (skipped)
		{
			stop_async(sb);
		}
		else
		{
			WaitIO(&audioIOB->ioa_Request);
			WaitIO(&audioIOB2->ioa_Request);

			if (sb->length > K128)
			{	WaitIO(&sb->moreIOB[0]->ioa_Request);
				WaitIO(&sb->moreIOB[1]->ioa_Request);
			}

			CloseDevice(&audioIOB->ioa_Request);
			if (sb->length > K128)
			{
				DeleteExtIO(&sb->moreIOB[0]->ioa_Request);
				DeleteExtIO(&sb->moreIOB[1]->ioa_Request);
			}

			DeleteExtIO(&sb->audioIOB[0]->ioa_Request);
			DeleteExtIO(&sb->audioIOB[1]->ioa_Request);
			sb->audioIOB[0] = sb->audioIOB[1] =
				sb->moreIOB[0] = sb->moreIOB[1] = NULL;

			DeletePort(sb->replyPort);
			sb->replyPort = NULL;
		}
	}
}

int check_async(struct SampleBuf *sb)
{	struct	IOAudio *audioIOB = (sb->moreIOB[0] ? sb->moreIOB[0] : sb->audioIOB[0]),
					*audioIOB2 = (sb->moreIOB[1] ? sb->moreIOB[1] : sb->audioIOB[1]);

	if (audioIOB)
	{
		return (CheckIO(&audioIOB->ioa_Request) && CheckIO(&audioIOB2->ioa_Request));
	}

	return TRUE;
}

void stop_async(struct SampleBuf *sb)
{	struct	IOAudio *audioIOB = (sb->moreIOB[0] ? sb->moreIOB[0] : sb->audioIOB[0]),
					*audioIOB2 = (sb->moreIOB[1] ? sb->moreIOB[1] : sb->audioIOB[1]);

	if (audioIOB)
	{	
		if (CheckIO(&audioIOB->ioa_Request) == FALSE)
			AbortIO(&audioIOB->ioa_Request);
		if (audioIOB2 && CheckIO(&audioIOB2->ioa_Request) == FALSE)
			AbortIO(&audioIOB2->ioa_Request);

		if (sb->length > K128)
		{	struct IOAudio	*m0 = sb->audioIOB[0],
							*m1 = sb->audioIOB[1];

			if (CheckIO(&m0->ioa_Request) == FALSE)
			{	AbortIO(&m0->ioa_Request);
				WaitIO(&m0->ioa_Request);
			}
			if (CheckIO(&m1->ioa_Request) == FALSE)
			{	AbortIO(&m1->ioa_Request);
				WaitIO(&m1->ioa_Request);
			}
		}

		if (CheckIO(&audioIOB->ioa_Request) == FALSE)
			WaitIO(&audioIOB->ioa_Request);
		if (audioIOB2 && CheckIO(&audioIOB2->ioa_Request) == FALSE)
			WaitIO(&audioIOB2->ioa_Request);

		CloseDevice(&sb->audioIOB[0]->ioa_Request);
		if (sb->length > K128)
		{
			DeleteExtIO(&sb->moreIOB[0]->ioa_Request);
			DeleteExtIO(&sb->moreIOB[1]->ioa_Request);
		}

		DeleteExtIO(&audioIOB->ioa_Request);
		if (audioIOB2) DeleteExtIO(&audioIOB2->ioa_Request);
		sb->audioIOB[0] = sb->audioIOB[1] =
			sb->moreIOB[0] = sb->moreIOB[1] = NULL;

		DeletePort(sb->replyPort);
		sb->replyPort = NULL;
	}
}

void play_continuous(struct SampleBuf *sb)
{	struct	IOAudio *audioIOB;

	sb->audioIOB[0] = sb->audioIOB[1] =
		sb->moreIOB[0] = sb->moreIOB[1] = NULL;

	if (sb->replyPort = CreatePort(NULL,0))
	{
			/* create audio I/O block */
		if ( sb->audioIOB[0] = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio)) )
		{
			audioIOB = sb->audioIOB[0];
			audioIOB->ioa_Request.io_Message.mn_Node.ln_Pri = 85;
			audioIOB->ioa_Data = allocationMap;
			audioIOB->ioa_Length = sizeof(allocationMap);

				/* open the audio device */
			if (OpenDevice(AUDIONAME, 0L, &audioIOB->ioa_Request, 0L) == 0)
			{
					/* setup the audio I/O block to play sound */
				audioIOB->ioa_Request.io_Command = CMD_WRITE;
				audioIOB->ioa_Request.io_Flags = ADIOF_PERVOL;
				audioIOB->ioa_Data = sb->sample;
				audioIOB->ioa_Length = sb->length;
				audioIOB->ioa_Period = sb->period;
				audioIOB->ioa_Volume = sb->volume;
				audioIOB->ioa_Cycles = 0;

					/* start the sound and wait */
				BeginIO(&audioIOB->ioa_Request);
				return;
			}

			DeleteExtIO(&audioIOB->ioa_Request);
			sb->audioIOB[0] = NULL;
		}

		DeletePort(sb->replyPort);
		sb->replyPort = NULL;
	}
}

#else

struct SampleBuf {
	void	*sample;
	long	length;
	WORD	volume;
	WORD	period;
	struct	MsgPort *replyPort;
	struct	IOAudio *audioIOB;
	struct	IOAudio *moreIOB;
};

void play_sample(struct SampleBuf *sb)
{	struct	IOAudio *audioIOB, *firstIOB=NULL;
	long	signals;

	sb->audioIOB = NULL;

	SetSignal(0L,SIGBREAKF_CTRL_C);

	if (sb->replyPort = CreatePort(NULL,0))
	{
			/* create audio I/O block */
		if ( sb->audioIOB = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio)) )
		{
			if (sb->length > K128)
			{
				sb->moreIOB = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio));
				if (sb->moreIOB == NULL) goto bad;
			}

			audioIOB = sb->audioIOB;
			audioIOB->ioa_Request.io_Message.mn_Node.ln_Pri = 85;
			audioIOB->ioa_Data = allocationMap;
			audioIOB->ioa_Length = sizeof(allocationMap);

				/* open the audio device */
			if (OpenDevice(AUDIONAME, 0L, &audioIOB->ioa_Request, 0L) == 0)
			{
					/* setup the audio I/O block to play sound */
				audioIOB->ioa_Request.io_Command = CMD_WRITE;
				audioIOB->ioa_Request.io_Flags = ADIOF_PERVOL;
				audioIOB->ioa_Data = sb->sample;
				audioIOB->ioa_Length = (sb->length > K128 ? K128 : sb->length);
				audioIOB->ioa_Period = sb->period;
				audioIOB->ioa_Volume = sb->volume;
				audioIOB->ioa_Cycles = 1;

				if (sb->length > K128) *sb->moreIOB = *audioIOB;

					/* start the sound and wait */
				BeginIO(&audioIOB->ioa_Request);

				if (sb->length > K128)
				{	firstIOB = audioIOB;
					audioIOB = sb->moreIOB;
					audioIOB->ioa_Data = (void *)((char *)sb->sample + K128);
					audioIOB->ioa_Length = sb->length - K128;
					BeginIO(&audioIOB->ioa_Request);
				}

				for (;;)
				{	signals = Wait((1<<sb->replyPort->mp_SigBit)|SIGBREAKF_CTRL_C);

					if (signals & SIGBREAKF_CTRL_C)
					{		/* abort only or second request */
						if (CheckIO(&audioIOB->ioa_Request) == FALSE)
							AbortIO(&audioIOB->ioa_Request);

						if (firstIOB && (CheckIO(&firstIOB->ioa_Request) == FALSE))
						{	AbortIO(&firstIOB->ioa_Request);
							WaitIO(&firstIOB->ioa_Request);
						}

						WaitIO(&audioIOB->ioa_Request);

						break;
					}

					if (CheckIO(&audioIOB->ioa_Request)) break;
				}
				/* normally we would Get the message, but we're deleting the port
					anyway...
				*/

				CloseDevice(&sb->audioIOB->ioa_Request);
			}

			if (sb->length > K128) DeleteExtIO(&sb->moreIOB->ioa_Request);
bad:		DeleteExtIO(&sb->audioIOB->ioa_Request);
			sb->audioIOB = NULL;
		}

		DeletePort(sb->replyPort);
		sb->replyPort = NULL;
	}
}

void play_async(struct SampleBuf *sb)
{	struct	IOAudio *audioIOB;

	sb->audioIOB = NULL;

	if (sb->replyPort = CreatePort(NULL,0))
	{
			/* create audio I/O block */
		if ( sb->audioIOB = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio)) )
		{
			audioIOB = sb->audioIOB;
			audioIOB->ioa_Request.io_Message.mn_Node.ln_Pri = 85;
			audioIOB->ioa_Data = allocationMap;
			audioIOB->ioa_Length = sizeof(allocationMap);

				/* open the audio device */
			if (OpenDevice(AUDIONAME, 0L, &audioIOB->ioa_Request, 0L) == 0)
			{
					/* setup the audio I/O block to play sound */
				audioIOB->ioa_Request.io_Command = CMD_WRITE;
				audioIOB->ioa_Request.io_Flags = ADIOF_PERVOL;
				audioIOB->ioa_Data = sb->sample;
				audioIOB->ioa_Length = sb->length;
				audioIOB->ioa_Period = sb->period;
				audioIOB->ioa_Volume = sb->volume;
				audioIOB->ioa_Cycles = 1;

					/* start the sound and wait */
				BeginIO(&audioIOB->ioa_Request);
				return;
			}

			DeleteExtIO(&audioIOB->ioa_Request);
			sb->audioIOB = NULL;
		}

		DeletePort(sb->replyPort);
		sb->replyPort = NULL;
	}
}

void wait_async(struct SampleBuf *sb)
{
	if (sb->audioIOB)
	{	WaitIO(&sb->audioIOB->ioa_Request);
		CloseDevice(&sb->audioIOB->ioa_Request);
		DeleteExtIO(&sb->audioIOB->ioa_Request);
		sb->audioIOB = NULL;
		DeletePort(sb->replyPort);
		sb->replyPort = NULL;
	}
}

void stop_async(struct SampleBuf *sb)
{
	if (sb->audioIOB)
	{	if (!CheckIO(&sb->audioIOB->ioa_Request)) AbortIO(&sb->audioIOB->ioa_Request);
		WaitIO(&sb->audioIOB->ioa_Request);
		CloseDevice(&sb->audioIOB->ioa_Request);
		DeleteExtIO(&sb->audioIOB->ioa_Request);
		sb->audioIOB = NULL;
		DeletePort(sb->replyPort);
		sb->replyPort = NULL;
	}
}

void play_continuous(struct SampleBuf *sb)
{	struct	IOAudio *audioIOB;

	sb->audioIOB = NULL;

	if (sb->replyPort = CreatePort(NULL,0))
	{
			/* create audio I/O block */
		if ( sb->audioIOB = (struct IOAudio *)CreateExtIO(sb->replyPort, sizeof(struct IOAudio)) )
		{
			audioIOB = sb->audioIOB;
			audioIOB->ioa_Request.io_Message.mn_Node.ln_Pri = 85;
			audioIOB->ioa_Data = allocationMap;
			audioIOB->ioa_Length = sizeof(allocationMap);

				/* open the audio device */
			if (OpenDevice(AUDIONAME, 0L, &audioIOB->ioa_Request, 0L) == 0)
			{
					/* setup the audio I/O block to play sound */
				audioIOB->ioa_Request.io_Command = CMD_WRITE;
				audioIOB->ioa_Request.io_Flags = ADIOF_PERVOL;
				audioIOB->ioa_Data = sb->sample;
				audioIOB->ioa_Length = sb->length;
				audioIOB->ioa_Period = sb->period;
				audioIOB->ioa_Volume = sb->volume;
				audioIOB->ioa_Cycles = 0;

					/* start the sound and wait */
				BeginIO(&audioIOB->ioa_Request);
				return;
			}

			DeleteExtIO(&audioIOB->ioa_Request);
			sb->audioIOB = NULL;
		}

		DeletePort(sb->replyPort);
		sb->replyPort = NULL;
	}
}
#endif

typedef struct
{	ULONG	oneShotHiSamples,repeatHiSamples,samplesPerHiCycle;
	UWORD	samplesPerSec;
	UBYTE	ctOctave,sCompression;
	LONG	volume;
} Voice8Header;

Voice8Header vhdr;

extern long	flength;

struct SampleBuf *load_sample_form(AFILE handle)
{
	struct SampleBuf *sb = NULL;
	LONG				value,filelength,proplength,samplelength;
	WORD				samplevolume,sampleperiod;

	ReadFile(handle,(char *)&value,4);
	if ( value != 'FORM') goto quit;

	ReadFile(handle,&filelength,4);
	flength = filelength;

	if (filelength > 12)
	{	ReadFile(handle,(char *)&value,4);
		if ( value != '8SVX' ) goto quit;

		if ( (filelength -= 8) < 8) goto quit;

		ReadFile(handle,(char *)&value,4);
		if ( value != 'VHDR' ) goto quit;

		ReadFile(handle,&proplength,4);
		ReadFile(handle,&vhdr,proplength);

		samplelength = vhdr.oneShotHiSamples;
		if (samplelength == 0 || samplelength == -1) goto quit;

		samplevolume = (64 * vhdr.volume) / 0x10000L;

		if (vhdr.samplesPerSec == 0)
		{
			sampleperiod = 350;
		}
		else sampleperiod = 3579546L / vhdr.samplesPerSec;

		filelength -= 12 + proplength;

		while (filelength > 8)
		{	ReadFile(handle,&value,4);
			ReadFile(handle,&proplength,4);
			if ( value != 'BODY' )
			{	proplength = proplength + 1 & ~1;
				SeekFile(handle,proplength);
				filelength -= 8 + proplength;
			}
			else
			{	if (proplength > samplelength)
					proplength = samplelength;

				sb = AllocMem(proplength + sizeof *sb,MEMF_CHIP);
				if (sb == NULL) goto quit;

				ReadFile(handle,(char *)(sb + 1),samplelength);
				sb->sample = (void *)(sb + 1);
				sb->length = samplelength;
				sb->volume = samplevolume;
				sb->period = sampleperiod;
#ifdef STEREO
				sb->audioIOB[0] = NULL;
#else
				sb->audioIOB = NULL;
#endif
				sb->replyPort = NULL;
				if (proplength & 1) SeekFile(handle,1L);
				goto quit;
			}
		}
	}

quit:
	return sb;
}

struct SampleBuf *load_sample(char *name)
{
	struct SampleBuf *sb = NULL;
	AFILE				handle;

	if (handle = OpenFile(name,MODE_OLDFILE))
	{
		sb = load_sample_form(handle);
		Close(handle);
	}

	return sb;
}

#if 0
struct SampleBuf *cat_load_sample(char *name)
{
	extern long			CATsize;
	extern AFILE		CATfile;
	struct SampleBuf	*sb = NULL;

	if (CATfile == NULL) return NULL;

	if (CATsize <= 0)
	{	CloseCat();
		return NULL;
	}

	if (sb = load_sample_form(CATfile)) CATsize -= flength + 8;
	else CloseCat();

	return sb;
}
#endif

void unload_sample(struct SampleBuf *sb)
{
	FreeMem(sb,sizeof *sb + sb->length);
}
