make "sample counts" frame based rather than mono sample based

that was always horribly confusing
This commit is contained in:
Bill Currie 2010-08-11 23:43:35 +00:00 committed by Jeff Teunissen
parent 3b76c595be
commit 2bb2d14b89
7 changed files with 86 additions and 80 deletions

View File

@ -55,11 +55,13 @@ struct sfx_s
struct sfxbuffer_s *(*touch) (sfx_t *sfx);
struct sfxbuffer_s *(*retain) (sfx_t *sfx);
void (*release) (sfx_t *sfx);
struct sfxbuffer_s *(*getbuffer) (sfx_t *sfx);
struct wavinfo_s *(*wavinfo) (sfx_t *sfx);
sfx_t *(*open) (sfx_t *sfx);
void (*close) (sfx_t *sfx);
void (*release) (sfx_t *sfx);
};
//@}

View File

@ -64,9 +64,10 @@ struct dma_s {
int speed; //!< sample rate
int samplebits; //!< bits per sample
int channels; //!< number of output channels
int samples; //!< mono samples in buffer
int frames; //!< frames in buffer
//!< 1 frame = channels samples
int submission_chunk; //!< don't mix less than this #
int samplepos; //!< in mono samples
int framepos; //!< ??
unsigned char *buffer; //!< destination for mixed sound
/** Transfer mixed samples to the output.
\param endtime sample end time (count = endtime - snd_paintedtime)

View File

@ -80,7 +80,7 @@ SND_WriteLinearBlastStereo16 (void)
{
int val, i;
for (i = 0; i < snd_linear_count; i += 2) {
for (i = 0; i < snd_linear_count * 2; i += 2) {
val = (snd_p[i] * snd_vol) >> 8;
if (val > 0x7fff)
snd_out[i] = 0x7fff;
@ -103,7 +103,7 @@ static void
s_xfer_stereo_16 (int endtime)
{
int lpaintedtime, lpos;
unsigned int *pbuf;
short *pbuf;
snd_vol = snd_volume->value * 256;
@ -111,25 +111,23 @@ s_xfer_stereo_16 (int endtime)
lpaintedtime = snd_paintedtime;
pbuf = (unsigned int *) snd_shm->buffer;
pbuf = (short *) snd_shm->buffer;
while (lpaintedtime < endtime) {
// handle recirculating buffer issues
lpos = lpaintedtime & ((snd_shm->samples >> 1) - 1);
lpos = lpaintedtime & (snd_shm->frames - 1);
snd_out = (short *) pbuf + (lpos << 1);
snd_out = pbuf + (lpos << 1);
snd_linear_count = (snd_shm->samples >> 1) - lpos;
snd_linear_count = snd_shm->frames - 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);
snd_p += snd_linear_count << 1;
lpaintedtime += snd_linear_count;
}
}
@ -147,7 +145,7 @@ s_xfer_paint_buffer (int endtime)
p = (int *) snd_paintbuffer;
count = (endtime - snd_paintedtime) * snd_shm->channels;
out_mask = snd_shm->samples - 1;
out_mask = snd_shm->frames - 1;
out_idx = snd_paintedtime * snd_shm->channels & out_mask;
step = 3 - snd_shm->channels;
snd_vol = snd_volume->value * 256;
@ -187,6 +185,7 @@ static void
s_clear_buffer (void)
{
int clear, i;
int count;
if (!sound_started || !snd_shm || !snd_shm->buffer)
return;
@ -196,7 +195,8 @@ s_clear_buffer (void)
else
clear = 0;
for (i = 0; i < snd_shm->samples * snd_shm->samplebits / 8; i++)
count = snd_shm->frames * snd_shm->channels * snd_shm->samplebits / 8;
for (i = 0; i < count; i++)
snd_shm->buffer[i] = clear;
}
@ -213,29 +213,29 @@ s_stop_all_sounds (void)
static void
s_get_soundtime (void)
{
int fullsamples, samplepos;
static int buffers, oldsamplepos;
int frames, framepos;
static int buffers, oldframepos;
fullsamples = snd_shm->samples / snd_shm->channels;
frames = snd_shm->frames;
// it is possible to miscount buffers if it has wrapped twice between
// calls to s_update. Oh well.
if ((samplepos = snd_output_funcs->pS_O_GetDMAPos ()) == -1)
if ((framepos = snd_output_funcs->pS_O_GetDMAPos ()) == -1)
return;
if (samplepos < oldsamplepos) {
if (framepos < oldframepos) {
buffers++; // buffer wrapped
if (snd_paintedtime > 0x40000000) { // time to chop things off to avoid
// 32 bit limits
buffers = 0;
snd_paintedtime = fullsamples;
snd_paintedtime = frames;
s_stop_all_sounds ();
}
}
oldsamplepos = samplepos;
oldframepos = framepos;
soundtime = buffers * fullsamples + samplepos / snd_shm->channels;
soundtime = buffers * frames + framepos;
}
static void
@ -256,7 +256,7 @@ s_update_ (void)
}
// mix ahead of current position
endtime = soundtime + snd_mixahead->value * snd_shm->speed;
samps = snd_shm->samples >> (snd_shm->channels - 1);
samps = snd_shm->frames;
if (endtime - soundtime > samps)
endtime = soundtime + samps;
@ -322,13 +322,13 @@ s_soundinfo_f (void)
return;
}
Sys_Printf ("%5d stereo\n", snd_shm->channels - 1);
Sys_Printf ("%5d samples\n", snd_shm->samples);
Sys_Printf ("%5d samplepos\n", snd_shm->samplepos);
Sys_Printf ("%5d channels\n", snd_shm->channels);
Sys_Printf ("%5d frames\n", snd_shm->frames);
Sys_Printf ("%5d framepos\n", snd_shm->framepos);
Sys_Printf ("%5d samplebits\n", snd_shm->samplebits);
Sys_Printf ("%5d submission_chunk\n", snd_shm->submission_chunk);
Sys_Printf ("%5d speed\n", snd_shm->speed);
Sys_Printf ("0x%p dma buffer\n", snd_shm->buffer);
Sys_Printf ("0x%lx dma buffer\n", (long) snd_shm->buffer);
Sys_Printf ("%5d total_channels\n", snd_total_channels);
}

View File

@ -321,7 +321,7 @@ SNDDMA_Init (void)
memset ((dma_t *) &sn, 0, sizeof (sn));
sn.channels = stereo + 1;
// don't mix less than this in mono samples:
// don't mix less than this in frames:
err = qfsnd_pcm_hw_params_get_period_size (hw, (snd_pcm_uframes_t *)
(char *)
&sn.submission_chunk, 0);
@ -331,7 +331,7 @@ SNDDMA_Init (void)
goto error;
}
sn.samplepos = 0;
sn.framepos = 0;
sn.samplebits = bps;
err = qfsnd_pcm_hw_params_get_buffer_size (hw, &buffer_size);
@ -346,12 +346,12 @@ SNDDMA_Init (void)
Sys_Printf ("to have a power of 2 buffer size\n");
}
sn.samples = buffer_size * sn.channels;
sn.frames = buffer_size;
sn.speed = rate;
SNDDMA_GetDMAPos (); //XXX sets sn.buffer
Sys_Printf ("%5d stereo\n", sn.channels - 1);
Sys_Printf ("%5d samples\n", sn.samples);
Sys_Printf ("%5d samplepos\n", sn.samplepos);
Sys_Printf ("%5d channels\n", sn.channels);
Sys_Printf ("%5d samples\n", sn.frames);
Sys_Printf ("%5d samplepos\n", sn.framepos);
Sys_Printf ("%5d samplebits\n", sn.samplebits);
Sys_Printf ("%5d submission_chunk\n", sn.submission_chunk);
Sys_Printf ("%5d speed\n", sn.speed);
@ -369,15 +369,13 @@ SNDDMA_GetDMAPos (void)
{
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t offset;
snd_pcm_uframes_t nframes = sn.samples/sn.channels;
snd_pcm_uframes_t nframes = sn.frames;
qfsnd_pcm_avail_update (pcm);
qfsnd_pcm_mmap_begin (pcm, &areas, &offset, &nframes);
offset *= sn.channels;
nframes *= sn.channels;
sn.samplepos = offset;
sn.framepos = offset;
sn.buffer = areas->addr; //XXX FIXME there's an area per channel
return sn.samplepos;
return sn.framepos;
}
static void

View File

@ -104,8 +104,8 @@ SNDDMA_Init (void)
static int
SNDDMA_GetDMAPos (void)
{
sn.samplepos = 0;
return sn.samplepos;
sn.framepos = 0;
return sn.framepos;
}
static void

View File

@ -250,7 +250,7 @@ try_open (int rw)
return 0;
}
sn.samples = info.fragstotal * info.fragsize / (sn.samplebits / 8);
sn.frames = info.fragstotal;
sn.submission_chunk = 1;
if (mmaped_io) { // memory map the dma buffer
@ -265,7 +265,7 @@ try_open (int rw)
return 0;
}
} else {
sn.buffer = malloc (sn.samples * (sn.samplebits / 8) * 2);
sn.buffer = malloc (sn.frames * sn.channels * (sn.samplebits / 8));
if (!sn.buffer) {
Sys_Printf ("SNDDMA_Init: memory allocation failure\n");
close (audio_fd);
@ -279,7 +279,7 @@ try_open (int rw)
if (rc < 0) {
Sys_Printf ("Could not toggle.: %s\n", strerror (errno));
if (mmaped_io)
munmap (sn.buffer, sn.samples * sn.samplebits / 8);
munmap (sn.buffer, sn.frames * sn.channels * sn.samplebits / 8);
close (audio_fd);
return 0;
}
@ -288,12 +288,12 @@ try_open (int rw)
if (rc < 0) {
Sys_Printf ("Could not toggle.: %s\n", strerror (errno));
if (mmaped_io)
munmap (sn.buffer, sn.samples * sn.samplebits / 8);
munmap (sn.buffer, sn.frames * sn.channels * sn.samplebits / 8);
close (audio_fd);
return 0;
}
sn.samplepos = 0;
sn.framepos = 0;
snd_inited = 1;
return &sn;
@ -319,16 +319,16 @@ SNDDMA_GetDMAPos (void)
if (ioctl (audio_fd, SNDCTL_DSP_GETOPTR, &count) == -1) {
Sys_Printf ("Uh, %s dead: %s\n", snd_dev, strerror (errno));
if (mmaped_io)
munmap (sn.buffer, sn.samples * sn.samplebits / 8);
munmap (sn.buffer, sn.frames * sn.channels * sn.samplebits / 8);
close (audio_fd);
snd_inited = 0;
return 0;
}
// sn.samplepos = (count.bytes / (sn.samplebits / 8)) & (sn.samples-1);
// fprintf(stderr, "%d \r", count.ptr);
sn.samplepos = count.ptr / (sn.samplebits / 8);
sn.framepos = count.ptr / (sn.samplebits / 8) / sn.channels; //XXX???
return sn.samplepos;
return sn.framepos;
}
@ -337,14 +337,17 @@ SNDDMA_Shutdown (void)
{
if (snd_inited) {
if (mmaped_io)
munmap (sn.buffer, sn.samples * sn.samplebits / 8);
munmap (sn.buffer, sn.frames * sn.channels * sn.samplebits / 8);
close (audio_fd);
snd_inited = 0;
}
}
#define BITSIZE (sn.samplebits / 8)
#define BYTES (samples / BITSIZE)
static int
sample_bytes (int frames)
{
return frames * sn.channels * sn.samplebits / 8;
}
/*
SNDDMA_Submit
@ -354,25 +357,27 @@ SNDDMA_Shutdown (void)
static void
SNDDMA_Submit (void)
{
int samples;
int frames;
int len;
int offset;
if (snd_inited && !mmaped_io) {
samples = *plugin_info_snd_output_data.paintedtime
frames = *plugin_info_snd_output_data.paintedtime
- *plugin_info_snd_output_data.soundtime;
offset = frames * sn.channels * sn.samplebits / 8;
if (sn.samplepos + BYTES <= sn.samples) {
if (write (audio_fd, sn.buffer + BYTES, samples) != samples)
if (sn.framepos + frames <= sn.frames) {
len = sample_bytes (frames);
if (write (audio_fd, sn.buffer + offset, len) != len)
Sys_Printf ("SNDDMA_Submit(): %s\n", strerror (errno));
} else {
if (write (audio_fd, sn.buffer + BYTES, sn.samples -
sn.samplepos) != sn.samples - sn.samplepos)
int len = sample_bytes (sn.frames - sn.framepos);
if (write (audio_fd, sn.buffer + offset, len) != len)
Sys_Printf ("SNDDMA_Submit(): %s\n", strerror (errno));
if (write (audio_fd, sn.buffer, BYTES - (sn.samples -
sn.samplepos)) !=
BYTES - (sn.samples - sn.samplepos))
if (write (audio_fd, sn.buffer, offset - len) != offset - len)
Sys_Printf ("SNDDMA_Submit(): %s\n", strerror (errno));
}
*plugin_info_snd_output_data.soundtime += samples;
*plugin_info_snd_output_data.soundtime += frames;
}
}

View File

@ -69,25 +69,25 @@ static snd_output_funcs_t plugin_info_snd_output_funcs;
static void
paint_audio (void *unused, Uint8 * stream, int len)
{
int sampleposbytes, samplesbytes, streamsamples;
int frameposbytes, framesbytes, frames;
streamsamples = len / (sn.samplebits / 8);
sampleposbytes = sn.samplepos * (sn.samplebits / 8);
samplesbytes = sn.samples * (sn.samplebits / 8);
frames = len / (sn.channels * (sn.samplebits / 8));
frameposbytes = sn.framepos * sn.channels * (sn.samplebits / 8);
framesbytes = sn.frames * sn.channels * (sn.samplebits / 8);
sn.samplepos += streamsamples;
while (sn.samplepos >= sn.samples)
sn.samplepos -= sn.samples;
sn.framepos += frames;
while (sn.framepos >= sn.frames)
sn.framepos -= sn.frames;
if (sn.samplepos + streamsamples <= sn.samples)
memcpy (stream, sn.buffer + sampleposbytes, len);
if (sn.framepos + frames <= sn.frames)
memcpy (stream, sn.buffer + frameposbytes, len);
else {
memcpy (stream, sn.buffer + sampleposbytes, samplesbytes -
sampleposbytes);
memcpy (stream + samplesbytes - sampleposbytes, sn.buffer, len -
(samplesbytes - sampleposbytes));
memcpy (stream, sn.buffer + frameposbytes, framesbytes -
frameposbytes);
memcpy (stream + framesbytes - frameposbytes, sn.buffer, len -
(framesbytes - frameposbytes));
}
*plugin_info_snd_output_data.soundtime += streamsamples;
*plugin_info_snd_output_data.soundtime += frames;
}
static void
@ -165,10 +165,10 @@ SNDDMA_Init (void)
sn.samplebits = (obtained.format & 0xFF);
sn.speed = obtained.freq;
sn.channels = obtained.channels;
sn.samples = obtained.samples * 16;
sn.samplepos = 0;
sn.frames = obtained.samples * 8; // 8 chunks in the buffer
sn.framepos = 0;
sn.submission_chunk = 1;
sn.buffer = calloc(sn.samples * (sn.samplebits / 8), 1);
sn.buffer = calloc(sn.frames * sn.channels * (sn.samplebits / 8), 1);
if (!sn.buffer)
{
Sys_Error ("Failed to allocate buffer for sound!");
@ -181,7 +181,7 @@ SNDDMA_Init (void)
static int
SNDDMA_GetDMAPos (void)
{
return sn.samplepos;
return sn.framepos;
}
static void