Example #1
0
bool S_UnloadBuffer( sfx_t *sfx )
{
	ALenum error;

	if( !sfx ) {
		return false;
	}
	if( sfx->filename[0] == '\0' || sfx->isLocked || !sfx->inMemory )
		return false;

	qalDeleteBuffers( 1, &sfx->buffer );
	if( ( error = qalGetError() ) != AL_NO_ERROR )
	{
		Com_Printf( "Couldn't delete sound buffer for %s (%s)", sfx->filename, S_ErrorMessage( error ) );
		sfx->isLocked = true;
		return false;
	}

	sfx->inMemory = false;

	return true;
}
Example #2
0
void S_StartBackgroundTrack( const char *intro, const char *loop )
{
    int count;
    const char *ext;
    bgTrack_t *t, f;
    bgTrack_t *introTrack, *loopTrack;
    ALenum error;
    int mode = 0;

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

    if( !intro || !intro[0] )
        return;

    s_bgTrackPaused = qfalse;

    ext = COM_FileExtension( intro );
    if( ext && !Q_stricmp( ext, ".m3u" ) )
    {
        // mode bits:
        // 1 - shuffle
        // 2 - loop the selected track
        if( loop && loop[0] )
            mode = atoi( loop );

        if( S_ReadPlaylistFile( intro, mode & 1 ? qtrue : qfalse ) )
            goto start_playback;
    }

    // the intro track loops unless another loop track has been specified
    introTrack = S_AllocTrack( intro );
    introTrack->next = introTrack->prev = introTrack;

    if( loop && loop[0] && Q_stricmp( intro, loop ) )
    {
        loopTrack = S_AllocTrack( loop );
        if( S_OpenMusicTrack( loopTrack ) )
        {
            S_CloseMusicTrack( loopTrack );
            loopTrack->next = introTrack->next = introTrack->prev = loopTrack;
            loopTrack->prev = introTrack;
        }
    }

    s_bgTrack = introTrack;

start_playback:
    // this effectively precaches the first 15 scheduled tracks in the playlist
    for( count = 0, t = s_bgTrack; count < 15 && t && t != s_bgTrack; count++ )
    {
        if( !t->isUrl )
        {
            S_OpenMusicTrack( t );

            if( t->next == t || t->next == s_bgTrack )
                break; // break on an endless loop or full cycle
            if( !t->ignore && ( mode & 2 ) )
            {
                // no point in precaching the whole playlist when we're only going
                // to loop one single track
                break;
            }
        }
        t = t->next;
    }

    // start playback with the first valid track
    if( count > 1 )
    {
        memset( &f, 0, sizeof( f ) );
        f.next = s_bgTrack;

        s_bgTrack = S_NextMusicTrack( &f );
    }
    else
    {
        S_OpenMusicTrack( s_bgTrack );
    }

    if( !s_bgTrack || s_bgTrack->ignore )
    {
        S_StopBackgroundTrack();
        return;
    }

    if( mode & 2 )
    {
        // loop the same track over and over
        s_bgTrack->next = s_bgTrack->prev = s_bgTrack;
    }

    music_source_get();
    if( !src )
    {
        Com_Printf( "Error couldn't get source for music\n" );
        S_StopBackgroundTrack();
        return;
    }

    alloced_buffers = qfalse;
    queued_buffers = qfalse;

    qalGenBuffers( MUSIC_BUFFERS, buffers );
    if( ( error = qalGetError() ) != AL_NO_ERROR )
    {
        Com_Printf( "Error couldn't generate music buffers (%s)\n", S_ErrorMessage( error ) );
        S_StopBackgroundTrack();
        return;
    }

    alloced_buffers = qtrue;
}
Example #3
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 );
}
Example #4
0
bool S_LoadBuffer( sfx_t *sfx )
{
	ALenum error;
	void *data;
	snd_info_t info;
	ALuint format;

	if( !sfx ) {
		return false;
	}
	if( sfx->filename[0] == '\0' || sfx->inMemory )
		return false;
	if( trap_FS_IsUrl( sfx->filename ) )
		return false;

	data = S_LoadSound( sfx->filename, &info );
	if( !data )
	{
		//Com_DPrintf( "Couldn't load %s\n", sfx->filename );
		return false;
	}

	if( info.channels > 1 )
	{
		void *temp = stereo_mono( data, &info );
		if( temp )
		{
			S_Free( data );
			data = temp;
		}
	}

	format = S_SoundFormat( info.width, info.channels );

	qalGenBuffers( 1, &sfx->buffer );
	if( ( error = qalGetError() ) != AL_NO_ERROR )
	{
		S_Free( data );
		Com_Printf( "Couldn't create a sound buffer for %s (%s)\n", sfx->filename, S_ErrorMessage( error ) );
		return false;
	}

	qalBufferData( sfx->buffer, format, data, info.size, info.rate );
	error = qalGetError();

	// If we ran out of memory, start evicting the least recently used sounds
	while( error == AL_OUT_OF_MEMORY )
	{
		if( !buffer_evict() )
		{
			S_Free( data );
			Com_Printf( "Out of memory loading %s\n", sfx->filename );
			return false;
		}

		// Try load it again
		qalGetError();
		qalBufferData( sfx->buffer, format, data, info.size, info.rate );
		error = qalGetError();
	}

	// Some other error condition
	if( error != AL_NO_ERROR )
	{
		S_Free( data );
		Com_Printf( "Couldn't fill sound buffer for %s (%s)", sfx->filename, S_ErrorMessage( error ) );
		return false;
	}

	S_Free( data );
	sfx->inMemory = true;

	return true;
}