Compare commits

...

12 Commits

Author SHA1 Message Date
a9151fdb86 music id added 2026-04-15 13:46:27 +02:00
298cde0779 moved ao library access to ao-play-async, because it only provides overhead and no benefits. All playing will be done via ao-play-async 2026-04-15 09:39:59 +02:00
373da4aa18 using semaphores... 2026-04-14 18:11:34 +02:00
d33bdb3482 created semaphore for queue and mutex for pause 2026-04-14 15:08:32 +02:00
d5957c86bd zlib dependency added for windows 2026-04-11 22:12:15 +02:00
6bcb2702a9 removed fprintf stderrs 2026-04-10 08:40:18 +02:00
be4f0ff9dd - 2026-04-10 08:32:06 +02:00
09955bebdc add dlls 2026-04-07 14:14:00 +02:00
2879e3f606 - 2026-04-07 14:12:58 +02:00
424128975d - 2026-04-07 14:12:08 +02:00
a3119a2444 taglib on windows. 2026-04-07 14:09:13 +02:00
18803c36f1 - 2026-04-07 13:45:54 +02:00
17 changed files with 397 additions and 78 deletions

15
.gitignore vendored
View File

@@ -12,23 +12,8 @@
*.gch *.gch
*.pch *.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files # Fortran module files
*.mod *.mod
*.smod *.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app

View File

