[audio] Clean up jack and alsa dependencies

I had forgotten to test with shared libs and it turns out jack and alsa
were directly accessing symbols in the renderer (and in jack's case,
linking in a duplicate of the renderer).

Fixes #16.
This commit is contained in:
Bill Currie 2021-06-26 16:18:18 +09:00
parent 0be609e0fd
commit f8ffb12713
8 changed files with 59 additions and 51 deletions

View File

@ -77,6 +77,7 @@ struct snd_s {
int frames; //!< frames in buffer
//!< 1 frame = channels samples
int submission_chunk; //!< don't mix less than this #
unsigned paintedtime; //!< sound clock in samples
int framepos; //!< position of dma cursor
unsigned char *buffer; //!< destination for mixed sound
/** Transfer mixed samples to the output.
@ -90,6 +91,9 @@ struct snd_s {
/** Optional data for the xfer function.
*/
void *xfer_data;
void (*finish_channels) (void);
void (*paint_channels) (struct snd_s *snd, unsigned endtime);
};
/** Describes the sound data.
@ -318,6 +322,12 @@ struct channel_s *SND_AllocChannel (snd_t *snd);
*/
void SND_ChannelStop (snd_t *snd, channel_t *chan);
/** Mark all channels as no longer in use.
For use by asynchronous output drivers.
*/
void SND_FinishChannels (void);
/** Scan channels looking for stopped channels.
\param wait if true, wait for the channels to be done. if false, force the
channels to be done. true is for threaded, false for
@ -397,9 +407,6 @@ void SND_LocalSound (snd_t *snd, const char *s);
\ingroup sound_render
*/
///@{
/** sound clock in samples
*/
extern unsigned snd_paintedtime;
/** Mix all active channels into the output buffer.
\param endtime sample time until when to mix

View File

@ -183,6 +183,18 @@ SND_ScanChannels (snd_t *snd, int wait)
}
}
void
SND_FinishChannels (void)
{
int i;
channel_t *ch;
for (i = 0; i < MAX_CHANNELS; i++) {
ch = &snd_channels[i];
ch->done = ch->stop = 1;
}
}
void
SND_StopAllSounds (snd_t *snd)
{

View File

@ -70,7 +70,10 @@ static general_data_t plugin_info_general_data;
static snd_output_funcs_t *snd_output_funcs;
static snd_output_data_t *snd_output_data;
static snd_t snd;
static snd_t snd = {
.finish_channels = SND_FinishChannels,
.paint_channels = SND_PaintChannels,
};
static int snd_shutdown = 0;
static void
@ -83,7 +86,7 @@ s_xfer_paint_buffer (snd_t *snd, portable_samplepair_t *paintbuffer, int count,
p = (float *) paintbuffer;
count *= snd->channels;
out_max = (snd->frames * snd->channels) - 1;
out_idx = snd_paintedtime * snd->channels;
out_idx = snd->paintedtime * snd->channels;
while (out_idx > out_max)
out_idx -= out_max + 1;
step = 3 - snd->channels;
@ -164,10 +167,10 @@ s_get_soundtime (void)
if (framepos < oldframepos) {
buffers++; // buffer wrapped
if (snd_paintedtime > 0x40000000) { // time to chop things off to avoid
if (snd.paintedtime > 0x40000000) { // time to chop things off to avoid
// 32 bit limits
buffers = 0;
snd_paintedtime = frames;
snd.paintedtime = frames;
s_stop_all_sounds ();
}
}
@ -188,9 +191,9 @@ s_update_ (void)
s_get_soundtime ();
// check to make sure that we haven't overshot
if (snd_paintedtime < soundtime) {
if (snd.paintedtime < soundtime) {
// Sys_Printf ("S_Update_ : overflow\n");
snd_paintedtime = soundtime;
snd.paintedtime = soundtime;
}
// mix ahead of current position
endtime = soundtime + snd_mixahead->value * snd.speed;
@ -492,6 +495,10 @@ static plugin_funcs_t plugin_info_funcs = {
.snd_render = &plugin_info_render_funcs,
};
snd_render_data_t snd_render_data = {
.paintedtime = &snd.paintedtime,
};
static plugin_data_t plugin_info_data = {
.general = &plugin_info_general_data,
.snd_render = &snd_render_data,

View File

@ -51,14 +51,6 @@
#define SAMPLE_GAP 4
snd_render_data_t snd_render_data = {
0,
0,
0,
&snd_paintedtime,
0,
};
static sfxbuffer_t *
snd_fail (sfx_t *sfx)
{

View File

@ -50,8 +50,6 @@
cvar_t *snd_volume;
unsigned snd_paintedtime; // sample PAIRS
portable_samplepair_t snd_paintbuffer[PAINTBUFFER_SIZE * 2];
static int max_overpaint; // number of extra samples painted
// due to phase shift
@ -118,11 +116,11 @@ SND_PaintChannels (snd_t *snd, unsigned endtime)
snd_paintbuffer[i].right = 0;
}
while (snd_paintedtime < endtime) {
while (snd->paintedtime < endtime) {
// if snd_paintbuffer is smaller than DMA buffer
end = endtime;
if (end - snd_paintedtime > PAINTBUFFER_SIZE)
end = snd_paintedtime + PAINTBUFFER_SIZE;
if (end - snd->paintedtime > PAINTBUFFER_SIZE)
end = snd->paintedtime + PAINTBUFFER_SIZE;
max_overpaint = 0;
@ -144,9 +142,9 @@ SND_PaintChannels (snd_t *snd, unsigned endtime)
}
if (!ch->end)
ch->end = snd_paintedtime + sfx->length - ch->pos;
ch->end = snd->paintedtime + sfx->length - ch->pos;
ltime = snd_paintedtime;
ltime = snd->paintedtime;
while (ltime < end) { // paint up to end
count = ((ch->end < end) ? ch->end : end) - ltime;
@ -171,15 +169,15 @@ SND_PaintChannels (snd_t *snd, unsigned endtime)
}
// transfer out according to DMA format
snd->xfer (snd, snd_paintbuffer, end - snd_paintedtime,
snd->xfer (snd, snd_paintbuffer, end - snd->paintedtime,
snd_volume->value);
memmove (snd_paintbuffer, snd_paintbuffer + end - snd_paintedtime,
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;
snd->paintedtime = end;
}
}

View File

@ -21,14 +21,15 @@ libs_audio_targets_snd_output_sdl_la_SOURCES= libs/audio/targets/snd_sdl.c
libs_audio_targets_snd_output_alsa_la_LDFLAGS= $(plugin_ldflags)
libs_audio_targets_snd_output_alsa_la_LIBADD= $(snd_deps)
libs_audio_targets_snd_output_alsa_la_DEPENDENCIES=$(snd_deps)
libs_audio_targets_snd_output_alsa_la_DEPENDENCIES= $(snd_deps)
libs_audio_targets_snd_output_alsa_la_CFLAGS= $(ALSA_CFLAGS)
libs_audio_targets_snd_output_alsa_la_SOURCES= libs/audio/targets/snd_alsa.c
libs_audio_targets_snd_output_jack_la_LDFLAGS= $(plugin_ldflags)
libs_audio_targets_snd_output_jack_la_SOURCES= libs/audio/targets/snd_jack.c $(snd_common) $(format_src)
libs_audio_targets_snd_output_jack_la_LIBADD= $(snd_libs) $(format_libs) $(JACK_LIBS)
libs_audio_targets_snd_output_jack_la_LDFLAGS= $(plugin_ldflags)
libs_audio_targets_snd_output_jack_la_LIBADD= $(snd_deps) $(JACK_LIBS)
libs_audio_targets_snd_output_jack_la_DEPENDENCIES= $(snd_libs)
libs_audio_targets_snd_output_jack_la_CFLAGS= $(JACK_CFLAGS)
libs_audio_targets_snd_output_jack_la_SOURCES= libs/audio/targets/snd_jack.c
libs_audio_targets_snd_output_oss_la_LDFLAGS= $(plugin_ldflags)
libs_audio_targets_snd_output_oss_la_LIBADD= $(snd_deps) $(OSS_LIBS)

View File

@ -202,7 +202,7 @@ alsa_xfer (snd_t *snd, portable_samplepair_t *paintbuffer, int count,
p = (float *) paintbuffer;
count *= snd->channels;
out_max = (snd->frames * snd->channels) - 1;
out_idx = snd_paintedtime * snd->channels;
out_idx = snd->paintedtime * snd->channels;
while (out_idx > out_max)
out_idx -= out_max + 1;
step = 3 - snd->channels;
@ -288,7 +288,7 @@ alsa_process (snd_pcm_t *pcm, snd_t *snd)
ret = 0;
}
snd->buffer = packet.areas[0].addr;
SND_PaintChannels (snd, snd_paintedtime + packet.nframes);
snd->paint_channels (snd, snd->paintedtime + packet.nframes);
if ((res = qfsnd_pcm_mmap_commit (pcm, packet.offset,
packet.nframes)) < 0
|| (snd_pcm_uframes_t) res != packet.nframes) {

View File

@ -59,18 +59,6 @@ static cvar_t *snd_jack_server;
static int s_jack_connect (snd_t *snd);
static void
s_finish_channels (void)
{
int i;
channel_t *ch;
for (i = 0; i < MAX_CHANNELS; i++) {
ch = &snd_channels[i];
ch->done = ch->stop = 1;
}
}
static void
s_update (snd_t *snd)
{
@ -85,7 +73,7 @@ s_update (snd_t *snd)
if (!snd_shutdown) {
if (now - snd_alive_time > 1.0) {
Sys_Printf ("jackd client thread seems to have died\n");
s_finish_channels ();
snd->finish_channels ();
snd_shutdown = 1;
}
}
@ -162,8 +150,8 @@ snd_jack_xfer (snd_t *snd, portable_samplepair_t *paintbuffer, int count,
}
for (i = 0; i < count; i++) {
/* max is +/- 1.0. need to implement clamping. */
*output[0]++ = volume * snd_paintbuffer[i].left;
*output[1]++ = volume * snd_paintbuffer[i].right;
*output[0]++ = volume * paintbuffer[i].left;
*output[1]++ = volume * paintbuffer[i].right;
}
}
@ -176,15 +164,17 @@ snd_jack_process (jack_nframes_t nframes, void *arg)
snd_alive = 1;
for (i = 0; i < 2; i++)
output[i] = (float *) jack_port_get_buffer (jack_out[i], nframes);
SND_PaintChannels (snd, snd_paintedtime + nframes);
snd->paint_channels (snd, snd->paintedtime + nframes);
return 0;
}
static void
snd_jack_shutdown (void *arg)
{
snd_t *snd = arg;
snd_shutdown = 1;
s_finish_channels ();
snd->finish_channels ();
}
static void
@ -217,12 +207,13 @@ s_jack_connect (snd_t *snd)
if (jack_set_xrun_callback (jack_handle, snd_jack_xrun, 0))
Sys_Printf ("Could not set xrun callback\n");
jack_set_process_callback (jack_handle, snd_jack_process, snd);
jack_on_shutdown (jack_handle, snd_jack_shutdown, 0);
jack_on_shutdown (jack_handle, snd_jack_shutdown, snd);
for (i = 0; i < 2; i++)
jack_out[i] = jack_port_register (jack_handle, va (0, "out_%d", i + 1),
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
snd->speed = jack_get_sample_rate (jack_handle);
snd->channels = 2;
s_jack_activate ();
sound_started = 1;
Sys_Printf ("Connected to JACK: %d Sps\n", snd->speed);