// Cvars declared in snd_main.h (shared with other snd_*.c files)
cvar_t _snd_mixahead = {CVAR_SAVE, "_snd_mixahead", "0.11", "how much sound to mix ahead of time"};
-cvar_t snd_streaming = { CVAR_SAVE, "snd_streaming", "1", "enables keeping compressed ogg sound files compressed, decompressing them only as needed, otherwise they will be decompressed completely at load (may use a lot of memory)"};
cvar_t snd_swapstereo = {CVAR_SAVE, "snd_swapstereo", "0", "swaps left/right speakers for old ISA soundblaster cards"};
extern cvar_t v_flipped;
cvar_t snd_channellayout = {0, "snd_channellayout", "0", "channel layout. Can be 0 (auto - snd_restart needed), 1 (standard layout), or 2 (ALSA layout)"};
Cvar_RegisterVariable(&nosound);
Cvar_RegisterVariable(&snd_precache);
Cvar_RegisterVariable(&snd_initialized);
- Cvar_RegisterVariable(&snd_streaming);
Cvar_RegisterVariable(&ambient_level);
Cvar_RegisterVariable(&ambient_fade);
Cvar_RegisterVariable(&snd_noextraupdate);
#include "quakedef.h"
#include "snd_main.h"
#include "snd_ogg.h"
-#include "snd_wav.h"
/*
per_ch->sb_offset = real_start;
- // We add exactly 1 sec of sound to the buffer:
- // 1- to ensure we won't lose any sample during the resampling process
- // 2- to force one call to OGG_FetchSound per second to regulate the workload
- if ((int)(sb->format.speed * STREAM_BUFFER_FILL) + sb->nbframes > sb->maxframes)
+ // We add more than one frame of sound to the buffer:
+ // 1- to ensure we won't lose many samples during the resampling process
+ // 2- to reduce calls to OGG_FetchSound to regulate workload
+ newlength = (int)(per_sfx->format.speed*STREAM_BUFFER_FILL);
+ if (newlength + sb->nbframes > sb->maxframes)
{
Con_Printf ("OGG_FetchSound: stream buffer overflow (%u sample frames / %u)\n",
sb->format.speed + sb->nbframes, sb->maxframes);
return NULL;
}
- newlength = (int)(per_sfx->format.speed*STREAM_BUFFER_FILL) * factor; // -> 1 sec of sound before resampling
+ newlength *= factor; // convert from sample frames to bytes
if(newlength > (int)sizeof(resampling_buffer))
newlength = sizeof(resampling_buffer);
fs_offset_t filesize;
ov_decode_t ov_decode;
OggVorbis_File vf;
+ ogg_stream_persfx_t* per_sfx;
vorbis_info *vi;
vorbis_comment *vc;
- ogg_int64_t len, buff_len;
+ ogg_int64_t len;
double peak, gaindb;
if (!vf_dll)
len = qov_pcm_total (&vf, -1) * vi->channels * 2; // 16 bits => "* 2"
- // Decide if we go for a stream or a simple PCM cache
- buff_len = (int)ceil (STREAM_BUFFER_DURATION * snd_renderbuffer->format.speed) * 2 * vi->channels;
- if (snd_streaming.integer && len > (ogg_int64_t)filesize + 3 * buff_len)
- {
- ogg_stream_persfx_t* per_sfx;
-
- if (developer_loading.integer >= 2)
- Con_Printf ("Ogg sound file \"%s\" will be streamed\n", filename);
- per_sfx = (ogg_stream_persfx_t *)Mem_Alloc (snd_mempool, sizeof (*per_sfx));
- strlcpy(per_sfx->name, sfx->name, sizeof(per_sfx->name));
- sfx->memsize += sizeof (*per_sfx);
- per_sfx->file = data;
- per_sfx->filesize = filesize;
- sfx->memsize += filesize;
-
- per_sfx->format.speed = vi->rate;
- per_sfx->format.width = 2; // We always work with 16 bits samples
- per_sfx->format.channels = vi->channels;
-
- sfx->fetcher_data = per_sfx;
- sfx->fetcher = &ogg_fetcher;
- sfx->flags |= SFXFLAG_STREAMED;
- sfx->total_length = (int)((size_t)len / (per_sfx->format.channels * 2) * ((double)snd_renderbuffer->format.speed / per_sfx->format.speed));
- vc = qov_comment(&vf, -1);
- OGG_DecodeTags(vc, &sfx->loopstart, &sfx->total_length, (double)snd_renderbuffer->format.speed / (double)per_sfx->format.speed, sfx->total_length, &peak, &gaindb);
- per_sfx->total_length = sfx->total_length;
- qov_clear (&vf);
- }
- else
- {
- char *buff;
- ogg_int64_t done;
- int bs, bigendian;
- long ret;
- snd_buffer_t *sb;
- snd_format_t ogg_format;
-
- if (developer_loading.integer >= 2)
- Con_Printf ("Ogg sound file \"%s\" will be cached\n", filename);
-
- // Decode it
- buff = (char *)Mem_Alloc (snd_mempool, (int)len);
- done = 0;
- bs = 0;
-#if BYTE_ORDER == BIG_ENDIAN
- bigendian = 1;
-#else
- bigendian = 0;
-#endif
- while ((ret = qov_read (&vf, &buff[done], (int)(len - done), bigendian, 2, 1, &bs)) > 0)
- done += ret;
-
- // Build the sound buffer
- ogg_format.speed = vi->rate;
- ogg_format.channels = vi->channels;
- ogg_format.width = 2; // We always work with 16 bits samples
- sb = Snd_CreateSndBuffer ((unsigned char *)buff, (size_t)done / (vi->channels * 2), &ogg_format, snd_renderbuffer->format.speed);
- if (sb == NULL)
- {
- qov_clear (&vf);
- Mem_Free (data);
- Mem_Free (buff);
- return false;
- }
-
- sfx->fetcher = &wav_fetcher;
- sfx->fetcher_data = sb;
-
- sfx->total_length = sb->nbframes;
- sfx->memsize += sb->maxframes * sb->format.channels * sb->format.width + sizeof (*sb) - sizeof (sb->samples);
-
- sfx->flags &= ~SFXFLAG_STREAMED;
- vc = qov_comment(&vf, -1);
- OGG_DecodeTags(vc, &sfx->loopstart, &sfx->total_length, (double)snd_renderbuffer->format.speed / (double)sb->format.speed, sfx->total_length, &peak, &gaindb);
- sb->nbframes = sfx->total_length;
- qov_clear (&vf);
- Mem_Free (data);
- Mem_Free (buff);
- }
+ if (developer_loading.integer >= 2)
+ Con_Printf ("Ogg sound file \"%s\" will be streamed\n", filename);
+ per_sfx = (ogg_stream_persfx_t *)Mem_Alloc (snd_mempool, sizeof (*per_sfx));
+ strlcpy(per_sfx->name, sfx->name, sizeof(per_sfx->name));
+ sfx->memsize += sizeof (*per_sfx);
+ per_sfx->file = data;
+ per_sfx->filesize = filesize;
+ sfx->memsize += filesize;
+
+ per_sfx->format.speed = vi->rate;
+ per_sfx->format.width = 2; // We always work with 16 bits samples
+ per_sfx->format.channels = vi->channels;
+
+ sfx->fetcher_data = per_sfx;
+ sfx->fetcher = &ogg_fetcher;
+ sfx->flags |= SFXFLAG_STREAMED;
+ sfx->total_length = (int)((size_t)len / (per_sfx->format.channels * 2) * ((double)snd_renderbuffer->format.speed / per_sfx->format.speed));
+ vc = qov_comment(&vf, -1);
+ OGG_DecodeTags(vc, &sfx->loopstart, &sfx->total_length, (double)snd_renderbuffer->format.speed / (double)per_sfx->format.speed, sfx->total_length, &peak, &gaindb);
+ per_sfx->total_length = sfx->total_length;
+ qov_clear (&vf);
if(peak)
{