static qboolean music_process( ALuint b ) { int l = 0; ALuint format; ALenum error; snd_stream_t *music_stream; start: if( s_bgTrackBuffering ) return qtrue; music_stream = s_bgTrack->stream; if( music_stream ) { l = S_ReadStream( music_stream, MUSIC_BUFFER_SIZE, decode_buffer ); } else { l = 0; } if( !l ) { bgTrack_t *cur; cur = s_bgTrack; if( !S_AdvanceBackgroundTrack( 1 ) ) { if( !S_ValidMusicFile( s_bgTrack ) ) return qfalse; } else { // we've advanced to the next track, close this one S_CloseMusicTrack( cur ); goto start; } if( !S_ResetStream( music_stream ) ) { // if failed, close the track? return qfalse; } goto start; } format = S_SoundFormat( music_stream->info.width, music_stream->info.channels ); qalBufferData( b, format, decode_buffer, l, music_stream->info.rate ); if( ( error = qalGetError() ) != AL_NO_ERROR ) return qfalse; return qtrue; }
/* * S_UpdateBackgroundTrack */ void S_UpdateBackgroundTrack( void ) { int samples, maxSamples; int read, maxRead, total; float scale; uint8_t data[MAX_RAW_SAMPLES*4]; if( !s_bgTrack ) return; if( !s_musicvolume->value && !s_bgTrack->muteOnPause ) return; if( s_bgTrackLoading || s_bgTrackPaused || s_bgTrackLocked > 0 ) return; if( !s_bgTrack->info.channels || ! s_bgTrack->info.width ) { s_bgTrack->ignore = true; S_AdvanceBackgroundTrack( 1 ); return; } scale = (float)s_bgTrack->info.rate / dma.speed; maxSamples = sizeof( data ) / s_bgTrack->info.channels / s_bgTrack->info.width; while( 1 ) { unsigned int rawSamplesLength; rawSamplesLength = S_GetRawSamplesLength(); if( rawSamplesLength >= BACKGROUND_TRACK_PRELOAD_MSEC ) return; samples = BACKGROUND_TRACK_PRELOAD_MSEC - rawSamplesLength; samples = (float)samples / 1000.0 * s_bgTrack->info.rate / scale; if( samples > maxSamples ) samples = maxSamples; if( samples > MAX_RAW_SAMPLES ) samples = MAX_RAW_SAMPLES; maxRead = samples * s_bgTrack->info.channels * s_bgTrack->info.width; total = 0; while( total < maxRead ) { int seek; if( s_bgTrack->read ) read = s_bgTrack->read( s_bgTrack, data + total, maxRead - total ); else read = trap_FS_Read( data + total, maxRead - total, s_bgTrack->file ); if( !read ) { if( !s_bgTrack->loop ) { if( !S_AdvanceBackgroundTrack( 1 ) ) { if( !S_ValidMusicFile( s_bgTrack ) ) { S_StopBackgroundTrack(); return; } } if( s_bgTrackBuffering || s_bgTrackLoading ) { return; } } if( s_bgTrack->seek ) seek = s_bgTrack->seek( s_bgTrack, s_bgTrack->info.dataofs ); else seek = trap_FS_Seek( s_bgTrack->file, s_bgTrack->info.dataofs, FS_SEEK_SET ); if( seek ) { // if the seek have failed we're going to loop here forever unless // we stop now S_StopBackgroundTrack(); return; } } total += read; } byteSwapRawSamples( samples, s_bgTrack->info.width, s_bgTrack->info.channels, data ); S_RawSamples2( samples, s_bgTrack->info.rate, s_bgTrack->info.width, s_bgTrack->info.channels, data, s_bgTrackMuted ? 0 : s_musicvolume->value * 255 ); } }
/* * S_NextBackgroundTrack */ void S_NextBackgroundTrack( void ) { S_AdvanceBackgroundTrack( 1 ); }
/* * S_PrevBackgroundTrack */ void S_PrevBackgroundTrack( void ) { S_AdvanceBackgroundTrack( -1 ); }