Пример #1
0
/*
* S_UpdateSources
*/
void S_UpdateSources( void )
{
	int i, entNum;
	ALint state;

	for( i = 0; i < src_count; i++ )
	{
		if( srclist[i].isLocked )
			continue;
		if( !srclist[i].isActive )
			continue;

		if( s_volume->modified )
			qalSourcef( srclist[i].source, AL_GAIN, srclist[i].fvol * s_volume->value );

		// Check if it's done, and flag it
		qalGetSourcei( srclist[i].source, AL_SOURCE_STATE, &state );
		if( state == AL_STOPPED )
		{
			source_kill( &srclist[i] );
			continue;
		}

		entNum = srclist[i].entNum;

		if( srclist[i].isLooping )
		{
			// If a looping effect hasn't been touched this frame, kill it
			if( !entlist[entNum].touched )
			{
				source_kill( &srclist[i] );
				entlist[entNum].src = NULL;
			}
			else
			{
				entlist[entNum].touched = qfalse;
			}
		}

		source_spatialize( &srclist[i] );
	}
}
/*
=================
S_AL_AllocateStreamChannel
=================
*/
static void S_AL_AllocateStreamChannel( void )
{
	// Allocate a streamSource at high priority
	streamSourceHandle = S_AL_SrcAlloc(SRCPRI_STREAM, -2, 0);
	if(streamSourceHandle == -1)
		return;

	// Lock the streamSource so nobody else can use it, and get the raw streamSource
	S_AL_SrcLock(streamSourceHandle);
	streamSource = S_AL_SrcGet(streamSourceHandle);

	// Set some streamSource parameters
	qalSourcei (streamSource, AL_BUFFER,          0            );
	qalSourcei (streamSource, AL_LOOPING,         AL_FALSE     );
	qalSource3f(streamSource, AL_POSITION,        0.0, 0.0, 0.0);
	qalSource3f(streamSource, AL_VELOCITY,        0.0, 0.0, 0.0);
	qalSource3f(streamSource, AL_DIRECTION,       0.0, 0.0, 0.0);
	qalSourcef (streamSource, AL_ROLLOFF_FACTOR,  0.0          );
	qalSourcei (streamSource, AL_SOURCE_RELATIVE, AL_TRUE      );
}
Пример #3
0
void AL_RawSamples( int samples, int rate, int width, int channels, byte *data, float volume )
{
	ALuint buffer;
	ALuint format;

	format = S_AL_Format( width, channels );

	// Create a buffer, and stuff the data into it
	qalGenBuffers(1, &buffer);
	qalBufferData(buffer, format, (ALvoid *)data, (samples * width * channels), rate);
	active_buffers++;

	// set volume
	qalSourcef( streamSource, AL_GAIN, volume );

	// Shove the data onto the streamSource
	qalSourceQueueBuffers(streamSource, 1, &buffer);

	// emulate behavior of S_RawSamples for s_rawend
	s_rawend += samples;
}
Пример #4
0
/**
 * Source aquire / release
 */
static void al_mus_source_get( void )
{
	// Allocate a source at high priority
	source_handle = al_src_alloc( SRCPRI_STREAM, -2, 0 );

	if ( source_handle == -1 )
	{
		return;
	}

	// Lock the source so nobody else can use it, and get the raw source
	al_src_lock( source_handle );
	source = al_src_get( source_handle );

	// Set some source parameters
	qalSource3f( source, AL_POSITION,        0.0, 0.0, 0.0 );
	qalSource3f( source, AL_VELOCITY,        0.0, 0.0, 0.0 );
	qalSource3f( source, AL_DIRECTION,       0.0, 0.0, 0.0 );
	qalSourcef( source, AL_ROLLOFF_FACTOR,  0.0 );
	qalSourcei( source, AL_SOURCE_RELATIVE, AL_TRUE );
}
Пример #5
0
 /*
  * Queues raw samples for playback. Used
  * by the background music an cinematics.
  */
 void
 AL_RawSamples ( q_int32_t samples, q_int32_t rate, q_int32_t width, q_int32_t channels,
                 byte *data, float volume )
 {
   ALuint buffer;
   ALuint format = 0;

   /* Work out format */
   if ( width == 1 ) {
     if ( channels == 1 ) {
       format = AL_FORMAT_MONO8;
     } else if ( channels == 2 ) {
       format = AL_FORMAT_STEREO8;
     }
   } else if ( width == 2 ) {
     if ( channels == 1 ) {
       format = AL_FORMAT_MONO16;
     } else if ( channels == 2 ) {
       format = AL_FORMAT_STEREO16;
     }
   }

   /* Create a buffer, and stuff the data into it */
   qalGenBuffers ( 1, &buffer );
   qalBufferData ( buffer, format, ( ALvoid * ) data,
                   ( samples * width * channels ), rate );
   active_buffers++;

   /* set volume */
   if ( volume > 1.0f ) {
     volume = 1.0f;
   }

   qalSourcef ( streamSource, AL_GAIN, volume );
   /* Shove the data onto the streamSource */
   qalSourceQueueBuffers ( streamSource, 1, &buffer );
   /* emulate behavior of S_RawSamples for s_rawend */
   s_rawend += samples;
 }
