mirror of
https://github.com/libretro/RetroArch
synced 2025-04-16 08:43:10 +00:00
(CoreAudio) Use straight pthread again
This commit is contained in:
parent
4c5a009f43
commit
2c2fa0ce30
@ -19,7 +19,7 @@
|
|||||||
#include <queues/fifo_buffer.h>
|
#include <queues/fifo_buffer.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <boolean.h>
|
#include <boolean.h>
|
||||||
#include <rthreads/rthreads.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#ifdef OSX
|
#ifdef OSX
|
||||||
#include <CoreAudio/CoreAudio.h>
|
#include <CoreAudio/CoreAudio.h>
|
||||||
@ -33,8 +33,8 @@
|
|||||||
|
|
||||||
typedef struct coreaudio
|
typedef struct coreaudio
|
||||||
{
|
{
|
||||||
slock_t *lock;
|
pthread_mutex_t lock;
|
||||||
scond_t *cond;
|
pthread_cond_t cond;
|
||||||
|
|
||||||
#ifdef OSX_PPC
|
#ifdef OSX_PPC
|
||||||
ComponentInstance dev;
|
ComponentInstance dev;
|
||||||
@ -71,8 +71,8 @@ static void coreaudio_free(void *data)
|
|||||||
if (dev->buffer)
|
if (dev->buffer)
|
||||||
fifo_free(dev->buffer);
|
fifo_free(dev->buffer);
|
||||||
|
|
||||||
slock_free(dev->lock);
|
pthread_mutex_destroy(&dev->lock);
|
||||||
scond_free(dev->cond);
|
pthread_cond_destroy(&dev->cond);
|
||||||
|
|
||||||
free(dev);
|
free(dev);
|
||||||
}
|
}
|
||||||
@ -82,8 +82,8 @@ static OSStatus audio_write_cb(void *userdata,
|
|||||||
const AudioTimeStamp *time_stamp, UInt32 bus_number,
|
const AudioTimeStamp *time_stamp, UInt32 bus_number,
|
||||||
UInt32 number_frames, AudioBufferList *io_data)
|
UInt32 number_frames, AudioBufferList *io_data)
|
||||||
{
|
{
|
||||||
|
void *outbuf;
|
||||||
unsigned write_avail;
|
unsigned write_avail;
|
||||||
void *outbuf = NULL;
|
|
||||||
coreaudio_t *dev = (coreaudio_t*)userdata;
|
coreaudio_t *dev = (coreaudio_t*)userdata;
|
||||||
|
|
||||||
(void)time_stamp;
|
(void)time_stamp;
|
||||||
@ -96,9 +96,9 @@ static OSStatus audio_write_cb(void *userdata,
|
|||||||
return noErr;
|
return noErr;
|
||||||
|
|
||||||
write_avail = io_data->mBuffers[0].mDataByteSize;
|
write_avail = io_data->mBuffers[0].mDataByteSize;
|
||||||
outbuf = io_data->mBuffers[0].mData;
|
outbuf = io_data->mBuffers[0].mData;
|
||||||
|
|
||||||
slock_lock(dev->lock);
|
pthread_mutex_lock(&dev->lock);
|
||||||
|
|
||||||
if (fifo_read_avail(dev->buffer) < write_avail)
|
if (fifo_read_avail(dev->buffer) < write_avail)
|
||||||
{
|
{
|
||||||
@ -107,15 +107,16 @@ static OSStatus audio_write_cb(void *userdata,
|
|||||||
/* Seems to be needed. */
|
/* Seems to be needed. */
|
||||||
memset(outbuf, 0, write_avail);
|
memset(outbuf, 0, write_avail);
|
||||||
|
|
||||||
goto end;
|
pthread_mutex_unlock(&dev->lock);
|
||||||
|
|
||||||
|
/* Technically possible to deadlock without. */
|
||||||
|
pthread_cond_signal(&dev->cond);
|
||||||
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
fifo_read(dev->buffer, outbuf, write_avail);
|
fifo_read(dev->buffer, outbuf, write_avail);
|
||||||
|
pthread_mutex_unlock(&dev->lock);
|
||||||
end:
|
pthread_cond_signal(&dev->cond);
|
||||||
slock_unlock(dev->lock);
|
|
||||||
scond_signal(dev->cond);
|
|
||||||
|
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,8 +124,7 @@ end:
|
|||||||
static void choose_output_device(coreaudio_t *dev, const char* device)
|
static void choose_output_device(coreaudio_t *dev, const char* device)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
UInt32 size = 0, deviceCount;
|
AudioDeviceID *devices;
|
||||||
AudioDeviceID *devices = NULL;
|
|
||||||
AudioObjectPropertyAddress propaddr =
|
AudioObjectPropertyAddress propaddr =
|
||||||
{
|
{
|
||||||
kAudioHardwarePropertyDevices,
|
kAudioHardwarePropertyDevices,
|
||||||
@ -132,23 +132,22 @@ static void choose_output_device(coreaudio_t *dev, const char* device)
|
|||||||
kAudioObjectPropertyElementMaster
|
kAudioObjectPropertyElementMaster
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UInt32 size = 0, deviceCount;
|
||||||
|
|
||||||
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
|
if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
|
||||||
&propaddr, 0, 0, &size) != noErr)
|
&propaddr, 0, 0, &size) != noErr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
deviceCount = size / sizeof(AudioDeviceID);
|
deviceCount = size / sizeof(AudioDeviceID);
|
||||||
devices = (AudioDeviceID*)malloc(size);
|
devices = (AudioDeviceID*)malloc(size);
|
||||||
|
|
||||||
if (!devices)
|
if (!devices || AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
|
||||||
&propaddr, 0, 0, &size, devices) != noErr)
|
&propaddr, 0, 0, &size, devices) != noErr)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
propaddr.mScope = kAudioDevicePropertyScopeOutput;
|
propaddr.mScope = kAudioDevicePropertyScopeOutput;
|
||||||
propaddr.mSelector = kAudioDevicePropertyDeviceName;
|
propaddr.mSelector = kAudioDevicePropertyDeviceName;
|
||||||
size = 1024;
|
size = 1024;
|
||||||
|
|
||||||
for (i = 0; i < deviceCount; i ++)
|
for (i = 0; i < deviceCount; i ++)
|
||||||
{
|
{
|
||||||
@ -196,12 +195,12 @@ static void *coreaudio_init(const char *device,
|
|||||||
AudioStreamBasicDescription stream_desc = {0};
|
AudioStreamBasicDescription stream_desc = {0};
|
||||||
static bool session_initialized = false;
|
static bool session_initialized = false;
|
||||||
coreaudio_t *dev = NULL;
|
coreaudio_t *dev = NULL;
|
||||||
settings_t *settings = config_get_ptr();
|
|
||||||
#ifdef OSX_PPC
|
#ifdef OSX_PPC
|
||||||
ComponentDescription desc = {0};
|
ComponentDescription desc = {0};
|
||||||
#else
|
#else
|
||||||
AudioComponentDescription desc = {0};
|
AudioComponentDescription desc = {0};
|
||||||
#endif
|
#endif
|
||||||
|
settings_t *settings = config_get_ptr();
|
||||||
|
|
||||||
(void)session_initialized;
|
(void)session_initialized;
|
||||||
(void)device;
|
(void)device;
|
||||||
@ -210,22 +209,8 @@ static void *coreaudio_init(const char *device,
|
|||||||
if (!dev)
|
if (!dev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dev->lock = slock_new();
|
pthread_mutex_init(&dev->lock, NULL);
|
||||||
|
pthread_cond_init(&dev->cond, NULL);
|
||||||
if (!dev->lock)
|
|
||||||
{
|
|
||||||
free(dev);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->cond = scond_new();
|
|
||||||
|
|
||||||
if (!dev->cond)
|
|
||||||
{
|
|
||||||
free(dev->lock);
|
|
||||||
free(dev);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef IOS
|
#ifdef IOS
|
||||||
if (!session_initialized)
|
if (!session_initialized)
|
||||||
@ -284,8 +269,7 @@ static void *coreaudio_init(const char *device,
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* Check returned audio format. */
|
/* Check returned audio format. */
|
||||||
i_size = sizeof(real_desc);
|
i_size = sizeof(real_desc);
|
||||||
|
|
||||||
if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
|
if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
|
||||||
kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr)
|
kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr)
|
||||||
goto error;
|
goto error;
|
||||||
@ -351,40 +335,46 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
|
|||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
|
|
||||||
#ifdef IOS
|
#ifdef IOS
|
||||||
|
struct timespec timeout;
|
||||||
struct timeval time;
|
struct timeval time;
|
||||||
|
|
||||||
gettimeofday(&time, 0);
|
gettimeofday(&time, 0);
|
||||||
|
|
||||||
|
memset(&timeout, 0, sizeof(timeout));
|
||||||
|
timeout.tv_sec = time.tv_sec + 3;
|
||||||
|
timeout.tv_nsec = time.tv_usec * 1000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (!g_interrupted && size > 0)
|
while (!g_interrupted && size > 0)
|
||||||
{
|
{
|
||||||
size_t write_avail;
|
size_t write_avail;
|
||||||
|
|
||||||
slock_lock(dev->lock);
|
pthread_mutex_lock(&dev->lock);
|
||||||
|
|
||||||
write_avail = fifo_write_avail(dev->buffer);
|
write_avail = fifo_write_avail(dev->buffer);
|
||||||
if (write_avail > size)
|
if (write_avail > size)
|
||||||
write_avail = size;
|
write_avail = size;
|
||||||
|
|
||||||
fifo_write(dev->buffer, buf, write_avail);
|
fifo_write(dev->buffer, buf, write_avail);
|
||||||
buf += write_avail;
|
buf += write_avail;
|
||||||
written += write_avail;
|
written += write_avail;
|
||||||
size -= write_avail;
|
size -= write_avail;
|
||||||
|
|
||||||
if (dev->nonblock)
|
if (dev->nonblock)
|
||||||
{
|
{
|
||||||
slock_unlock(dev->lock);
|
pthread_mutex_unlock(&dev->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef IOS
|
#ifdef IOS
|
||||||
if (write_avail == 0 && !scond_wait_timeout(
|
if (write_avail == 0 && pthread_cond_timedwait(
|
||||||
dev->cond, dev->lock, time.tv_usec))
|
&dev->cond, &dev->lock, &timeout) == ETIMEDOUT)
|
||||||
g_interrupted = true;
|
g_interrupted = true;
|
||||||
#else
|
#else
|
||||||
if (write_avail == 0)
|
if (write_avail == 0)
|
||||||
scond_wait(dev->cond, dev->lock);
|
pthread_cond_wait(&dev->cond, &dev->lock);
|
||||||
#endif
|
#endif
|
||||||
slock_unlock(dev->lock);
|
pthread_mutex_unlock(&dev->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
@ -434,9 +424,9 @@ static size_t coreaudio_write_avail(void *data)
|
|||||||
size_t avail;
|
size_t avail;
|
||||||
coreaudio_t *dev = (coreaudio_t*)data;
|
coreaudio_t *dev = (coreaudio_t*)data;
|
||||||
|
|
||||||
slock_lock(dev->lock);
|
pthread_mutex_lock(&dev->lock);
|
||||||
avail = fifo_write_avail(dev->buffer);
|
avail = fifo_write_avail(dev->buffer);
|
||||||
slock_unlock(dev->lock);
|
pthread_mutex_unlock(&dev->lock);
|
||||||
|
|
||||||
return avail;
|
return avail;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user