- 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);
+ sfx->total_length = qov_pcm_total(&vf, -1);
+
+ if (snd_streaming.integer && (snd_streaming.integer >= 2 || sfx->total_length > max(sizeof(ogg_stream_perchannel_t), snd_streaming_length.value * sfx->format.speed)))
+ {
+ // large sounds use the OGG fetcher to decode the file on demand (but the entire file is held in memory)
+ 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));
+ sfx->memsize += sizeof (*per_sfx);
+ per_sfx->file = data;
+ per_sfx->filesize = filesize;
+ sfx->memsize += filesize;
+ sfx->fetcher_data = per_sfx;
+ sfx->fetcher = &ogg_fetcher;
+ sfx->flags |= SFXFLAG_STREAMED;
+ vc = qov_comment(&vf, -1);
+ OGG_DecodeTags(vc, &sfx->loopstart, &sfx->total_length, sfx->total_length, &peak, &gaindb);
+ qov_clear(&vf);
+ }
+ else
+ {
+ // small sounds are entirely loaded and use the PCM fetcher
+ char *buff;
+ ogg_int64_t len;
+ ogg_int64_t done;
+ int bs;
+ long ret;
+ if (developer_loading.integer >= 2)
+ Con_Printf ("Ogg sound file \"%s\" will be cached\n", filename);
+ len = sfx->total_length * sfx->format.channels * sfx->format.width;
+ sfx->flags &= ~SFXFLAG_STREAMED;
+ sfx->memsize += len;
+ sfx->fetcher = &wav_fetcher;
+ sfx->fetcher_data = Mem_Alloc(snd_mempool, (size_t)len);
+ buff = (char *)sfx->fetcher_data;
+ done = 0;
+ bs = 0;
+ while ((ret = qov_read(&vf, &buff[done], (int)(len - done), mem_bigendian, 2, 1, &bs)) > 0)
+ done += ret;
+ vc = qov_comment(&vf, -1);
+ OGG_DecodeTags(vc, &sfx->loopstart, &sfx->total_length, sfx->total_length, &peak, &gaindb);
+ qov_clear(&vf);
+ Mem_Free(data);
+ }