mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-05-31 16:51: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 submission_chunk; //!< don't mix less than this #
|
||||||
int samplepos; //!< in mono samples
|
int samplepos; //!< in mono samples
|
||||||
unsigned char *buffer; //!< destination for mixed sound
|
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.
|
/** Describes the sound data.
|
||||||
|
@ -187,6 +191,8 @@ extern struct cvar_s *snd_stereo_phase_separation;
|
||||||
extern volatile dma_t *snd_shm;
|
extern volatile dma_t *snd_shm;
|
||||||
|
|
||||||
extern snd_render_data_t snd_render_data;
|
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 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
|
static void
|
||||||
s_clear_buffer (void)
|
s_clear_buffer (void)
|
||||||
{
|
{
|
||||||
|
@ -244,6 +355,7 @@ s_startup (void)
|
||||||
sound_started = 0;
|
sound_started = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
snd_shm->xfer = s_xfer_paint_buffer;
|
||||||
|
|
||||||
sound_started = 1;
|
sound_started = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ static int snd_blocked = 0;
|
||||||
static jack_client_t *jack_handle;
|
static jack_client_t *jack_handle;
|
||||||
static jack_port_t *jack_out[2];
|
static jack_port_t *jack_out[2];
|
||||||
static dma_t _snd_shm;
|
static dma_t _snd_shm;
|
||||||
|
static float *output[2];
|
||||||
|
|
||||||
static void
|
static void
|
||||||
s_extra_update (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
|
static int
|
||||||
snd_jack_process (jack_nframes_t nframes, void *arg)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +115,7 @@ s_init (void)
|
||||||
const char **ports;
|
const char **ports;
|
||||||
|
|
||||||
snd_shm = &_snd_shm;
|
snd_shm = &_snd_shm;
|
||||||
|
snd_shm->xfer = snd_jack_xfer;
|
||||||
|
|
||||||
snd_interp = Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE, NULL,
|
snd_interp = Cvar_Get ("snd_interp", "1", CVAR_ARCHIVE, NULL,
|
||||||
"control sample interpolation");
|
"control sample interpolation");
|
||||||
|
|
|
@ -47,121 +47,10 @@ static __attribute__ ((used)) const char rcsid[] =
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "snd_render.h"
|
#include "snd_render.h"
|
||||||
|
|
||||||
#define PAINTBUFFER_SIZE 512
|
portable_samplepair_t snd_paintbuffer[PAINTBUFFER_SIZE * 2];
|
||||||
static portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE * 2];
|
|
||||||
static int max_overpaint; // number of extra samples painted
|
static int max_overpaint; // number of extra samples painted
|
||||||
// due to phase shift
|
// due to phase shift
|
||||||
static int snd_scaletable[32][256];
|
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 */
|
/* CHANNEL MIXING */
|
||||||
|
|
||||||
|
@ -174,13 +63,13 @@ SND_PaintChannels (unsigned int endtime)
|
||||||
sfxbuffer_t *sc;
|
sfxbuffer_t *sc;
|
||||||
|
|
||||||
while (snd_paintedtime < endtime) {
|
while (snd_paintedtime < endtime) {
|
||||||
// if paintbuffer is smaller than DMA buffer
|
// if snd_paintbuffer is smaller than DMA buffer
|
||||||
end = endtime;
|
end = endtime;
|
||||||
if (endtime - snd_paintedtime > PAINTBUFFER_SIZE)
|
if (endtime - snd_paintedtime > PAINTBUFFER_SIZE)
|
||||||
end = snd_paintedtime + PAINTBUFFER_SIZE;
|
end = snd_paintedtime + PAINTBUFFER_SIZE;
|
||||||
|
|
||||||
// clear the paint buffer
|
// clear the paint buffer
|
||||||
// memset (paintbuffer, 0, (end - snd_paintedtime) *
|
// memset (snd_paintbuffer, 0, (end - snd_paintedtime) *
|
||||||
// sizeof (portable_samplepair_t));
|
// sizeof (portable_samplepair_t));
|
||||||
max_overpaint = 0;
|
max_overpaint = 0;
|
||||||
|
|
||||||
|
@ -230,12 +119,12 @@ SND_PaintChannels (unsigned int endtime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// transfer out according to DMA format
|
// transfer out according to DMA format
|
||||||
s_xfer_paint_buffer (end);
|
snd_shm->xfer (end);
|
||||||
|
|
||||||
memmove (paintbuffer, paintbuffer + end - snd_paintedtime,
|
memmove (snd_paintbuffer, snd_paintbuffer + end - snd_paintedtime,
|
||||||
max_overpaint * sizeof (paintbuffer[0]));
|
max_overpaint * sizeof (snd_paintbuffer[0]));
|
||||||
memset (paintbuffer + max_overpaint, 0, sizeof (paintbuffer)
|
memset (snd_paintbuffer + max_overpaint, 0, sizeof (snd_paintbuffer)
|
||||||
- max_overpaint * sizeof (paintbuffer[0]));
|
- max_overpaint * sizeof (snd_paintbuffer[0]));
|
||||||
|
|
||||||
snd_paintedtime = end;
|
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];
|
rscale = snd_scaletable[ch->rightvol >> 3];
|
||||||
sfx = (unsigned char *) bytes;
|
sfx = (unsigned char *) bytes;
|
||||||
|
|
||||||
pair = paintbuffer + offs;
|
pair = snd_paintbuffer + offs;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
data = sfx[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;
|
sfx = (signed short *) bytes;
|
||||||
|
|
||||||
pair = paintbuffer + offs;
|
pair = snd_paintbuffer + offs;
|
||||||
|
|
||||||
if (ch->phase >= 0) {
|
if (ch->phase >= 0) {
|
||||||
left_phase = ch->phase;
|
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];
|
rscale = snd_scaletable[ch->rightvol >> 3];
|
||||||
|
|
||||||
samp = bytes;
|
samp = bytes;
|
||||||
pair = paintbuffer + offs;
|
pair = snd_paintbuffer + offs;
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
pair->left += lscale[*samp++];
|
pair->left += lscale[*samp++];
|
||||||
pair->right += rscale[*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;
|
int rightvol = ch->rightvol;
|
||||||
|
|
||||||
samp = (short *) bytes;
|
samp = (short *) bytes;
|
||||||
pair = paintbuffer + offs;
|
pair = snd_paintbuffer + offs;
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
pair->left += (*samp++ * leftvol) >> 8;
|
pair->left += (*samp++ * leftvol) >> 8;
|
||||||
pair->right += (*samp++ * rightvol) >> 8;
|
pair->right += (*samp++ * rightvol) >> 8;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue