/* ====================== S_StartBackgroundTrack ====================== */ void S_Base_StartBackgroundTrack( const char *intro, const char *loop ){ if ( !intro ) { intro = ""; } if ( !loop || !loop[0] ) { loop = intro; } Com_DPrintf( "S_StartBackgroundTrack( %s, %s )\n", intro, loop ); if ( !intro[0] ) { return; } if ( !strncmp( s_backgroundLoop, intro, sizeof( s_backgroundLoop ) ) ) { return; } if( !loop ) { s_backgroundLoop[0] = 0; } else { 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_backgroundStream) { S_CodecCloseStream(s_backgroundStream); s_backgroundStream = NULL; } // Open stream s_backgroundStream = S_CodecOpenStream(intro); if(!s_backgroundStream) { Com_Printf( S_COLOR_YELLOW "WARNING: couldn't open music file %s\n", intro ); return; } if(s_backgroundStream->info.channels != 2 || s_backgroundStream->info.rate != 22050) { Com_Printf(S_COLOR_YELLOW "WARNING: music file %s is not 22k stereo\n", intro ); } }
/* ====================== S_OpenBackgroundStream ====================== */ static void S_OpenBackgroundStream( const char *filename ) { // close the background track, but DON'T reset s_rawend // if restarting the same back ground track if(s_backgroundStream) { S_CodecCloseStream(s_backgroundStream); s_backgroundStream = NULL; } // Open stream s_backgroundStream = S_CodecOpenStream(filename); if(!s_backgroundStream) { Com_Printf( S_COLOR_YELLOW "WARNING: couldn't open music file %s\n", filename ); return; } if(s_backgroundStream->info.channels != 2 || s_backgroundStream->info.rate != 22050) { Com_Printf(S_COLOR_YELLOW "WARNING: music file %s is not 22k stereo\n", filename ); } }
static void S_Base_StartBackgroundTrack(const char *intro, const char *loop) { if(!intro) intro = ""; if(!loop || !loop[0]) loop = intro; comdprintf("sndstartbackgroundtrack( %s, %s )\n", intro, loop); if(!*intro) { S_Base_StopBackgroundTrack(); return; } if(!loop) s_backgroundLoop[0] = 0; else 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_backgroundStream) { S_CodecCloseStream(s_backgroundStream); s_backgroundStream = NULL; } /* Open stream */ s_backgroundStream = S_CodecOpenStream(intro); if(!s_backgroundStream) { comprintf(S_COLOR_YELLOW "WARNING: couldn't open music file %s\n", intro); return; } if(s_backgroundStream->info.channels != 2 || s_backgroundStream->info.rate != 22050) comprintf(S_COLOR_YELLOW "WARNING: music file %s is not 22k stereo\n", intro); }
/* ================= 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; }
/* ================= S_AL_MusicProcess ================= */ static void S_AL_MusicProcess(ALuint b) { ALenum error; int l; ALuint format; snd_stream_t *curstream; if(intro_stream) curstream = intro_stream; else curstream = mus_stream; if(!curstream) return; l = S_CodecReadStream(curstream, MUSIC_BUFFER_SIZE, decode_buffer); // Run out data to read, start at the beginning again if(l == 0) { S_CodecCloseStream(curstream); // the intro stream just finished playing so we don't need to reopen // the music stream. if(intro_stream) intro_stream = NULL; else mus_stream = S_CodecOpenStream(s_backgroundLoop); curstream = mus_stream; if(!curstream) { S_AL_StopBackgroundTrack(); return; } l = S_CodecReadStream(curstream, MUSIC_BUFFER_SIZE, decode_buffer); } format = S_AL_Format(curstream->info.width, curstream->info.channels); if( l == 0 ) { // We have no data to buffer, so buffer silence byte dummyData[ 2 ] = { 0 }; qalBufferData( b, AL_FORMAT_MONO16, (void *)dummyData, 2, 22050 ); } else qalBufferData(b, format, decode_buffer, l, curstream->info.rate); if( ( error = qalGetError( ) ) != AL_NO_ERROR ) { S_AL_StopBackgroundTrack( ); Com_Printf( S_COLOR_RED "ERROR: while buffering data for music stream - %s\n", S_AL_ErrorMsg( error ) ); return; } }
float S_StartStreamingSoundEx(const char *intro, const char *loop, int entnum, int channel, qboolean music, int param) { streamingSound_t *ss = 0; int freeTrack = 0; if (music) { ss = &streamingSounds[0]; if (param < 0) { if (intro && strlen(intro)) { Q_strncpyz(ss->queueStream, intro, MAX_QPATH); ss->queueStreamType = param; // Cvar for save game if (param == -2) { Cvar_Set("s_currentMusic", intro); } if (s_debugStreams->integer) { if (param == -1) { Com_Printf("S_StartStreamingSoundEx: queueing '%s' for play once\n", intro); } else if (param == -2) { Com_Printf("S_StartStreamingSoundEx: queueing '%s' as new loop\n", intro); } } } else { ss->loopStream[0] = '\0'; ss->queueStream[0] = '\0'; ss->queueStreamType = 0; if (s_debugStreams->integer) { Com_Printf("S_StartStreamingSoundEx: queue cleared\n"); } } } } else { int i; for (i = 1; i < MAX_STREAMING_SOUNDS; i++) { if (!streamingSounds[i].stream && !freeTrack) { freeTrack = i; } else if ((entnum >= 0) && (channel != CHAN_AUTO) && (streamingSounds[i].entnum == entnum)) { // found a match, override this channel S_StopStreamingSound(i); ss = &streamingSounds[i]; break; } } } // Normal streaming sounds, select a free track if (!ss && freeTrack) { ss = &streamingSounds[freeTrack]; if (s_debugStreams->integer) { Com_Printf("S_StartStreamingSoundEx: Free slot found, %d\n", freeTrack); } } // cannot find a free track, bail... if (!ss) { if (!s_muted->integer) { Com_Printf("S_StartStreamingSoundEx: No free streaming tracks\n"); } return 0.0f; } // Set the name of the track Q_strncpyz(ss->name, intro, MAX_QPATH); // looping track passed to stream if (loop) { // if we don't hit the special case in music, "onetimeonly", // copy the new loop stream over if (!music || Q_stricmp(loop, "onetimeonly")) { Q_strncpyz(ss->loopStream, loop, MAX_QPATH); } } else { ss->loopStream[0] = '\0'; } // clear current music cvar Cvar_Set("s_currentMusic", ""); // set the stream parameters ss->channel = channel; // not music track, parameter is attenuation if (!music) { ss->attenuation = param; } ss->entnum = entnum; ss->fadeStartVol = 0; // music track, positive parameter is fadeUpTime if (music && param > 0) { ss->fadeStart = s_soundtime; ss->fadeEnd = ss->fadeStart + (((float)(ss->stream->info.rate) / 1000.0f) * param); ss->fadeTargetVol = 1.0f; } else { ss->fadeStart = 0; ss->fadeEnd = 0; ss->fadeTargetVol = 0; } // close the stream if (ss->stream) { S_CodecCloseStream(ss->stream); } // Open stream ss->stream = S_CodecOpenStream(intro); if (!ss->stream) { Com_Printf(S_COLOR_YELLOW "WARNING S_StartStreamingSoundEx: couldn't open stream file %s\n", intro); return 0.0f; } if (ss->stream->info.channels != 2 || ss->stream->info.rate != 22050) { Com_DPrintf(S_COLOR_YELLOW "WARNING S_StartStreamingSoundEx: stream file %s is not 22050k [%i] stereo [%i]\n", intro, ss->stream->info.rate, ss->stream->info.channels); } // return the length of sound return (ss->stream->info.samples / (float)ss->stream->info.rate) * 1000.0f; }