music id added
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#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) {
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user