/* ====================== 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; if(!s_backgroundStream) { return; } // don't bother playing anything if musicvolume is 0 if ( s_musicVolume->value <= 0 ) { return; } // see how many samples should be copied into the raw buffer if ( s_rawend[0] < s_soundtime ) { s_rawend[0] = s_soundtime; } while ( s_rawend[0] < s_soundtime + MAX_RAW_SAMPLES ) { bufferSamples = MAX_RAW_SAMPLES - (s_rawend[0] - s_soundtime); // decide how much data needs to be read from the file fileSamples = bufferSamples * s_backgroundStream->info.rate / dma.speed; if (!fileSamples) return; // our max buffer size fileBytes = fileSamples * (s_backgroundStream->info.width * s_backgroundStream->info.channels); if ( fileBytes > sizeof(raw) ) { fileBytes = sizeof(raw); fileSamples = fileBytes / (s_backgroundStream->info.width * s_backgroundStream->info.channels); } // Read r = S_CodecReadStream(s_backgroundStream, fileBytes, raw); if(r < fileBytes) { fileSamples = r / (s_backgroundStream->info.width * s_backgroundStream->info.channels); } if(r > 0) { // add to raw buffer S_Base_RawSamples(0, fileSamples, s_backgroundStream->info.rate, s_backgroundStream->info.width, s_backgroundStream->info.channels, raw, s_musicVolume->value, -1); } else { // loop if(s_backgroundLoop[0]) { S_CodecCloseStream(s_backgroundStream); s_backgroundStream = NULL; S_Base_StartBackgroundTrack( s_backgroundLoop, s_backgroundLoop ); if(!s_backgroundStream) return; } else { S_Base_StopBackgroundTrack(); return; } } } }
void sndupdatebackgroundtrack(void) { int bufferSamples; int fileSamples; byte raw[30000]; /* just enough to fit in a mac stack frame */ int fileBytes; int r; if(!s_backgroundStream) return; if(s_musicVolume->value <= 0) return; /* see how many samples should be copied into the raw buffer */ if(s_rawend[0] < s_soundtime) s_rawend[0] = s_soundtime; while(s_rawend[0] < s_soundtime + MAX_RAW_SAMPLES) { bufferSamples = MAX_RAW_SAMPLES - (s_rawend[0] - s_soundtime); /* decide how much data needs to be read from the file */ fileSamples = bufferSamples * s_backgroundStream->info.rate / dma.speed; if(!fileSamples) return; /* our max buffer size */ fileBytes = fileSamples * (s_backgroundStream->info.width * s_backgroundStream->info.channels); if(fileBytes > sizeof(raw)) { fileBytes = sizeof(raw); fileSamples = fileBytes / (s_backgroundStream->info.width * s_backgroundStream->info.channels); } r = S_CodecReadStream(s_backgroundStream, fileBytes, raw); if(r < fileBytes) { fileBytes = r; fileSamples = r / (s_backgroundStream->info.width * s_backgroundStream->info.channels); } if(r > 0) /* add to raw buffer */ S_Base_RawSamples(0, fileSamples, s_backgroundStream->info.rate, s_backgroundStream->info.width, s_backgroundStream->info.channels, raw, s_musicVolume->value, -1); else { /* loop */ if(s_backgroundLoop[0]) { S_CodecCloseStream(s_backgroundStream); s_backgroundStream = NULL; S_Base_StartBackgroundTrack(s_backgroundLoop, s_backgroundLoop); if(!s_backgroundStream) return; } else { S_Base_StopBackgroundTrack(); 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; }