static portable_sampleframe_t paintbuffer[PAINTBUFFER_SIZE];
+static portable_sampleframe_t paintbuffer_unswapped[PAINTBUFFER_SIZE];
+extern speakerlayout_t snd_speakerlayout; // for querying the listeners
extern void SCR_CaptureVideo_SoundFrame(const portable_sampleframe_t *paintbuffer, size_t length);
static void S_CaptureAVISound(size_t length)
{
+ size_t i;
+ unsigned int j;
+
if (!cls.capturevideo.active)
return;
- SCR_CaptureVideo_SoundFrame(paintbuffer, length);
+ // undo whatever swapping the channel layout (swapstereo, ALSA) did
+ for(j = 0; j < snd_speakerlayout.channels; ++j)
+ {
+ unsigned int j0 = snd_speakerlayout.listeners[j].channel_unswapped;
+ for(i = 0; i < length; ++i)
+ paintbuffer_unswapped[i].sample[j0] = paintbuffer[i].sample[j];
+ }
+
+ SCR_CaptureVideo_SoundFrame(paintbuffer_unswapped, length);
}
static void S_ConvertPaintBuffer(const portable_sampleframe_t *painted_ptr, void *rb_ptr, int nbframes, int width, int channels)
*snd_out++ = bound(-32768, val, 32767);
}
}
+
+ // noise is really really annoying
+ if (cls.timedemo)
+ memset(rb_ptr, 0, nbframes * channels * width);
}
else // 8bit
{
*snd_out++ = bound(0, val, 255);
}
}
+
+ // noise is really really annoying
+ if (cls.timedemo)
+ memset(rb_ptr, 128, nbframes * channels);
}
}
static qboolean SND_PaintChannel (channel_t *ch, portable_sampleframe_t *paint, unsigned int count)
{
- int snd_vol, vol[SND_LISTENERS];
+ int vol[SND_LISTENERS];
const snd_buffer_t *sb;
unsigned int i, sb_offset;
+ sfx_t *sfx;
- // If this channel manages its own volume
- if (ch->flags & CHANNELFLAG_FULLVOLUME)
- snd_vol = 256;
- else
- snd_vol = (int)(volume.value * 256);
+ sfx = ch->sfx; // fetch the volatile variable
+ if (!sfx) // given that this is called by the mixer thread, this never happens, but...
+ return false;
- // calculate mixing volumes based on channel volumes and volume cvar
- // also limit the volumes to values that won't clip
+ // move to the stack (do we need to?)
for (i = 0;i < SND_LISTENERS;i++)
- {
- vol[i] = ch->listener_volume[i] * snd_vol;
- vol[i] = bound(0, vol[i], 65536);
- }
+ vol[i] = ch->listener_volume[i];
// if volumes are all zero, just return
for (i = 0;i < SND_LISTENERS;i++)
return false;
sb_offset = ch->pos;
- sb = ch->sfx->fetcher->getsb (ch->sfx->fetcher_data, &ch->fetcher_data, &sb_offset, count);
+ sb = sfx->fetcher->getsb (sfx->fetcher_data, &ch->fetcher_data, &sb_offset, count);
if (sb == NULL)
{
Con_DPrintf("SND_PaintChannel: ERROR: can't get sound buffer from sfx \"%s\"\n",
- ch->sfx->name); // , count); // or add this? FIXME
+ sfx->name); // , count); // or add this? FIXME
return false;
}
else
samples += 2;
}
}
+ else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
+ {
+ for (i = 0;i < count;i++)
+ {
+ paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
+ paint[i].sample[1] -= (samples[1] * vol[1]) >> 8;
+ samples += 2;
+ }
+ }
else if (vol[0] + vol[1] > 0)
{
for (i = 0;i < count;i++)
samples += 1;
}
}
+ else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
+ {
+ for (i = 0;i < count;i++)
+ {
+ paint[i].sample[0] += (samples[0] * vol[0]) >> 8;
+ paint[i].sample[1] -= (samples[0] * vol[1]) >> 8;
+ samples += 1;
+ }
+ }
else if (vol[0] + vol[1] > 0)
{
for (i = 0;i < count;i++)
samples += 2;
}
}
+ else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
+ {
+ for (i = 0;i < count;i++)
+ {
+ paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
+ paint[i].sample[1] -= (samples[1] * vol[1]) >> 16;
+ samples += 2;
+ }
+ }
else if (vol[0] + vol[1] > 0)
{
for (i = 0;i < count;i++)
samples += 1;
}
}
+ else if (vol[0] + vol[1] > 0 && ch->prologic_invert == -1)
+ {
+ for (i = 0;i < count;i++)
+ {
+ paint[i].sample[0] += (samples[0] * vol[0]) >> 16;
+ paint[i].sample[1] -= (samples[0] * vol[1]) >> 16;
+ samples += 1;
+ }
+ }
else if (vol[0] + vol[1] > 0)
{
for (i = 0;i < count;i++)
for (i = 0; i < total_channels ; i++, ch++)
{
sfx_t *sfx;
- unsigned int ltime;
- unsigned int count;
+ int ltime;
+ int count;
sfx = ch->sfx;
if (sfx == NULL)
continue;
if (ch->flags & CHANNELFLAG_PAUSED)
continue;
+ if (!sfx->total_length)
+ continue;
+ if (sfx->total_length > 1<<30)
+ Sys_Error("S_MixToBuffer: sfx corrupt\n");
ltime = 0;
if (ch->pos < 0)
{
count = -ch->pos;
- count = min(count, frames - ltime);
+ count = min(count, (int)frames - ltime);
ch->pos += count;
ltime += count;
}
- while (ltime < frames)
+ while (ltime < (int)frames)
{
// paint up to end of buffer or of input, whichever is lower
count = sfx->total_length - ch->pos;
- count = bound(0, count, frames - ltime);
+ count = bound(0, count, (int)frames - ltime);
+ // mix the remaining samples
if (count)
{
SND_PaintChannel (ch, paintbuffer + ltime, count);
ch->pos += count;
ltime += count;
}
-
// if at end of sfx, loop or stop the channel
- if (ch->pos >= (int)sfx->total_length)
+ else
{
if (sfx->loopstart < sfx->total_length)
ch->pos = sfx->loopstart;
ch->pos = 0;
else
{
- S_StopChannel (ch - channels, false);
+ S_StopChannel (ch - channels, false, false);
break;
}
}