/* ====================== S_StartBackgroundTrack ====================== */ void S_StartBackgroundTrack( const char *intro, const char *loop ){ int len; char dump[16]; char name[MAX_QPATH]; if ( !intro ) { intro = ""; } if ( !loop || !loop[0] ) { loop = intro; } Com_DPrintf( "S_StartBackgroundTrack( %s, %s )\n", intro, loop ); Q_strncpyz( name, intro, sizeof( name ) - 4 ); COM_DefaultExtension( name, sizeof( name ), ".wav" ); if ( !intro[0] ) { return; } Q_strncpyz( s_backgroundLoop, loop, sizeof( s_backgroundLoop ) ); // close the background track, but DON'T reset s_rawend // if restarting the same back ground track if ( s_backgroundFile ) { Sys_EndStreamedFile( s_backgroundFile ); FS_FCloseFile( s_backgroundFile ); s_backgroundFile = 0; } // // open up a wav file and get all the info // FS_FOpenFileRead( name, &s_backgroundFile, qtrue ); if ( !s_backgroundFile ) { Com_Printf( S_COLOR_YELLOW "WARNING: couldn't open music file %s\n", name ); return; } // skip the riff wav header FS_Read(dump, 12, s_backgroundFile); if ( !S_FindWavChunk( s_backgroundFile, "fmt " ) ) { Com_Printf( "No fmt chunk in %s\n", name ); FS_FCloseFile( s_backgroundFile ); s_backgroundFile = 0; return; } // save name for soundinfo s_backgroundInfo.format = FGetLittleShort( s_backgroundFile ); s_backgroundInfo.channels = FGetLittleShort( s_backgroundFile ); s_backgroundInfo.rate = FGetLittleLong( s_backgroundFile ); FGetLittleLong( s_backgroundFile ); FGetLittleShort( s_backgroundFile ); s_backgroundInfo.width = FGetLittleShort( s_backgroundFile ) / 8; if ( s_backgroundInfo.format != WAV_FORMAT_PCM ) { FS_FCloseFile( s_backgroundFile ); s_backgroundFile = 0; Com_Printf("Not a microsoft PCM format wav: %s\n", name); return; } if ( s_backgroundInfo.channels != 2 || s_backgroundInfo.rate != 22050 ) { Com_Printf(S_COLOR_YELLOW "WARNING: music file %s is not 22k stereo\n", name ); } if ( ( len = S_FindWavChunk( s_backgroundFile, "data" ) ) == 0 ) { FS_FCloseFile( s_backgroundFile ); s_backgroundFile = 0; Com_Printf("No data chunk in %s\n", name); return; } s_backgroundInfo.samples = len / (s_backgroundInfo.width * s_backgroundInfo.channels); s_backgroundSamples = s_backgroundInfo.samples; // // start the background streaming // Sys_BeginStreamedFile( s_backgroundFile, 0x10000 ); }
/* ====================== S_UpdateBackgroundTrack ====================== */ void S_UpdateBackgroundTrack( void ) { int bufferSamples; int fileSamples; byte raw[30000]; // just enough to fit in a mac stack frame int fileBytes; int r; static float musicVolume = 0.5f; if ( !s_backgroundFile ) { return; } // graeme see if this is OK musicVolume = (musicVolume + (s_musicVolume->value * 2))/4.0f; // don't bother playing anything if musicvolume is 0 if ( musicVolume <= 0 ) { return; } // see how many samples should be copied into the raw buffer if ( s_rawend < s_soundtime ) { s_rawend = s_soundtime; } while ( s_rawend < s_soundtime + MAX_RAW_SAMPLES ) { bufferSamples = MAX_RAW_SAMPLES - (s_rawend - s_soundtime); // decide how much data needs to be read from the file fileSamples = bufferSamples * s_backgroundInfo.rate / dma.speed; // don't try and read past the end of the file if ( fileSamples > s_backgroundSamples ) { fileSamples = s_backgroundSamples; } // our max buffer size fileBytes = fileSamples * (s_backgroundInfo.width * s_backgroundInfo.channels); if ( fileBytes > sizeof(raw) ) { fileBytes = sizeof(raw); fileSamples = fileBytes / (s_backgroundInfo.width * s_backgroundInfo.channels); } r = Sys_StreamedRead( raw, 1, fileBytes, s_backgroundFile ); if ( r != fileBytes ) { Com_Printf("StreamedRead failure on music track\n"); S_StopBackgroundTrack(); return; } // byte swap if needed S_ByteSwapRawSamples( fileSamples, s_backgroundInfo.width, s_backgroundInfo.channels, raw ); // add to raw buffer S_RawSamples( fileSamples, s_backgroundInfo.rate, s_backgroundInfo.width, s_backgroundInfo.channels, raw, musicVolume ); s_backgroundSamples -= fileSamples; if ( !s_backgroundSamples ) { // loop if (s_backgroundLoop[0]) { Sys_EndStreamedFile( s_backgroundFile ); FS_FCloseFile( s_backgroundFile ); s_backgroundFile = 0; S_StartBackgroundTrack( s_backgroundLoop, s_backgroundLoop ); if ( !s_backgroundFile ) { return; // loop failed to restart } } else { s_backgroundFile = 0; return; } } } }