Beispiel #1
0
/*
========================
S_ScanChannelStarts

Returns qtrue if any new sounds were started since the last mix
========================
*/
qboolean S_ScanChannelStarts( void ) {
	channel_t		*ch;
	int				i;
	qboolean		newSamples;

	newSamples = qfalse;
	ch = s_channels;

	for (i=0; i<MAX_CHANNELS ; i++, ch++) {
		if ( !ch->thesfx ) {
			continue;
		}
		// if this channel was just started this frame,
		// set the sample count to it begins mixing
		// into the very first sample
		if ( ch->startSample == START_SAMPLE_IMMEDIATE ) {
			ch->startSample = s_paintedtime;
			newSamples = qtrue;
			continue;
		}

		// if it is completely finished by now, clear it
		if ( ch->startSample + (ch->thesfx->soundLength) <= s_paintedtime ) {
			S_ChannelFree(ch);
		}
	}

	return newSamples;
}
Beispiel #2
0
/*
========================
S_ScanChannelStarts

Returns qtrue if any new sounds were started since the last mix
========================
*/
static qboolean S_ScanChannelStarts( void ) {
	channel_t		*ch;
	int				i;
	qboolean		newSamples;
	float scale;

	newSamples = qfalse;
	ch = s_channels;

	if (s_useTimescale->integer) {
		scale = com_timescale->value;
	} else if (s_forceScale->value > 0.0) {
		scale = s_forceScale->value;
	} else {
		scale = 1;
	}

	for (i=0; i<MAX_CHANNELS ; i++, ch++) {
		if ( !ch->thesfx ) {
			continue;
		}
		// if this channel was just started this frame,
		// set the sample count to it begins mixing
		// into the very first sample
		if ( ch->startSample == START_SAMPLE_IMMEDIATE ) {
			ch->startSample = s_paintedtime;
			newSamples = qtrue;
			continue;
		}

		// if it is completely finished by now, clear it
		if ( ch->startSample + (ceil((float)ch->thesfx->soundLength / scale)) <= s_paintedtime ) {
			//Com_Printf("freeing %p\n", ch);
			S_ChannelFree(ch);
		}
	}

	return newSamples;
}
Beispiel #3
0
void S_Base_ClearSounds(qboolean clearStreaming, qboolean clearMusic)
{
	if (!s_soundStarted)
	{
		return;
	}

	// stop looping sounds
	Com_Memset(loopSounds, 0, MAX_LOOP_SOUNDS * sizeof(loopSound_t));
	Com_Memset(loop_channels, 0, MAX_CHANNELS * sizeof(channel_t));
	numLoopChannels = 0;
	numLoopSounds   = 0;

	// moved this up so streaming sounds dont get updated with the music, below,
	// and leave us with a snippet off streaming sounds after we reload
	if (clearStreaming)
	{
		int              i;
		streamingSound_t *ss;
		channel_t        *ch;

		for (i = 0, ss = streamingSounds; i < MAX_STREAMING_SOUNDS; i++, ss++)
		{
			if (i > 0 || clearMusic)
			{
				S_StopStreamingSound(i);
			}
		}

		// we should also kill all channels, since we are killing streaming sounds anyway
		// (fixes siren in forest playing after a map_restart/loadgame
		ch = s_channels;
		for (i = 0; i < MAX_CHANNELS; i++, ch++)
		{
			if (ch->thesfx)
			{
				S_ChannelFree(ch);
			}
		}
	}

	if (!clearMusic)
	{
		S_UpdateStreamingSounds();
	}

	if (clearStreaming && clearMusic)
	{
		int clear;

		if (dma.samplebits == 8)
		{
			clear = 0x80;
		}
		else
		{
			clear = 0;
		}

		SNDDMA_BeginPainting();
		if (dma.buffer)
		{
			Com_Memset(dma.buffer, clear, dma.samples * dma.samplebits / 8);
		}
		SNDDMA_Submit();

		// clear out channels so they don't finish playing when audio restarts
		S_ChannelSetup();
	}
}
Beispiel #4
0
/*
====================
S_StartSoundEx

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
====================
*/
void S_Base_StartSoundEx(vec3_t origin, int entnum, int entchannel, sfxHandle_t sfxHandle, int flags, int volume)
{
	channel_t *ch;
	sfx_t     *sfx;
	int       i, time;

	if (!s_soundStarted || s_soundMuted)
	{
		//Com_Printf(S_COLOR_YELLOW "S_Base_StartSoundEx: sound not started or muted\n");
		return;
	}

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

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

	sfx = &knownSfx[sfxHandle];

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

	if (s_show->integer == 1)
	{
		Com_Printf("S_Base_StartSoundEx: %i : %s\n", s_paintedtime, sfx->soundName);
	}

	time = Sys_Milliseconds();
	ch   = s_channels;

	for (i = 0; i < MAX_CHANNELS ; i++, ch++)
	{
		if (ch->entnum == entnum && ch->thesfx)
		{
			if (ch->thesfx == sfx && time - ch->allocTime < 50) // double played in one frame
			{
				return;
			}
			else if (ch->entchannel == entchannel && (flags & SND_CUTOFF_ALL)) // cut the sounds that are flagged to be cut
			{
				S_ChannelFree(ch);
			}
		}
	}

	sfx->lastTimeUsed = time;

	ch = S_ChannelMalloc();
	if (!ch)
	{
		int oldest = sfx->lastTimeUsed;
		int chosen = -1;

		ch = s_channels;

		for (i = 0 ; i < MAX_CHANNELS ; i++, ch++)
		{
			if (ch->entnum != listener_number && ch->entnum == entnum && 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("S_Base_StartSoundEx WARNING: dropping sound\n");
					return;
				}
			}
		}
		ch            = &s_channels[chosen];
		ch->allocTime = sfx->lastTimeUsed;
	}

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

	ch->flags       = flags;
	ch->master_vol  = volume;
	ch->entnum      = entnum;
	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;
}