@@ -1,16 +1,26 @@
all: all:
mkdir -p build mkdir -p build
cmake -S ao-play-async -B build cmake -S ao-play-async -B build
(cd build; make) (cd build; make)
install: install: all
mkdir -p ../../lib
SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \ SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \
FILES=`ls build/*.so` 2>/dev/null; if [ "$$FILES" != "" ]; then cp $$FILES ../../lib/$$SUBDIR; fi mkdir -p lib/$$SUBDIR
SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \ SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \
FILES=`ls build/*.dll` 2>/dev/null; if [ "$$FILES" != "" ]; then cp $$FILES ../../lib/$$SUBDIR; fi FILES=`ls build/*.so` 2>/dev/null; if [ "$$FILES" != "" ]; then cp $$FILES lib/$$SUBDIR; fi
SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \
FILES=`ls build/*.dll` 2>/dev/null; if [ "$$FILES" != "" ]; then cp $$FILES lib/$$SUBDIR; fi
test: install
cp lib/linux-x86_64/*.so ~/.local/share/racket/racket-sound-lib/linux-x86_64
zip: install
SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \
(cd lib; zip -y -r -9 $$SUBDIR.zip $$SUBDIR)
SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \
(cd lib; rm -rf $$SUBDIR)
clean: clean:
rm -rf build rm -rf build

View File

@@ -72,3 +72,4 @@ CMakeLists.txt.user*
*.dll *.dll
*.exe *.exe
build

View File

@@ -10,4 +10,6 @@ add_library(ao-play-async SHARED
ao_playasync.h ao_playasync.h
) )
target_link_libraries(ao-play-async PRIVATE ao)
target_compile_definitions(ao-play-async PRIVATE AOPLAYASYNC_LIBRARY) target_compile_definitions(ao-play-async PRIVATE AOPLAYASYNC_LIBRARY)

View File

@@ -16,27 +16,74 @@
#ifdef USE_PTHREADS #ifdef USE_PTHREADS
#include <pthread.h> #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);
}
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_TRYWAIT(sem) (sem_trywait(&sem) == 0)
#define SEM_POST(sem) sem_post(&sem)
#define YIELD() yield()
#endif #endif
#ifndef WIN32 #ifndef WIN32
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <assert.h>
#include <malloc.h> #include <malloc.h>
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <ao/ao.h>
typedef enum { typedef enum {
PLAY = 1, PLAY = 1,
STOP = 2 STOP = 2
} Command_t; } Command_t;
typedef void * ao_device;
typedef struct _queue_ { typedef struct _queue_ {
Command_t command; Command_t command;
@@ -44,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;
@@ -53,36 +101,43 @@ typedef int(*ao_play_func_t)(void *, char *, uint32_t);
typedef struct { typedef struct {
Queue_t *play_queue; Queue_t *play_queue;
Queue_t *last_frame; Queue_t *last_frame;
int paused;
ao_device *ao_device; ao_device *ao_device;
#ifdef USE_WINDOWS_THREADS #ifdef USE_WINDOWS_THREADS
HANDLE mutex; HANDLE mutex;
HANDLE pause_mutex;
HANDLE thread; HANDLE thread;
DWORD thread_id; DWORD thread_id;
#endif #endif
#ifdef USE_PTHREADS #ifdef USE_PTHREADS
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_mutex_t pause_mutex;
pthread_mutex_t clear_mutex;
pthread_t thread; pthread_t thread;
sem_t queue_sem;
#endif #endif
double at_second; double at_second;
double music_duration; double music_duration;
ao_play_func_t ao_play_f; int at_music_id;
int buf_size; int buf_size;
int paused;
} AO_Handle; } AO_Handle;
//static int(*ao_play)(void *device, char *samples, uint32_t n) = NULL;
static Queue_t *get(AO_Handle *h, int ms_wait)
static Queue_t *front(AO_Handle *h)
{ {
assert(h->play_queue != NULL); Queue_t *q = NULL;
return h->play_queue; int r;
} if (ms_wait <= 0) {
r = SEM_TRYWAIT(h->queue_sem);
static Queue_t *get(AO_Handle *h) } else {
{ r = SEM_WAIT(h->queue_sem, ms_wait);
assert(h->play_queue != NULL); }
Queue_t *q = h->play_queue; if (r) {
MUTEX_LOCK(h->mutex);
if (h->play_queue != NULL) { // Clear could have cleared the play_queue.
q = h->play_queue;
h->play_queue = h->play_queue->next; h->play_queue = h->play_queue->next;
if (h->play_queue == NULL) { if (h->play_queue == NULL) {
h->last_frame = NULL; h->last_frame = NULL;
@@ -90,11 +145,15 @@ static Queue_t *get(AO_Handle *h)
h->play_queue->prev = NULL; h->play_queue->prev = NULL;
} }
h->buf_size -= q->buflen; h->buf_size -= q->buflen;
}
MUTEX_UNLOCK(h->mutex);
}
return q; return q;
} }
static void add(AO_Handle *h, Queue_t *elem) static void add(AO_Handle *h, Queue_t *elem)
{ {
MUTEX_LOCK(h->mutex);
if (h->last_frame == NULL) { if (h->last_frame == NULL) {
h->play_queue = elem; h->play_queue = elem;
elem->next = NULL; elem->next = NULL;
@@ -107,9 +166,11 @@ static void add(AO_Handle *h, Queue_t *elem)
h->last_frame = elem; h->last_frame = elem;
} }
h->buf_size += elem->buflen; h->buf_size += elem->buflen;
SEM_POST(h->queue_sem);
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;
@@ -120,11 +181,12 @@ 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;
q->buflen = buf_len; q->buflen = buf_len;
q->command = command; q->command = (Command_t) command;
q->next = NULL; q->next = NULL;
q->prev = NULL; q->prev = NULL;
return q; return q;
@@ -140,10 +202,18 @@ static void del_elem(Queue_t *q)
static void clear(AO_Handle *h) static void clear(AO_Handle *h)
{ {
while (h->play_queue != NULL) { //fprintf(stderr, "Wait for clear mutex\n");
Queue_t *q = get(h); MUTEX_LOCK(h->clear_mutex);
//fprintf(stderr, "Starting clear\n");
int count = 0;
Queue_t *q = get(h, 0);
while (q != NULL) {
del_elem(q); del_elem(q);
count += 1;
q = get(h, 0);
} }
fprintf(stderr, "%d elements cleared\n", count);
MUTEX_UNLOCK(h->clear_mutex);
} }
#ifdef USE_PTHREADS #ifdef USE_PTHREADS
@@ -154,30 +224,28 @@ static DWORD run(LPVOID arg)
#endif #endif
{ {
AO_Handle *handle = (AO_Handle *) arg; AO_Handle *handle = (AO_Handle *) arg;
int go_on = (1 == 1); int go_on = (1 == 1);
while(go_on) { while(go_on) {
MUTEX_LOCK(handle->mutex); MUTEX_LOCK(handle->pause_mutex);
int has_frames = (!handle->paused) && (handle->play_queue != NULL); MUTEX_UNLOCK(handle->pause_mutex);
MUTEX_LOCK(handle->clear_mutex);
if (has_frames) { Queue_t *q = get(handle, 250);
Queue_t *q = get(handle); MUTEX_UNLOCK(handle->clear_mutex);
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;
MUTEX_UNLOCK(handle->mutex); handle->at_music_id = q->music_id;
if (q->command == STOP) { if (q->command == STOP) {
go_on = (1 == 0); go_on = (1 == 0);
} else { } else {
//fprintf(stderr, "playing buf at %lf\n", handle->at_second); ao_play(handle->ao_device, (char *) q->buf, q->buflen);
handle->ao_play_f(handle->ao_device, q->buf, q->buflen);
} }
del_elem(q); del_elem(q);
} else { } else {
MUTEX_UNLOCK(handle->mutex); YIELD();
sleep_ms(5); // sleep for 5ms
} }
} }
@@ -189,24 +257,67 @@ static DWORD run(LPVOID arg)
#endif #endif
} }
void *ao_create_async(void *ao_device_yeah, void *ao_play_f) int ao_async_version()
{ {
//if (ao_play == NULL) { get_ao_play(); } return VERSION;
}
#ifdef _WIN32
#else
#include <dlfcn.h>
#endif
static void at_exit_shutdown_ao()
{
ao_shutdown();
}
static void init_ao()
{
static int init = 0;
if (!init) {
ao_initialize();
atexit(at_exit_shutdown_ao);
}
}
void *ao_create_async(int bits, int rate, int channels, int byte_format)
{
init_ao();
AO_Handle *handle = (AO_Handle *) malloc(sizeof(AO_Handle)); AO_Handle *handle = (AO_Handle *) malloc(sizeof(AO_Handle));
handle->ao_device = (ao_device *) ao_device_yeah; ao_sample_format fmt;
fmt.bits = bits;
fmt.rate = rate;
fmt.byte_format = byte_format;
fmt.channels = channels;
fmt.matrix = NULL;
ao_device *dev = ao_open_live(ao_default_driver_id(), &fmt, NULL);
if (dev == NULL) {
fprintf(stderr, "Cannot open ao-device, error code = %d\n", errno);
return NULL;
}
handle->ao_device = dev;
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->ao_play_f = ao_play_f;
handle->buf_size = 0; handle->buf_size = 0;
handle->paused = (1 == 0); handle->paused = (1 == 0);
#ifdef USE_PTHREADS #ifdef USE_PTHREADS
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; pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
handle->mutex = m; handle->mutex = m;
sem_init(&handle->queue_sem, 0, 0);
pthread_create(&handle->thread, NULL, run, handle); pthread_create(&handle->thread, NULL, run, handle);
#endif #endif
@@ -214,21 +325,35 @@ void *ao_create_async(void *ao_device_yeah, void *ao_play_f)
handle->mutex = CreateMutex(NULL, // default security attributes handle->mutex = CreateMutex(NULL, // default security attributes
FALSE, // initially not owned FALSE, // initially not owned
NULL); NULL);
handle->pause_mutex = CreateMutex(NULL, // default security attributes
FALSE, // initially not owned
NULL);
handle->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) run, handle, 0, &handle->thread_id); handle->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) run, handle, 0, &handle->thread_id);
// TODO Windows Semaphores!
#endif #endif
MUTEX_UNLOCK(handle->pause_mutex);
MUTEX_UNLOCK(handle->clear_mutex);
return (void *) handle; return (void *) handle;
} }
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, calling clear\n");
MUTEX_LOCK(h->mutex);
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);
MUTEX_UNLOCK(h->mutex);
fprintf(stderr, "stop command queued\n");
#ifdef USE_PTHREADS #ifdef USE_PTHREADS
void *retval; void *retval;
@@ -239,24 +364,148 @@ void ao_stop_async(void *ao_handle)
CloseHandle(h->thread); CloseHandle(h->thread);
CloseHandle(h->mutex); CloseHandle(h->mutex);
#endif #endif
ao_close(h->ao_device);
fprintf(stderr, "device closed\n");
free(h); free(h);
fprintf(stderr, "async handle freed\n");
} }
void ao_play_async(void *ao_handle, double at_second, double music_duration, int buf_size, void *mem) /*
(define (abs x) (if (>= x 0) x (* x -1)))
(define (make-sample-bytes sample bytes-per-sample endianess)
(letrec ((mk (lambda (i d)
(if (< i bytes-per-sample)
(cons (bitwise-and d 255)
(mk (+ i 1) (arithmetic-shift d -8)))
'()))))
(let ((bytes (mk 0 sample)))
(if (eq? endianess 'big-endian)
(reverse bytes)
bytes))))
;(get-sample (lambda (k channel)
; (let ((chan-buf (list-ref buffer channel)))
; (vector-ref chan-buf k))))
)
;(letrec ((i 0)
; (fill (lambda (k channel)
; (if (< k buf-len)
; (if (< channel channels)
; (let* ((sample (get-sample k channel))
; (bytes (make-sample-bytes sample bytes-per-sample endianess))
; )
; (for-each (lambda (byte)
; (ptr-set! audio _byte i byte)
; (set! i (+ i 1)))
; bytes)
; ;; process sample
; (fill k (+ channel 1)))
; (fill (+ k 1) 0))
; 'filled))
; ))
; (fill 0 0)
*/
#define AO_FMT_LITTLE 1
#define AO_FMT_BIG 2
#define AO_FMT_NATIVE 4
static inline void make_sample_bytes(int32_t sample, int bytes_per_sample, int endianess, unsigned char b[4])
{
int i;
for (i = 0; i < bytes_per_sample; i++) {
b[i] = sample&0xff;
sample = sample >> 8;
}
if (endianess == AO_FMT_BIG) {
unsigned char b1[4] = { 0, 0, 0, 0 };
for(i = 0; i < bytes_per_sample; i++) {
b1[bytes_per_sample - i - 1] = b[i];
}
for(i = 0; i < bytes_per_sample; i++) {
b[i] = b1[i];
}
}
}
void *convertFlac(void *mem, int buf_len, BufferInfo_t *info, int *audio_size)
{
// buf_size equals number of samples of 32bit for all channels. So buf_size for flac = 4 * buf_len * channels
int bytes = info->sample_bits / 8;
int endianness = info->endiannes;
int store_size = info->channels * bytes * buf_len;
unsigned char *new_mem = (unsigned char *) malloc(store_size);
*audio_size = store_size;
int32_t **buffer = (int32_t **) mem;
int i, k, channel;
i = 0;
for(k = 0; k < buf_len; k++) {
for(channel = 0; channel < info->channels; channel++) {
int32_t *chan = buffer[channel];
int32_t sample = chan[k];
unsigned char b[4];
make_sample_bytes(sample, bytes, endianness, b);
for(int j = 0; j < bytes; j++) {
new_mem[i++] = b[j];
}
}
}
return (void *) new_mem;
}
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;
Queue_t *q = new_elem(PLAY, at_second, music_duration, buf_size, mem);
MUTEX_LOCK(h->mutex); Queue_t *q = NULL;
switch(info.type) {
case flac: {
int store_size = 0;
void *store_mem = convertFlac(mem, buf_size, &info, &store_size);
q = new_elem(PLAY, music_id, at_second, music_duration, store_size, store_mem);
free(store_mem);
}
break;
case ao: {
q = new_elem(PLAY, music_id, at_second, music_duration, buf_size, mem);
}
break;
case mpg123: {
static int warned = 0;
if (!warned) {
warned = 1;
fprintf(stderr, "format mpg123 not supported yet\n");
}
return;
}
break;
case ao_ogg: {
static int warned = 0;
if (!warned) {
warned = 1;
fprintf(stderr, "format ao_ogg not supported yet\n");
}
return;
}
break;
}
add(h, q); add(h, q);
MUTEX_UNLOCK(h->mutex);
} }
void ao_clear_async(void *ao_handle) void ao_clear_async(void *ao_handle)
{ {
AO_Handle *h = (AO_Handle *) ao_handle; AO_Handle *h = (AO_Handle *) ao_handle;
MUTEX_LOCK(h->mutex);
clear(h); clear(h);
MUTEX_UNLOCK(h->mutex);
} }
double ao_is_at_second_async(void *ao_handle) double ao_is_at_second_async(void *ao_handle)
@@ -268,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;
@@ -290,7 +548,19 @@ void ao_pause_async(void *ao_handle, int paused)
{ {
AO_Handle *h = (AO_Handle *) ao_handle; AO_Handle *h = (AO_Handle *) ao_handle;
MUTEX_LOCK(h->mutex); MUTEX_LOCK(h->mutex);
if (h->paused) {
if (!paused) {
h->paused = paused; h->paused = paused;
MUTEX_UNLOCK(h->pause_mutex);
}
} else {
if (paused) {
h->paused = paused;
MUTEX_LOCK(h->pause_mutex);
}
}
MUTEX_UNLOCK(h->mutex); MUTEX_UNLOCK(h->mutex);
} }

