From 916a698ac5e7b3ae3753485acedfba3b8b33407d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 17 Mar 2007 07:05:24 +0000 Subject: [PATCH] it makes noise, but dies due to caching bugs --- include/snd_render.h | 6 ++ libs/audio/renderer/snd_dma.c | 112 +++++++++++++++++++++++++++ libs/audio/renderer/snd_jack.c | 22 ++++++ libs/audio/renderer/snd_mix.c | 135 +++------------------------------ 4 files changed, 152 insertions(+), 123 deletions(-) diff --git a/include/snd_render.h b/include/snd_render.h index 2bda8c49f..e89499c54 100644 --- a/include/snd_render.h +++ b/include/snd_render.h @@ -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]; //@} diff --git a/libs/audio/renderer/snd_dma.c b/libs/audio/renderer/snd_dma.c index be792dd91..7149ddb20 100644 --- a/libs/audio/renderer/snd_dma.c +++ b/libs/audio/renderer/snd_dma.c @@ -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; } diff --git a/libs/audio/renderer/snd_jack.c b/libs/audio/renderer/snd_jack.c index 8e9e21667..d369139b0 100644 --- a/libs/audio/renderer/snd_jack.c +++ b/libs/audio/renderer/snd_jack.c @@ -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"); diff --git a/libs/audio/renderer/snd_mix.c b/libs/audio/renderer/snd_mix.c index 2f162811f..d90f0829e 100644 --- a/libs/audio/renderer/snd_mix.c +++ b/libs/audio/renderer/snd_mix.c @@ -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;