/*
=================
S_AL_StartBackgroundTrack
=================
*/
static
void S_AL_StartBackgroundTrack( const char *intro, const char *loop )
{
	int i;
	qboolean issame;

	// Stop any existing music that might be playing
	S_AL_StopBackgroundTrack();

	if((!intro || !*intro) && (!loop || !*loop))
		return;

	// Allocate a musicSource
	S_AL_MusicSourceGet();
	if(musicSourceHandle == -1)
		return;

	if (!loop || !*loop)
	{
		loop = intro;
		issame = qtrue;
	}
	else if(intro && *intro && !strcmp(intro, loop))
		issame = qtrue;
	else
		issame = qfalse;

	// Copy the loop over
	strncpy( s_backgroundLoop, loop, sizeof( s_backgroundLoop ) );

	if(!issame)
	{
		// Open the intro and don't mind whether it succeeds.
		// The important part is the loop.
		intro_stream = S_CodecOpenStream(intro);
	}
	else
		intro_stream = NULL;

	mus_stream = S_CodecOpenStream(s_backgroundLoop);
	if(!mus_stream)
	{
		S_AL_CloseMusicFiles();
		S_AL_MusicSourceFree();
		return;
	}

	// Generate the musicBuffers
	qalGenBuffers(NUM_MUSIC_BUFFERS, musicBuffers);
	
	// Queue the musicBuffers up
	for(i = 0; i < NUM_MUSIC_BUFFERS; i++)
	{
		S_AL_MusicProcess(musicBuffers[i]);
	}

	qalSourceQueueBuffers(musicSource, NUM_MUSIC_BUFFERS, musicBuffers);

	// Set the initial gain property
	qalSourcef(musicSource, AL_GAIN, s_alGain->value * s_musicVolume->value);
	
	// Start playing
	qalSourcePlay(musicSource);

	musicPlaying = qtrue;
}
/*
=================
S_AL_SrcUpdate

Update state (move things around, manage sources, and so on)
=================
*/
static
void S_AL_SrcUpdate( void )
{
	int i;
	int entityNum;
	ALint state;
	src_t *curSource;	

	for(i = 0; i < srcCount; i++)
	{
		entityNum = srcList[i].entity;
		curSource = &srcList[i];

		if(curSource->isLocked)
			continue;

		if(!curSource->isActive)
			continue;

		// Update source parameters
		if((s_alGain->modified)||(s_volume->modified))
			curSource->curGain = s_alGain->value * s_volume->value;
		if((s_alRolloff->modified)&&(!curSource->local))
			qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
		if(s_alMinDistance->modified)
			qalSourcef(curSource->alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);

		if(curSource->isLooping)
		{
			sentity_t *sent = &entityList[ entityNum ];

			// If a looping effect hasn't been touched this frame, kill it
			if(sent->loopAddedThisFrame)
			{
				// The sound has changed without an intervening removal
				if(curSource->isActive && !sent->startLoopingSound &&
						curSource->sfx != sent->loopSfx)
				{
					qalSourceStop(curSource->alSource);
					qalSourcei(curSource->alSource, AL_BUFFER, 0);
					sent->startLoopingSound = qtrue;
				}

				// The sound hasn't been started yet
				if(sent->startLoopingSound)
				{
					S_AL_SrcSetup(i, sent->loopSfx, sent->loopPriority,
							entityNum, -1, curSource->local);
					curSource->isLooping = qtrue;
					qalSourcei(curSource->alSource, AL_LOOPING, AL_TRUE);
					qalSourcePlay(curSource->alSource);

					sent->startLoopingSound = qfalse;
				}

				// Update locality
				if(curSource->local)
				{
					qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_TRUE);
					qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, 0.0f);
				}
				else
				{
					qalSourcei(curSource->alSource, AL_SOURCE_RELATIVE, AL_FALSE);
					qalSourcef(curSource->alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
				}
			}
			else
				S_AL_SrcKill( i );

			continue;
		}

		// Check if it's done, and flag it
		qalGetSourcei(curSource->alSource, AL_SOURCE_STATE, &state);
		if(state == AL_STOPPED)
		{
			S_AL_SrcKill(i);
			continue;
		}

		// Query relativity of source, don't move if it's true
		qalGetSourcei(curSource->alSource, AL_SOURCE_RELATIVE, &state);

		// See if it needs to be moved
		if(curSource->isTracking && !state)
		{
			qalSourcefv(curSource->alSource, AL_POSITION, entityList[entityNum].origin);
 			S_AL_ScaleGain(curSource, entityList[entityNum].origin);
		}
	}
}
Пример #8
0
void SndAl_RawSamples( int stream, int samples, int rate, int width, int channels, const byte *data, float volume, int entityNum )
{
	ALuint buffer;
	ALuint format = AL_FORMAT_STEREO16;
	ALint  state;

	// Work out AL format
	if ( width == 1 )
	{
		if ( channels == 1 )
		{
			format = AL_FORMAT_MONO8;
		}
		else if ( channels == 2 )
		{
			format = AL_FORMAT_STEREO8;
		}
	}
	else if ( width == 2 )
	{
		if ( channels == 1 )
		{
			format = AL_FORMAT_MONO16;
		}
		else if ( channels == 2 )
		{
			format = AL_FORMAT_STEREO16;
		}
	}

	// Create the source if necessary
	if ( source_handle == -1 )
	{
		allocate_channel();

		// Failed?
		if ( source_handle == -1 )
		{
			si.Printf( PRINT_ALL, "Can't allocate streaming source\n" );
			return;
		}
	}

	// Create a buffer, and stuff the data into it
	qalGenBuffers( 1, &buffer );
	qalBufferData( buffer, format, data, ( samples * width * channels ), rate );

	// Shove the data onto the source
	qalSourceQueueBuffers( source, 1, &buffer );

	// Start the source playing if necessary
	qalGetSourcei( source, AL_SOURCE_STATE, &state );

	// Volume
	qalSourcef( source, AL_GAIN, volume * s_volume->value * s_gain->value );

	if ( !is_playing )
	{
		qalSourcePlay( source );
		is_playing = qtrue;
	}
}
Пример #9
0
void S_UpdateMusic( void )
{
    int i, processed;
    ALint state;
    ALenum error;
    ALuint b;
    int num_processed_buffers;
    ALuint processed_buffers[MUSIC_BUFFERS];

    if( !s_bgTrack )
        return;
    if( !s_musicvolume->value && !s_bgTrack->isUrl )
        return;
    if( s_bgTrackPaused || s_bgTrackLocked )
        return;

    if( s_bgTrackBuffering )
    {
        if( S_EoStream( s_bgTrack->stream ) ) {
            // we should now advance to the next track
            S_CloseMusicTrack( s_bgTrack );
        }
        else {
            if( S_FTellSteam( s_bgTrack->stream ) < BACKGROUND_TRACK_BUFFERING_SIZE )
                return;

            // in case we delayed openening to let the stream be cached for a while,
            // start actually reading from it now
            if( !S_ContOpenStream( s_bgTrack->stream ) ) {
                // let music_process do the dirty job of advancing to the next track
                S_CloseMusicTrack( s_bgTrack );
                s_bgTrack->ignore = qtrue;
            }
        }
        s_bgTrackBuffering = qfalse;
    }

    if( !queued_buffers )
    {
        // if we haven't queued any buffers yet, do it now
        num_processed_buffers = MUSIC_BUFFERS;
        memcpy( processed_buffers, buffers, sizeof( buffers ) );
    }
    else
    {
        num_processed_buffers = 0;

        processed = 0;
        qalGetSourcei( source, AL_BUFFERS_PROCESSED, &processed );
        while( processed-- )
        {
            qalSourceUnqueueBuffers( source, 1, &b );
            processed_buffers[num_processed_buffers++] = b;
        }
    }

    for( i = 0; i < num_processed_buffers; i++ )
    {
        b = processed_buffers[i];
        if( !music_process( b ) )
        {
            Com_Printf( "Error processing music data\n" );
            S_StopBackgroundTrack();
            return;
        }

        qalSourceQueueBuffers( source, 1, &b );
        if( ( error = qalGetError() ) != AL_NO_ERROR )
        {
            Com_Printf( "Couldn't queue music data (%s)\n", S_ErrorMessage( error ) );
            S_StopBackgroundTrack();
            return;
        }
    }

    // If it's not still playing, give it a kick
    qalGetSourcei( source, AL_SOURCE_STATE, &state );
    if( !queued_buffers || state != AL_PLAYING )
    {
        queued_buffers = qtrue;
        qalSourcePlay( source );
    }

    if( s_musicvolume->modified )
        qalSourcef( source, AL_GAIN, s_musicvolume->value );
}