Source to src/s_sound.c


Enter a symbol's name here to quickly find it.

/* s_sound.c */
#include "doomdef.h"
#include "music.h"

#define EXTERN_BUFFER_SIZE (EXTERNALQUADS*32/2)

sfxchannel_t	sfxchannels[SFXCHANNELS];

boolean			channelschanged;	/* set by S_StartSound to signal */
									/* update to remix speculative samples */

int				finalquad;			/* the last quad mixed by update. */
									
int 			sfxvolume = 128;	/* range 0 - 255 */
int 			musicvolume = 128;	/* range 0 - 255 */
int				oldsfxvolume = 128;	/* to detect transition to sound off */

int				soundtics;			/* time spent mixing sounds */
int				soundstarttics;		/* time S_Update started */

int				sfxsample;			/* the sample about to be output */
									/* by S_WriteOutSamples */

/*			 MUSIC VARIABLES */

sfx_t           *instruments[256];	/* pointers to all patches */

channel_t       music_channels[10];	/* master music channel list */

int             musictime;			/* internal music time, follows samplecount */
int             next_eventtime;		/* when next event will occur */
unsigned char   *music;				/* pointer to current music data */
unsigned char   *music_start;		/* current music start pointer */
unsigned char   *music_end;			/* current music end pointer */
unsigned char	*music_memory;		/* current location of cached music */

int             samples_per_midiclock;	/* multiplier for midi clocks */

int				musictics = 0;

#define abs(x) ((x)<0 ? -(x) : (x))


/*
==================
=
= S_Init
=
==================
*/

void S_Init(void)
{
	int		i,l;
	int	lump, end;
	int instnum;

/*				SFX */
	
	for (i=1 ; i < NUMSFX ; i++)
	{
		l = W_CheckNumForName(S_sfx[i].name);
		if (l != -1)
			S_sfx[i].md_data = W_POINTLUMPNUM(l);
	}	

/*				MUSIC */

 	D_memset(instruments, 0, 256 * 4);
 	lump = W_GetNumForName("inststrt");			/* get available instruments[] */
 	end	= W_GetNumForName("instend");
 	while (lump != end)
 	{
 		instnum = (lumpinfo[lump].name[1]-'0')*100
 				+ (lumpinfo[lump].name[2]-'0')*10
 				+ (lumpinfo[lump].name[3]-'0')
 				+ (lumpinfo[lump].name[0] == 'P' ? 128 : 0);
 		instruments[instnum] = (sfx_t *) (wadfileptr + lumpinfo[lump].filepos);
 		lump++;
 	}
 
 	/* hack test */

	music_memory = 0;
	music = 0;
	D_memset(music_channels, 0, sizeof(music_channels));
	musictime = 0;
	next_eventtime = 0;
/*	S_StartSong(1,1); */
  
}


/*
==================
=
= S_Clear
=
==================
*/

void S_Clear (void)
{
	D_memset (sfxchannels,0,sizeof(sfxchannels));
	D_memset (soundbuffer,0,0x4000);
}

void S_RestartSounds (void)
{
}

/*
==================
=
= S_StartSound
=
==================
*/

