mirror of
https://github.com/libretro/RetroArch
synced 2025-02-26 15:39:55 +00:00
(Audio driver) Add 'alive' function callback
This commit is contained in:
parent
a0497ac50e
commit
a35c61ec90
36
audio/alsa.c
36
audio/alsa.c
@ -202,18 +202,27 @@ static ssize_t alsa_write(void *data, const void *buf_, size_t size_)
|
||||
return written;
|
||||
}
|
||||
|
||||
static bool alsa_alive(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
if (alsa)
|
||||
return !alsa->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool alsa_stop(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
|
||||
if (alsa->can_pause && !alsa->is_paused)
|
||||
if (alsa->can_pause
|
||||
&& !alsa->is_paused)
|
||||
{
|
||||
if (snd_pcm_pause(alsa->pcm, 1) == 0)
|
||||
{
|
||||
alsa->is_paused = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
int ret = snd_pcm_pause(alsa->pcm, 1);
|
||||
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
alsa->is_paused = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -228,20 +237,20 @@ static void alsa_set_nonblock_state(void *data, bool state)
|
||||
static bool alsa_start(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
if (alsa->can_pause && alsa->is_paused)
|
||||
|
||||
if (alsa->can_pause
|
||||
&& alsa->is_paused)
|
||||
{
|
||||
int ret = snd_pcm_pause(alsa->pcm, 0);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA]: Failed to unpause: %s.\n",
|
||||
snd_strerror(ret));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
alsa->is_paused = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
alsa->is_paused = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -289,6 +298,7 @@ audio_driver_t audio_alsa = {
|
||||
alsa_write,
|
||||
alsa_stop,
|
||||
alsa_start,
|
||||
alsa_alive,
|
||||
alsa_set_nonblock_state,
|
||||
alsa_free,
|
||||
alsa_use_float,
|
||||
|
@ -273,12 +273,40 @@ static bool alsa_qsa_stop(void *data)
|
||||
|
||||
if (alsa->can_pause && !alsa->is_paused)
|
||||
{
|
||||
if (snd_pcm_playback_pause(alsa->pcm) == 0)
|
||||
int ret = snd_pcm_playback_pause(alsa->pcm);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
alsa->is_paused = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool alsa_qsa_alive(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
if (alsa)
|
||||
return !alsa->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool alsa_qsa_start(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
|
||||
if (alsa->can_pause && alsa->is_paused)
|
||||
{
|
||||
int ret = snd_pcm_playback_resume(alsa->pcm);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
alsa->is_paused = true;
|
||||
return true;
|
||||
RARCH_ERR("[ALSA QSA]: Failed to unpause: %s.\n",
|
||||
snd_strerror(ret));
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
alsa->is_paused = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -300,28 +328,6 @@ static void alsa_qsa_set_nonblock_state(void *data, bool state)
|
||||
alsa->nonblock = state;
|
||||
}
|
||||
|
||||
static bool alsa_qsa_start(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
|
||||
if (alsa->can_pause && alsa->is_paused)
|
||||
{
|
||||
int ret = snd_pcm_playback_resume(alsa->pcm);
|
||||
if (ret < 0)
|
||||
{
|
||||
RARCH_ERR("[ALSA QSA]: Failed to unpause: %s.\n",
|
||||
snd_strerror(ret));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
alsa->is_paused = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool alsa_qsa_use_float(void *data)
|
||||
{
|
||||
@ -366,6 +372,7 @@ audio_driver_t audio_alsa = {
|
||||
alsa_qsa_write,
|
||||
alsa_qsa_stop,
|
||||
alsa_qsa_start,
|
||||
alsa_qsa_alive,
|
||||
alsa_qsa_set_nonblock_state,
|
||||
alsa_qsa_free,
|
||||
alsa_qsa_use_float,
|
||||
|
@ -30,6 +30,7 @@ typedef struct alsa_thread
|
||||
{
|
||||
snd_pcm_t *pcm;
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
bool has_float;
|
||||
volatile bool thread_dead;
|
||||
|
||||
@ -280,9 +281,20 @@ static ssize_t alsa_thread_write(void *data, const void *buf, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
static bool alsa_thread_alive(void *data)
|
||||
{
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||
if (alsa)
|
||||
return !alsa->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool alsa_thread_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||
|
||||
if (alsa)
|
||||
alsa->is_paused = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -294,7 +306,10 @@ static void alsa_thread_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static bool alsa_thread_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||
|
||||
if (alsa)
|
||||
alsa->is_paused = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -321,6 +336,7 @@ audio_driver_t audio_alsathread = {
|
||||
alsa_thread_write,
|
||||
alsa_thread_stop,
|
||||
alsa_thread_start,
|
||||
alsa_thread_alive,
|
||||
alsa_thread_set_nonblock_state,
|
||||
alsa_thread_free,
|
||||
alsa_thread_use_float,
|
||||
|
@ -43,6 +43,7 @@ typedef struct coreaudio
|
||||
AudioComponentInstance dev;
|
||||
#endif
|
||||
bool dev_alive;
|
||||
bool is_paused;
|
||||
|
||||
fifo_buffer_t *buffer;
|
||||
bool nonblock;
|
||||
@ -363,22 +364,32 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
|
||||
return written;
|
||||
}
|
||||
|
||||
static bool coreaudio_stop(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
return AudioOutputUnitStop(dev->dev) == noErr;
|
||||
}
|
||||
|
||||
static void coreaudio_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
dev->nonblock = state;
|
||||
}
|
||||
|
||||
static bool coreaudio_alive(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
if (dev)
|
||||
return !dev->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool coreaudio_stop(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
dev->is_paused = (AudioOutputUnitStop(dev->dev) == noErr) ? true : false;
|
||||
return dev->is_paused ? true : false;
|
||||
}
|
||||
|
||||
static bool coreaudio_start(void *data)
|
||||
{
|
||||
coreaudio_t *dev = (coreaudio_t*)data;
|
||||
return AudioOutputUnitStart(dev->dev) == noErr;
|
||||
dev->is_paused = (AudioOutputUnitStart(dev->dev) == noErr) ? false : true;
|
||||
return dev->is_paused ? false : true;
|
||||
}
|
||||
|
||||
static bool coreaudio_use_float(void *data)
|
||||
@ -407,6 +418,7 @@ audio_driver_t audio_coreaudio = {
|
||||
coreaudio_write,
|
||||
coreaudio_stop,
|
||||
coreaudio_start,
|
||||
coreaudio_alive,
|
||||
coreaudio_set_nonblock_state,
|
||||
coreaudio_free,
|
||||
coreaudio_use_float,
|
||||
|
@ -69,6 +69,7 @@ typedef struct dsound
|
||||
unsigned buffer_size;
|
||||
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
volatile bool thread_alive;
|
||||
} dsound_t;
|
||||
|
||||
@ -384,7 +385,8 @@ static bool dsound_stop(void *data)
|
||||
{
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
dsound_stop_thread(ds);
|
||||
return IDirectSoundBuffer_Stop(ds->dsb) == DS_OK;
|
||||
ds->is_paused = (IDirectSoundBuffer_Stop(ds->dsb) == DS_OK) ? true : false;
|
||||
return (ds->is_paused) ? true : false;
|
||||
}
|
||||
|
||||
static bool dsound_start(void *data)
|
||||
@ -395,7 +397,16 @@ static bool dsound_start(void *data)
|
||||
if (!dsound_start_thread(ds))
|
||||
return false;
|
||||
|
||||
return IDirectSoundBuffer_Play(ds->dsb, 0, 0, DSBPLAY_LOOPING) == DS_OK;
|
||||
ds->is_paused = (IDirectSoundBuffer_Play(ds->dsb, 0, 0, DSBPLAY_LOOPING) == DS_OK) ? false : true;
|
||||
return (ds->is_paused) ? false : true;
|
||||
}
|
||||
|
||||
static bool dsound_alive(void *data)
|
||||
{
|
||||
dsound_t *ds = (dsound_t*)data;
|
||||
if (ds)
|
||||
return !ds->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dsound_set_nonblock_state(void *data, bool state)
|
||||
@ -462,6 +473,7 @@ audio_driver_t audio_dsound = {
|
||||
dsound_write,
|
||||
dsound_stop,
|
||||
dsound_start,
|
||||
dsound_alive,
|
||||
dsound_set_nonblock_state,
|
||||
dsound_free,
|
||||
dsound_use_float,
|
||||
|
@ -53,6 +53,7 @@ typedef struct
|
||||
|
||||
OSCond cond;
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
} gx_audio_t;
|
||||
|
||||
static volatile gx_audio_t *gx_audio_data;
|
||||
@ -163,6 +164,7 @@ static bool gx_audio_stop(void *data)
|
||||
AIStopDMA();
|
||||
memset(wa->data, 0, sizeof(wa->data));
|
||||
DCFlushRange(wa->data, sizeof(wa->data));
|
||||
wa->is_paused = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -178,11 +180,20 @@ static void gx_audio_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static bool gx_audio_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
gx_audio_t *wa = (gx_audio_t*)data;
|
||||
AIStartDMA();
|
||||
wa->is_paused = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gx_audio_alive(void *data)
|
||||
{
|
||||
gx_audio_t *wa = (gx_audio_t*)data;
|
||||
if (wa)
|
||||
return !wa->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gx_audio_free(void *data)
|
||||
{
|
||||
gx_audio_t *wa = (gx_audio_t*)data;
|
||||
@ -225,6 +236,7 @@ audio_driver_t audio_gx = {
|
||||
gx_audio_write,
|
||||
gx_audio_stop,
|
||||
gx_audio_start,
|
||||
gx_audio_alive,
|
||||
gx_audio_set_nonblock_state,
|
||||
gx_audio_free,
|
||||
gx_audio_use_float,
|
||||
|
18
audio/jack.c
18
audio/jack.c
@ -36,6 +36,7 @@ typedef struct jack
|
||||
jack_ringbuffer_t *buffer[2];
|
||||
volatile bool shutdown;
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t cond_lock;
|
||||
@ -274,10 +275,20 @@ static ssize_t ja_write(void *data, const void *buf, size_t size)
|
||||
|
||||
static bool ja_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
if (jd)
|
||||
jd->is_paused = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ja_alive(void *data)
|
||||
{
|
||||
jack_t *jd = (jack_t*)data;
|
||||
if (jd)
|
||||
return !jd->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ja_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
jack_t *jd = (jack_t*)data;
|
||||
@ -286,7 +297,9 @@ static void ja_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static bool ja_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
jack_t *jd = (jack_t*)data;
|
||||
if (jd)
|
||||
jd->is_paused = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -335,6 +348,7 @@ audio_driver_t audio_jack = {
|
||||
ja_write,
|
||||
ja_stop,
|
||||
ja_start,
|
||||
ja_alive,
|
||||
ja_set_nonblock_state,
|
||||
ja_free,
|
||||
ja_use_float,
|
||||
|
@ -43,6 +43,12 @@ static bool null_audio_stop(void *data)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool null_audio_alive(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool null_audio_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
@ -66,6 +72,7 @@ audio_driver_t audio_null = {
|
||||
null_audio_write,
|
||||
null_audio_stop,
|
||||
null_audio_start,
|
||||
null_audio_alive,
|
||||
null_audio_set_nonblock_state,
|
||||
null_audio_free,
|
||||
null_audio_use_float,
|
||||
|
@ -50,6 +50,7 @@ typedef struct al
|
||||
ALCcontext *ctx;
|
||||
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
} al_t;
|
||||
|
||||
static void al_free(void *data)
|
||||
@ -204,10 +205,20 @@ static ssize_t al_write(void *data, const void *buf_, size_t size)
|
||||
|
||||
static bool al_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
al_t *al = (al_t*)data;
|
||||
if (al)
|
||||
al->is_paused = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool al_alive(void *data)
|
||||
{
|
||||
al_t *al = (al_t*)data;
|
||||
if (al)
|
||||
return !al->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void al_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
al_t *al = (al_t*)data;
|
||||
@ -216,7 +227,9 @@ static void al_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static bool al_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
al_t *al = (al_t*)data;
|
||||
if (al)
|
||||
al->is_paused = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -244,6 +257,7 @@ audio_driver_t audio_openal = {
|
||||
al_write,
|
||||
al_stop,
|
||||
al_start,
|
||||
al_alive,
|
||||
al_set_nonblock_state,
|
||||
al_free,
|
||||
al_use_float,
|
||||
|
@ -52,6 +52,7 @@ typedef struct sl
|
||||
slock_t *lock;
|
||||
scond_t *cond;
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
unsigned buf_size;
|
||||
unsigned buf_count;
|
||||
} sl_t;
|
||||
@ -199,7 +200,16 @@ error:
|
||||
static bool sl_stop(void *data)
|
||||
{
|
||||
sl_t *sl = (sl_t*)data;
|
||||
return SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_STOPPED) == SL_RESULT_SUCCESS;
|
||||
sl->is_paused = (SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_STOPPED) == SL_RESULT_SUCCESS) ? true : false;
|
||||
return sl->is_paused ? true : false;
|
||||
}
|
||||
|
||||
static bool sl_alive(void *data)
|
||||
{
|
||||
sl_t *sl = (sl_t*)data;
|
||||
if (sl)
|
||||
return !sl->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void sl_set_nonblock_state(void *data, bool state)
|
||||
@ -211,7 +221,8 @@ static void sl_set_nonblock_state(void *data, bool state)
|
||||
static bool sl_start(void *data)
|
||||
{
|
||||
sl_t *sl = (sl_t*)data;
|
||||
return SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_PLAYING) == SL_RESULT_SUCCESS;
|
||||
sl->is_paused = (SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_PLAYING) == SL_RESULT_SUCCESS) ? false : true;
|
||||
return sl->is_paused ? false : true;
|
||||
}
|
||||
|
||||
|
||||
@ -289,6 +300,7 @@ audio_driver_t audio_opensl = {
|
||||
sl_write,
|
||||
sl_stop,
|
||||
sl_start,
|
||||
sl_alive,
|
||||
sl_set_nonblock_state,
|
||||
sl_free,
|
||||
sl_use_float,
|
||||
|
16
audio/oss.c
16
audio/oss.c
@ -39,6 +39,8 @@
|
||||
#define DEFAULT_OSS_DEV "/dev/dsp"
|
||||
#endif
|
||||
|
||||
static bool oss_is_paused;
|
||||
|
||||
static void *oss_init(const char *device, unsigned rate, unsigned latency)
|
||||
{
|
||||
int *fd = (int*)calloc(1, sizeof(int));
|
||||
@ -124,14 +126,23 @@ static bool oss_stop(void *data)
|
||||
{
|
||||
int *fd = (int*)data;
|
||||
ioctl(*fd, SNDCTL_DSP_RESET, 0);
|
||||
oss_is_paused = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool oss_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
oss_is_paused = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool oss_alive(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return !oss_is_paused;
|
||||
}
|
||||
|
||||
static void oss_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
int *fd = (int*)data;
|
||||
@ -155,9 +166,9 @@ static void oss_free(void *data)
|
||||
|
||||
static size_t oss_write_avail(void *data)
|
||||
{
|
||||
audio_buf_info info;
|
||||
int *fd = (int*)data;
|
||||
|
||||
audio_buf_info info;
|
||||
if (ioctl(*fd, SNDCTL_DSP_GETOSPACE, &info) < 0)
|
||||
{
|
||||
RARCH_ERR("SNDCTL_DSP_GETOSPACE failed ...\n");
|
||||
@ -169,9 +180,9 @@ static size_t oss_write_avail(void *data)
|
||||
|
||||
static size_t oss_buffer_size(void *data)
|
||||
{
|
||||
audio_buf_info info;
|
||||
int *fd = (int*)data;
|
||||
|
||||
audio_buf_info info;
|
||||
if (ioctl(*fd, SNDCTL_DSP_GETOSPACE, &info) < 0)
|
||||
{
|
||||
RARCH_ERR("SNDCTL_DSP_GETOSPACE failed ...\n");
|
||||
@ -192,6 +203,7 @@ audio_driver_t audio_oss = {
|
||||
oss_write,
|
||||
oss_stop,
|
||||
oss_start,
|
||||
oss_alive,
|
||||
oss_set_nonblock_state,
|
||||
oss_free,
|
||||
oss_use_float,
|
||||
|
@ -185,6 +185,12 @@ static bool ps3_audio_start(void *data)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ps3_audio_alive(void *data)
|
||||
{
|
||||
ps3_audio_t *aud = data;
|
||||
return aud->started;
|
||||
}
|
||||
|
||||
static void ps3_audio_set_nonblock_state(void *data, bool toggle)
|
||||
{
|
||||
ps3_audio_t *aud = data;
|
||||
@ -223,6 +229,7 @@ audio_driver_t audio_ps3 = {
|
||||
ps3_audio_write,
|
||||
ps3_audio_stop,
|
||||
ps3_audio_start,
|
||||
ps3_audio_alive,
|
||||
ps3_audio_set_nonblock_state,
|
||||
ps3_audio_free,
|
||||
ps3_audio_use_float,
|
||||
|
@ -150,6 +150,14 @@ static ssize_t psp_audio_write(void *data, const void *buf, size_t size)
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
static bool psp_audio_alive(void *data)
|
||||
{
|
||||
psp1_audio_t* psp = (psp1_audio_t*)data;
|
||||
if (psp)
|
||||
return psp->running;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool psp_audio_stop(void *data)
|
||||
{
|
||||
SceKernelThreadRunStatus runStatus;
|
||||
@ -222,6 +230,7 @@ audio_driver_t audio_psp1 = {
|
||||
psp_audio_write,
|
||||
psp_audio_stop,
|
||||
psp_audio_start,
|
||||
psp_audio_alive,
|
||||
psp_audio_set_nonblock_state,
|
||||
psp_audio_free,
|
||||
psp_audio_use_float,
|
||||
|
@ -30,6 +30,7 @@ typedef struct
|
||||
size_t buffer_size;
|
||||
bool nonblock;
|
||||
bool success;
|
||||
bool is_paused;
|
||||
} pa_t;
|
||||
|
||||
static void pulse_free(void *data)
|
||||
@ -254,9 +255,18 @@ static bool pulse_stop(void *data)
|
||||
pa_threaded_mainloop_wait(pa->mainloop);
|
||||
bool ret = pa->success;
|
||||
pa_threaded_mainloop_unlock(pa->mainloop);
|
||||
pa->is_paused = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool pulse_alive(void *data)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
if (pa)
|
||||
return !pa->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pulse_start(void *data)
|
||||
{
|
||||
RARCH_LOG("[PulseAudio]: Unpausing.\n");
|
||||
@ -267,6 +277,7 @@ static bool pulse_start(void *data)
|
||||
pa_threaded_mainloop_wait(pa->mainloop);
|
||||
bool ret = pa->success;
|
||||
pa_threaded_mainloop_unlock(pa->mainloop);
|
||||
pa->is_paused = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -303,6 +314,7 @@ audio_driver_t audio_pulse = {
|
||||
pulse_write,
|
||||
pulse_stop,
|
||||
pulse_start,
|
||||
pulse_alive,
|
||||
pulse_set_nonblock_state,
|
||||
pulse_free,
|
||||
pulse_use_float,
|
||||
|
17
audio/roar.c
17
audio/roar.c
@ -78,10 +78,20 @@ static ssize_t ra_write(void *data, const void *buf, size_t size)
|
||||
|
||||
static bool ra_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
roar_t *roar = (roar_t*)data;
|
||||
if (roar)
|
||||
roar->is_paused = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ra_alive(void *data)
|
||||
{
|
||||
roar_t *roar = (roar_t*)data;
|
||||
if (roar)
|
||||
return !roar->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ra_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
roar_t *roar = (roar_t*)data;
|
||||
@ -92,7 +102,9 @@ static void ra_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static bool ra_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
roar_t *roar = (roar_t*)data;
|
||||
if (roar)
|
||||
roar->is_paused = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -114,6 +126,7 @@ audio_driver_t audio_roar = {
|
||||
ra_write,
|
||||
ra_stop,
|
||||
ra_start,
|
||||
ra_alive,
|
||||
ra_set_nonblock_state,
|
||||
ra_free,
|
||||
ra_use_float,
|
||||
|
@ -25,6 +25,7 @@ typedef struct rsd
|
||||
{
|
||||
rsound_t *rd;
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
volatile bool has_error;
|
||||
|
||||
fifo_buffer_t *buffer;
|
||||
@ -146,6 +147,7 @@ static bool rs_stop(void *data)
|
||||
{
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
rsd_stop(rsd->rd);
|
||||
rsd->is_paused = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -156,11 +158,20 @@ static void rs_set_nonblock_state(void *data, bool state)
|
||||
rsd->nonblock = state;
|
||||
}
|
||||
|
||||
static bool rs_alive(void *data)
|
||||
{
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
if (rsd)
|
||||
return !rsd->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rs_start(void *data)
|
||||
{
|
||||
rsd_t *rsd = (rsd_t*)data;
|
||||
if (rsd_start(rsd->rd) < 0)
|
||||
return false;
|
||||
rsd->is_paused = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -208,6 +219,7 @@ audio_driver_t audio_rsound = {
|
||||
rs_write,
|
||||
rs_stop,
|
||||
rs_start,
|
||||
rs_alive,
|
||||
rs_set_nonblock_state,
|
||||
rs_free,
|
||||
rs_use_float,
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include "../emscripten/RWebAudio.h"
|
||||
|
||||
static bool rwebaudio_is_paused;
|
||||
|
||||
static void rwebaudio_free(void *data)
|
||||
{
|
||||
RWebAudioFree();
|
||||
@ -42,6 +44,7 @@ static ssize_t rwebaudio_write(void *data, const void *buf, size_t size)
|
||||
static bool rwebaudio_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
rwebaudio_is_paused = true;
|
||||
return RWebAudioStop();
|
||||
}
|
||||
|
||||
@ -51,9 +54,16 @@ static void rwebaudio_set_nonblock_state(void *data, bool state)
|
||||
RWebAudioSetNonblockState(state);
|
||||
}
|
||||
|
||||
static bool rwebaudio_alive(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return !rwebaudio_is_paused;
|
||||
}
|
||||
|
||||
static bool rwebaudio_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
rwebaudio_is_paused = false;
|
||||
return RWebAudioStart();
|
||||
}
|
||||
|
||||
@ -80,6 +90,7 @@ audio_driver_t audio_rwebaudio = {
|
||||
rwebaudio_write,
|
||||
rwebaudio_stop,
|
||||
rwebaudio_start,
|
||||
rwebaudio_alive,
|
||||
rwebaudio_set_nonblock_state,
|
||||
rwebaudio_free,
|
||||
rwebaudio_use_float,
|
||||
|
@ -31,6 +31,7 @@
|
||||
typedef struct sdl_audio
|
||||
{
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
|
||||
slock_t *lock;
|
||||
scond_t *cond;
|
||||
@ -157,14 +158,25 @@ static ssize_t sdl_audio_write(void *data, const void *buf, size_t size)
|
||||
|
||||
static bool sdl_audio_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
sdl->is_paused = true;
|
||||
SDL_PauseAudio(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sdl_audio_alive(void *data)
|
||||
{
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
if (sdl)
|
||||
return !sdl->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool sdl_audio_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
sdl_audio_t *sdl = (sdl_audio_t*)data;
|
||||
sdl->is_paused = false;
|
||||
|
||||
SDL_PauseAudio(0);
|
||||
return true;
|
||||
}
|
||||
@ -201,6 +213,7 @@ audio_driver_t audio_sdl = {
|
||||
sdl_audio_write,
|
||||
sdl_audio_stop,
|
||||
sdl_audio_start,
|
||||
sdl_audio_alive,
|
||||
sdl_audio_set_nonblock_state,
|
||||
sdl_audio_free,
|
||||
sdl_use_float,
|
||||
|
@ -31,6 +31,7 @@ typedef struct audio_thread
|
||||
scond_t *cond;
|
||||
bool alive;
|
||||
bool stopped;
|
||||
bool is_paused;
|
||||
bool use_float;
|
||||
|
||||
int inited;
|
||||
@ -132,10 +133,21 @@ static void audio_thread_free(void *data)
|
||||
free(thr);
|
||||
}
|
||||
|
||||
static bool audio_thread_alive(void *data)
|
||||
{
|
||||
bool alive = false;
|
||||
audio_thread_t *thr = (audio_thread_t*)data;
|
||||
audio_thread_block(thr);
|
||||
alive = !thr->is_paused;
|
||||
audio_thread_unblock(thr);
|
||||
return alive;
|
||||
}
|
||||
|
||||
static bool audio_thread_stop(void *data)
|
||||
{
|
||||
audio_thread_t *thr = (audio_thread_t*)data;
|
||||
audio_thread_block(thr);
|
||||
thr->is_paused = true;
|
||||
g_extern.system.audio_callback.set_state(false);
|
||||
return true;
|
||||
}
|
||||
@ -144,6 +156,7 @@ static bool audio_thread_start(void *data)
|
||||
{
|
||||
audio_thread_t *thr = (audio_thread_t*)data;
|
||||
g_extern.system.audio_callback.set_state(true);
|
||||
thr->is_paused = false;
|
||||
audio_thread_unblock(thr);
|
||||
return true;
|
||||
}
|
||||
@ -181,6 +194,7 @@ static const audio_driver_t audio_thread = {
|
||||
audio_thread_write,
|
||||
audio_thread_stop,
|
||||
audio_thread_start,
|
||||
audio_thread_alive,
|
||||
audio_thread_set_nonblock_state,
|
||||
audio_thread_free,
|
||||
audio_thread_use_float,
|
||||
|
@ -23,6 +23,7 @@ typedef struct
|
||||
{
|
||||
xaudio2_t *xa;
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
size_t bufsize;
|
||||
} xa_t;
|
||||
|
||||
@ -80,10 +81,19 @@ static ssize_t xa_write(void *data, const void *buf, size_t size)
|
||||
|
||||
static bool xa_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
xa_t *xa = (xa_t*)data;
|
||||
xa->is_paused = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool xa_alive(void *data)
|
||||
{
|
||||
xa_t *xa = (xa_t*)data;
|
||||
if (xa)
|
||||
return !xa->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void xa_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
xa_t *xa = (xa_t*)data;
|
||||
@ -92,7 +102,8 @@ static void xa_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static bool xa_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
xa_t *xa = (xa_t*)data;
|
||||
xa->is_paused = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -130,6 +141,7 @@ audio_driver_t audio_xa = {
|
||||
xa_write,
|
||||
xa_stop,
|
||||
xa_start,
|
||||
xa_alive,
|
||||
xa_set_nonblock_state,
|
||||
xa_free,
|
||||
xa_use_float,
|
||||
|
@ -28,6 +28,7 @@ typedef struct
|
||||
{
|
||||
uint32_t buffer[2048];
|
||||
bool nonblock;
|
||||
bool is_paused;
|
||||
} xenon_audio_t;
|
||||
|
||||
static void *xenon360_audio_init(const char *device,
|
||||
@ -86,10 +87,19 @@ static ssize_t xenon360_audio_write(void *data, const void *buf, size_t size)
|
||||
|
||||
static bool xenon360_audio_stop(void *data)
|
||||
{
|
||||
(void)data;
|
||||
xenon_audio_t *xa = data;
|
||||
xa->is_paused = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool xenon360_audio_alive(void *data)
|
||||
{
|
||||
xenon_audio_t *xa = data;
|
||||
if (xa)
|
||||
return !xa->is_paused;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void xenon360_audio_set_nonblock_state(void *data, bool state)
|
||||
{
|
||||
xenon_audio_t *xa = data;
|
||||
@ -98,7 +108,8 @@ static void xenon360_audio_set_nonblock_state(void *data, bool state)
|
||||
|
||||
static bool xenon360_audio_start(void *data)
|
||||
{
|
||||
(void)data;
|
||||
xenon_audio_t *xa = data;
|
||||
xa->is_paused = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -119,6 +130,7 @@ audio_driver_t audio_xenon360 = {
|
||||
xenon360_audio_write,
|
||||
xenon360_audio_stop,
|
||||
xenon360_audio_start,
|
||||
xenon360_audio_alive,
|
||||
xenon360_audio_set_nonblock_state,
|
||||
xenon360_audio_free,
|
||||
xenon360_use_float,
|
||||
|
3
driver.h
3
driver.h
@ -184,6 +184,9 @@ typedef struct audio_driver
|
||||
bool (*stop)(void *data);
|
||||
bool (*start)(void *data);
|
||||
|
||||
/* Is the audio driver currently running? */
|
||||
bool (*alive)(void *data);
|
||||
|
||||
/* Should we care about blocking in audio thread? Fast forwarding. */
|
||||
void (*set_nonblock_state)(void *data, bool toggle);
|
||||
void (*free)(void *data);
|
||||
|
17
retroarch.c
17
retroarch.c
@ -3137,11 +3137,22 @@ void rarch_main_command(unsigned cmd)
|
||||
#endif
|
||||
break;
|
||||
case RARCH_CMD_AUDIO_STOP:
|
||||
if (driver.audio_data)
|
||||
driver.audio->stop(driver.audio_data);
|
||||
if (!driver.audio_data)
|
||||
return;
|
||||
|
||||
if (!driver.audio->alive(driver.audio_data))
|
||||
return;
|
||||
|
||||
driver.audio->stop(driver.audio_data);
|
||||
break;
|
||||
case RARCH_CMD_AUDIO_START:
|
||||
if (driver.audio_data && !g_extern.audio_data.mute
|
||||
if (!driver.audio_data)
|
||||
return;
|
||||
|
||||
if (driver.audio->alive(driver.audio_data))
|
||||
return;
|
||||
|
||||
if (!g_extern.audio_data.mute
|
||||
&& !driver.audio->start(driver.audio_data))
|
||||
{
|
||||
RARCH_ERR("Failed to start audio driver. Will continue without audio.\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user