music id added

This commit is contained in:
2026-04-15 13:46:27 +02:00
parent 298cde0779
commit a9151fdb86
2 changed files with 68 additions and 8 deletions

View File

@@ -17,6 +17,7 @@
#ifdef USE_PTHREADS #ifdef USE_PTHREADS
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#include <sched.h>
#define TIME_NS_IN_MSEC 1000000ULL #define TIME_NS_IN_MSEC 1000000ULL
static void makeSemTimeoutTime(struct timespec *ts, int ms) { static void makeSemTimeoutTime(struct timespec *ts, int ms) {
@@ -37,11 +38,33 @@
return (r == 0); 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_LOCK(m) pthread_mutex_lock(&m)
#define MUTEX_UNLOCK(m) pthread_mutex_unlock(&m) #define MUTEX_UNLOCK(m) pthread_mutex_unlock(&m)
#define SEM_WAIT(sem, ms) _SEM_WAIT(&sem, ms) #define SEM_WAIT(sem, ms) _SEM_WAIT(&sem, ms)
#define SEM_TRYWAIT(sem) (sem_trywait(&sem) == 0) #define SEM_TRYWAIT(sem) (sem_trywait(&sem) == 0)
#define SEM_POST(sem) sem_post(&sem) #define SEM_POST(sem) sem_post(&sem)
#define YIELD() yield()
#endif #endif
#ifndef WIN32 #ifndef WIN32
@@ -68,6 +91,7 @@ typedef struct _queue_ {
int buflen; int buflen;
double at_second; double at_second;
double music_duration; double music_duration;
int music_id;
struct _queue_ *next; struct _queue_ *next;
struct _queue_ *prev; struct _queue_ *prev;
} Queue_t; } Queue_t;
@@ -96,6 +120,7 @@ typedef struct {
#endif #endif
double at_second; double at_second;
double music_duration; double music_duration;
int at_music_id;
int buf_size; int buf_size;
} AO_Handle; } AO_Handle;
@@ -103,7 +128,12 @@ typedef struct {
static Queue_t *get(AO_Handle *h, int ms_wait) static Queue_t *get(AO_Handle *h, int ms_wait)
{ {
Queue_t *q = NULL; 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) { if (r) {
MUTEX_LOCK(h->mutex); MUTEX_LOCK(h->mutex);
if (h->play_queue != NULL) { // Clear could have cleared the play_queue. 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); 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)); Queue_t *q = (Queue_t *) malloc(sizeof(Queue_t));
void *new_buf; void *new_buf;
@@ -151,6 +181,7 @@ static Queue_t *new_elem(int command, double at_second, double music_duration, i
} else { } else {
new_buf = NULL; new_buf = NULL;
} }
q->music_id = music_id;
q->at_second = at_second; q->at_second = at_second;
q->music_duration = music_duration; q->music_duration = music_duration;
q->buf = new_buf; q->buf = new_buf;
@@ -171,7 +202,9 @@ static void del_elem(Queue_t *q)
static void clear(AO_Handle *h) static void clear(AO_Handle *h)
{ {
//fprintf(stderr, "Wait for clear mutex\n");
MUTEX_LOCK(h->clear_mutex); MUTEX_LOCK(h->clear_mutex);
//fprintf(stderr, "Starting clear\n");
int count = 0; int count = 0;
Queue_t *q = get(h, 0); Queue_t *q = get(h, 0);
while (q != NULL) { while (q != NULL) {
@@ -202,6 +235,7 @@ static DWORD run(LPVOID arg)
if (q != NULL) { if (q != NULL) {
handle->at_second = q->at_second; handle->at_second = q->at_second;
handle->music_duration = q->music_duration; handle->music_duration = q->music_duration;
handle->at_music_id = q->music_id;
if (q->command == STOP) { if (q->command == STOP) {
go_on = (1 == 0); go_on = (1 == 0);
@@ -210,6 +244,8 @@ static DWORD run(LPVOID arg)
} }
del_elem(q); 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->play_queue = NULL;
handle->last_frame = NULL; handle->last_frame = NULL;
handle->at_second = -1; handle->at_second = -1;
handle->at_music_id = -1;
handle->buf_size = 0; 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) void ao_stop_async(void *ao_handle)
{ {
AO_Handle *h = (AO_Handle *) 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); 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); add(h, q);
fprintf(stderr, "stop command queued\n");
#ifdef USE_PTHREADS #ifdef USE_PTHREADS
void *retval; void *retval;
pthread_join(h->thread, &retval); pthread_join(h->thread, &retval);
@@ -320,7 +365,12 @@ void ao_stop_async(void *ao_handle)
CloseHandle(h->mutex); CloseHandle(h->mutex);
#endif #endif
ao_close(h->ao_device); ao_close(h->ao_device);
fprintf(stderr, "device closed\n");
free(h); 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; 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; 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: { case flac: {
int store_size = 0; int store_size = 0;
void *store_mem = convertFlac(mem, buf_size, &info, &store_size); 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); free(store_mem);
} }
break; break;
case ao: { 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; break;
case mpg123: { case mpg123: {
@@ -467,6 +517,15 @@ double ao_is_at_second_async(void *ao_handle)
return s; 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) double ao_music_duration_async(void *ao_handle)
{ {
AO_Handle *h = (AO_Handle *) ao_handle; AO_Handle *h = (AO_Handle *) ao_handle;

View File

@@ -31,10 +31,11 @@ typedef struct {
AOPLAYASYNC_EXPORT int ao_async_version(void); 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_create_async(int bits, int rate, int channels, int byte_format);
AOPLAYASYNC_EXPORT void ao_stop_async(void *handle); 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 void ao_clear_async(void *handle);
AOPLAYASYNC_EXPORT double ao_is_at_second_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 double ao_music_duration_async(void *handle);
AOPLAYASYNC_EXPORT void ao_pause_async(void *ao_handle, int paused); AOPLAYASYNC_EXPORT void ao_pause_async(void *ao_handle, int paused);