mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
make "sample counts" frame based rather than mono sample based
that was always horribly confusing
This commit is contained in:
parent
3b76c595be
commit
2bb2d14b89
7 changed files with 86 additions and 80 deletions
|
@ -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);
|
||||
};
|
||||
//@}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue