early-access version 1667
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -103,6 +103,8 @@ static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *,
|
||||
static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_writable_size) (pa_stream *);
|
||||
static size_t (*PULSEAUDIO_pa_stream_readable_size) (pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_begin_write) (pa_stream *, void **, size_t*);
|
||||
static int (*PULSEAUDIO_pa_stream_cancel_write) (pa_stream *);
|
||||
static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t,
|
||||
pa_free_cb_t, int64_t, pa_seek_mode_t);
|
||||
static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *,
|
||||
@@ -216,6 +218,8 @@ load_pulseaudio_syms(void)
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_writable_size);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_readable_size);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_write);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_begin_write);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_cancel_write);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_drain);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_disconnect);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_peek);
|
||||
@@ -366,7 +370,7 @@ PULSEAUDIO_PlayDevice(_THIS)
|
||||
/* Write the audio data */
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
if (SDL_AtomicGet(&this->enabled)) {
|
||||
if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
|
||||
if (PULSEAUDIO_pa_stream_write(h->stream, h->pabuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
}
|
||||
@@ -375,7 +379,21 @@ PULSEAUDIO_PlayDevice(_THIS)
|
||||
static Uint8 *
|
||||
PULSEAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return (this->hidden->mixbuf);
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
size_t nbytes = h->mixlen;
|
||||
int ret;
|
||||
|
||||
ret = PULSEAUDIO_pa_stream_begin_write(h->stream, &h->pabuf, &nbytes);
|
||||
|
||||
if (ret != 0) {
|
||||
/* fall back it intermediate buffer */
|
||||
h->pabuf = h->mixbuf;
|
||||
} else if (nbytes < h->mixlen) {
|
||||
PULSEAUDIO_pa_stream_cancel_write(h->stream);
|
||||
h->pabuf = h->mixbuf;
|
||||
}
|
||||
|
||||
return (Uint8 *)h->pabuf;
|
||||
}
|
||||
|
||||
|
||||
@@ -600,6 +618,7 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
|
||||
/* Reduced prebuffering compared to the defaults. */
|
||||
#ifdef PA_STREAM_ADJUST_LATENCY
|
||||
paattr.fragsize = this->spec.size;
|
||||
/* 2x original requested bufsize */
|
||||
paattr.tlength = h->mixlen * 4;
|
||||
paattr.prebuf = -1;
|
||||
@@ -608,6 +627,7 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
paattr.minreq = h->mixlen;
|
||||
flags = PA_STREAM_ADJUST_LATENCY;
|
||||
#else
|
||||
paattr.fragsize = this->spec.size;
|
||||
paattr.tlength = h->mixlen*2;
|
||||
paattr.prebuf = h->mixlen*2;
|
||||
paattr.maxlength = h->mixlen*2;
|
||||
@@ -676,12 +696,45 @@ static SDL_Thread *hotplug_thread = NULL;
|
||||
|
||||
/* device handles are device index + 1, cast to void*, so we never pass a NULL. */
|
||||
|
||||
static SDL_AudioFormat
|
||||
PulseFormatToSDLFormat(pa_sample_format_t format)
|
||||
{
|
||||
switch (format) {
|
||||
case PA_SAMPLE_U8:
|
||||
return AUDIO_U8;
|
||||
case PA_SAMPLE_S16LE:
|
||||
return AUDIO_S16LSB;
|
||||
case PA_SAMPLE_S16BE:
|
||||
return AUDIO_S16MSB;
|
||||
case PA_SAMPLE_S32LE:
|
||||
return AUDIO_S32LSB;
|
||||
case PA_SAMPLE_S32BE:
|
||||
return AUDIO_S32MSB;
|
||||
case PA_SAMPLE_FLOAT32LE:
|
||||
return AUDIO_F32LSB;
|
||||
case PA_SAMPLE_FLOAT32BE:
|
||||
return AUDIO_F32MSB;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is called when PulseAudio adds an output ("sink") device. */
|
||||
static void
|
||||
SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
{
|
||||
SDL_AudioSpec spec;
|
||||
if (i) {
|
||||
SDL_AddAudioDevice(SDL_FALSE, i->description, (void *) ((size_t) i->index+1));
|
||||
spec.freq = i->sample_spec.rate;
|
||||
spec.channels = i->sample_spec.channels;
|
||||
spec.format = PulseFormatToSDLFormat(i->sample_spec.format);
|
||||
spec.silence = 0;
|
||||
spec.samples = 0;
|
||||
spec.size = 0;
|
||||
spec.callback = NULL;
|
||||
spec.userdata = NULL;
|
||||
|
||||
SDL_AddAudioDevice(SDL_FALSE, i->description, &spec, (void *) ((size_t) i->index+1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -689,10 +742,20 @@ SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
static void
|
||||
SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
|
||||
{
|
||||
SDL_AudioSpec spec;
|
||||
if (i) {
|
||||
/* Skip "monitor" sources. These are just output from other sinks. */
|
||||
if (i->monitor_of_sink == PA_INVALID_INDEX) {
|
||||
SDL_AddAudioDevice(SDL_TRUE, i->description, (void *) ((size_t) i->index+1));
|
||||
spec.freq = i->sample_spec.rate;
|
||||
spec.channels = i->sample_spec.channels;
|
||||
spec.format = PulseFormatToSDLFormat(i->sample_spec.format);
|
||||
spec.silence = 0;
|
||||
spec.samples = 0;
|
||||
spec.size = 0;
|
||||
spec.callback = NULL;
|
||||
spec.userdata = NULL;
|
||||
|
||||
SDL_AddAudioDevice(SDL_TRUE, i->description, &spec, (void *) ((size_t) i->index+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -43,6 +43,12 @@ struct SDL_PrivateAudioData
|
||||
Uint8 *mixbuf;
|
||||
int mixlen;
|
||||
|
||||
/* Pointer to the actual buffer in use in the current
|
||||
GetDeviceBuf() -> PlayDevice() iteration.
|
||||
Can be either the pointer returned by pa_stream_begin_write()
|
||||
or mixbuf */
|
||||
void *pabuf;
|
||||
|
||||
const Uint8 *capturebuf;
|
||||
int capturelen;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user