(Audio) SOme control flow changes (no functional changes) and some cleanups
This commit is contained in:
parent
e3a5c5ea46
commit
3aa8db2c08
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#include "../../verbosity.h"
|
#include "../../verbosity.h"
|
||||||
|
|
||||||
static const char* mmdevice_data_flow_name(unsigned data_flow)
|
static const char *mmdevice_data_flow_name(unsigned data_flow)
|
||||||
{
|
{
|
||||||
switch (data_flow)
|
switch (data_flow)
|
||||||
{
|
{
|
||||||
|
|
|
@ -214,9 +214,10 @@ end:
|
||||||
|
|
||||||
static int alsa_thread_microphone_read(void *driver_context, void *mic_context, void *s, size_t len)
|
static int alsa_thread_microphone_read(void *driver_context, void *mic_context, void *s, size_t len)
|
||||||
{
|
{
|
||||||
|
snd_pcm_state_t state;
|
||||||
|
size_t _len = 0;
|
||||||
alsa_thread_microphone_t *alsa = (alsa_thread_microphone_t*)driver_context;
|
alsa_thread_microphone_t *alsa = (alsa_thread_microphone_t*)driver_context;
|
||||||
alsa_thread_microphone_handle_t *mic = (alsa_thread_microphone_handle_t*)mic_context;
|
alsa_thread_microphone_handle_t *mic = (alsa_thread_microphone_handle_t*)mic_context;
|
||||||
snd_pcm_state_t state;
|
|
||||||
|
|
||||||
if (!alsa || !mic || !s) /* If any of the parameters were invalid... */
|
if (!alsa || !mic || !s) /* If any of the parameters were invalid... */
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -245,28 +246,23 @@ static int alsa_thread_microphone_read(void *driver_context, void *mic_context,
|
||||||
if (alsa->nonblock)
|
if (alsa->nonblock)
|
||||||
{
|
{
|
||||||
size_t avail;
|
size_t avail;
|
||||||
size_t write_amt;
|
|
||||||
|
|
||||||
/* "Hey, I'm gonna borrow the queue." */
|
/* "Hey, I'm gonna borrow the queue." */
|
||||||
slock_lock(mic->info.fifo_lock);
|
slock_lock(mic->info.fifo_lock);
|
||||||
|
|
||||||
avail = FIFO_READ_AVAIL(mic->info.buffer);
|
avail = FIFO_READ_AVAIL(mic->info.buffer);
|
||||||
write_amt = MIN(avail, len);
|
_len = MIN(avail, len);
|
||||||
|
|
||||||
/* "It's okay if you don't have any new samples, I'll just check in on you later." */
|
/* "It's okay if you don't have any new samples, I'll just check in on you later." */
|
||||||
fifo_read(mic->info.buffer, s, write_amt);
|
fifo_read(mic->info.buffer, s, _len);
|
||||||
|
|
||||||
/* "Here, take this queue back." */
|
/* "Here, take this queue back." */
|
||||||
slock_unlock(mic->info.fifo_lock);
|
slock_unlock(mic->info.fifo_lock);
|
||||||
|
|
||||||
return (int)write_amt;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t read = 0;
|
|
||||||
|
|
||||||
/* Until we've read all requested samples (or we're told to stop)... */
|
/* Until we've read all requested samples (or we're told to stop)... */
|
||||||
while (read < len && !mic->info.thread_dead)
|
while (_len < len && !mic->info.thread_dead)
|
||||||
{
|
{
|
||||||
size_t avail;
|
size_t avail;
|
||||||
|
|
||||||
|
@ -294,21 +290,20 @@ static int alsa_thread_microphone_read(void *driver_context, void *mic_context,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t read_amt = MIN(len - read, avail);
|
size_t read_amt = MIN(len - _len, avail);
|
||||||
|
|
||||||
/* "I'll just go ahead and consume all these samples..."
|
/* "I'll just go ahead and consume all these samples..."
|
||||||
* (As many as will fit in s, or as many as are available.) */
|
* (As many as will fit in s, or as many as are available.) */
|
||||||
fifo_read(mic->info.buffer,s + read, read_amt);
|
fifo_read(mic->info.buffer,s + _len, read_amt);
|
||||||
|
|
||||||
/* "I'm done, you can take the queue back now." */
|
/* "I'm done, you can take the queue back now." */
|
||||||
slock_unlock(mic->info.fifo_lock);
|
slock_unlock(mic->info.fifo_lock);
|
||||||
read += read_amt;
|
_len += read_amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "I'll be right back..." */
|
/* "I'll be right back..." */
|
||||||
}
|
}
|
||||||
return (int)read;
|
|
||||||
}
|
}
|
||||||
|
return _len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool alsa_thread_microphone_mic_alive(const void *driver_context, const void *mic_context);
|
static bool alsa_thread_microphone_mic_alive(const void *driver_context, const void *mic_context);
|
||||||
|
@ -475,8 +470,9 @@ static void alsa_worker_thread(void *data)
|
||||||
|
|
||||||
frames = snd_pcm_writei(alsa->info.pcm, buf, alsa->info.stream_info.period_frames);
|
frames = snd_pcm_writei(alsa->info.pcm, buf, alsa->info.stream_info.period_frames);
|
||||||
|
|
||||||
if (frames == -EPIPE || frames == -EINTR ||
|
if ( frames == -EPIPE
|
||||||
frames == -ESTRPIPE)
|
|| frames == -EINTR
|
||||||
|
|| frames == -ESTRPIPE)
|
||||||
{
|
{
|
||||||
if (snd_pcm_recover(alsa->info.pcm, frames, false) < 0)
|
if (snd_pcm_recover(alsa->info.pcm, frames, false) < 0)
|
||||||
{
|
{
|
||||||
|
@ -625,7 +621,6 @@ static bool alsa_thread_alive(void *data)
|
||||||
static bool alsa_thread_stop(void *data)
|
static bool alsa_thread_stop(void *data)
|
||||||
{
|
{
|
||||||
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
alsa_thread_t *alsa = (alsa_thread_t*)data;
|
||||||
|
|
||||||
if (alsa)
|
if (alsa)
|
||||||
alsa->is_paused = true;
|
alsa->is_paused = true;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -36,8 +36,8 @@ static void *audioio_init(const char *device, unsigned rate, unsigned latency,
|
||||||
unsigned block_frames, unsigned *new_out_rate)
|
unsigned block_frames, unsigned *new_out_rate)
|
||||||
{
|
{
|
||||||
struct audio_info info;
|
struct audio_info info;
|
||||||
const char *audiodev = device ? device : DEFAULT_DEV;
|
const char *audiodev = device ? device : DEFAULT_DEV;
|
||||||
int *fd = (int*)calloc(1, sizeof(int));
|
int *fd = (int*)calloc(1, sizeof(int));
|
||||||
|
|
||||||
if (!fd)
|
if (!fd)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -45,17 +45,17 @@ static void *audioio_init(const char *device, unsigned rate, unsigned latency,
|
||||||
AUDIO_INITINFO(&info);
|
AUDIO_INITINFO(&info);
|
||||||
|
|
||||||
#ifdef AUMODE_PLAY_ALL
|
#ifdef AUMODE_PLAY_ALL
|
||||||
info.mode = AUMODE_PLAY_ALL;
|
info.mode = AUMODE_PLAY_ALL;
|
||||||
#elif defined(AUMODE_PLAY)
|
#elif defined(AUMODE_PLAY)
|
||||||
info.mode = AUMODE_PLAY;
|
info.mode = AUMODE_PLAY;
|
||||||
#endif
|
#endif
|
||||||
info.play.sample_rate = rate;
|
info.play.sample_rate = rate;
|
||||||
info.play.channels = 2;
|
info.play.channels = 2;
|
||||||
info.play.precision = 16;
|
info.play.precision = 16;
|
||||||
#ifdef AUDIO_ENCODING_SLINEAR
|
#ifdef AUDIO_ENCODING_SLINEAR
|
||||||
info.play.encoding = AUDIO_ENCODING_SLINEAR;
|
info.play.encoding = AUDIO_ENCODING_SLINEAR;
|
||||||
#else
|
#else
|
||||||
info.play.encoding = AUDIO_ENCODING_LINEAR;
|
info.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((*fd = open(audiodev, O_WRONLY)) < 0)
|
if ((*fd = open(audiodev, O_WRONLY)) < 0)
|
||||||
|
|
|
@ -149,15 +149,15 @@ static void audioworklet_thread_inited_cb(EMSCRIPTEN_WEBAUDIO_T context, bool su
|
||||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||||
WebAudioWorkletProcessorCreateOptions opts = { "retroarch", 0 };
|
WebAudioWorkletProcessorCreateOptions opts = { "retroarch", 0 };
|
||||||
|
|
||||||
if (!success)
|
if (success)
|
||||||
|
emscripten_create_wasm_audio_worklet_processor_async(context, &opts,
|
||||||
|
audioworklet_processor_inited_cb, audioworklet);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
RARCH_ERR("[AudioWorklet] Failed to init worklet thread! Is the worklet file in the right place?\n");
|
RARCH_ERR("[AudioWorklet] Failed to init worklet thread! Is the worklet file in the right place?\n");
|
||||||
audioworklet->init_error = true;
|
audioworklet->init_error = true;
|
||||||
audioworklet->init_done = true;
|
audioworklet->init_done = true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emscripten_create_wasm_audio_worklet_processor_async(context, &opts, audioworklet_processor_inited_cb, audioworklet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void audioworklet_ctx_statechange_cb(void *data, bool state)
|
static void audioworklet_ctx_statechange_cb(void *data, bool state)
|
||||||
|
@ -190,9 +190,9 @@ static void audioworklet_ctx_create(void *data)
|
||||||
|
|
||||||
static void audioworklet_alloc_buffer(void *data)
|
static void audioworklet_alloc_buffer(void *data)
|
||||||
{
|
{
|
||||||
|
size_t buffer_size;
|
||||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||||
|
|
||||||
size_t buffer_size;
|
|
||||||
audioworklet->visible_buffer_size = (audioworklet->latency * audioworklet->rate * 2 * sizeof(float)) / 1000;
|
audioworklet->visible_buffer_size = (audioworklet->latency * audioworklet->rate * 2 * sizeof(float)) / 1000;
|
||||||
buffer_size = audioworklet->visible_buffer_size;
|
buffer_size = audioworklet->visible_buffer_size;
|
||||||
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
||||||
|
@ -239,9 +239,9 @@ static void *audioworklet_init(const char *device, unsigned rate,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
RARCH_LOG("[AudioWorklet] Reusing old context.\n");
|
RARCH_LOG("[AudioWorklet] Reusing old context.\n");
|
||||||
audioworklet = audioworklet_static_data;
|
audioworklet = audioworklet_static_data;
|
||||||
audioworklet->latency = latency;
|
audioworklet->latency = latency;
|
||||||
*new_rate = audioworklet->rate;
|
*new_rate = audioworklet->rate;
|
||||||
RARCH_LOG("[AudioWorklet] Device rate: %d Hz.\n", *new_rate);
|
RARCH_LOG("[AudioWorklet] Device rate: %d Hz.\n", *new_rate);
|
||||||
audioworklet_alloc_buffer(audioworklet);
|
audioworklet_alloc_buffer(audioworklet);
|
||||||
audioworklet_resume_ctx(audioworklet);
|
audioworklet_resume_ctx(audioworklet);
|
||||||
|
@ -259,7 +259,7 @@ static void *audioworklet_init(const char *device, unsigned rate,
|
||||||
|
|
||||||
audioworklet->latency = latency;
|
audioworklet->latency = latency;
|
||||||
platform_emscripten_run_on_browser_thread_sync(audioworklet_ctx_create, audioworklet);
|
platform_emscripten_run_on_browser_thread_sync(audioworklet_ctx_create, audioworklet);
|
||||||
*new_rate = audioworklet->rate;
|
*new_rate = audioworklet->rate;
|
||||||
RARCH_LOG("[AudioWorklet] Device rate: %d Hz.\n", *new_rate);
|
RARCH_LOG("[AudioWorklet] Device rate: %d Hz.\n", *new_rate);
|
||||||
audioworklet->initing = true;
|
audioworklet->initing = true;
|
||||||
audioworklet_alloc_buffer(audioworklet);
|
audioworklet_alloc_buffer(audioworklet);
|
||||||
|
@ -295,10 +295,10 @@ static ssize_t audioworklet_write(void *data, const void *s, size_t ss)
|
||||||
size_t max_write;
|
size_t max_write;
|
||||||
size_t to_write_frames;
|
size_t to_write_frames;
|
||||||
size_t to_write_bytes;
|
size_t to_write_bytes;
|
||||||
size_t _len = 0;
|
size_t _len = 0;
|
||||||
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
audioworklet_data_t *audioworklet = (audioworklet_data_t*)data;
|
||||||
const float *samples = (const float*)s;
|
const float *samples = (const float*)s;
|
||||||
size_t num_frames = ss / 2 / sizeof(float);
|
size_t num_frames = ss / 2 / sizeof(float);
|
||||||
|
|
||||||
/* too early! might happen with external blocking */
|
/* too early! might happen with external blocking */
|
||||||
if (!audioworklet->driver_running)
|
if (!audioworklet->driver_running)
|
||||||
|
@ -382,51 +382,51 @@ bool audioworklet_external_block(void)
|
||||||
{
|
{
|
||||||
audioworklet_data_t *audioworklet = audioworklet_static_data;
|
audioworklet_data_t *audioworklet = audioworklet_static_data;
|
||||||
|
|
||||||
if (!audioworklet)
|
if (audioworklet)
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN_AUDIO_FAKE_BLOCK
|
|
||||||
if (!audioworklet->block_requested)
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (audioworklet->initing && !audioworklet->init_done)
|
|
||||||
#ifdef EMSCRIPTEN_AUDIO_ASYNC_BLOCK
|
|
||||||
retro_sleep(1);
|
|
||||||
#else
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
if (audioworklet->init_done && !audioworklet->driver_running)
|
|
||||||
{
|
{
|
||||||
audioworklet->initing = false;
|
#ifdef EMSCRIPTEN_AUDIO_FAKE_BLOCK
|
||||||
if (audioworklet->init_error)
|
if (!audioworklet->block_requested)
|
||||||
{
|
|
||||||
audioworklet_init_error(audioworklet);
|
|
||||||
abort();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
audioworklet->driver_running = true;
|
|
||||||
}
|
|
||||||
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
|
||||||
if (!audioworklet->driver_running)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
while (emscripten_atomic_load_u32(&audioworklet->write_avail_bytes) < audioworklet->write_avail_diff)
|
|
||||||
{
|
|
||||||
audioworklet_resume_ctx(audioworklet);
|
|
||||||
#ifdef EMSCRIPTEN_AUDIO_ASYNC_BLOCK
|
|
||||||
retro_sleep(1);
|
|
||||||
#else
|
|
||||||
return true;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
while (audioworklet->initing && !audioworklet->init_done)
|
||||||
|
#ifdef EMSCRIPTEN_AUDIO_ASYNC_BLOCK
|
||||||
|
retro_sleep(1);
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
if (audioworklet->init_done && !audioworklet->driver_running)
|
||||||
|
{
|
||||||
|
audioworklet->initing = false;
|
||||||
|
if (audioworklet->init_error)
|
||||||
|
{
|
||||||
|
audioworklet_init_error(audioworklet);
|
||||||
|
abort();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
audioworklet->driver_running = true;
|
||||||
|
}
|
||||||
|
#ifdef EMSCRIPTEN_AUDIO_EXTERNAL_WRITE_BLOCK
|
||||||
|
if (!audioworklet->driver_running)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (emscripten_atomic_load_u32(&audioworklet->write_avail_bytes) < audioworklet->write_avail_diff)
|
||||||
|
{
|
||||||
|
audioworklet_resume_ctx(audioworklet);
|
||||||
|
#ifdef EMSCRIPTEN_AUDIO_ASYNC_BLOCK
|
||||||
|
retro_sleep(1);
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN_AUDIO_FAKE_BLOCK
|
#ifdef EMSCRIPTEN_AUDIO_FAKE_BLOCK
|
||||||
audioworklet->block_requested = false;
|
audioworklet->block_requested = false;
|
||||||
platform_emscripten_exit_fake_block();
|
platform_emscripten_exit_fake_block();
|
||||||
return true; /* return to RAF if needed */
|
return true; /* return to RAF if needed */
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -102,18 +102,11 @@ static OSStatus coreaudio_audio_write_cb(void *userdata,
|
||||||
if (FIFO_READ_AVAIL(dev->buffer) < write_avail)
|
if (FIFO_READ_AVAIL(dev->buffer) < write_avail)
|
||||||
{
|
{
|
||||||
*action_flags = kAudioUnitRenderAction_OutputIsSilence;
|
*action_flags = kAudioUnitRenderAction_OutputIsSilence;
|
||||||
|
|
||||||
/* Seems to be needed. */
|
/* Seems to be needed. */
|
||||||
memset(outbuf, 0, write_avail);
|
memset(outbuf, 0, write_avail);
|
||||||
|
|
||||||
slock_unlock(dev->lock);
|
|
||||||
|
|
||||||
/* Technically possible to deadlock without. */
|
|
||||||
scond_signal(dev->cond);
|
|
||||||
return noErr;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
fifo_read(dev->buffer, outbuf, write_avail);
|
fifo_read(dev->buffer, outbuf, write_avail);
|
||||||
slock_unlock(dev->lock);
|
slock_unlock(dev->lock);
|
||||||
scond_signal(dev->cond);
|
scond_signal(dev->cond);
|
||||||
return noErr;
|
return noErr;
|
||||||
|
@ -123,10 +116,10 @@ static OSStatus coreaudio_audio_write_cb(void *userdata,
|
||||||
static void coreaudio_choose_output_device(coreaudio_t *dev, const char* device)
|
static void coreaudio_choose_output_device(coreaudio_t *dev, const char* device)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
UInt32 deviceCount;
|
UInt32 device_count;
|
||||||
AudioObjectPropertyAddress propaddr;
|
AudioObjectPropertyAddress propaddr;
|
||||||
AudioDeviceID *devices = NULL;
|
AudioDeviceID *devices = NULL;
|
||||||
UInt32 size = 0;
|
UInt32 size = 0;
|
||||||
|
|
||||||
propaddr.mSelector = kAudioHardwarePropertyDevices;
|
propaddr.mSelector = kAudioHardwarePropertyDevices;
|
||||||
#if HAS_MACOSX_10_12
|
#if HAS_MACOSX_10_12
|
||||||
|
@ -140,36 +133,35 @@ static void coreaudio_choose_output_device(coreaudio_t *dev, const char* device)
|
||||||
&propaddr, 0, 0, &size) != noErr)
|
&propaddr, 0, 0, &size) != noErr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
deviceCount = size / sizeof(AudioDeviceID);
|
device_count = size / sizeof(AudioDeviceID);
|
||||||
devices = (AudioDeviceID*)malloc(size);
|
devices = (AudioDeviceID*)malloc(size);
|
||||||
|
|
||||||
if (!devices || AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
|
||||||
&propaddr, 0, 0, &size, devices) != noErr)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
|
if (devices && AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
||||||
|
&propaddr, 0, 0, &size, devices) == noErr)
|
||||||
|
{
|
||||||
#if HAS_MACOSX_10_12
|
#if HAS_MACOSX_10_12
|
||||||
#else
|
#else
|
||||||
propaddr.mScope = kAudioDevicePropertyScopeOutput;
|
propaddr.mScope = kAudioDevicePropertyScopeOutput;
|
||||||
#endif
|
#endif
|
||||||
propaddr.mSelector = kAudioDevicePropertyDeviceName;
|
propaddr.mSelector = kAudioDevicePropertyDeviceName;
|
||||||
|
|
||||||
for (i = 0; i < (int)deviceCount; i ++)
|
for (i = 0; i < (int)device_count; i ++)
|
||||||
{
|
|
||||||
char device_name[1024];
|
|
||||||
device_name[0] = 0;
|
|
||||||
size = 1024;
|
|
||||||
|
|
||||||
if (AudioObjectGetPropertyData(devices[i],
|
|
||||||
&propaddr, 0, 0, &size, device_name) == noErr
|
|
||||||
&& string_is_equal(device_name, device))
|
|
||||||
{
|
{
|
||||||
AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice,
|
char device_name[1024];
|
||||||
kAudioUnitScope_Global, 0, &devices[i], sizeof(AudioDeviceID));
|
device_name[0] = 0;
|
||||||
goto done;
|
size = 1024;
|
||||||
|
|
||||||
|
if (AudioObjectGetPropertyData(devices[i],
|
||||||
|
&propaddr, 0, 0, &size, device_name) == noErr
|
||||||
|
&& string_is_equal(device_name, device))
|
||||||
|
{
|
||||||
|
AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice,
|
||||||
|
kAudioUnitScope_Global, 0, &devices[i], sizeof(AudioDeviceID));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
|
||||||
free(devices);
|
free(devices);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -245,9 +237,11 @@ static void *coreaudio_init(const char *device,
|
||||||
stream_desc.mBytesPerFrame = 2 * sizeof(float);
|
stream_desc.mBytesPerFrame = 2 * sizeof(float);
|
||||||
stream_desc.mFramesPerPacket = 1;
|
stream_desc.mFramesPerPacket = 1;
|
||||||
stream_desc.mFormatID = kAudioFormatLinearPCM;
|
stream_desc.mFormatID = kAudioFormatLinearPCM;
|
||||||
stream_desc.mFormatFlags = kAudioFormatFlagIsFloat |
|
stream_desc.mFormatFlags = kAudioFormatFlagIsFloat
|
||||||
kAudioFormatFlagIsPacked | (is_little_endian() ?
|
| kAudioFormatFlagIsPacked;
|
||||||
0 : kAudioFormatFlagIsBigEndian);
|
|
||||||
|
if (!is_little_endian())
|
||||||
|
stream_desc.mFormatFlags |= kAudioFormatFlagIsBigEndian;
|
||||||
|
|
||||||
if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
|
if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
|
||||||
kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)) != noErr)
|
kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)) != noErr)
|
||||||
|
@ -374,19 +368,25 @@ static bool coreaudio_alive(void *data)
|
||||||
static bool coreaudio_stop(void *data)
|
static bool coreaudio_stop(void *data)
|
||||||
{
|
{
|
||||||
coreaudio_t *dev = (coreaudio_t*)data;
|
coreaudio_t *dev = (coreaudio_t*)data;
|
||||||
if (!dev)
|
if (dev)
|
||||||
return false;
|
{
|
||||||
dev->is_paused = (AudioOutputUnitStop(dev->dev) == noErr) ? true : false;
|
dev->is_paused = (AudioOutputUnitStop(dev->dev) == noErr) ? true : false;
|
||||||
return dev->is_paused ? true : false;
|
if (dev->is_paused)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool coreaudio_start(void *data, bool is_shutdown)
|
static bool coreaudio_start(void *data, bool is_shutdown)
|
||||||
{
|
{
|
||||||
coreaudio_t *dev = (coreaudio_t*)data;
|
coreaudio_t *dev = (coreaudio_t*)data;
|
||||||
if (!dev)
|
if (dev)
|
||||||
return false;
|
{
|
||||||
dev->is_paused = (AudioOutputUnitStart(dev->dev) == noErr) ? false : true;
|
dev->is_paused = (AudioOutputUnitStart(dev->dev) == noErr) ? false : true;
|
||||||
return dev->is_paused ? false : true;
|
if (dev->is_paused)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool coreaudio_use_float(void *data) { return true; }
|
static bool coreaudio_use_float(void *data) { return true; }
|
||||||
|
|
|
@ -240,20 +240,19 @@ static bool ctr_csnd_audio_start(void *data, bool is_shutdown)
|
||||||
|
|
||||||
/* Prevents restarting audio when the menu
|
/* Prevents restarting audio when the menu
|
||||||
* is toggled off on shutdown */
|
* is toggled off on shutdown */
|
||||||
if (is_shutdown)
|
if (!is_shutdown)
|
||||||
return true;
|
{
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
CSND_SetPlayState(0x8, 1);
|
CSND_SetPlayState(0x8, 1);
|
||||||
CSND_SetPlayState(0x9, 1);
|
CSND_SetPlayState(0x9, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CSND_SetVol(0x8, 0x00008000, 0);
|
CSND_SetVol(0x8, 0x00008000, 0);
|
||||||
CSND_SetVol(0x9, 0x80000000, 0);
|
CSND_SetVol(0x9, 0x80000000, 0);
|
||||||
|
|
||||||
csndExecCmds(false);
|
csndExecCmds(false);
|
||||||
|
ctr->playing = true;
|
||||||
ctr->playing = true;
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -277,7 +276,6 @@ static size_t ctr_csnd_audio_write_avail(void *data)
|
||||||
|
|
||||||
static size_t ctr_csnd_audio_buffer_size(void *data)
|
static size_t ctr_csnd_audio_buffer_size(void *data)
|
||||||
{
|
{
|
||||||
(void)data;
|
|
||||||
return CTR_CSND_AUDIO_COUNT;
|
return CTR_CSND_AUDIO_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,11 +171,11 @@ static bool ctr_dsp_audio_start(void *data, bool is_shutdown)
|
||||||
|
|
||||||
/* Prevents restarting audio when the menu
|
/* Prevents restarting audio when the menu
|
||||||
* is toggled off on shutdown */
|
* is toggled off on shutdown */
|
||||||
if (is_shutdown)
|
if (!is_shutdown)
|
||||||
return true;
|
{
|
||||||
|
ndspSetMasterVol(1.0);
|
||||||
ndspSetMasterVol(1.0);
|
ctr->playing = true;
|
||||||
ctr->playing = true;
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,6 @@ static size_t ctr_dsp_audio_write_avail(void *data)
|
||||||
|
|
||||||
static size_t ctr_dsp_audio_buffer_size(void *data)
|
static size_t ctr_dsp_audio_buffer_size(void *data)
|
||||||
{
|
{
|
||||||
(void)data;
|
|
||||||
return CTR_DSP_AUDIO_COUNT;
|
return CTR_DSP_AUDIO_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,31 +149,30 @@ static bool dsound_grab_region(dsound_t *ds, uint32_t write_ptr,
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
RARCH_WARN("[DirectSound] %s.\n", "DSERR_BUFFERLOST");
|
RARCH_WARN("[DirectSound] %s.\n", "DSERR_BUFFERLOST");
|
||||||
#endif
|
#endif
|
||||||
if ((IDirectSoundBuffer_Restore(ds->dsb)) != DS_OK)
|
if ((IDirectSoundBuffer_Restore(ds->dsb)) == DS_OK)
|
||||||
return false;
|
if ((IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE,
|
||||||
if ((IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE,
|
®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0)) == DS_OK)
|
||||||
®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0)) != DS_OK)
|
return true;
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
switch (res)
|
else
|
||||||
{
|
{
|
||||||
case DSERR_INVALIDCALL:
|
switch (res)
|
||||||
RARCH_WARN("[DirectSound] %s.\n", "DSERR_INVALIDCALL");
|
{
|
||||||
break;
|
case DSERR_INVALIDCALL:
|
||||||
case DSERR_INVALIDPARAM:
|
RARCH_WARN("[DirectSound] %s.\n", "DSERR_INVALIDCALL");
|
||||||
RARCH_WARN("[DirectSound] %s.\n", "DSERR_INVALIDPARAM");
|
break;
|
||||||
break;
|
case DSERR_INVALIDPARAM:
|
||||||
case DSERR_PRIOLEVELNEEDED:
|
RARCH_WARN("[DirectSound] %s.\n", "DSERR_INVALIDPARAM");
|
||||||
RARCH_WARN("[DirectSound] %s.\n", "DSERR_PRIOLEVELNEEDED");
|
break;
|
||||||
break;
|
case DSERR_PRIOLEVELNEEDED:
|
||||||
default:
|
RARCH_WARN("[DirectSound] %s.\n", "DSERR_PRIOLEVELNEEDED");
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,34 +68,28 @@ static size_t ja_read_deinterleaved(float *dst[2], jack_nframes_t dst_offset,
|
||||||
|
|
||||||
static int ja_process_cb(jack_nframes_t nframes, void *data)
|
static int ja_process_cb(jack_nframes_t nframes, void *data)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
jack_nframes_t read = 0;
|
|
||||||
jack_t *jd = (jack_t*)data;
|
jack_t *jd = (jack_t*)data;
|
||||||
jack_ringbuffer_data_t buf[2];
|
|
||||||
float *dst[2];
|
|
||||||
|
|
||||||
if (nframes <= 0)
|
if (nframes > 0)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_THREADS
|
int i;
|
||||||
scond_signal(jd->cond);
|
float *dst[2];
|
||||||
#endif
|
jack_ringbuffer_data_t buf[2];
|
||||||
return 0;
|
jack_nframes_t read = 0;
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
dst[i] = (float *)jack_port_get_buffer(jd->ports[i], nframes);
|
|
||||||
|
|
||||||
jack_ringbuffer_get_read_vector(jd->buffer, buf);
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
read += ja_read_deinterleaved(dst, read, buf[i], nframes - read);
|
|
||||||
|
|
||||||
jack_ringbuffer_read_advance(jd->buffer, read * sizeof(float) * 2);
|
|
||||||
|
|
||||||
for (; read < nframes; read++)
|
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
dst[i][read] = 0.0f;
|
dst[i] = (float *)jack_port_get_buffer(jd->ports[i], nframes);
|
||||||
|
|
||||||
|
jack_ringbuffer_get_read_vector(jd->buffer, buf);
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
read += ja_read_deinterleaved(dst, read, buf[i], nframes - read);
|
||||||
|
|
||||||
|
jack_ringbuffer_read_advance(jd->buffer, read * sizeof(float) * 2);
|
||||||
|
|
||||||
|
for (; read < nframes; read++)
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
dst[i][read] = 0.0f;
|
||||||
|
}
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
scond_signal(jd->cond);
|
scond_signal(jd->cond);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -88,8 +88,8 @@ static void *rwebaudio_init(const char *device, unsigned rate, unsigned latency,
|
||||||
RARCH_ERR("[RWebAudio] Failed to initialize driver.\n");
|
RARCH_ERR("[RWebAudio] Failed to initialize driver.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rwebaudio_static_data = rwebaudio;
|
rwebaudio_static_data = rwebaudio;
|
||||||
*new_rate = RWebAudioSampleRate();
|
*new_rate = RWebAudioSampleRate();
|
||||||
rwebaudio->tmpbuf_frames = RWEBAUDIO_BUFFER_SIZE_MS * *new_rate / 1000;
|
rwebaudio->tmpbuf_frames = RWEBAUDIO_BUFFER_SIZE_MS * *new_rate / 1000;
|
||||||
rwebaudio->tmpbuf_left = memalign(sizeof(float), rwebaudio->tmpbuf_frames * sizeof(float));
|
rwebaudio->tmpbuf_left = memalign(sizeof(float), rwebaudio->tmpbuf_frames * sizeof(float));
|
||||||
rwebaudio->tmpbuf_right = memalign(sizeof(float), rwebaudio->tmpbuf_frames * sizeof(float));
|
rwebaudio->tmpbuf_right = memalign(sizeof(float), rwebaudio->tmpbuf_frames * sizeof(float));
|
||||||
|
@ -230,13 +230,12 @@ static void rwebaudio_set_nonblock_state(void *data, bool state)
|
||||||
static size_t rwebaudio_write_avail(void *data)
|
static size_t rwebaudio_write_avail(void *data)
|
||||||
{
|
{
|
||||||
rwebaudio_data_t *rwebaudio = (rwebaudio_data_t*)data;
|
rwebaudio_data_t *rwebaudio = (rwebaudio_data_t*)data;
|
||||||
size_t avail_frames;
|
if (rwebaudio)
|
||||||
if (!rwebaudio)
|
{
|
||||||
return 0;
|
size_t avail_frames = RWebAudioWriteAvailFrames();
|
||||||
|
if (avail_frames > rwebaudio->tmpbuf_offset)
|
||||||
avail_frames = RWebAudioWriteAvailFrames();
|
return (avail_frames - rwebaudio->tmpbuf_offset) * 2 * sizeof(float);
|
||||||
if (avail_frames > rwebaudio->tmpbuf_offset)
|
}
|
||||||
return (avail_frames - rwebaudio->tmpbuf_offset) * 2 * sizeof(float);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,13 +180,14 @@ static bool switch_audio_start(void *data, bool is_shutdown)
|
||||||
static bool switch_audio_alive(void *data)
|
static bool switch_audio_alive(void *data)
|
||||||
{
|
{
|
||||||
switch_audio_t *swa = (switch_audio_t*) data;
|
switch_audio_t *swa = (switch_audio_t*) data;
|
||||||
if (!swa)
|
return (swa && !swa->is_paused);
|
||||||
return false;
|
|
||||||
return !swa->is_paused;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void switch_audio_free(void *data)
|
static void switch_audio_free(void *data)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_LIBNX
|
||||||
|
int i;
|
||||||
|
#endif
|
||||||
switch_audio_t *swa = (switch_audio_t*) data;
|
switch_audio_t *swa = (switch_audio_t*) data;
|
||||||
|
|
||||||
if (!swa)
|
if (!swa)
|
||||||
|
@ -197,8 +198,6 @@ static void switch_audio_free(void *data)
|
||||||
audoutStopAudioOut();
|
audoutStopAudioOut();
|
||||||
|
|
||||||
audoutExit();
|
audoutExit();
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < BUFFER_COUNT; i++)
|
for (i = 0; i < BUFFER_COUNT; i++)
|
||||||
free(swa->buffers[i].buffer);
|
free(swa->buffers[i].buffer);
|
||||||
#else
|
#else
|
||||||
|
@ -208,10 +207,8 @@ static void switch_audio_free(void *data)
|
||||||
free(swa);
|
free(swa);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool switch_audio_use_float(void *data)
|
/* TODO/FIXME - implement float too? */
|
||||||
{
|
static bool switch_audio_use_float(void *data) { return false; /* force INT16 */ }
|
||||||
return false; /* force INT16 */
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t switch_audio_write_avail(void *data)
|
static size_t switch_audio_write_avail(void *data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -176,19 +176,18 @@ static int ax_audio_limit(int in)
|
||||||
|
|
||||||
static bool ax_audio_start(void* data, bool is_shutdown)
|
static bool ax_audio_start(void* data, bool is_shutdown)
|
||||||
{
|
{
|
||||||
ax_audio_t* ax = (ax_audio_t*)data;
|
|
||||||
|
|
||||||
/* Prevents restarting audio when the menu
|
/* Prevents restarting audio when the menu
|
||||||
* is toggled off on shutdown */
|
* is toggled off on shutdown */
|
||||||
if (is_shutdown)
|
if (!is_shutdown)
|
||||||
return true;
|
|
||||||
|
|
||||||
/* Set back to playing on enough buffered data */
|
|
||||||
if (ax->written > AX_AUDIO_SAMPLE_LOAD)
|
|
||||||
{
|
{
|
||||||
AXSetMultiVoiceCurrentOffset(ax->mvoice,
|
ax_audio_t* ax = (ax_audio_t*)data;
|
||||||
ax_audio_limit(ax->pos - ax->written));
|
/* Set back to playing on enough buffered data */
|
||||||
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_PLAYING);
|
if (ax->written > AX_AUDIO_SAMPLE_LOAD)
|
||||||
|
{
|
||||||
|
AXSetMultiVoiceCurrentOffset(ax->mvoice,
|
||||||
|
ax_audio_limit(ax->pos - ax->written));
|
||||||
|
AXSetMultiVoiceState(ax->mvoice, AX_VOICE_STATE_PLAYING);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -196,10 +195,9 @@ static bool ax_audio_start(void* data, bool is_shutdown)
|
||||||
|
|
||||||
static ssize_t ax_audio_write(void* data, const void* buf, size_t len)
|
static ssize_t ax_audio_write(void* data, const void* buf, size_t len)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
|
||||||
size_t count_avail = 0;
|
size_t count_avail = 0;
|
||||||
ax_audio_t* ax = (ax_audio_t*)data;
|
ax_audio_t *ax = (ax_audio_t*)data;
|
||||||
const uint16_t* src = buf;
|
const uint16_t *src = buf;
|
||||||
size_t count = len >> 2;
|
size_t count = len >> 2;
|
||||||
|
|
||||||
if (!len || (len & 0x3))
|
if (!len || (len & 0x3))
|
||||||
|
@ -236,10 +234,11 @@ static ssize_t ax_audio_write(void* data, const void* buf, size_t len)
|
||||||
/* make sure we have input size */
|
/* make sure we have input size */
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
|
size_t i;
|
||||||
/* write in new data */
|
/* write in new data */
|
||||||
size_t start_pos = ax->pos;
|
size_t start_pos = ax->pos;
|
||||||
int flush_p2_needed = 0;
|
int flush_p2_needed = 0;
|
||||||
int flush_p2 = 0;
|
int flush_p2 = 0;
|
||||||
|
|
||||||
for (i = 0; i < (count << 1); i += 2)
|
for (i = 0; i < (count << 1); i += 2)
|
||||||
{
|
{
|
||||||
|
@ -251,7 +250,7 @@ static ssize_t ax_audio_write(void* data, const void* buf, size_t len)
|
||||||
if (ax->pos == 0)
|
if (ax->pos == 0)
|
||||||
{
|
{
|
||||||
flush_p2_needed = 1;
|
flush_p2_needed = 1;
|
||||||
flush_p2 = ((count << 1) - i);
|
flush_p2 = ((count << 1) - i);
|
||||||
DCStoreRangeNoSync(ax->buffer_l + start_pos,
|
DCStoreRangeNoSync(ax->buffer_l + start_pos,
|
||||||
(AX_AUDIO_COUNT - start_pos) << 1);
|
(AX_AUDIO_COUNT - start_pos) << 1);
|
||||||
DCStoreRangeNoSync(ax->buffer_r + start_pos, (AX_AUDIO_COUNT - start_pos) << 1);
|
DCStoreRangeNoSync(ax->buffer_r + start_pos, (AX_AUDIO_COUNT - start_pos) << 1);
|
||||||
|
|
Loading…
Reference in New Issue