Beispiel #1
0
void al_mus_update( void )
{
	int   processed;
	ALint state;

	if ( !mus_playing )
	{
		return;
	}

	qalGetSourcei( source, AL_BUFFERS_PROCESSED, &processed );

	if ( processed )
	{
		while ( processed-- )
		{
			ALuint b;
			qalSourceUnqueueBuffers( source, 1, &b );
			al_mus_process( b );
			qalSourceQueueBuffers( source, 1, &b );
		}
	}

	// If it's not still playing, give it a kick
	qalGetSourcei( source, AL_SOURCE_STATE, &state );

	if ( state == AL_STOPPED )
	{
		si.Printf( PRINT_ALL, "Musical kick\n" );
		qalSourcePlay( source );
	}

	// Set the gain property
	qalSourcef( source, AL_GAIN, s_gain->value * s_musicVolume->value );
}
/*
=================
S_AL_MusicUpdate
=================
*/
static
void S_AL_MusicUpdate( void )
{
	int		numBuffers;
	ALint	state;

	if(!musicPlaying)
		return;

	qalGetSourcei( musicSource, AL_BUFFERS_PROCESSED, &numBuffers );
	while( numBuffers-- )
	{
		ALuint b;
		qalSourceUnqueueBuffers(musicSource, 1, &b);
		S_AL_MusicProcess(b);
		qalSourceQueueBuffers(musicSource, 1, &b);
	}

	// Hitches can cause OpenAL to be starved of buffers when streaming.
	// If this happens, it will stop playback. This restarts the source if
	// it is no longer playing, and if there are buffers available
	qalGetSourcei( musicSource, AL_SOURCE_STATE, &state );
	qalGetSourcei( musicSource, AL_BUFFERS_QUEUED, &numBuffers );
	if( state == AL_STOPPED && numBuffers )
	{
		Com_DPrintf( S_COLOR_YELLOW "Restarted OpenAL music\n" );
		qalSourcePlay(musicSource);
	}

	// Set the gain property
	qalSourcef(musicSource, AL_GAIN, s_alGain->value * s_musicVolume->value);
}
/*
=================
S_AL_RawSamples
=================
*/
static
void S_AL_RawSamples(int samples, int rate, int width, int channels, const byte *data, float volume)
{
	ALuint buffer;
	ALuint format;

	format = S_AL_Format( width, channels );

	// Create the streamSource if necessary
	if(streamSourceHandle == -1)
	{
		S_AL_AllocateStreamChannel();
	
		// Failed?
		if(streamSourceHandle == -1)
		{
			Com_Printf( S_COLOR_RED "ERROR: Can't allocate streaming streamSource\n");
			return;
		}
	}

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

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

	// Volume
	qalSourcef (streamSource, AL_GAIN, volume * s_volume->value * s_alGain->value);
}
Beispiel #4
0
/**
 * Background music playback
 */
void SndAl_StartBackgroundTrack( const char *intro, const char *loop )
{
	int i;

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

	if ( !intro || !intro[ 0 ] )
	{
		intro = loop;
	}

	if ( !loop || !loop[ 0 ] )
	{
		loop = intro;
	}

	if ( ( !intro || !intro[ 0 ] ) && ( !intro || !intro[ 0 ] ) )
	{
		return;
	}

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

	// Open the intro
	mus_stream = si.StreamOpen( intro );

	if ( !mus_stream )
	{
		return;
	}

	// Allocate a source
	al_mus_source_get();

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

	// Generate the buffers
	qalGenBuffers( BUFFERS, buffers );

	// Queue the buffers up
	for ( i = 0; i < BUFFERS; i++ )
	{
		al_mus_process( buffers[ i ] );
	}

	qalSourceQueueBuffers( source, BUFFERS, buffers );

	// Start playing
	qalSourcePlay( source );

	mus_playing = qtrue;
}
/*
=================
S_StreamRawSamples

Cinematic streaming
=================
*/
void S_StreamRawSamples (const byte *data, int samples, int rate, int width, int channels)
{
	int			processed, state, size;
	unsigned	format, buffer;

	if (!s_initialized)
		return;

	if (!s_streamingChannel)
		return;

	// Unqueue and delete any processed buffers
	qalGetSourcei(s_streamingChannel->sourceNum, AL_BUFFERS_PROCESSED, &processed);
	if (processed > 0){
		while (processed--){
			qalSourceUnqueueBuffers(s_streamingChannel->sourceNum, 1, &buffer);
			qalDeleteBuffers(1, &buffer);
		}
	}

	// Calculate buffer size
	size = samples * width * channels;

	// Set buffer format
	if (width == 2)
	{
		if (channels == 2)
			format = AL_FORMAT_STEREO16;
		else
			format = AL_FORMAT_MONO16;
	}
	else
	{
		if (channels == 2)
			format = AL_FORMAT_STEREO8;
		else
			format = AL_FORMAT_MONO8;
	}

	// Upload and queue the new buffer
	qalGenBuffers(1, &buffer);
	qalBufferData(buffer, format, (byte *)data, size, rate);
	qalSourceQueueBuffers(s_streamingChannel->sourceNum, 1, &buffer);

	// Update volume
	qalSourcef(s_streamingChannel->sourceNum, AL_GAIN, s_sfxVolume->value);

	// If not playing, then do so
	qalGetSourcei(s_streamingChannel->sourceNum, AL_SOURCE_STATE, &state);
	if (state != AL_PLAYING)
		qalSourcePlay(s_streamingChannel->sourceNum);
}
Beispiel #6
0
/*
 * Queues raw samples for playback. Used
 * by the background music an cinematics.
 */
void
AL_RawSamples(int samples, int rate, int width, int 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;
}
Beispiel #7
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;
}
/*
=================
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;
}
Beispiel #9
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;
	}
}
Beispiel #10
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 );
}