/* ================= S_StopBackgroundTrack ================= */ void S_StopBackgroundTrack (void) { if (!ogg_started) // was sound_started return; S_StopStreaming (); S_CloseBackgroundTrack(&s_bgTrack); ogg_status = STOP; memset(&s_bgTrack, 0, sizeof(bgTrack_t)); }
/* ================= S_StreamBackgroundTrack ================= */ void S_StreamBackgroundTrack (void) { byte data[BUFFER_SIZE]; int queued = 0; //, processed, state; int size, read, dummy; //unsigned buffer; int samples; // Knightmare added if (!s_bgTrack.file || !s_musicvolume->value) return; if (!s_streamingChannel) return; // Unqueue and delete any processed buffers /*qalGetSourcei(s_streamingChannel->sourceNum, AL_BUFFERS_PROCESSED, &processed); if (processed > 0){ while (processed--){ qalSourceUnqueueBuffers(s_streamingChannel->sourceNum, 1, &buffer); qalDeleteBuffers(1, &buffer); } }*/ //Com_Printf("Streaming background track\n"); // Make sure we always have at least 4 buffers in the queue //qalGetSourcei(s_streamingChannel->sourceNum, AL_BUFFERS_QUEUED, &queued); while (queued < 4) { size = 0; // Stream from disk while (size < BUFFER_SIZE) { read = ov_read(s_bgTrack.vorbisFile, data + size, BUFFER_SIZE - size, 0, 2, 1, &dummy); if (read == 0) { // End of file if (!s_bgTrack.looping) { // Close the intro track S_CloseBackgroundTrack(&s_bgTrack); // Open the loop track if (!S_OpenBackgroundTrack(s_bgTrack.loopName, &s_bgTrack)) { S_StopBackgroundTrack(); return; } s_bgTrack.looping = true; } // Restart the track, skipping over the header ov_raw_seek(s_bgTrack.vorbisFile, (ogg_int64_t)s_bgTrack.start); // Try streaming again read = ov_read(s_bgTrack.vorbisFile, data + size, BUFFER_SIZE - size, 0, 2, 1, &dummy); } if (read <= 0) { // An error occurred S_StopBackgroundTrack(); return; } size += read; } // Knightmare added samples = size / (s_bgTrack.width * s_bgTrack.channels); S_RawSamples(samples, s_bgTrack.rate,s_bgTrack. width, s_bgTrack.channels, data, true); // Upload and queue the new buffer /*qalGenBuffers(1, &buffer); qalBufferData(buffer, s_bgTrack.format, data, size, s_bgTrack.rate); qalSourceQueueBuffers(s_streamingChannel->sourceNum, 1, &buffer);*/ queued++; } // Update volume //qalSourcef(s_streamingChannel->sourceNum, AL_GAIN, s_musicVolume->value); // If not playing, then do so /*qalGetSourcei(s_streamingChannel->sourceNum, AL_SOURCE_STATE, &state); if (state != AL_PLAYING) qalSourcePlay(s_streamingChannel->sourceNum);*/ }
/* ============ S_StreamBackgroundTrack ============ */ void S_StreamBackgroundTrack (void) { int samples, maxSamples; int read, maxRead, total, dummy; float scale; byte data[MAX_RAW_SAMPLES*4]; if (!s_bgTrack.file || !s_musicvolume->value) return; if (!s_streamingChannel) return; if (s_rawend < paintedtime) s_rawend = paintedtime; scale = (float)s_bgTrack.rate / dma.speed; maxSamples = sizeof(data) / s_bgTrack.channels / s_bgTrack.width; while (1) { samples = (paintedtime + MAX_RAW_SAMPLES - s_rawend) * scale; if (samples <= 0) return; if (samples > maxSamples) samples = maxSamples; maxRead = samples * s_bgTrack.channels * s_bgTrack.width; total = 0; while (total < maxRead) { read = ov_read(s_bgTrack.vorbisFile, data + total, maxRead - total, 0, 2, 1, &dummy); if (!read) { // End of file if (!s_bgTrack.looping) { // Close the intro track S_CloseBackgroundTrack(&s_bgTrack); // Open the loop track if (!S_OpenBackgroundTrack(s_bgTrack.loopName, &s_bgTrack)) { S_StopBackgroundTrack(); return; } s_bgTrack.looping = true; } else { // check if it's time to switch to the ambient track if ( ++ogg_loopcounter >= (int)ogg_loopcount->value && (!cl.configstrings[CS_MAXCLIENTS][0] || !strcmp(cl.configstrings[CS_MAXCLIENTS], "1")) ) { // Close the loop track S_CloseBackgroundTrack(&s_bgTrack); if (!S_OpenBackgroundTrack(s_bgTrack.ambientName, &s_bgTrack)) { if (!S_OpenBackgroundTrack(s_bgTrack.loopName, &s_bgTrack)) { S_StopBackgroundTrack(); return; } } else s_bgTrack.ambient_looping = true; } } // Restart the track, skipping over the header ov_raw_seek(s_bgTrack.vorbisFile, (ogg_int64_t)s_bgTrack.start); } /*if (s_bgTrack.read) read = s_bgTrack->read( s_bgTrack, data + total, maxRead - total ); else read = FS_Read( data + total, maxRead - total, s_bgTrack->file ); if (!read) { if (s_bgTrackIntro.file != s_bgTrackLoop.file) { if (s_bgTrackIntro.close) s_bgTrackIntro.close(&s_bgTrackIntro); else FS_FCloseFile(s_bgTrackIntro.file); s_bgTrackIntro = s_bgTrackLoop; } s_bgTrack = &s_bgTrackLoop; if (s_bgTrack->seek) s_bgTrack->seek( s_bgTrack, s_bgTrack->info.dataofs ); else FS_Seek(s_bgTrack->file, s_bgTrack->info.dataofs, FS_SEEK_SET); }*/ total += read; } S_RawSamples (samples, s_bgTrack.rate, s_bgTrack.width, s_bgTrack.channels, data, true ); } }
/* ============ S_StreamBackgroundTrack ============ */ void S_StreamBackgroundTrack (void) { int samples, maxSamples; int read, maxRead, total, dummy; float scale; char data[MAX_RAW_SAMPLES*4]; if (!ogg_started) return; if (!s_bgTrack.buffer || !s_musicvolume->value) return; if (!s_streamingChannel) return; if (s_rawend < paintedtime) s_rawend = paintedtime; scale = (float)s_bgTrack.rate / dma.speed; maxSamples = sizeof(data) / s_bgTrack.channels / s_bgTrack.width; while (1) { samples = (paintedtime + MAX_RAW_SAMPLES - s_rawend) * scale; if (samples <= 0) return; if (samples > maxSamples) samples = maxSamples; maxRead = samples * s_bgTrack.channels * s_bgTrack.width; total = 0; while (total < maxRead) { read = ov_read((OggVorbis_File*)s_bgTrack.vorbisFile, data + total, maxRead - total, 0, 2, 1, &dummy); if (!read) { // end of file if (!s_bgTrack.looping) { // close the intro track S_CloseBackgroundTrack(&s_bgTrack); // open the loop track if (!S_OpenBackgroundTrack(s_bgTrack.loopName, &s_bgTrack)) { S_StopBackgroundTrack(); return; } s_bgTrack.looping = true; } else { // check if its time to switch to the ambient track if ( ++ogg_loopcounter >= (int)ogg_loopcount->value && (!cl.configstrings[CS_MAXCLIENTS][0] || !strcmp(cl.configstrings[CS_MAXCLIENTS], "1")) ) { // close the loop track S_CloseBackgroundTrack(&s_bgTrack); if (!S_OpenBackgroundTrack(s_bgTrack.ambientName, &s_bgTrack)) { if (!S_OpenBackgroundTrack(s_bgTrack.loopName, &s_bgTrack)) { S_StopBackgroundTrack(); return; } } else s_bgTrack.ambient_looping = true; } } // restart the track, skipping over the header ov_raw_seek((OggVorbis_File*)s_bgTrack.vorbisFile, (ogg_int64_t)s_bgTrack.start); } total += read; } S_RawSamples (samples, s_bgTrack.rate, s_bgTrack.width, s_bgTrack.channels, data, true); } }