From a9151fdb868f01cf9037da69a0d0ff27fe9749c1 Mon Sep 17 00:00:00 2001 From: Hans Dijkema Date: Wed, 15 Apr 2026 13:46:27 +0200 Subject: [PATCH] music id added --- ao-play-async/ao_playasync.c | 73 ++++++++++++++++++++++++++++++++---- ao-play-async/ao_playasync.h | 3 +- 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/ao-play-async/ao_playasync.c b/ao-play-async/ao_playasync.c index 5e6d5f0..a6168d9 100644 --- a/ao-play-async/ao_playasync.c +++ b/ao-play-async/ao_playasync.c @@ -17,6 +17,7 @@ #ifdef USE_PTHREADS #include #include + #include #define TIME_NS_IN_MSEC 1000000ULL static void makeSemTimeoutTime(struct timespec *ts, int ms) { @@ -37,11 +38,33 @@ return (r == 0); } + static int msleep(long msec) + { + struct timespec ts; + int res; + + if (msec < 0) { + return -1; + } + + ts.tv_sec = msec / 1000; + ts.tv_nsec = (msec % 1000) * 1000000; + + res = nanosleep(&ts, &ts); + return res; + } + + static void yield() + { + msleep(5); + } + #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) (sem_trywait(&sem) == 0) #define SEM_POST(sem) sem_post(&sem) + #define YIELD() yield() #endif #ifndef WIN32 @@ -68,6 +91,7 @@ typedef struct _queue_ { int buflen; double at_second; double music_duration; + int music_id; struct _queue_ *next; struct _queue_ *prev; } Queue_t; @@ -96,6 +120,7 @@ typedef struct { #endif double at_second; double music_duration; + int at_music_id; int buf_size; } AO_Handle; @@ -103,7 +128,12 @@ typedef struct { static Queue_t *get(AO_Handle *h, int ms_wait) { Queue_t *q = NULL; - int r = (ms_wait <= 0) ? SEM_TRYWAIT(h->queue_sem) : SEM_WAIT(h->queue_sem, ms_wait); + int r; + if (ms_wait <= 0) { + r = SEM_TRYWAIT(h->queue_sem); + } else { + r = SEM_WAIT(h->queue_sem, ms_wait); + } if (r) { MUTEX_LOCK(h->mutex); if (h->play_queue != NULL) { // Clear could have cleared the play_queue. @@ -140,7 +170,7 @@ static void add(AO_Handle *h, Queue_t *elem) MUTEX_UNLOCK(h->mutex); } -static Queue_t *new_elem(int command, double at_second, double music_duration, int buf_len, void *buf) +static Queue_t *new_elem(int command, int music_id, double at_second, double music_duration, int buf_len, void *buf) { Queue_t *q = (Queue_t *) malloc(sizeof(Queue_t)); void *new_buf; @@ -151,6 +181,7 @@ static Queue_t *new_elem(int command, double at_second, double music_duration, i } else { new_buf = NULL; } + q->music_id = music_id; q->at_second = at_second; q->music_duration = music_duration; q->buf = new_buf; @@ -171,7 +202,9 @@ static void del_elem(Queue_t *q) static void clear(AO_Handle *h) { + //fprintf(stderr, "Wait for clear mutex\n"); MUTEX_LOCK(h->clear_mutex); + //fprintf(stderr, "Starting clear\n"); int count = 0; Queue_t *q = get(h, 0); while (q != NULL) { @@ -202,6 +235,7 @@ static DWORD run(LPVOID arg) if (q != NULL) { handle->at_second = q->at_second; handle->music_duration = q->music_duration; + handle->at_music_id = q->music_id; if (q->command == STOP) { go_on = (1 == 0); @@ -210,6 +244,8 @@ static DWORD run(LPVOID arg) } del_elem(q); + } else { + YIELD(); } } @@ -268,6 +304,7 @@ void *ao_create_async(int bits, int rate, int channels, int byte_format) handle->play_queue = NULL; handle->last_frame = NULL; handle->at_second = -1; + handle->at_music_id = -1; handle->buf_size = 0; @@ -304,12 +341,20 @@ void *ao_create_async(int bits, int rate, int channels, int byte_format) void ao_stop_async(void *ao_handle) { AO_Handle *h = (AO_Handle *) ao_handle; - fprintf(stderr, "stopping ao_async\n"); + fprintf(stderr, "stopping ao_async, calling clear\n"); clear(h); - Queue_t *q = new_elem(STOP, 0.0, 0.0, 0, NULL); + + fprintf(stderr, "queue cleared\n"); + + if (h->paused) { + MUTEX_UNLOCK(h->pause_mutex); + } + Queue_t *q = new_elem(STOP, 0, 0.0, 0.0, 0, NULL); add(h, q); + fprintf(stderr, "stop command queued\n"); + #ifdef USE_PTHREADS void *retval; pthread_join(h->thread, &retval); @@ -320,7 +365,12 @@ void ao_stop_async(void *ao_handle) CloseHandle(h->mutex); #endif ao_close(h->ao_device); + + fprintf(stderr, "device closed\n"); + free(h); + + fprintf(stderr, "async handle freed\n"); } /* @@ -411,7 +461,7 @@ void *convertFlac(void *mem, int buf_len, BufferInfo_t *info, int *audio_size) return (void *) new_mem; } -void ao_play_async(void *ao_handle, double at_second, double music_duration, int buf_size, void *mem, BufferInfo_t info) +void ao_play_async(void *ao_handle, int music_id, double at_second, double music_duration, int buf_size, void *mem, BufferInfo_t info) { AO_Handle *h = (AO_Handle *) ao_handle; @@ -421,12 +471,12 @@ void ao_play_async(void *ao_handle, double at_second, double music_duration, int case flac: { int store_size = 0; void *store_mem = convertFlac(mem, buf_size, &info, &store_size); - q = new_elem(PLAY, at_second, music_duration, store_size, store_mem); + q = new_elem(PLAY, music_id, at_second, music_duration, store_size, store_mem); free(store_mem); } break; case ao: { - q = new_elem(PLAY, at_second, music_duration, buf_size, mem); + q = new_elem(PLAY, music_id, at_second, music_duration, buf_size, mem); } break; case mpg123: { @@ -467,6 +517,15 @@ double ao_is_at_second_async(void *ao_handle) return s; } +int ao_is_at_music_id_async(void *ao_handle) +{ + AO_Handle *h = (AO_Handle *) ao_handle; + MUTEX_LOCK(h->mutex); + int s = h->at_music_id; + MUTEX_UNLOCK(h->mutex); + return s; +} + double ao_music_duration_async(void *ao_handle) { AO_Handle *h = (AO_Handle *) ao_handle; diff --git a/ao-play-async/ao_playasync.h b/ao-play-async/ao_playasync.h index 6a04ff1..1bf75f5 100644 --- a/ao-play-async/ao_playasync.h +++ b/ao-play-async/ao_playasync.h @@ -31,10 +31,11 @@ typedef struct { AOPLAYASYNC_EXPORT int ao_async_version(void); AOPLAYASYNC_EXPORT void *ao_create_async(int bits, int rate, int channels, int byte_format); AOPLAYASYNC_EXPORT void ao_stop_async(void *handle); -AOPLAYASYNC_EXPORT void ao_play_async(void *handle, double at_second, double music_duration, int buf_size, void *mem, BufferInfo_t info); +AOPLAYASYNC_EXPORT void ao_play_async(void *handle, int music_id, double at_second, double music_duration, int buf_size, void *mem, BufferInfo_t info); AOPLAYASYNC_EXPORT void ao_clear_async(void *handle); AOPLAYASYNC_EXPORT double ao_is_at_second_async(void *handle); +AOPLAYASYNC_EXPORT int ao_is_at_music_id_async(void *handle); AOPLAYASYNC_EXPORT double ao_music_duration_async(void *handle); AOPLAYASYNC_EXPORT void ao_pause_async(void *ao_handle, int paused);