View File

@@ -11,12 +11,31 @@
#define AOPLAYASYNC_EXPORT extern #define AOPLAYASYNC_EXPORT extern
#endif #endif
AOPLAYASYNC_EXPORT void *ao_create_async(void *ao_handle, void *ao_play_f); #define VERSION 2
typedef enum {
ao = 1,
flac = 2,
mpg123 = 3,
ao_ogg = 4
} BufferType_t;
typedef struct {
BufferType_t type;
int sample_bits;
int sample_rate;
int channels;
int endiannes;
} BufferInfo_t;
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_stop_async(void *handle);
AOPLAYASYNC_EXPORT void ao_play_async(void *handle, double at_second, double music_duration, int buf_size, void *mem); 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);

BIN
lib/linux-x86_64.zip Normal file

Binary file not shown.

BIN
lib/windows-x86_64.zip Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/windows-x86_64/tag.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/windows-x86_64/zlib.dll Normal file

Binary file not shown.

17
src/Building Win32.txt Normal file
View File

@@ -0,0 +1,17 @@
Building for Win32.
Extract the taglib sources.
Add this in CMakeLists.txt:
set(ZLIB_LIBRARY "c:/devel/libraries/nwin64/lib/zlib.lib")
set(ZLIB_INCLUDE_DIR "c:/devel/libraries/nwin64/include")
set(BUILD_TESTING OFF)
set(BUILD_SHARED_LIBS ON)
Or any place you have zlib.lib stored.
Copy the shared libraries to ../lib/windows_<arch>/

15
src/Makefile Normal file
View File

@@ -0,0 +1,15 @@
TAGLIB=taglib-2.2.1
all:
tar xf ${TAGLIB}.tar.gz
SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \
(cd ${TAGLIB}; cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=../lib/$$SUBDIR -DCMAKE_BUILD_TYPE=Release .)
(cd ${TAGLIB}; make)
(cd ${TAGLIB}; make install)
SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \
(cd lib/$$SUBDIR/lib; tar cf - *so *.so.*) | (cd ../lib/$$SUBDIR; tar xvf - )
clean:
rm -rf ${TAGLIB}
rm -rf lib

BIN
src/taglib-2.2.1.tar.gz Normal file

Binary file not shown.