mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-20 17:31:08 +00:00
it makes noise, but dies due to caching bugs
This commit is contained in:
parent
9691afb782
commit
916a698ac5
4 changed files with 152 additions and 123 deletions
|
@ -68,6 +68,10 @@ struct dma_s {
|
|||
int submission_chunk; //!< don't mix less than this #
|
||||
int samplepos; //!< in mono samples
|
||||
unsigned char *buffer; //!< destination for mixed sound
|
||||
/** Transfer mixed samples to the output.
|
||||
\param endtime sample end time (count = endtime - snd_paintedtime)
|
||||
*/
|
||||
void (*xfer) (int endtime);
|
||||
};
|
||||
|
||||
/** Describes the sound data.
|
||||
|
@ -187,6 +191,8 @@ extern struct cvar_s *snd_stereo_phase_separation;
|
|||
extern volatile dma_t *snd_shm;
|
||||
|
||||
extern snd_render_data_t snd_render_data;
|
||||
#define PAINTBUFFER_SIZE 512
|
||||
extern portable_samplepair_t snd_paintbuffer[PAINTBUFFER_SIZE * 2];
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
@ -78,6 +78,117 @@ static general_data_t plugin_info_general_data;
|
|||
|
||||
static snd_output_funcs_t *snd_output_funcs;
|
||||
|
||||
static int *snd_p, snd_linear_count, snd_vol;
|
||||
static short *snd_out;
|
||||
|
||||
static void
|
||||
SND_WriteLinearBlastStereo16 (void)
|
||||
{
|
||||
int val, i;
|
||||
|
||||
for (i = 0; i < snd_linear_count; i += 2) {
|
||||
val = (snd_p[i] * snd_vol) >> 8;
|
||||
if (val > 0x7fff)
|
||||
snd_out[i] = 0x7fff;
|
||||
else if (val < (short) 0x8000)
|
||||
snd_out[i] = (short) 0x8000;
|
||||
else
|
||||
snd_out[i] = val;
|
||||
|
||||
val = (snd_p[i + 1] * snd_vol) >> 8;
|
||||
if (val > 0x7fff)
|
||||
snd_out[i + 1] = 0x7fff;
|
||||
else if (val < (short) 0x8000)
|
||||
snd_out[i + 1] = (short) 0x8000;
|
||||
else
|
||||
snd_out[i + 1] = val;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
s_xfer_stereo_16 (int endtime)
|
||||
{
|
||||
int lpaintedtime, lpos;
|
||||
unsigned int *pbuf;
|
||||
|
||||
snd_vol = snd_volume->value * 256;
|
||||
|
||||
snd_p = (int *) snd_paintbuffer;
|
||||
lpaintedtime = snd_paintedtime;
|
||||
|
||||
|
||||
pbuf = (unsigned int *) snd_shm->buffer;
|
||||
|
||||
while (lpaintedtime < endtime) {
|
||||
// handle recirculating buffer issues
|
||||
lpos = lpaintedtime & ((snd_shm->samples >> 1) - 1);
|
||||
|
||||
snd_out = (short *) pbuf + (lpos << 1);
|
||||
|
||||
snd_linear_count = (snd_shm->samples >> 1) - lpos;
|
||||
if (lpaintedtime + snd_linear_count > endtime)
|
||||
snd_linear_count = endtime - lpaintedtime;
|
||||
|
||||
snd_linear_count <<= 1;
|
||||
|
||||
// write a linear blast of samples
|
||||
SND_WriteLinearBlastStereo16 ();
|
||||
|
||||
snd_p += snd_linear_count;
|
||||
lpaintedtime += (snd_linear_count >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
s_xfer_paint_buffer (int endtime)
|
||||
{
|
||||
int count, out_idx, out_mask, snd_vol, step, val;
|
||||
int *p;
|
||||
unsigned int *pbuf;
|
||||
|
||||
if (snd_shm->samplebits == 16 && snd_shm->channels == 2) {
|
||||
s_xfer_stereo_16 (endtime);
|
||||
return;
|
||||
}
|
||||
|
||||
p = (int *) snd_paintbuffer;
|
||||
count = (endtime - snd_paintedtime) * snd_shm->channels;
|
||||
out_mask = snd_shm->samples - 1;
|
||||
out_idx = snd_paintedtime * snd_shm->channels & out_mask;
|
||||
step = 3 - snd_shm->channels;
|
||||
snd_vol = snd_volume->value * 256;
|
||||
|
||||
pbuf = (unsigned int *) snd_shm->buffer;
|
||||
|
||||
if (snd_shm->samplebits == 16) {
|
||||
short *out = (short *) pbuf;
|
||||
|
||||
while (count--) {
|
||||
val = (*p * snd_vol) >> 8;
|
||||
p += step;
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
else if (val < (short) 0x8000)
|
||||
val = (short) 0x8000;
|
||||
out[out_idx] = val;
|
||||
out_idx = (out_idx + 1) & out_mask;
|
||||
}
|
||||
} else if (snd_shm->samplebits == 8) {
|
||||
unsigned char *out = (unsigned char *) pbuf;
|
||||
|
||||
while (count--) {
|
||||
val = (*p * snd_vol) >> 8;
|
||||
p += step;
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
else if (val < (short) 0x8000)
|
||||
val = (short) 0x8000;
|
||||
out[out_idx] = (val >> 8) + 128;
|
||||
out_idx = (out_idx + 1) & out_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
s_clear_buffer (void)
|
||||
{
|
||||
|
@ -244,6 +355,7 @@ s_startup (void)
|
|||
sound_started = 0;
|
||||
return;
|
||||
}
|
||||
snd_shm->xfer = s_xfer_paint_buffer;
|
||||
|
||||
sound_started = 1;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ static int snd_blocked = 0;
|
|||
static jack_client_t *jack_handle;
|
||||
static jack_port_t *jack_out[2];
|
||||
static dma_t _snd_shm;
|
||||
static float *output[2];
|
||||
|
||||
static void
|
||||
s_extra_update (void)
|
||||
|
@ -76,9 +77,29 @@ s_unblock_sound (void)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
snd_jack_xfer (int endtime)
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
|
||||
count = endtime - snd_paintedtime;
|
||||
for (i = 0; i < count; i++) {
|
||||
*output[0]++ = snd_paintbuffer[i].left / 65536.0;
|
||||
*output[1]++ = snd_paintbuffer[i].right / 65536.0;
|
||||
}
|
||||
output[0] += count;
|
||||
output[1] += count;
|
||||
}
|
||||
|
||||
static int
|
||||
snd_jack_process (jack_nframes_t nframes, void *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
output[i] = (float *) jack_port_get_buffer (jack_out[i], nframes);
|
||||
SND_PaintChannels (snd_paintedtime + nframes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -94,6 +115,7 @@ s_init (void)
|
|||
const char **ports;
|
||||
|
||||
snd_shm = &_snd_shm;
|
||||
snd_shm->xfer = snd_jack_xfer;
|
||||
|
||||
snd_interp = Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE, NULL,
|
||||
"control sample interpolation");
|
||||
|
|
|
@ -47,121 +47,10 @@ static __attribute__ ((used)) const char rcsid[] =
|
|||
#include "compat.h"
|
||||
#include "snd_render.h"
|
||||
|
||||
#define PAINTBUFFER_SIZE 512
|
||||
static portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE * 2];
|
||||
portable_samplepair_t snd_paintbuffer[PAINTBUFFER_SIZE * 2];
|
||||
static int max_overpaint; // number of extra samples painted
|
||||
// due to phase shift
|
||||
static int snd_scaletable[32][256];
|
||||
static int *snd_p, snd_linear_count, snd_vol;
|
||||
static short *snd_out;
|
||||
|
||||
static void
|
||||
SND_WriteLinearBlastStereo16 (void)
|
||||
{
|
||||
int val, i;
|
||||
|
||||
for (i = 0; i < snd_linear_count; i += 2) {
|
||||
val = (snd_p[i] * snd_vol) >> 8;
|
||||
if (val > 0x7fff)
|
||||
snd_out[i] = 0x7fff;
|
||||
else if (val < (short) 0x8000)
|
||||
snd_out[i] = (short) 0x8000;
|
||||
else
|
||||
snd_out[i] = val;
|
||||
|
||||
val = (snd_p[i + 1] * snd_vol) >> 8;
|
||||
if (val > 0x7fff)
|
||||
snd_out[i + 1] = 0x7fff;
|
||||
else if (val < (short) 0x8000)
|
||||
snd_out[i + 1] = (short) 0x8000;
|
||||
else
|
||||
snd_out[i + 1] = val;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
s_xfer_stereo_16 (int endtime)
|
||||
{
|
||||
int lpaintedtime, lpos;
|
||||
unsigned int *pbuf;
|
||||
|
||||
snd_vol = snd_volume->value * 256;
|
||||
|
||||
snd_p = (int *) paintbuffer;
|
||||
lpaintedtime = snd_paintedtime;
|
||||
|
||||
|
||||
pbuf = (unsigned int *) snd_shm->buffer;
|
||||
|
||||
while (lpaintedtime < endtime) {
|
||||
// handle recirculating buffer issues
|
||||
lpos = lpaintedtime & ((snd_shm->samples >> 1) - 1);
|
||||
|
||||
snd_out = (short *) pbuf + (lpos << 1);
|
||||
|
||||
snd_linear_count = (snd_shm->samples >> 1) - lpos;
|
||||
if (lpaintedtime + snd_linear_count > endtime)
|
||||
snd_linear_count = endtime - lpaintedtime;
|
||||
|
||||
snd_linear_count <<= 1;
|
||||
|
||||
// write a linear blast of samples
|
||||
SND_WriteLinearBlastStereo16 ();
|
||||
|
||||
snd_p += snd_linear_count;
|
||||
lpaintedtime += (snd_linear_count >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
s_xfer_paint_buffer (int endtime)
|
||||
{
|
||||
int count, out_idx, out_mask, snd_vol, step, val;
|
||||
int *p;
|
||||
unsigned int *pbuf;
|
||||
|
||||
if (snd_shm->samplebits == 16 && snd_shm->channels == 2) {
|
||||
s_xfer_stereo_16 (endtime);
|
||||
return;
|
||||
}
|
||||
|
||||
p = (int *) paintbuffer;
|
||||
count = (endtime - snd_paintedtime) * snd_shm->channels;
|
||||
out_mask = snd_shm->samples - 1;
|
||||
out_idx = snd_paintedtime * snd_shm->channels & out_mask;
|
||||
step = 3 - snd_shm->channels;
|
||||
snd_vol = snd_volume->value * 256;
|
||||
|
||||
pbuf = (unsigned int *) snd_shm->buffer;
|
||||
|
||||
if (snd_shm->samplebits == 16) {
|
||||
short *out = (short *) pbuf;
|
||||
|
||||
while (count--) {
|
||||
val = (*p * snd_vol) >> 8;
|
||||
p += step;
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
else if (val < (short) 0x8000)
|
||||
val = (short) 0x8000;
|
||||
out[out_idx] = val;
|
||||
out_idx = (out_idx + 1) & out_mask;
|
||||
}
|
||||
} else if (snd_shm->samplebits == 8) {
|
||||
unsigned char *out = (unsigned char *) pbuf;
|
||||
|
||||
while (count--) {
|
||||
val = (*p * snd_vol) >> 8;
|
||||
p += step;
|
||||
if (val > 0x7fff)
|
||||
val = 0x7fff;
|
||||
else if (val < (short) 0x8000)
|
||||
val = (short) 0x8000;
|
||||
out[out_idx] = (val >> 8) + 128;
|
||||
out_idx = (out_idx + 1) & out_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* CHANNEL MIXING */
|
||||
|
||||
|
@ -174,13 +63,13 @@ SND_PaintChannels (unsigned int endtime)
|
|||
sfxbuffer_t *sc;
|
||||
|
||||
while (snd_paintedtime < endtime) {
|
||||
// if paintbuffer is smaller than DMA buffer
|
||||
// if snd_paintbuffer is smaller than DMA buffer
|
||||
end = endtime;
|
||||
if (endtime - snd_paintedtime > PAINTBUFFER_SIZE)
|
||||
end = snd_paintedtime + PAINTBUFFER_SIZE;
|
||||
|
||||
// clear the paint buffer
|
||||
// memset (paintbuffer, 0, (end - snd_paintedtime) *
|
||||
// memset (snd_paintbuffer, 0, (end - snd_paintedtime) *
|
||||
// sizeof (portable_samplepair_t));
|
||||
max_overpaint = 0;
|
||||
|
||||
|
@ -230,12 +119,12 @@ SND_PaintChannels (unsigned int endtime)
|
|||
}
|
||||
|
||||
// transfer out according to DMA format
|
||||
s_xfer_paint_buffer (end);
|
||||
snd_shm->xfer (end);
|
||||
|
||||
memmove (paintbuffer, paintbuffer + end - snd_paintedtime,
|
||||
max_overpaint * sizeof (paintbuffer[0]));
|
||||
memset (paintbuffer + max_overpaint, 0, sizeof (paintbuffer)
|
||||
- max_overpaint * sizeof (paintbuffer[0]));
|
||||
memmove (snd_paintbuffer, snd_paintbuffer + end - snd_paintedtime,
|
||||
max_overpaint * sizeof (snd_paintbuffer[0]));
|
||||
memset (snd_paintbuffer + max_overpaint, 0, sizeof (snd_paintbuffer)
|
||||
- max_overpaint * sizeof (snd_paintbuffer[0]));
|
||||
|
||||
snd_paintedtime = end;
|
||||
}
|
||||
|
@ -269,7 +158,7 @@ snd_paint_mono_8 (int offs, channel_t *ch, void *bytes, unsigned int count)
|
|||
rscale = snd_scaletable[ch->rightvol >> 3];
|
||||
sfx = (unsigned char *) bytes;
|
||||
|
||||
pair = paintbuffer + offs;
|
||||
pair = snd_paintbuffer + offs;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
data = sfx[i];
|
||||
|
@ -295,7 +184,7 @@ snd_paint_mono_16 (int offs, channel_t *ch, void *bytes, unsigned int count)
|
|||
|
||||
sfx = (signed short *) bytes;
|
||||
|
||||
pair = paintbuffer + offs;
|
||||
pair = snd_paintbuffer + offs;
|
||||
|
||||
if (ch->phase >= 0) {
|
||||
left_phase = ch->phase;
|
||||
|
@ -391,7 +280,7 @@ snd_paint_stereo_8 (int offs, channel_t *ch, void *bytes, unsigned int count)
|
|||
rscale = snd_scaletable[ch->rightvol >> 3];
|
||||
|
||||
samp = bytes;
|
||||
pair = paintbuffer + offs;
|
||||
pair = snd_paintbuffer + offs;
|
||||
while (count-- > 0) {
|
||||
pair->left += lscale[*samp++];
|
||||
pair->right += rscale[*samp++];
|
||||
|
@ -408,7 +297,7 @@ snd_paint_stereo_16 (int offs, channel_t *ch, void *bytes, unsigned int count)
|
|||
int rightvol = ch->rightvol;
|
||||
|
||||
samp = (short *) bytes;
|
||||
pair = paintbuffer + offs;
|
||||
pair = snd_paintbuffer + offs;
|
||||
while (count-- > 0) {
|
||||
pair->left += (*samp++ * leftvol) >> 8;
|
||||
pair->right += (*samp++ * rightvol) >> 8;
|
||||
|
|
Loading…
Reference in a new issue