Пример #1
0
/*
* S_OpenBackgroundTrackProc
*/
static void *S_OpenBackgroundTrackProc( void *ptrack ) {
	bgTrack_t *track = ptrack;
	unsigned start;
	bool buffering;

	S_OpenMusicTrack( track, &buffering );

	s_bgTrackBuffering = buffering;

	start = trap_Milliseconds();
	while( s_bgTrackBuffering ) {
		if( trap_Milliseconds() > start + BACKGROUND_TRACK_BUFFERING_TIMEOUT ) {
		} else if( trap_FS_Eof( track->file ) ) {
		} else {
			if( trap_FS_Seek( track->file, BACKGROUND_TRACK_BUFFERING_SIZE, FS_SEEK_SET ) < 0 ) {
				continue;
			}
			trap_FS_Seek( track->file, 0, FS_SEEK_SET );
		}

		// in case we delayed openening to let the stream cache for a while,
		// start actually reading from it now
		if( !track->open( track, NULL ) ) {
			track->ignore = true;
		}
		s_bgTrackBuffering = false;
	}

	s_bgTrack = track;
	s_bgTrackLoading = false;
	return NULL;
}
Пример #2
0
/*
* S_StartBackgroundTrack
*/
void S_StartBackgroundTrack( const char *intro, const char *loop, int mode ) {
	const char *ext;
	bgTrack_t *introTrack, *loopTrack;
	bgTrack_t *firstTrack = NULL;

	S_StopBackgroundTrack();

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

	s_bgTrackMuted = false;
	s_bgTrackPaused = false;

	ext = COM_FileExtension( intro );
	if( ext && !Q_stricmp( ext, ".m3u" ) ) {
		// mode bits:
		// 1 - shuffle
		// 2 - loop the selected track
		// 4 - stream (even if muted)

		firstTrack = S_ReadPlaylistFile( intro,
										 mode & 1 ? true : false, mode & 2 ? true : false );
		if( firstTrack ) {
			goto start_playback;
		}
	}

	// the intro track loops unless another loop track has been specified
	introTrack = S_AllocTrack( intro );
	introTrack->loop = true;
	introTrack->next = introTrack->prev = introTrack;
	introTrack->muteOnPause = introTrack->isUrl || mode & 4 ? true : false;

	if( loop && loop[0] && Q_stricmp( intro, loop ) ) {
		loopTrack = S_AllocTrack( loop );
		if( S_OpenMusicTrack( loopTrack, NULL ) ) {
			S_CloseMusicTrack( loopTrack );

			introTrack->next = introTrack->prev = loopTrack;
			introTrack->loop = false;

			loopTrack->loop = true;
			loopTrack->muteOnPause = loopTrack->isUrl || mode & 4 ? true : false;
			loopTrack->next = loopTrack->prev = loopTrack;
		}
	}

	firstTrack = introTrack;

start_playback:

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

	S_OpenBackgroundTrackTask( firstTrack );
}
Пример #3
0
/*
* S_PauseBackgroundTrack
*/
void S_PauseBackgroundTrack( void )
{
    if( !s_bgTrack ) {
        return;
    }

    // in case of a streaming URL, reset the stream
    if( s_bgTrack->isUrl ) {
        if( s_bgTrackPaused ) {
            S_OpenMusicTrack( s_bgTrack );
        }
        else {
            S_CloseMusicTrack( s_bgTrack );
        }
    }

    s_bgTrackPaused = !s_bgTrackPaused;
}
Пример #4
0
/*
* S_NextMusicTrack
*/
static bgTrack_t *S_NextMusicTrack( bgTrack_t *track )
{
    bgTrack_t *next;

    next = track ? track->next : NULL;
    if( next ) track = next->prev; // HACK to prevent endless loops where original 'track' comes from stack
    while( next && next != track )
    {
        if( !next->ignore )
        {
            // already marked as invalid so don't try opening again
            if( S_OpenMusicTrack( next ) )
                break;
        }
        next = next->next;
    }

    return next;
}
Пример #5
0
/*
* S_PrevMusicTrack
*/
static bgTrack_t *S_PrevMusicTrack( bgTrack_t *track )
{
    bgTrack_t *prev;

    prev = track ? track->prev : NULL;
    if( prev ) track = prev->next; // HACK to prevent endless loops where original 'track' comes from stack
    while( prev && prev != track )
    {
        if( !prev->ignore )
        {
            // already marked as invalid so don't try opening again
            if( S_OpenMusicTrack( prev ) )
                break;
        }
        prev = prev->next;
    }

    return prev;
}
Пример #6
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;
}