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