void S_StartSound(mobj_t *origin, int sound_id)
{
#ifdef JAGUAR
	sfxchannel_t	*channel, *newchannel;
	int 			i;
	int 		dist_approx;
	player_t 	*player;
	int 		dx, dy;
	short		vol;
	sfxinfo_t	*sfx;

/* */
/* spatialize */
/* */
	player = &players[consoleplayer];

	if (!origin || origin == player->mo)
		vol = 127;
	else
	{
		dx = abs(origin->x - player->mo->x);
		dy = abs(origin->y - player->mo->y);
		dist_approx = dx + dy - ((dx < dy ? dx : dy) >> 1);
		vol = dist_approx >> 20;
		if (vol > 127)
			return;		/* too far away */
		vol = 127 - vol;
	}


/* Get sound effect data pointer */
	sfx = &S_sfx[sound_id];
	
	newchannel = NULL;
	
/* reject sounds started at the same instant and singular sounds */
	for (channel=sfxchannels,i=0 ; i<SFXCHANNELS ; i++,channel++)
	{
		if (channel->sfx == sfx)
		{
			if (channel->startquad == finalquad)
			{
				return;		/* exact sound allready started */
			}

			if (sfx->singularity)
			{
				newchannel = channel;	/* overlay this	 */
				goto gotchannel;
			}
		}
		if (channel->origin == origin)
		{	/* cut off whatever was coming from this origin */
			newchannel = channel;
			goto gotchannel;
		}
		
		if (channel->stopquad <= finalquad)
			newchannel = channel;	/* this is a dead channel, ok to reuse */
	}

/* if there weren't any dead channels, try to kill an equal or lower */
/* priority channel */

	if (!newchannel)
	{
		for (newchannel=sfxchannels,i=0 ; i<SFXCHANNELS ; i++, newchannel++)
			if (newchannel->sfx->priority >= sfx->priority)
				goto gotchannel;
		return;		/* couldn't override a channel */
	}


/* */
/* fill in the new values */
/* */
gotchannel:
	newchannel->sfx = sfx;
	newchannel->origin = origin;
	newchannel->startquad = finalquad;
	newchannel->stopquad = finalquad + (sfx->md_data->samples>>2);
	newchannel->source = (int *)&sfx->md_data->data;	
	newchannel->volume = vol * (short)sfxvolume;
	
#endif
}





/*
===================
=
= S_UpdateSounds
=
===================
*/

extern	int	sfx_start;
extern	int music_dspcode;

void S_UpdateSounds(void)
{
#ifdef JAGUAR

	int st;

/* */
/* if sound was just turned off, clear out the buffer */
/* */
	if (!sfxvolume)
	{
		if (oldsfxvolume)
		{
			oldsfxvolume = 0;
			S_Clear ();
		}
		return;
	}
	else
	{
		if (!oldsfxvolume)
			finalquad = (samplecount >> 3) - 100;	/* don't mix lots of junk */
		oldsfxvolume = sfxvolume;
	}
	
/* */
/* print debugging info */
/* */
#if 0
	for (i=0 ; i<SFXCHANNELS ; i++)
	{
		PrintNumber (1,1+i,sfxchannels[i].sfx - S_sfx);
	}

#endif

	soundstarttics = samplecount;		/* for timing calculations */

/* */
/* run the mixing in parallel on the dsp */
/*	 */

	if (music)
	{
		
		if (!musictime)
			musictime = next_eventtime = samplecount + EXTERN_BUFFER_SIZE/2;
		while (samplecount - musictime > EXTERN_BUFFER_SIZE)
		{
			musictime += EXTERN_BUFFER_SIZE;
			next_eventtime += EXTERN_BUFFER_SIZE;
		}
		st = samplecount;
		DSPFunction (&music_dspcode);
		musictics = samplecount - st;

	}
	else
	{
#if 0
((int *)0x1f8000)[ticon*2] = samplecount;
((int *)0x1f8000)[ticon*2+1] = sfxsample;
#endif
		dspfinished = 0x1234;
		dspcodestart = (int)&sfx_start;
	}

#endif
}

void S_StartSong(int music_id, int looping)
{

	int lump;

/*	next_eventtime = musictime; */
	musictime = 0;
	samples_per_midiclock = 0;
	lump = W_GetNumForName(S_music[music_id].name);
	music_memory = music = 
		(unsigned char *) W_CacheLumpNum(lump, PU_STATIC);
	music_start = looping ? music : 0;
	music_end = (unsigned char *) music + lumpinfo[lump].size ;

}

void S_StopSong(void)
{

	int i;
	int *ptr;

	Z_Free (music_memory);
	music = 0;							/* prevent the DSP from running */

	ptr = soundbuffer+1;				/* clear music output buffer */
	for (i=(EXTERNALQUADS*32)/4;i;i-=8)
	{
		ptr[0] = 0;
		ptr[2] = 0;
		ptr[4] = 0;
		ptr[6] = 0;
		ptr += 8;
	}

}