changes for Mac OS X

This commit is contained in:
2026-05-06 17:26:55 +02:00
parent 51a0138877
commit f4e2a6aa31
9 changed files with 141 additions and 36 deletions
+6
View File
@@ -18,6 +18,12 @@ if(WIN32)
target_link_directories(ao-play-async PRIVATE ../lib/windows-x86_64)
endif()
if(APPLE)
set(AO_HOME /opt/homebrew)
include_directories(${AO_HOME}/include)
target_link_directories(ao-play-async PRIVATE ${AO_HOME}/lib)
endif()
if(WIN32)
target_link_libraries(ao-play-async PRIVATE libao-1.2.2 winmm.lib ksuser.lib)
else()
+93 -36
View File
@@ -6,42 +6,18 @@
#define USE_WINDOWS_THREADS
#define sleep_ms(ms) Sleep(ms)
#else
#ifdef __APPLE__
#define USE_DISPATCH
#include <time.h>
#define sleep_ms(ms) msleep(ms)
#else
#define USE_PTHREADS
#include <sched.h>
#define sleep_ms(ms) usleep(ms * 1000)
#endif
#ifdef USE_WINDOWS_THREADS
#define MUTEX_LOCK(m) WaitForSingleObject(m, INFINITE)
#define MUTEX_UNLOCK(m) ReleaseMutex(m)
#define SEM_WAIT(sem, ms) (WaitForSingleObject(sem, ms) == WAIT_OBJECT_0)
#define SEM_TRYWAIT(sem) (WaitForSingleObject(sem, 0) == WAIT_OBJECT_0)
#define SEM_POST(sem) ReleaseSemaphore(sem, 1, NULL)
#define YIELD() sleep_ms(5)
#endif
#ifdef USE_PTHREADS
#include <pthread.h>
#include <semaphore.h>
#include <sched.h>
#define TIME_NS_IN_MSEC 1000000ULL
static void makeSemTimeoutTime(struct timespec *ts, int ms) {
clock_gettime(CLOCK_REALTIME, ts);
ts->tv_sec += ms / 1000;
ts->tv_nsec += (ms % 1000) * TIME_NS_IN_MSEC;
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec = ts->tv_nsec - 1000000000L;
}
}
static int _SEM_WAIT(sem_t *sem, int ms)
{
struct timespec ts;
makeSemTimeoutTime(&ts, ms);
int r = sem_timedwait(sem, &ts);
return (r == 0);
}
#if defined(USE_PTHREADS) || defined(USE_DISPATCH)
static int msleep(long msec)
{
@@ -63,6 +39,63 @@
{
msleep(5);
}
#endif
#ifdef USE_DISPATCH
#include <pthread.h>
#include <dispatch/dispatch.h>
#include <stdint.h>
static inline dispatch_time_t makeDispatchTimeoutTime(int ms)
{
return dispatch_time(DISPATCH_TIME_NOW,
(int64_t)ms * NSEC_PER_MSEC);
}
static int _SEM_WAIT(dispatch_semaphore_t sem, int ms)
{
return dispatch_semaphore_wait(sem, makeDispatchTimeoutTime(ms)) == 0;
}
#define MUTEX_LOCK(m) pthread_mutex_lock(&m)
#define MUTEX_UNLOCK(m) pthread_mutex_unlock(&m)
#define SEM_WAIT(sem, ms) _SEM_WAIT(sem, ms)
#define SEM_TRYWAIT(sem) (dispatch_semaphore_wait(sem, DISPATCH_TIME_NOW) == 0)
#define SEM_POST(sem) dispatch_semaphore_signal(sem)
#define YIELD() sleep_ms(5)
#endif
#ifdef USE_WINDOWS_THREADS
#define MUTEX_LOCK(m) WaitForSingleObject(m, INFINITE)
#define MUTEX_UNLOCK(m) ReleaseMutex(m)
#define SEM_WAIT(sem, ms) (WaitForSingleObject(sem, ms) == WAIT_OBJECT_0)
#define SEM_TRYWAIT(sem) (WaitForSingleObject(sem, 0) == WAIT_OBJECT_0)
#define SEM_POST(sem) ReleaseSemaphore(sem, 1, NULL)
#define YIELD() sleep_ms(5)
#endif
#ifdef USE_PTHREADS
#include <pthread.h>
#include <semaphore.h>
#define TIME_NS_IN_MSEC 1000000ULL
static void makeSemTimeoutTime(struct timespec *ts, int ms) {
clock_gettime(CLOCK_REALTIME, ts);
ts->tv_sec += ms / 1000;
ts->tv_nsec += (ms % 1000) * TIME_NS_IN_MSEC;
if (ts->tv_nsec >= 1000000000L) {
ts->tv_sec++;
ts->tv_nsec = ts->tv_nsec - 1000000000L;
}
}
static int _SEM_WAIT(sem_t *sem, int ms)
{
struct timespec ts;
makeSemTimeoutTime(&ts, ms);
int r = sem_timedwait(sem, &ts);
return (r == 0);
}
#define MUTEX_LOCK(m) pthread_mutex_lock(&m)
#define MUTEX_UNLOCK(m) pthread_mutex_unlock(&m)
@@ -76,7 +109,9 @@
#include <unistd.h>
#endif
#ifndef __APPLE__
#include <malloc.h>
#endif
#include <string.h>
#include <stdint.h>
#include <stdio.h>
@@ -124,12 +159,17 @@ typedef struct {
DWORD thread_id;
HANDLE queue_sem;
#endif
#ifdef USE_PTHREADS
#if defined(USE_PTHREADS) || defined(USE_DISPATCH)
pthread_mutex_t mutex;
pthread_mutex_t pause_mutex;
pthread_mutex_t clear_mutex;
pthread_t thread;
#ifdef USE_PTHREADS
sem_t queue_sem;
#endif
#ifdef USE_DISPATCH
dispatch_semaphore_t queue_sem;
#endif
#endif
double at_second;
double music_duration;
@@ -279,7 +319,7 @@ static void inline adjustVolume(AO_Handle *handle, char *_buf, int buf_size, int
}
}
#ifdef USE_PTHREADS
#if defined(USE_PTHREADS) || defined(USE_DISPATCH)
static void *run(void *arg)
#endif
#ifdef USE_WINDOWS_THREADS
@@ -317,7 +357,7 @@ static DWORD run(LPVOID arg)
}
}
#ifdef USE_PTHREADS
#if defined(USE_PTHREADS) || defined(USE_DISPATCH)
return NULL;
#endif
#ifdef USE_WINDOWS_THREADS
@@ -514,17 +554,23 @@ void *ao_create_async(int bits, int rate, int channels, int byte_format, const c
handle->paused = (1 == 0);
#ifdef USE_PTHREADS
#if defined(USE_PTHREADS) || defined(USE_DISPATCH)
pthread_mutex_t p = PTHREAD_MUTEX_INITIALIZER;
handle->pause_mutex = p;
pthread_mutex_t c = PTHREAD_MUTEX_INITIALIZER;
handle->clear_mutex = c;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
handle->mutex = m;
#ifdef USE_PTHREADS
sem_init(&handle->queue_sem, 0, 0);
#endif
#ifdef USE_DISPATCH
handle->queue_sem = dispatch_semaphore_create(0);
#endif
pthread_create(&handle->thread, NULL, run, handle);
#endif
#ifdef USE_WINDOWS_THREADS
handle->mutex = CreateMutex(NULL, // default security attributes
FALSE, // initially not owned
@@ -562,10 +608,19 @@ void ao_stop_async(void *ao_handle)
fprintf(stderr, "stop command queued\n");
#ifdef USE_PTHREADS
#if defined(USE_PTHREADS) || defined(USE_DISPATCH)
void *retval;
pthread_join(h->thread, &retval);
#ifdef USE_PTHREADS
sem_destroy(&h->queue_sem);
#endif
pthread_mutex_destroy(&h->pause_mutex);
pthread_mutex_destroy(&h->clear_mutex);
pthread_mutex_destroy(&h->mutex);
#endif
#ifdef USE_WINDOWS_THREADS
WaitForSingleObject(h->thread, INFINITE);
CloseHandle(h->thread);
@@ -708,3 +763,5 @@ int ao_real_output_bits_async(void *handle)
AO_Handle *h = (AO_Handle *) handle;
return h->dev_bits_per_sample;
}