mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-16 14:56:00 +00:00
audio: WaitDevice/WaitCaptureDevice now returns a result.
This is an attempt to centralize all the error handling, instead of implicitly counting on WaitDevice implementations to disconnect the device to report an error.
This commit is contained in:
@@ -524,9 +524,9 @@ void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device)
|
|||||||
// stubs for audio drivers that don't need a specific entry point...
|
// stubs for audio drivers that don't need a specific entry point...
|
||||||
|
|
||||||
static void SDL_AudioThreadDeinit_Default(SDL_AudioDevice *device) { /* no-op. */ }
|
static void SDL_AudioThreadDeinit_Default(SDL_AudioDevice *device) { /* no-op. */ }
|
||||||
static void SDL_AudioWaitDevice_Default(SDL_AudioDevice *device) { /* no-op. */ }
|
static int SDL_AudioWaitDevice_Default(SDL_AudioDevice *device) { return 0; /* no-op. */ }
|
||||||
static int SDL_AudioPlayDevice_Default(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) { return 0; /* no-op. */ }
|
static int SDL_AudioPlayDevice_Default(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size) { return 0; /* no-op. */ }
|
||||||
static void SDL_AudioWaitCaptureDevice_Default(SDL_AudioDevice *device) { /* no-op. */ }
|
static int SDL_AudioWaitCaptureDevice_Default(SDL_AudioDevice *device) { return 0; /* no-op. */ }
|
||||||
static void SDL_AudioFlushCapture_Default(SDL_AudioDevice *device) { /* no-op. */ }
|
static void SDL_AudioFlushCapture_Default(SDL_AudioDevice *device) { /* no-op. */ }
|
||||||
static void SDL_AudioCloseDevice_Default(SDL_AudioDevice *device) { /* no-op. */ }
|
static void SDL_AudioCloseDevice_Default(SDL_AudioDevice *device) { /* no-op. */ }
|
||||||
static void SDL_AudioDeinitialize_Default(void) { /* no-op. */ }
|
static void SDL_AudioDeinitialize_Default(void) { /* no-op. */ }
|
||||||
@@ -938,7 +938,10 @@ static int SDLCALL OutputAudioThread(void *devicep) // thread entry point
|
|||||||
SDL_assert(!device->iscapture);
|
SDL_assert(!device->iscapture);
|
||||||
SDL_OutputAudioThreadSetup(device);
|
SDL_OutputAudioThreadSetup(device);
|
||||||
do {
|
do {
|
||||||
current_audio.impl.WaitDevice(device);
|
if (current_audio.impl.WaitDevice(device) < 0) {
|
||||||
|
SDL_AudioDeviceDisconnected(device); // doh.
|
||||||
|
break;
|
||||||
|
}
|
||||||
} while (SDL_OutputAudioThreadIterate(device));
|
} while (SDL_OutputAudioThreadIterate(device));
|
||||||
|
|
||||||
SDL_OutputAudioThreadShutdown(device);
|
SDL_OutputAudioThreadShutdown(device);
|
||||||
@@ -1039,7 +1042,10 @@ static int SDLCALL CaptureAudioThread(void *devicep) // thread entry point
|
|||||||
SDL_CaptureAudioThreadSetup(device);
|
SDL_CaptureAudioThreadSetup(device);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
current_audio.impl.WaitCaptureDevice(device);
|
if (current_audio.impl.WaitCaptureDevice(device) < 0) {
|
||||||
|
SDL_AudioDeviceDisconnected(device); // doh.
|
||||||
|
break;
|
||||||
|
}
|
||||||
} while (SDL_CaptureAudioThreadIterate(device));
|
} while (SDL_CaptureAudioThreadIterate(device));
|
||||||
|
|
||||||
SDL_CaptureAudioThreadShutdown(device);
|
SDL_CaptureAudioThreadShutdown(device);
|
||||||
|
@@ -128,10 +128,10 @@ typedef struct SDL_AudioDriverImpl
|
|||||||
int (*OpenDevice)(SDL_AudioDevice *device);
|
int (*OpenDevice)(SDL_AudioDevice *device);
|
||||||
void (*ThreadInit)(SDL_AudioDevice *device); // Called by audio thread at start
|
void (*ThreadInit)(SDL_AudioDevice *device); // Called by audio thread at start
|
||||||
void (*ThreadDeinit)(SDL_AudioDevice *device); // Called by audio thread at end
|
void (*ThreadDeinit)(SDL_AudioDevice *device); // Called by audio thread at end
|
||||||
void (*WaitDevice)(SDL_AudioDevice *device);
|
int (*WaitDevice)(SDL_AudioDevice *device);
|
||||||
int (*PlayDevice)(SDL_AudioDevice *device, const Uint8 *buffer, int buflen); // buffer and buflen are always from GetDeviceBuf, passed here for convenience.
|
int (*PlayDevice)(SDL_AudioDevice *device, const Uint8 *buffer, int buflen); // buffer and buflen are always from GetDeviceBuf, passed here for convenience.
|
||||||
Uint8 *(*GetDeviceBuf)(SDL_AudioDevice *device, int *buffer_size);
|
Uint8 *(*GetDeviceBuf)(SDL_AudioDevice *device, int *buffer_size);
|
||||||
void (*WaitCaptureDevice)(SDL_AudioDevice *device);
|
int (*WaitCaptureDevice)(SDL_AudioDevice *device);
|
||||||
int (*CaptureFromDevice)(SDL_AudioDevice *device, void *buffer, int buflen);
|
int (*CaptureFromDevice)(SDL_AudioDevice *device, void *buffer, int buflen);
|
||||||
void (*FlushCapture)(SDL_AudioDevice *device);
|
void (*FlushCapture)(SDL_AudioDevice *device);
|
||||||
void (*CloseDevice)(SDL_AudioDevice *device);
|
void (*CloseDevice)(SDL_AudioDevice *device);
|
||||||
|
@@ -164,9 +164,10 @@ static Uint8 *AAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *bufsize)
|
|||||||
return &hidden->mixbuf[offset];
|
return &hidden->mixbuf[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AAUDIO_WaitDevice(SDL_AudioDevice *device)
|
static int AAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
SDL_WaitSemaphore(device->hidden->semaphore);
|
SDL_WaitSemaphore(device->hidden->semaphore);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int BuildAAudioStream(SDL_AudioDevice *device);
|
static int BuildAAudioStream(SDL_AudioDevice *device);
|
||||||
|
@@ -326,7 +326,7 @@ static void no_swizzle(SDL_AudioDevice *device, void *buffer, Uint32 bufferlen)
|
|||||||
#endif // SND_CHMAP_API_VERSION
|
#endif // SND_CHMAP_API_VERSION
|
||||||
|
|
||||||
// This function waits until it is possible to write a full sound buffer
|
// This function waits until it is possible to write a full sound buffer
|
||||||
static void ALSA_WaitDevice(SDL_AudioDevice *device)
|
static int ALSA_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
const int fulldelay = (int) ((((Uint64) device->sample_frames) * 1000) / device->spec.freq);
|
const int fulldelay = (int) ((((Uint64) device->sample_frames) * 1000) / device->spec.freq);
|
||||||
const int delay = SDL_max(fulldelay, 10);
|
const int delay = SDL_max(fulldelay, 10);
|
||||||
@@ -338,9 +338,9 @@ static void ALSA_WaitDevice(SDL_AudioDevice *device)
|
|||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
// Hmm, not much we can do - abort
|
// Hmm, not much we can do - abort
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "ALSA: snd_pcm_wait failed (unrecoverable): %s", ALSA_snd_strerror(rc));
|
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "ALSA: snd_pcm_wait failed (unrecoverable): %s", ALSA_snd_strerror(rc));
|
||||||
SDL_AudioDeviceDisconnected(device);
|
return -1;
|
||||||
}
|
}
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
@@ -349,6 +349,8 @@ static void ALSA_WaitDevice(SDL_AudioDevice *device)
|
|||||||
|
|
||||||
// Timed out! Make sure we aren't shutting down and then wait again.
|
// Timed out! Make sure we aren't shutting down and then wait again.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ALSA_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
static int ALSA_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
||||||
|
@@ -225,7 +225,7 @@ static void DSOUND_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSOUND_WaitDevice(SDL_AudioDevice *device)
|
static int DSOUND_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
/* Semi-busy wait, since we have no way of getting play notification
|
/* Semi-busy wait, since we have no way of getting play notification
|
||||||
on a primary mixing buffer located in hardware (DirectX 5.0)
|
on a primary mixing buffer located in hardware (DirectX 5.0)
|
||||||
@@ -251,12 +251,13 @@ static void DSOUND_WaitDevice(SDL_AudioDevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((result != DS_OK) && (result != DSERR_BUFFERLOST)) {
|
if ((result != DS_OK) && (result != DSERR_BUFFERLOST)) {
|
||||||
SDL_AudioDeviceDisconnected(device);
|
return -1;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Delay(1); // not ready yet; sleep a bit.
|
SDL_Delay(1); // not ready yet; sleep a bit.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DSOUND_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
static int DSOUND_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
||||||
@@ -328,19 +329,20 @@ static Uint8 *DSOUND_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
|||||||
return device->hidden->locked_buf;
|
return device->hidden->locked_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSOUND_WaitCaptureDevice(SDL_AudioDevice *device)
|
static int DSOUND_WaitCaptureDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = device->hidden;
|
struct SDL_PrivateAudioData *h = device->hidden;
|
||||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||||
DWORD junk, cursor;
|
DWORD junk, cursor;
|
||||||
if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) {
|
if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) {
|
||||||
SDL_AudioDeviceDisconnected(device);
|
return -1;
|
||||||
return;
|
|
||||||
} else if ((cursor / device->buffer_size) != h->lastchunk) {
|
} else if ((cursor / device->buffer_size) != h->lastchunk) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
SDL_Delay(1);
|
SDL_Delay(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DSOUND_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
static int DSOUND_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
||||||
|
@@ -35,9 +35,10 @@
|
|||||||
#define DISKDEFAULT_INFILE "sdlaudio-in.raw"
|
#define DISKDEFAULT_INFILE "sdlaudio-in.raw"
|
||||||
#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY"
|
#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY"
|
||||||
|
|
||||||
static void DISKAUDIO_WaitDevice(SDL_AudioDevice *device)
|
static int DISKAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
SDL_Delay(device->hidden->io_delay);
|
SDL_Delay(device->hidden->io_delay);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DISKAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size)
|
static int DISKAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size)
|
||||||
|
@@ -201,7 +201,7 @@ static int DSP_OpenDevice(SDL_AudioDevice *device)
|
|||||||
return 0; // We're ready to rock and roll. :-)
|
return 0; // We're ready to rock and roll. :-)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DSP_WaitDevice(SDL_AudioDevice *device)
|
static int DSP_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
const unsigned long ioctlreq = device->iscapture ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE;
|
const unsigned long ioctlreq = device->iscapture ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE;
|
||||||
struct SDL_PrivateAudioData *h = device->hidden;
|
struct SDL_PrivateAudioData *h = device->hidden;
|
||||||
@@ -215,14 +215,15 @@ static void DSP_WaitDevice(SDL_AudioDevice *device)
|
|||||||
}
|
}
|
||||||
// Hmm, not much we can do - abort
|
// Hmm, not much we can do - abort
|
||||||
fprintf(stderr, "dsp WaitDevice ioctl failed (unrecoverable): %s\n", strerror(errno));
|
fprintf(stderr, "dsp WaitDevice ioctl failed (unrecoverable): %s\n", strerror(errno));
|
||||||
SDL_AudioDeviceDisconnected(device);
|
return -1;
|
||||||
return;
|
|
||||||
} else if (info.bytes < device->buffer_size) {
|
} else if (info.bytes < device->buffer_size) {
|
||||||
SDL_Delay(10);
|
SDL_Delay(10);
|
||||||
} else {
|
} else {
|
||||||
break; // ready to go!
|
break; // ready to go!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DSP_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
static int DSP_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
||||||
|
@@ -28,9 +28,10 @@
|
|||||||
// !!! FIXME: this should be an SDL hint, not an environment variable.
|
// !!! FIXME: this should be an SDL hint, not an environment variable.
|
||||||
#define DUMMYENVR_IODELAY "SDL_DUMMYAUDIODELAY"
|
#define DUMMYENVR_IODELAY "SDL_DUMMYAUDIODELAY"
|
||||||
|
|
||||||
static void DUMMYAUDIO_WaitDevice(SDL_AudioDevice *device)
|
static int DUMMYAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
SDL_Delay(device->hidden->io_delay);
|
SDL_Delay(device->hidden->io_delay);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int DUMMYAUDIO_OpenDevice(SDL_AudioDevice *device)
|
static int DUMMYAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||||
|
@@ -200,7 +200,7 @@ static int N3DSAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, in
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void N3DSAUDIO_WaitDevice(SDL_AudioDevice *device)
|
static int N3DSAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
contextLock(device);
|
contextLock(device);
|
||||||
while (!device->hidden->isCancelled && !SDL_AtomicGet(&device->shutdown) &&
|
while (!device->hidden->isCancelled && !SDL_AtomicGet(&device->shutdown) &&
|
||||||
@@ -208,6 +208,7 @@ static void N3DSAUDIO_WaitDevice(SDL_AudioDevice *device)
|
|||||||
CondVar_Wait(&device->hidden->cv, &device->hidden->lock);
|
CondVar_Wait(&device->hidden->cv, &device->hidden->lock);
|
||||||
}
|
}
|
||||||
contextUnlock(device);
|
contextUnlock(device);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *N3DSAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
static Uint8 *N3DSAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
||||||
|
@@ -115,7 +115,7 @@ static void NETBSDAUDIO_Status(SDL_AudioDevice *device)
|
|||||||
#endif // DEBUG_AUDIO
|
#endif // DEBUG_AUDIO
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NETBSDAUDIO_WaitDevice(SDL_AudioDevice *device)
|
static int NETBSDAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
const SDL_bool iscapture = device->iscapture;
|
const SDL_bool iscapture = device->iscapture;
|
||||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||||
@@ -127,8 +127,7 @@ static void NETBSDAUDIO_WaitDevice(SDL_AudioDevice *device)
|
|||||||
}
|
}
|
||||||
// Hmm, not much we can do - abort
|
// Hmm, not much we can do - abort
|
||||||
fprintf(stderr, "netbsdaudio WaitDevice ioctl failed (unrecoverable): %s\n", strerror(errno));
|
fprintf(stderr, "netbsdaudio WaitDevice ioctl failed (unrecoverable): %s\n", strerror(errno));
|
||||||
SDL_AudioDeviceDisconnected(device);
|
return -1;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const size_t remain = (size_t)((iscapture ? info.record.seek : info.play.seek) * SDL_AUDIO_BYTESIZE(device->spec.format));
|
const size_t remain = (size_t)((iscapture ? info.record.seek : info.play.seek) * SDL_AUDIO_BYTESIZE(device->spec.format));
|
||||||
if (!iscapture && (remain >= device->buffer_size)) {
|
if (!iscapture && (remain >= device->buffer_size)) {
|
||||||
@@ -139,6 +138,8 @@ static void NETBSDAUDIO_WaitDevice(SDL_AudioDevice *device)
|
|||||||
break; /* ready to go! */
|
break; /* ready to go! */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int NETBSDAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
static int NETBSDAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
||||||
|
@@ -628,14 +628,14 @@ static int openslES_OpenDevice(SDL_AudioDevice *device)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void openslES_WaitDevice(SDL_AudioDevice *device)
|
static int openslES_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *audiodata = device->hidden;
|
struct SDL_PrivateAudioData *audiodata = device->hidden;
|
||||||
|
|
||||||
LOGV("openslES_WaitDevice()");
|
LOGV("openslES_WaitDevice()");
|
||||||
|
|
||||||
// Wait for an audio chunk to finish
|
// Wait for an audio chunk to finish
|
||||||
SDL_WaitSemaphore(audiodata->playsem);
|
return SDL_WaitSemaphore(audiodata->playsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int openslES_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
static int openslES_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
||||||
|
@@ -91,9 +91,10 @@ static int PS2AUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int
|
|||||||
return (audsrv_play_audio((char *)buffer, buflen) != buflen) ? -1 : 0;
|
return (audsrv_play_audio((char *)buffer, buflen) != buflen) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PS2AUDIO_WaitDevice(SDL_AudioDevice *device)
|
static int PS2AUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
audsrv_wait_audio(device->buffer_size);
|
audsrv_wait_audio(device->buffer_size);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *PS2AUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
static Uint8 *PS2AUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
||||||
|
@@ -118,9 +118,9 @@ static int PSPAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int
|
|||||||
return (rc == 0) ? 0 : -1;
|
return (rc == 0) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PSPAUDIO_WaitDevice(SDL_AudioDevice *device)
|
static int PSPAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
// Because we block when sending audio, there's no need for this function to do anything.
|
return 0; // Because we block when sending audio, there's no need for this function to do anything.
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *PSPAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
static Uint8 *PSPAUDIO_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
||||||
|
@@ -396,9 +396,10 @@ static void WriteCallback(pa_stream *p, size_t nbytes, void *userdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This function waits until it is possible to write a full sound buffer */
|
/* This function waits until it is possible to write a full sound buffer */
|
||||||
static void PULSEAUDIO_WaitDevice(SDL_AudioDevice *device)
|
static int PULSEAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = device->hidden;
|
struct SDL_PrivateAudioData *h = device->hidden;
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
/*printf("PULSEAUDIO PLAYDEVICE START! mixlen=%d\n", available);*/
|
/*printf("PULSEAUDIO PLAYDEVICE START! mixlen=%d\n", available);*/
|
||||||
|
|
||||||
@@ -410,11 +411,14 @@ static void PULSEAUDIO_WaitDevice(SDL_AudioDevice *device)
|
|||||||
|
|
||||||
if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
|
if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
|
||||||
/*printf("PULSEAUDIO DEVICE FAILURE IN WAITDEVICE!\n");*/
|
/*printf("PULSEAUDIO DEVICE FAILURE IN WAITDEVICE!\n");*/
|
||||||
SDL_AudioDeviceDisconnected(device);
|
retval = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PULSEAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size)
|
static int PULSEAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size)
|
||||||
@@ -462,21 +466,23 @@ static void ReadCallback(pa_stream *p, size_t nbytes, void *userdata)
|
|||||||
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); /* the capture code queries what it needs, we just need to signal to end any wait */
|
PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); /* the capture code queries what it needs, we just need to signal to end any wait */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PULSEAUDIO_WaitCaptureDevice(SDL_AudioDevice *device)
|
static int PULSEAUDIO_WaitCaptureDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
struct SDL_PrivateAudioData *h = device->hidden;
|
struct SDL_PrivateAudioData *h = device->hidden;
|
||||||
|
|
||||||
if (h->capturebuf != NULL) {
|
if (h->capturebuf != NULL) {
|
||||||
return; // there's still data available to read.
|
return 0; // there's still data available to read.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
|
||||||
|
|
||||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||||
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
|
||||||
if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
|
if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
|
||||||
//printf("PULSEAUDIO DEVICE FAILURE IN WAITCAPTUREDEVICE!\n");
|
//printf("PULSEAUDIO DEVICE FAILURE IN WAITCAPTUREDEVICE!\n");
|
||||||
SDL_AudioDeviceDisconnected(device);
|
retval = -1;
|
||||||
break;
|
break;
|
||||||
} else if (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0) {
|
} else if (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0) {
|
||||||
// a new fragment is available!
|
// a new fragment is available!
|
||||||
@@ -497,6 +503,8 @@ static void PULSEAUDIO_WaitCaptureDevice(SDL_AudioDevice *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);
|
||||||
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PULSEAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
static int PULSEAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
||||||
|
@@ -86,21 +86,19 @@ static void QSA_InitAudioParams(snd_pcm_channel_params_t * cpars)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This function waits until it is possible to write a full sound buffer
|
// This function waits until it is possible to write a full sound buffer
|
||||||
static void QSA_WaitDevice(SDL_AudioDevice *device)
|
static int QSA_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
int result;
|
|
||||||
|
|
||||||
// Setup timeout for playing one fragment equal to 2 seconds
|
// Setup timeout for playing one fragment equal to 2 seconds
|
||||||
// If timeout occurred than something wrong with hardware or driver
|
// If timeout occurred than something wrong with hardware or driver
|
||||||
// For example, Vortex 8820 audio driver stucks on second DAC because
|
// For example, Vortex 8820 audio driver stucks on second DAC because
|
||||||
// it doesn't exist !
|
// it doesn't exist !
|
||||||
result = SDL_IOReady(device->hidden->audio_fd,
|
const int result = SDL_IOReady(device->hidden->audio_fd,
|
||||||
device->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE,
|
device->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE,
|
||||||
2 * 1000);
|
2 * 1000);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case -1:
|
case -1:
|
||||||
SDL_SetError("QSA: SDL_IOReady() failed: %s", strerror(errno)); // !!! FIXME: Should we just disconnect the device in this case?
|
SDL_LogError(SDL_LOG_CATEGORY_AUDIO, "QSA: SDL_IOReady() failed: %s", strerror(errno));
|
||||||
break;
|
return -1;
|
||||||
case 0:
|
case 0:
|
||||||
device->hidden->timeout_on_wait = SDL_TRUE; // !!! FIXME: Should we just disconnect the device in this case?
|
device->hidden->timeout_on_wait = SDL_TRUE; // !!! FIXME: Should we just disconnect the device in this case?
|
||||||
break;
|
break;
|
||||||
@@ -108,6 +106,8 @@ static void QSA_WaitDevice(SDL_AudioDevice *device)
|
|||||||
device->hidden->timeout_on_wait = SDL_FALSE;
|
device->hidden->timeout_on_wait = SDL_FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int QSA_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
static int QSA_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
||||||
|
@@ -147,32 +147,31 @@ static int LoadSNDIOLibrary(void)
|
|||||||
|
|
||||||
#endif // SDL_AUDIO_DRIVER_SNDIO_DYNAMIC
|
#endif // SDL_AUDIO_DRIVER_SNDIO_DYNAMIC
|
||||||
|
|
||||||
static void SNDIO_WaitDevice(SDL_AudioDevice *device)
|
static int SNDIO_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
const SDL_bool iscapture = device->iscapture;
|
const SDL_bool iscapture = device->iscapture;
|
||||||
|
|
||||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||||
if (SNDIO_sio_eof(device->hidden->dev)) {
|
if (SNDIO_sio_eof(device->hidden->dev)) {
|
||||||
SDL_AudioDeviceDisconnected(device);
|
return -1;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int nfds = SNDIO_sio_pollfd(device->hidden->dev, device->hidden->pfd, iscapture ? POLLIN : POLLOUT);
|
const int nfds = SNDIO_sio_pollfd(device->hidden->dev, device->hidden->pfd, iscapture ? POLLIN : POLLOUT);
|
||||||
if (nfds <= 0 || poll(device->hidden->pfd, nfds, 10) < 0) {
|
if (nfds <= 0 || poll(device->hidden->pfd, nfds, 10) < 0) {
|
||||||
SDL_AudioDeviceDisconnected(device);
|
return -1;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int revents = SNDIO_sio_revents(device->hidden->dev, device->hidden->pfd);
|
const int revents = SNDIO_sio_revents(device->hidden->dev, device->hidden->pfd);
|
||||||
if (iscapture && (revents & POLLIN)) {
|
if (iscapture && (revents & POLLIN)) {
|
||||||
return;
|
break;
|
||||||
} else if (!iscapture && (revents & POLLOUT)) {
|
} else if (!iscapture && (revents & POLLOUT)) {
|
||||||
return;
|
break;
|
||||||
} else if (revents & POLLHUP) {
|
} else if (revents & POLLHUP) {
|
||||||
SDL_AudioDeviceDisconnected(device);
|
return -1;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SNDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
static int SNDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buflen)
|
||||||
|
@@ -136,12 +136,13 @@ static int VITAAUD_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This function waits until it is possible to write a full sound buffer
|
// This function waits until it is possible to write a full sound buffer
|
||||||
static void VITAAUD_WaitDevice(SDL_AudioDevice *device)
|
static int VITAAUD_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
// !!! FIXME: we might just need to sleep roughly as long as playback buffers take to process, based on sample rate, etc.
|
// !!! FIXME: we might just need to sleep roughly as long as playback buffers take to process, based on sample rate, etc.
|
||||||
while (!SDL_AtomicGet(&device->shutdown) && (sceAudioOutGetRestSample(device->hidden->port) >= device->buffer_size)) {
|
while (!SDL_AtomicGet(&device->shutdown) && (sceAudioOutGetRestSample(device->hidden->port) >= device->buffer_size)) {
|
||||||
SDL_Delay(1);
|
SDL_Delay(1);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint8 *VITAAUD_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
static Uint8 *VITAAUD_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
||||||
@@ -172,7 +173,7 @@ static void VITAAUD_CloseDevice(SDL_AudioDevice *device)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void VITAAUD_WaitCaptureDevice(SDL_AudioDevice *device)
|
static int VITAAUD_WaitCaptureDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
// there's only a blocking call to obtain more data, so we'll just sleep as
|
// there's only a blocking call to obtain more data, so we'll just sleep as
|
||||||
// long as a buffer would run.
|
// long as a buffer would run.
|
||||||
@@ -180,6 +181,7 @@ static void VITAAUD_WaitCaptureDevice(SDL_AudioDevice *device)
|
|||||||
while (!SDL_AtomicGet(&device->shutdown) && (SDL_GetTicks() < endticks)) {
|
while (!SDL_AtomicGet(&device->shutdown) && (SDL_GetTicks() < endticks)) {
|
||||||
SDL_Delay(1);
|
SDL_Delay(1);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int VITAAUD_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
static int VITAAUD_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
||||||
|
@@ -431,7 +431,7 @@ static int WASAPI_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int b
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WASAPI_WaitDevice(SDL_AudioDevice *device)
|
static int WASAPI_WaitDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
// WaitDevice does not hold the device lock, so check for recovery/disconnect details here.
|
// WaitDevice does not hold the device lock, so check for recovery/disconnect details here.
|
||||||
while (RecoverWasapiIfLost(device) && device->hidden->client && device->hidden->event) {
|
while (RecoverWasapiIfLost(device) && device->hidden->client && device->hidden->event) {
|
||||||
@@ -450,9 +450,11 @@ static void WASAPI_WaitDevice(SDL_AudioDevice *device)
|
|||||||
} else if (waitResult != WAIT_TIMEOUT) {
|
} else if (waitResult != WAIT_TIMEOUT) {
|
||||||
//SDL_Log("WASAPI FAILED EVENT!");*/
|
//SDL_Log("WASAPI FAILED EVENT!");*/
|
||||||
IAudioClient_Stop(device->hidden->client);
|
IAudioClient_Stop(device->hidden->client);
|
||||||
WASAPI_DisconnectDevice(device);
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int WASAPI_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
static int WASAPI_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, int buflen)
|
||||||
|
Reference in New Issue
Block a user