extern cvar_t snd_softclip;
static portable_sampleframe_t paintbuffer[PAINTBUFFER_SIZE];
-static portable_sampleframe_t paintbuffer_unswapped[PAINTBUFFER_SIZE];
extern speakerlayout_t snd_speakerlayout; // for querying the listeners
#ifdef CONFIG_VIDEO_CAPTURE
+static portable_sampleframe_t paintbuffer_unswapped[PAINTBUFFER_SIZE];
+
static void S_CaptureAVISound(const portable_sampleframe_t *sampleframes, size_t length)
{
size_t i;
static void S_ConvertPaintBuffer(portable_sampleframe_t *painted_ptr, void *rb_ptr, int nbframes, int width, int nchannels)
{
int i;
+ float val;
if (width == 4) // 32bit float
{
float *snd_out = (float*)rb_ptr;
}
+
+/*
+===============================================================================
+
+UNDERWATER EFFECT
+
+Muffles the intensity of sounds when the player is underwater
+
+===============================================================================
+*/
+
+static struct
+{
+ float intensity;
+ float alpha;
+ float accum[SND_LISTENERS];
+}
+underwater = {0.f, 1.f, {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}};
+
+void S_SetUnderwaterIntensity(void)
+{
+ float target = cl.view_underwater ? bound(0.f, snd_waterfx.value, 2.f) : 0.f;
+
+ if (underwater.intensity < target)
+ {
+ underwater.intensity += cl.realframetime * 4.f;
+ underwater.intensity = min(underwater.intensity, target);
+ }
+ else if (underwater.intensity > target)
+ {
+ underwater.intensity -= cl.realframetime * 4.f;
+ underwater.intensity = max(underwater.intensity, target);
+ }
+
+ underwater.alpha = underwater.intensity ? exp(-underwater.intensity * log(12.f)) : 1.f;
+}
+
+static void S_UnderwaterFilter(int endtime)
+{
+ int i;
+ int sl;
+
+ if (!underwater.intensity)
+ {
+ if (endtime > 0)
+ for (sl = 0; sl < SND_LISTENERS; sl++)
+ underwater.accum[sl] = paintbuffer[endtime-1].sample[sl];
+ return;
+ }
+
+ for (i = 0; i < endtime; i++)
+ for (sl = 0; sl < SND_LISTENERS; sl++)
+ {
+ underwater.accum[sl] += underwater.alpha * (paintbuffer[i].sample[sl] - underwater.accum[sl]);
+ paintbuffer[i].sample[sl] = underwater.accum[sl];
+ }
+}
+
+
+
/*
===============================================================================
double posd;
double speedd;
float maxvol;
- qboolean looping;
- qboolean silent;
+ qbool looping;
+ qbool silent;
// mix as many times as needed to fill the requested buffer
while (bufferframes)
S_SoftClipPaintBuffer(paintbuffer, totalmixframes, snd_renderbuffer->format.width, snd_renderbuffer->format.channels);
+ S_UnderwaterFilter(totalmixframes);
+
+
#ifdef CONFIG_VIDEO_CAPTURE
if (!snd_usethreadedmixing)
S_CaptureAVISound(paintbuffer, totalmixframes);