Ejemplo n.º 1
0
/*
* S_Spatialize
*/
static void S_SpatializeChannel( channel_t *ch )
{
	vec3_t origin, velocity;

	if( ch->fixed_origin ) {
		VectorCopy( ch->origin, origin );
		VectorClear( velocity );
	}
	else {
		VectorCopy( s_ent_spatialization[ch->entnum].origin, origin );
		VectorCopy( s_ent_spatialization[ch->entnum].velocity, velocity );
	}

	if( s_pseudoAcoustics->value )
	{
		S_SpatializeOriginHQ( origin, ch->master_vol, ch->dist_mult, &ch->leftvol, &ch->rightvol,
							&ch->lpf_lcoeff, &ch->lpf_rcoeff, &ch->ldelay, &ch->rdelay );
	}
	else
	{
		S_SpatializeOrigin( origin, ch->master_vol, ch->dist_mult, &ch->leftvol, &ch->rightvol );
		ch->lpf_lcoeff = ch->lpf_rcoeff = 0.0f;
		ch->ldelay = ch->rdelay = 0;
	}
}
Ejemplo n.º 2
0
/*
============
S_Respatialize

Change the volumes of all the playing sounds for changes in their positions
============
*/
void SOrig_Respatialize( int entityNum, const vec3_t head, vec3_t axis[ 3 ], int inwater )
{
	int       i;
	channel_t *ch;
	vec3_t    origin;

	if ( !s_soundStarted || s_soundMuted )
	{
		return;
	}

	listener_number = entityNum;
	VectorCopy( head, listener_origin );
	VectorCopy( axis[ 0 ], listener_axis[ 0 ] );
	VectorCopy( axis[ 1 ], listener_axis[ 1 ] );
	VectorCopy( axis[ 2 ], listener_axis[ 2 ] );

	// update spatialization for dynamic sounds
	ch = s_channels;

	for ( i = 0; i < MAX_CHANNELS; i++, ch++ )
	{
		if ( !ch->thesfx )
		{
			continue;
		}

		// anything coming from the view entity will always be full volume
		if ( ch->entnum == listener_number )
		{
			ch->leftvol = ch->master_vol;
			ch->rightvol = ch->master_vol;
		}
		else
		{
			if ( ch->fixed_origin )
			{
				VectorCopy( ch->origin, origin );
			}
			else
			{
				VectorCopy( loopSounds[ ch->entnum ].origin, origin );
			}

			S_SpatializeOrigin( origin, ch->master_vol, &ch->leftvol, &ch->rightvol );
		}
	}

	// add loopsounds
	S_AddLoopSounds();
}
Ejemplo n.º 3
0
/*
=================
S_Spatialize
=================
*/
static void S_Spatialize(channel_t *ch)
{
	vec3_t		origin;

	// anything coming from the view entity will always be full volume
	if (ch->entnum == cl.playernum+1) {
		ch->leftvol = ch->master_vol;
		ch->rightvol = ch->master_vol;
		return;
	}

	if (ch->fixed_origin)
		VectorCopy (ch->origin, origin);
	else
		CL_GetEntitySoundOrigin (ch->entnum, origin);

	S_SpatializeOrigin (origin, ch->master_vol, ch->dist_mult, &ch->leftvol, &ch->rightvol);
}           
Ejemplo n.º 4
0
/*
============
S_Base_Respatialize

Change the volumes of all the playing sounds for changes in their positions
============
*/
static void S_Base_Respatialize( int entityNum, const vec3_t head, const vec3_t axis[3], int inwater ) {
	int			i;
	channel_t	*ch;
	vec3_t		origin;

	if ( !s_soundStarted || s_soundMuted ) {
		return;
	}

	listener_number = entityNum;
	//Com_Printf("%s()  %d\n", __FUNCTION__, entityNum);
	VectorCopy(head, listener_origin);
	VectorCopy(axis[0], listener_axis[0]);
	VectorCopy(axis[1], listener_axis[1]);
	VectorCopy(axis[2], listener_axis[2]);

	// update spatialization for dynamic sounds	
	ch = s_channels;
	for ( i = 0 ; i < MAX_CHANNELS ; i++, ch++ ) {
		if ( !ch->thesfx ) {
			continue;
		}
		// local and first person sounds will always be full volume
		if (ch->fullVolume) {
			ch->leftvol = ch->master_vol;
			ch->rightvol = ch->master_vol;
		} else {
			if (ch->fixed_origin) {
				VectorCopy( ch->origin, origin );
			} else {
				VectorCopy( loopSounds[ ch->entnum ].origin, origin );
			}

			S_SpatializeOrigin (origin, ch->master_vol, &ch->leftvol, &ch->rightvol);
		}
	}

	// add loopsounds
	S_AddLoopSounds ();
}
Ejemplo n.º 5
0
Archivo: dma.c Proyecto: icanhas/yantar
/* Change the volumes of all the playing sounds for changes in their positions */
static void
S_Base_Respatialize(int entityNum, const Vec3 head, Vec3 axis[3],
                    int inwater)
{
    int i;
    Channel	*ch;
    Vec3		origin;

    UNUSED(inwater);

    if(!s_soundStarted || s_soundMuted)
        return;
    listener_number = entityNum;
    copyv3(head, listener_origin);
    copyv3(axis[0], listener_axis[0]);
    copyv3(axis[1], listener_axis[1]);
    copyv3(axis[2], listener_axis[2]);

    /* update spatialization for dynamic sounds */
    ch = s_channels;
    for(i = 0; i < MAX_CHANNELS; i++, ch++) {
        if(!ch->thesfx)
            continue;
        /* anything coming from the view entity will always be full volume */
        if(ch->entnum == listener_number) {
            ch->leftvol = ch->master_vol;
            ch->rightvol = ch->master_vol;
        } else {
            if(ch->fixed_origin)
                copyv3(ch->origin, origin);
            else
                copyv3(loopSounds[ ch->entnum ].origin,
                       origin);

            S_SpatializeOrigin (origin, ch->master_vol, &ch->leftvol,
                                &ch->rightvol);
        }
    }
    S_AddLoopSounds ();
}
Ejemplo n.º 6
0
/*
==================
AddLoopSounds

Entities with a ->sound field will generated looped sounds
that are automatically started, stopped, and merged together
as the entities are sent to the client
==================
*/
static void AddLoopSounds()
{
	int		i;
	int		num;
	clEntityState_t	*ent;

	if (cl_paused->integer) return;
	if (cls.state != ca_active) return;
	if (!cl.sound_ambient) return;

	int sounds[MAX_EDICTS];
	for (i = 0; i < cl.frame.num_entities; i++)
	{
		num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
		ent = &cl_parse_entities[num];
		sounds[i] = ent->sound;
	}

	float atten = SOUND_LOOPATTENUATE2;
	if (bspfile.type == map_q3)
		atten = SOUND_LOOPATTENUATE3;

	for (i = 0; i < cl.frame.num_entities; i++)
	{
		if (!sounds[i]) continue;
		sfx_t *sfx = cl.sound_precache[sounds[i]];
		if (!sfx) continue;		// bad sound effect
		sfxcache_t *sc = sfx->cache;
		if (!sc) continue;

		num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
		ent = &cl_parse_entities[num];

		// find the total contribution of all sounds of this type
		int left_total, right_total;
		S_SpatializeOrigin(ent->origin, 255.0, atten, &left_total, &right_total);
		for (int j = i + 1; j < cl.frame.num_entities; j++)
		{
			if (sounds[j] != sounds[i]) continue;
			sounds[j] = 0;	// don't check this again later

			num = (cl.frame.parse_entities + j)&(MAX_PARSE_ENTITIES-1);
			ent = &cl_parse_entities[num];

			int left, right;
			S_SpatializeOrigin(ent->origin, 255.0, atten, &left, &right);
			left_total += left;
			right_total += right;
		}

		if (left_total == 0 && right_total == 0)
			continue;		// not audible

		// allocate a channel
		channel_t *ch = S_PickChannel(0, 0);
		if (!ch) return;

		if (left_total > 255)
			left_total = 255;
		if (right_total > 255)
			right_total = 255;
		ch->leftvol   = left_total;
		ch->rightvol  = right_total;
		ch->autosound = true;	// remove next frame
		ch->sfx       = sfx;
		ch->pos       = paintedtime % sc->length;
		ch->end       = paintedtime + sc->length - ch->pos;
	}
}
Ejemplo n.º 7
0
/*
==================
S_AddLoopSounds

Spatialize all of the looping sounds.
All sounds are on the same cycle, so any duplicates can just
sum up the channel multipliers.
==================
*/
void S_AddLoopSounds (void) {
	int			i, j, time;
	int			left_total, right_total, left, right;
	channel_t	*ch;
	loopSound_t	*loop, *loop2;
	static int	loopFrame;


	numLoopChannels = 0;

	time = Com_Milliseconds();

	loopFrame++;
	for ( i = 0 ; i < MAX_GENTITIES ; i++) {
		loop = &loopSounds[i];
		if ( !loop->active || loop->mergeFrame == loopFrame ) {
			continue;	// already merged into an earlier sound
		}

		if (loop->kill) {
			S_SpatializeOrigin( loop->origin, 127, &left_total, &right_total);			// 3d
		} else {
			S_SpatializeOrigin( loop->origin, 90,  &left_total, &right_total);			// sphere
		}

		loop->sfx->lastTimeUsed = time;

		for (j=(i+1); j< MAX_GENTITIES ; j++) {
			loop2 = &loopSounds[j];
			if ( !loop2->active || loop2->doppler || loop2->sfx != loop->sfx) {
				continue;
			}
			loop2->mergeFrame = loopFrame;

			if (loop2->kill) {
				S_SpatializeOrigin( loop2->origin, 127, &left, &right);				// 3d
			} else {
				S_SpatializeOrigin( loop2->origin, 90,  &left, &right);				// sphere
			}

			loop2->sfx->lastTimeUsed = time;
			left_total += left;
			right_total += right;
		}
		if (left_total == 0 && right_total == 0) {
			continue;		// not audible
		}

		// allocate a channel
		ch = &loop_channels[numLoopChannels];
		
		if (left_total > 255) {
			left_total = 255;
		}
		if (right_total > 255) {
			right_total = 255;
		}
		
		ch->master_vol = 127;
		ch->leftvol = left_total;
		ch->rightvol = right_total;
		ch->thesfx = loop->sfx;
		ch->doppler = loop->doppler;
		ch->dopplerScale = loop->dopplerScale;
		ch->oldDopplerScale = loop->oldDopplerScale;
		ch->fullVolume = qfalse;
		numLoopChannels++;
		if (numLoopChannels == MAX_CHANNELS) {
			return;
		}
	}
}
Ejemplo n.º 8
0
/*
==================
S_AddLoopSounds

Entities with a ->sound field will generated looped sounds
that are automatically started, stopped, and merged together
as the entities are sent to the client
==================
*/
void S_AddLoopSounds (void)
{
	int			i, j;
	int			sounds[MAX_EDICTS];
	int			left, right, left_total, right_total;
	channel_t	*ch;
	sfx_t		*sfx;
	sfxcache_t	*sc;
	int			num;
	vec3_t		origin_v;	// Knightmare added
	entity_state_t	*ent;

	if (cl_paused->value)
		return;

	if (cls.state != ca_active)
		return;

	if (!cl.sound_prepped)
		return;

	for (i=0 ; i<cl.frame.num_entities ; i++)
	{
		num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
		ent = &cl_parse_entities[num];
		sounds[i] = ent->sound;
	}

	for (i=0 ; i<cl.frame.num_entities ; i++)
	{
		if (!sounds[i])
			continue;

		sfx = cl.sound_precache[sounds[i]];
		if (!sfx)
			continue;		// bad sound effect
		sc = sfx->cache;
		if (!sc)
			continue;

		num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
		ent = &cl_parse_entities[num];

		// Knightmare- find correct origin for bmodels without origin brushes
		if (ent->solid == 31) // special value for bmodels
		{
			cmodel_t	*cmodel;
			qboolean	outofbounds = false;
			int			k;

			cmodel = cl.model_clip[ent->modelindex];
			if (cmodel)
			{
				for (k=0; k<3; k++)
					if (ent->origin[k] < cmodel->mins[k] || ent->origin[k] > cmodel->maxs[k])
						outofbounds = true;
			}
			if (cmodel && outofbounds) {
				for (k=0; k<3; k++)
					origin_v[k] = ent->origin[k]+0.5*(cmodel->mins[k]+cmodel->maxs[k]);
			}
			else
				VectorCopy (ent->origin, origin_v);
		}
		else
			VectorCopy (ent->origin, origin_v);

		// find the total contribution of all sounds of this type
		S_SpatializeOrigin (origin_v, 255.0, SOUND_LOOPATTENUATE, // Knightmare changed, was ent->origin
			&left_total, &right_total);
		for (j=i+1 ; j<cl.frame.num_entities ; j++)
		{
			if (sounds[j] != sounds[i])
				continue;
			sounds[j] = 0;	// don't check this again later

			num = (cl.frame.parse_entities + j)&(MAX_PARSE_ENTITIES-1);
			ent = &cl_parse_entities[num];

			S_SpatializeOrigin (origin_v, 255.0, SOUND_LOOPATTENUATE,  // Knightmare changed, was ent->origin
				&left, &right);
			left_total += left;
			right_total += right;
		}

		if (left_total == 0 && right_total == 0)
			continue;		// not audible

		// allocate a channel
		ch = S_PickChannel(0, 0);
		if (!ch)
			return;

		if (left_total > 255)
			left_total = 255;
		if (right_total > 255)
			right_total = 255;
		ch->leftvol = left_total;
		ch->rightvol = right_total;
		ch->autosound = true;	// remove next frame
		ch->sfx = sfx;
		ch->pos = paintedtime % sc->length;
		ch->end = paintedtime + sc->length - ch->pos;
	}
}
Ejemplo n.º 9
0
/**
 * @brief Spatialize all of the looping sounds.
 *        All sounds are on the same cycle, so any duplicates can just
 *        sum up the channel multipliers.
 */
void S_AddLoopSounds(void)
{
	int         i, j, time;
	int         left_total, right_total, left, right;
	channel_t   *ch;
	loopSound_t *loop, *loop2;
	static int  loopFrame;

	if (!s_soundStarted || s_soundMuted)
	{
		return;
	}

	numLoopChannels = 0;

	time = Sys_Milliseconds();

	loopFrame++;
	for (i = 0 ; i < numLoopSounds; i++)
	{
		loop = &loopSounds[i];
		if (!loop->active || loop->mergeFrame == loopFrame)
		{
			continue;   // already merged into an earlier sound
		}

		if (loop->kill)
		{
			S_SpatializeOrigin(loop->origin, 127, &left_total, &right_total, loop->range, qfalse);            // 3d
		}
		else
		{
			S_SpatializeOrigin(loop->origin, 90, &left_total, &right_total, loop->range, qfalse);             // sphere
		}

		// adjust according to volume
		left_total  = (int)((float)loop->volume * (float)left_total / 256.0);
		right_total = (int)((float)loop->volume * (float)right_total / 256.0);

		loop->sfx->lastTimeUsed = time;

		for (j = (i + 1); j < MAX_GENTITIES ; j++)
		{
			loop2 = &loopSounds[j];
			if (!loop2->active || loop2->doppler || loop2->sfx != loop->sfx)
			{
				continue;
			}
			loop2->mergeFrame = loopFrame;

			if (loop2->kill)
			{
				S_SpatializeOrigin(loop2->origin, 127, &left, &right, loop->range, qfalse);               // 3d
			}
			else
			{
				S_SpatializeOrigin(loop2->origin, 90, &left, &right, loop->range, qfalse);                // sphere
			}

			// adjust according to volume
			left  = (int)((float)loop2->volume * (float)left / 256.0);
			right = (int)((float)loop2->volume * (float)right / 256.0);

			loop2->sfx->lastTimeUsed = time;
			left_total              += left;
			right_total             += right;
		}
		if (left_total == 0 && right_total == 0)
		{
			continue;       // not audible
		}

		// allocate a channel
		ch = &loop_channels[numLoopChannels];

		if (left_total > 255)
		{
			left_total = 255;
		}
		if (right_total > 255)
		{
			right_total = 255;
		}

		ch->master_vol      = 127;
		ch->leftvol         = left_total;
		ch->rightvol        = right_total;
		ch->thesfx          = loop->sfx;
		ch->doppler         = loop->doppler;
		ch->dopplerScale    = loop->dopplerScale;
		ch->oldDopplerScale = loop->oldDopplerScale;
		ch->startSample     = loop->startSample; // allow offsetting of sound samples
		numLoopChannels++;
		if (numLoopChannels == MAX_CHANNELS)
		{
			Com_Printf("S_AddLoopSounds warning: MAX_CHANNELS %i reached - loop sound dropped\n", MAX_CHANNELS);
			return;
		}
	}
}
Ejemplo n.º 10
0
void S_UpdateStreamingSounds(void)
{
	int              bufferSamples;
	int              fileSamples;
	byte             raw[30000]; // just enough to fit in a mac stack frame
	int              fileBytes;
	int              rs;
	int              i, j;
	float            lvol, rvol;
	float            streamingVol;
	streamingSound_t *ss;

	for (i = 0; i < MAX_STREAMING_SOUNDS; i++)
	{
		ss = &streamingSounds[i];
		if (!ss->stream)
		{
			continue;
		}
		// don't bother playing anything if musicvolume is 0
		if (i == 0 && s_musicVolume->value <= 0.0f)
		{
			continue;
		}
		// get the raw stream index
		j = RAW_STREAM(i);

		// see how many samples should be copied into the raw buffer
		if (s_rawend[j] < s_soundtime)
		{
			s_rawend[j] = s_soundtime;
		}

		while (s_rawend[j] < s_soundtime + MAX_RAW_SAMPLES)
		{
			bufferSamples = MAX_RAW_SAMPLES - (s_rawend[j] - s_soundtime);

			// decide how much data needs to be read from the file
			fileSamples = bufferSamples * ss->stream->info.rate / dma.speed;

			if (!fileSamples)
			{
				break;
			}

			// our max buffer size
			fileBytes = fileSamples * (ss->stream->info.width * ss->stream->info.channels);
			if (fileBytes > sizeof(raw))
			{
				fileBytes   = sizeof(raw);
				fileSamples = fileBytes / (ss->stream->info.width * ss->stream->info.channels);
			}

			// read stream
			rs = S_CodecReadStream(ss->stream, fileBytes, raw);
			if (rs < fileBytes)
			{
				fileSamples = rs / (ss->stream->info.width * ss->stream->info.channels);
			}

			// calculate the streaming volume based on stream fade and global fade
			streamingVol = S_GetStreamingFade(ss);
			// stop the stream if we had faded out of existence
			if (streamingVol == 0.0f)
			{
				S_StopStreamingSound(i);
				break;
			}
			streamingVol *= s_volCurrent;

			if (rs > 0)
			{
				if (i == 0)
				{
					lvol = rvol = s_musicVolume->value * streamingVol;
				}
				else
				{
					// attenuate if required
					if (ss->entnum >= 0 && ss->attenuation)
					{
						int r, l;

						S_SpatializeOrigin(entityPositions[ss->entnum], s_volume->value * 255.0f, &l, &r, SOUND_RANGE_DEFAULT, qfalse);
						if ((lvol = ((float)l / 255.0f)) > 1.0f)
						{
							lvol = 1.0f;
						}
						if ((rvol = ((float)r / 255.0f)) > 1.0f)
						{
							rvol = 1.0f;
						}
						lvol *= streamingVol;
						rvol *= streamingVol;
					}
					else
					{
						lvol = rvol = streamingVol;
					}
				}
				// add to raw buffer
				S_Base_RawSamples(j, fileSamples, ss->stream->info.rate,
				                  ss->stream->info.width,
				                  ss->stream->info.channels,
				                  raw, lvol, rvol);
			}
			else
			{
				if (s_debugStreams->integer)
				{
					Com_Printf("STREAM %d: ending...\n", i);
					Com_Printf("Queue stream: %s\nLoopStream: %s\n", ss->queueStream, ss->loopStream);
				}
				// special case for music track queue
				if (i == 0 && ss->queueStreamType && *ss->queueStream)
				{
					switch (ss->queueStreamType)
					{
					case QUEUED_PLAY_ONCE_SILENT:
						break;
					case QUEUED_PLAY_ONCE:
						S_StartBackgroundTrack(ss->queueStream, ss->name, 0);
						break;
					case QUEUED_PLAY_LOOPED:
						S_StartBackgroundTrack(ss->queueStream, ss->queueStream, 0);
						break;
					}
					// queue is done, clear it
					ss->queueStream[0]  = '\0';
					ss->queueStreamType = 0;
					break;
				}

				// loop
				if (*ss->loopStream)
				{
					// TODO: Implement a rewind?
					char loopStream[MAX_QPATH];

					Q_strncpyz(loopStream, ss->loopStream, MAX_QPATH);
					S_StartStreamingSoundEx(loopStream, loopStream,
					                        ss->entnum, ss->channel, i == 0, i == 0 ? 0 : ss->attenuation);
				}
				else
				{
					S_FreeStreamingSound(i);
				}
				break;
			}
		}
	}
}
Ejemplo n.º 11
0
static void S_AddLoopSounds (void) {
	int			i, j, time;
	int			left_total, right_total, left, right;
	channel_t	*ch;
	loopSound_t	*loop, *loop2;
	int numLoopSoundsPresent;
	static int loopFrame = 0;

	numLoopSoundsPresent = 0;
	for (i = 0;  i < MAX_LOOP_SOUNDS;  i++) {
		const loopSound_t *ls;

		ls = &loopSounds[i];

		if (ls->active) {
			LoopSoundsPresent[numLoopSoundsPresent] = i;
			numLoopSoundsPresent++;
			//Com_Printf("loopSound %d:  '%s'\n", i, ls->sfx->soundName);
		}
	}

	//Com_Printf("^5numLoopSoundsPresent %d\n", numLoopSoundsPresent);

	numLoopChannels = 0;

	time = S_Milliseconds();

	loopFrame++;

	//for ( i = 0 ; i < MAX_LOOP_SOUNDS ; i++) {
	for (i = 0;  i < numLoopSoundsPresent;  i++) {
		//loop = &loopSounds[i];
		loop = &loopSounds[LoopSoundsPresent[i]];

		if ( !loop->active || loop->mergeFrame == loopFrame ) {
			continue;	// already merged into an earlier sound
		}

		if (loop->kill) {
			S_SpatializeOrigin( loop->origin, 127, &left_total, &right_total);			// 3d
		} else {
			S_SpatializeOrigin( loop->origin, 90,  &left_total, &right_total);			// sphere
		}

		loop->sfx->lastTimeUsed = time;

		//FIXME linked list for loop sounds
#if 1
		//FIXME omg
		//for (j=(i+1); j< MAX_LOOP_SOUNDS ; j++) {
		for (j = i + 1;  j < numLoopSoundsPresent;  j++) {
			//loop2 = &loopSounds[j];
			loop2 = &loopSounds[LoopSoundsPresent[j]];

			if ( !loop2->active || loop2->doppler || loop2->sfx != loop->sfx) {
				continue;
			}
			loop2->mergeFrame = loopFrame;

			//Com_Printf("^5testing loop  %d %d\n", i, j);

			if (loop2->kill) {
				S_SpatializeOrigin( loop2->origin, 127, &left, &right);				// 3d
			} else {
				S_SpatializeOrigin( loop2->origin, 90,  &left, &right);				// sphere
			}

			loop2->sfx->lastTimeUsed = time;
			left_total += left;
			right_total += right;
		}
#endif

		if (left_total == 0 && right_total == 0) {
			continue;		// not audible
		}

		// allocate a channel
		if (numLoopChannels >= MAX_CHANNELS) {
			Com_Printf(S_COLOR_YELLOW "%s() max loop channels %d\n", __FUNCTION__, numLoopChannels);
			return;
		}
		ch = &loop_channels[numLoopChannels];

		if (left_total > 255) {
			left_total = 255;
		}
		if (right_total > 255) {
			right_total = 255;
		}

		ch->master_vol = 127;
		ch->leftvol = left_total;
		ch->rightvol = right_total;
		ch->thesfx = loop->sfx;
		ch->doppler = loop->doppler;
		ch->dopplerScale = loop->dopplerScale;
		ch->oldDopplerScale = loop->oldDopplerScale;
		numLoopChannels++;
	}
}
Ejemplo n.º 12
0
/*
* S_AddLoopSounds
*/
static void S_AddLoopSounds( void )
{
	int i, j;
	int left, right, left_total, right_total;
	channel_t *ch;
	sfx_t *sfx;
	sfxcache_t *sc;
	
	for( i = 0; i < num_loopsfx; i++ )
	{
		if( !loop_sfx[i].sfx )
			continue;

		sfx = loop_sfx[i].sfx;
		sc = sfx->cache;
		if( !sc )
			continue;

		// find the total contribution of all sounds of this type
		if( loop_sfx[i].attenuation )
		{
			S_SpatializeOrigin( S_LoopSoundOrigin( &loop_sfx[i] ),
				loop_sfx[i].volume, loop_sfx[i].attenuation, &left_total, &right_total );

			for( j = i+1; j < num_loopsfx; j++ )
			{
				if( loop_sfx[j].sfx != loop_sfx[i].sfx )
					continue;
				if( loop_sfx[j].entnum == loop_sfx[i].entnum )
				{
					loop_sfx[j].sfx = NULL; // don't check this again later
					continue;
				}

				loop_sfx[j].sfx = NULL; // don't check this again later

				S_SpatializeOrigin( S_LoopSoundOrigin( &loop_sfx[j] ), 
					loop_sfx[i].volume, loop_sfx[i].attenuation, &left, &right );
				left_total += left;
				right_total += right;
			}

			if( left_total == 0 && right_total == 0 )
				continue; // not audible
		}
		else
		{
			for( j = i+1; j < num_loopsfx; j++ )
			{
				if( loop_sfx[j].sfx != loop_sfx[i].sfx )
					continue;
				if( loop_sfx[j].entnum == loop_sfx[i].entnum )
				{
					loop_sfx[j].sfx = NULL; // don't check this again later
					continue;
				}
			}
			left_total = loop_sfx[i].volume;
			right_total = loop_sfx[i].volume;
		}

		// allocate a channel
		ch = S_PickChannel( 0, 0 );
		if( !ch )
			return;

		if( left_total > 255 )
			left_total = 255;
		if( right_total > 255 )
			right_total = 255;
		ch->leftvol = left_total;
		ch->rightvol = right_total;
		ch->autosound = true; // remove next frame
		ch->sfx = sfx;
		ch->pos = paintedtime % sc->length;
		ch->end = paintedtime + sc->length - ch->pos;
	}

	num_loopsfx = 0;
}
Ejemplo n.º 13
0
/*
============
S_Base_RawSamples

Music streaming
============
*/
void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_channels, const byte *data, float volume, int entityNum)
{
	int		i;
	int		src, dst;
	float	scale;
	int		intVolumeLeft, intVolumeRight;
	portable_samplepair_t *rawsamples;

	if ( !s_soundStarted || s_soundMuted ) {
		return;
	}

	if ( (stream < 0) || (stream >= MAX_RAW_STREAMS) ) {
		return;
	}

	rawsamples = s_rawsamples[stream];

	if ( s_muted->integer ) {
		intVolumeLeft = intVolumeRight = 0;
	} else {
		int leftvol, rightvol;

		if ( entityNum >= 0 && entityNum < MAX_GENTITIES ) {
			// support spatialized raw streams, e.g. for VoIP
			S_SpatializeOrigin( loopSounds[ entityNum ].origin, 256, &leftvol, &rightvol );
		} else {
			leftvol = rightvol = 256;
		}

		intVolumeLeft = leftvol * volume * s_volume->value;
		intVolumeRight = rightvol * volume * s_volume->value;
	}

	if ( s_rawend[stream] < s_soundtime ) {
		Com_DPrintf( "S_Base_RawSamples: resetting minimum: %i < %i\n", s_rawend[stream], s_soundtime );
		s_rawend[stream] = s_soundtime;
	}

	scale = (float)rate / dma.speed;

//Com_Printf ("%i < %i < %i\n", s_soundtime, s_paintedtime, s_rawend[stream]);
	if (s_channels == 2 && width == 2)
	{
		if (scale == 1.0)
		{	// optimized case
			for (i=0 ; i<samples ; i++)
			{
				dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
				s_rawend[stream]++;
				rawsamples[dst].left = ((short *)data)[i*2] * intVolumeLeft;
				rawsamples[dst].right = ((short *)data)[i*2+1] * intVolumeRight;
			}
		}
		else
		{
			for (i=0 ; ; i++)
			{
				src = i*scale;
				if (src >= samples)
					break;
				dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
				s_rawend[stream]++;
				rawsamples[dst].left = ((short *)data)[src*2] * intVolumeLeft;
				rawsamples[dst].right = ((short *)data)[src*2+1] * intVolumeRight;
			}
		}
	}
	else if (s_channels == 1 && width == 2)
	{
		for (i=0 ; ; i++)
		{
			src = i*scale;
			if (src >= samples)
				break;
			dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
			s_rawend[stream]++;
			rawsamples[dst].left = ((short *)data)[src] * intVolumeLeft;
			rawsamples[dst].right = ((short *)data)[src] * intVolumeRight;
		}
	}
	else if (s_channels == 2 && width == 1)
	{
		intVolumeLeft *= 256;
		intVolumeRight *= 256;

		for (i=0 ; ; i++)
		{
			src = i*scale;
			if (src >= samples)
				break;
			dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
			s_rawend[stream]++;
			rawsamples[dst].left = ((char *)data)[src*2] * intVolumeLeft;
			rawsamples[dst].right = ((char *)data)[src*2+1] * intVolumeRight;
		}
	}
	else if (s_channels == 1 && width == 1)
	{
		intVolumeLeft *= 256;
		intVolumeRight *= 256;

		for (i=0 ; ; i++)
		{
			src = i*scale;
			if (src >= samples)
				break;
			dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
			s_rawend[stream]++;
			rawsamples[dst].left = (((byte *)data)[src]-128) * intVolumeLeft;
			rawsamples[dst].right = (((byte *)data)[src]-128) * intVolumeRight;
		}
	}

	if ( s_rawend[stream] > s_soundtime + MAX_RAW_SAMPLES ) {
		Com_DPrintf( "S_Base_RawSamples: overflowed %i > %i\n", s_rawend[stream], s_soundtime );
	}
}
Ejemplo n.º 14
0
/*
============
S_Update

Called once each time through the main loop
============
*/
void S_Base_Update( void ) {
	int			i;
	vec3_t		origin;
	int			total;
	channel_t	*ch;

	if ( !s_soundStarted || s_soundMuted ) {
//		Com_DPrintf ("not started or muted\n");
		return;
	}

	// update spatialization for dynamic sounds
	if (respatialize) {
		respatialize = qfalse;

		ch = s_channels;
		for ( i = 0 ; i < MAX_CHANNELS ; i++, ch++ ) {
			if ( !ch->thesfx ) {
				continue;
			}

			// local and first person sounds will always be full volume
			if (ch->fullVolume) {
				ch->leftvol = ch->master_vol;
				ch->rightvol = ch->master_vol;
			} else {
				if (ch->fixed_origin) {
					VectorCopy( ch->origin, origin );
				} else {
					VectorCopy( loopSounds[ ch->entnum ].origin, origin );
				}

				S_SpatializeOrigin (origin, ch->master_vol, &ch->leftvol, &ch->rightvol);
			}
		}

		// add loopsounds
		S_AddLoopSounds ();
	}

	//
	// debugging output
	//
	if ( s_show->integer == 2 ) {
		total = 0;
		ch = s_channels;
		for (i=0 ; i<MAX_CHANNELS; i++, ch++) {
			if (ch->thesfx && (ch->leftvol || ch->rightvol) ) {
				Com_Printf ("%d %d %s\n", ch->leftvol, ch->rightvol, ch->thesfx->soundName);
				total++;
			}
		}
		
		Com_Printf ("----(%i)---- painted: %i\n", total, s_paintedtime);
	}

	// add raw data from streamed samples
	S_UpdateBackgroundTrack();

	// mix some sound
	S_Update_();
}
Ejemplo n.º 15
0
Archivo: dma.c Proyecto: icanhas/yantar
/*
 * Spatialize all of the looping sounds.
 * All sounds are on the same cycle, so any duplicates can just
 * sum up the channel multipliers.
 */
static void
S_AddLoopSounds(void)
{
    int	i, j, time;
    int	left_total, right_total, left, right;
    Channel	*ch;
    Loopsnd *loop, *loop2;
    static int	loopFrame;


    numLoopChannels = 0;
    time = commillisecs();

    loopFrame++;
    for(i = 0; i < MAX_GENTITIES; i++) {
        loop = &loopSounds[i];
        if(!loop->active || loop->mergeFrame == loopFrame)
            continue;	/* already merged into an earlier sound */

        if(loop->kill)
            S_SpatializeOrigin(loop->origin, 127, &left_total,
                               &right_total);	/* 3d */
        else
            S_SpatializeOrigin(loop->origin, 90,  &left_total,
                               &right_total);	/* sphere */

        loop->sfx->lastTimeUsed = time;

        for(j=(i+1); j< MAX_GENTITIES; j++) {
            loop2 = &loopSounds[j];
            if(!loop2->active || loop2->doppler || loop2->sfx !=
                    loop->sfx)
                continue;
            loop2->mergeFrame = loopFrame;

            if(loop2->kill)
                S_SpatializeOrigin(loop2->origin, 127, &left,
                                   &right);	/* 3d */
            else
                S_SpatializeOrigin(loop2->origin, 90,  &left,
                                   &right);	/* sphere */

            loop2->sfx->lastTimeUsed = time;
            left_total += left;
            right_total += right;
        }
        if(left_total == 0 && right_total == 0)
            continue;	/* not audible */

        /* allocate a channel */
        ch = &loop_channels[numLoopChannels];

        if(left_total > 255)
            left_total = 255;
        if(right_total > 255)
            right_total = 255;

        ch->master_vol = 127;
        ch->leftvol	= left_total;
        ch->rightvol	= right_total;
        ch->thesfx	= loop->sfx;
        ch->doppler	= loop->doppler;
        ch->dopplerScale = loop->dopplerScale;
        ch->oldDopplerScale = loop->oldDopplerScale;
        numLoopChannels++;
        if(numLoopChannels == MAX_CHANNELS)
            return;
    }
}
Ejemplo n.º 16
0
/*
==================
S_AddLoopSounds

Entities with a ->sound field will generated looped sounds
that are automatically started, stopped, and merged together
as the entities are sent to the client
==================
*/
static void S_AddLoopSounds (void)
{
	int			i, j;
	int			sounds[MAX_EDICTS];
	int			left, right, left_total, right_total;
	channel_t	*ch;
	sfx_t		*sfx;
	sfxcache_t	*sc;
	int			num;
	entity_state_t	*ent;
	vec3_t		origin;

	if (cl_paused->integer || cls.state != ca_active || !cl.sound_prepped)
		return;

	for (i=0 ; i<cl.frame.num_entities ; i++)
	{
		num = (cl.frame.parse_entities + i) & PARSE_ENTITIES_MASK;
		ent = &cl_parse_entities[num];
		sounds[i] = ent->sound;
	}

	for (i=0 ; i<cl.frame.num_entities ; i++)
	{
		if (!sounds[i])
			continue;

		sfx = cl.sound_precache[sounds[i]];
		if (!sfx)
			continue;		// bad sound effect
		sc = sfx->cache;
		if (!sc || sc->length <= 0)
			continue;

		num = (cl.frame.parse_entities + i) & PARSE_ENTITIES_MASK;
		ent = &cl_parse_entities[num];

		CL_GetEntitySoundOrigin (ent->number, origin);
		// find the total contribution of all sounds of this type
		S_SpatializeOrigin (origin, 255.0f, SOUND_LOOPATTENUATE,
			&left_total, &right_total);
		for (j=i+1 ; j<cl.frame.num_entities ; j++)
		{
			if (sounds[j] != sounds[i])
				continue;
			sounds[j] = 0;	// don't check this again later

			num = (cl.frame.parse_entities + j) & PARSE_ENTITIES_MASK;
			ent = &cl_parse_entities[num];

			S_SpatializeOrigin (ent->origin, 255.0f, SOUND_LOOPATTENUATE, 
				&left, &right);
			left_total += left;
			right_total += right;
		}

		if (left_total == 0 && right_total == 0)
			continue;		// not audible

		// allocate a channel
		ch = S_PickChannel(0, 0);
		if (!ch)
			return;

		if (left_total > 255)
			left_total = 255;
		if (right_total > 255)
			right_total = 255;
		ch->leftvol = left_total;
		ch->rightvol = right_total;
		ch->autosound = true;	// remove next frame
		ch->sfx = sfx;
		ch->pos = paintedtime % sc->length;
		ch->end = paintedtime + sc->length - ch->pos;
	}
}
Ejemplo n.º 17
0
/*
====================
S_Base_StartSound

Validates the parms and ques the sound up
if pos is NULL, the sound will be dynamically sourced from the entity
Entchannel 0 will never override a playing sound
====================
*/
static void S_Base_StartSound (const vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfxHandle) {
	channel_t	*ch;
	sfx_t		*sfx;
  int i, oldest, chosen, time;
  int	inplay, allowed;

	if ( !s_soundStarted || s_soundMuted ) {
		return;
	}

	if ( !origin && ( entityNum < 0 || entityNum >= MAX_GENTITIES ) ) {
		Com_Error( ERR_DROP, "S_StartSound: bad entitynum %i", entityNum );
	}

	if ( sfxHandle < 0 || sfxHandle >= s_numSfx ) {
		Com_Printf( S_COLOR_YELLOW "S_StartSound: handle %i out of range\n", sfxHandle );
		return;
	}

	sfx = &s_knownSfx[ sfxHandle ];

	if (sfx->inMemory == qfalse) {
		S_memoryLoad(sfx);
	}

	if ( s_show->integer == 1 ) {
		Com_Printf("%f  %i : %s  (%d -> %d)\n", (float)cl.serverTime + Overf, s_paintedtime, sfx->soundName, listener_number, entityNum);
	}

	time = S_Milliseconds();

//	Com_Printf("playing %s\n", sfx->soundName);
	// pick a channel to play on

	allowed = s_maxSoundInstances->integer;
	if (allowed < 0) {  // old q3 code
		allowed = 4;

		if (entityNum == listener_number) {
			allowed = 8;
		}
	}

	ch = s_channels;
	inplay = 0;
	for ( i = 0; i < MAX_CHANNELS ; i++, ch++ ) {
		if (ch->entnum == entityNum && ch->thesfx == sfx) {
			if (time - ch->allocTime < 50) {
				//Com_Printf("^2%f double sound start '%s' last played (%d)  length %f\n", (float)cl.serverTime + Overf, sfx->soundName, time - ch->allocTime, (float)sfx->soundLength / (float)dma.speed);
			}

			if (time - ch->allocTime < s_maxSoundRepeatTime->integer) {
			//if (time - ch->allocTime < (int)((float)sfx->soundLength / (float)dma.speed * 1000.0)) {
				if (s_showMiss->integer) {
					Com_Printf("^3%f double sound start '%s' last played (%d)  length %f\n", (float)cl.serverTime + Overf, sfx->soundName, time - ch->allocTime, (float)sfx->soundLength / (float)dma.speed);
				}
				return;
			}
			inplay++;
		}
	}

	//Com_Printf("inplay %d\n", inplay);

	if (inplay > 4) {
		//Com_Printf("^5%f inplay > x  %d > %d  '%s'\n", (float)cl.serverTime + Overf, inplay, allowed, sfx->soundName);
	}

	if (inplay > allowed) {
		if (s_showMiss->integer > 1) {
			Com_Printf("^1%f inplay > allowed  %d > %d  '%s' ent %d ch %d/%d\n", (float)cl.serverTime + Overf, inplay, allowed, sfx->soundName, entityNum, entchannel, listener_number);
		}
		return;
	}

	sfx->lastTimeUsed = time;

	ch = S_ChannelMalloc();	// entityNum, entchannel);
	if (!ch) {
		if (s_showMiss->integer > 2) {
			Com_Printf("^1%f %s() couldn't allocate channel\n", (float)cl.serverTime + Overf, __FUNCTION__);
		}
		ch = s_channels;

		oldest = sfx->lastTimeUsed;
		chosen = -1;
		for ( i = 0 ; i < MAX_CHANNELS ; i++, ch++ ) {
			if (ch->entnum != listener_number && ch->entnum == entityNum && ch->allocTime<oldest && ch->entchannel != CHAN_ANNOUNCER) {
				oldest = ch->allocTime;
				chosen = i;
			}
		}
		if (chosen == -1) {
			ch = s_channels;
			for ( i = 0 ; i < MAX_CHANNELS ; i++, ch++ ) {
				if (ch->entnum != listener_number && ch->allocTime<oldest && ch->entchannel != CHAN_ANNOUNCER) {
					oldest = ch->allocTime;
					chosen = i;
				}
			}
			if (chosen == -1) {
				ch = s_channels;
				if (ch->entnum == listener_number) {
					for ( i = 0 ; i < MAX_CHANNELS ; i++, ch++ ) {
						if (ch->allocTime<oldest) {
							oldest = ch->allocTime;
							chosen = i;
						}
					}
				}
				if (chosen == -1) {
					Com_Printf("dropping sound\n");
					return;
				}
			}
		}
		ch = &s_channels[chosen];
		ch->allocTime = sfx->lastTimeUsed;
		//Com_Printf("use old\n");
	} else {
		//Com_Printf("alloc\n");
	}

	if (origin) {
		VectorCopy (origin, ch->origin);
		ch->fixed_origin = qtrue;
	} else {
		ch->fixed_origin = qfalse;
	}

	ch->master_vol = 127;
	ch->leftvol = 127;
	ch->rightvol = 127;
	ch->entnum = entityNum;
	ch->thesfx = sfx;
	ch->startSample = START_SAMPLE_IMMEDIATE;
	ch->entchannel = entchannel;
	ch->leftvol = ch->master_vol;		// these will get calced at next spatialize
	ch->rightvol = ch->master_vol;		// unless the game isn't running
	ch->doppler = qfalse;

	if (ch->entnum != listener_number) {
		if (ch->fixed_origin) {
			S_SpatializeOrigin (origin, ch->master_vol, &ch->leftvol, &ch->rightvol);
		}
	} else {
		//Com_Printf("dont respa!!!\n");
	}
}