diff --git a/.gitignore b/.gitignore index bbb7395..7d031e0 100644 --- a/.gitignore +++ b/.gitignore @@ -20,5 +20,8 @@ build lib/linux-x86_64 build-ffmpeg +.DS_Store +*.user + /ffmpeg-audio/.qtcreator diff --git a/Makefile b/Makefile index 1fcc77f..d4bb1bd 100644 --- a/Makefile +++ b/Makefile @@ -11,9 +11,11 @@ all: install: all mkdir -p lib/$(SUBDIR) @echo "copying from src/$(SUBDIR) to lib/$(SUBDIR)" + exit (cd src/$(SUBDIR);tar cf - . ) | (cd lib/$(SUBDIR); tar xvf - ) FILES=`ls build/*.so build-ffmpeg/*.so` 2>/dev/null; if [ "$$FILES" != "" ]; then cp $$FILES lib/$(SUBDIR); fi FILES=`ls build/*.dll build-ffmpeg/*.dll` 2>/dev/null; if [ "$$FILES" != "" ]; then cp $$FILES lib/$(SUBDIR); fi + FILES=`ls build/*.dylib build-ffmpeg/*.dylib` 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 diff --git a/ao-play-async/CMakeLists.txt b/ao-play-async/CMakeLists.txt index 0b36660..5597955 100644 --- a/ao-play-async/CMakeLists.txt +++ b/ao-play-async/CMakeLists.txt @@ -18,6 +18,12 @@ if(WIN32) target_link_directories(ao-play-async PRIVATE ../lib/windows-x86_64) endif() +if(APPLE) + set(AO_HOME /opt/homebrew) + include_directories(${AO_HOME}/include) + target_link_directories(ao-play-async PRIVATE ${AO_HOME}/lib) +endif() + if(WIN32) target_link_libraries(ao-play-async PRIVATE libao-1.2.2 winmm.lib ksuser.lib) else() diff --git a/ao-play-async/ao_playasync.c b/ao-play-async/ao_playasync.c index 3b53612..6870344 100644 --- a/ao-play-async/ao_playasync.c +++ b/ao-play-async/ao_playasync.c @@ -6,42 +6,18 @@ #define USE_WINDOWS_THREADS #define sleep_ms(ms) Sleep(ms) #else +#ifdef __APPLE__ +#define USE_DISPATCH +#include +#define sleep_ms(ms) msleep(ms) +#else #define USE_PTHREADS +#include #define sleep_ms(ms) usleep(ms * 1000) #endif - -#ifdef USE_WINDOWS_THREADS - #define MUTEX_LOCK(m) WaitForSingleObject(m, INFINITE) - #define MUTEX_UNLOCK(m) ReleaseMutex(m) - #define SEM_WAIT(sem, ms) (WaitForSingleObject(sem, ms) == WAIT_OBJECT_0) - #define SEM_TRYWAIT(sem) (WaitForSingleObject(sem, 0) == WAIT_OBJECT_0) - #define SEM_POST(sem) ReleaseSemaphore(sem, 1, NULL) - #define YIELD() sleep_ms(5) #endif -#ifdef USE_PTHREADS - #include - #include - #include - - #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); - } +#if defined(USE_PTHREADS) || defined(USE_DISPATCH) static int msleep(long msec) { @@ -63,6 +39,63 @@ { msleep(5); } +#endif + +#ifdef USE_DISPATCH + #include + #include + #include + + static inline dispatch_time_t makeDispatchTimeoutTime(int ms) + { + return dispatch_time(DISPATCH_TIME_NOW, + (int64_t)ms * NSEC_PER_MSEC); + } + + static int _SEM_WAIT(dispatch_semaphore_t sem, int ms) + { + return dispatch_semaphore_wait(sem, makeDispatchTimeoutTime(ms)) == 0; + } + + #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) (dispatch_semaphore_wait(sem, DISPATCH_TIME_NOW) == 0) + #define SEM_POST(sem) dispatch_semaphore_signal(sem) + #define YIELD() sleep_ms(5) +#endif + +#ifdef USE_WINDOWS_THREADS + #define MUTEX_LOCK(m) WaitForSingleObject(m, INFINITE) + #define MUTEX_UNLOCK(m) ReleaseMutex(m) + #define SEM_WAIT(sem, ms) (WaitForSingleObject(sem, ms) == WAIT_OBJECT_0) + #define SEM_TRYWAIT(sem) (WaitForSingleObject(sem, 0) == WAIT_OBJECT_0) + #define SEM_POST(sem) ReleaseSemaphore(sem, 1, NULL) + #define YIELD() sleep_ms(5) +#endif + +#ifdef USE_PTHREADS + #include + #include + + #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); + } #define MUTEX_LOCK(m) pthread_mutex_lock(&m) #define MUTEX_UNLOCK(m) pthread_mutex_unlock(&m) @@ -76,7 +109,9 @@ #include #endif +#ifndef __APPLE__ #include +#endif #include #include #include @@ -124,12 +159,17 @@ typedef struct { DWORD thread_id; HANDLE queue_sem; #endif -#ifdef USE_PTHREADS +#if defined(USE_PTHREADS) || defined(USE_DISPATCH) pthread_mutex_t mutex; pthread_mutex_t pause_mutex; pthread_mutex_t clear_mutex; pthread_t thread; + #ifdef USE_PTHREADS sem_t queue_sem; + #endif + #ifdef USE_DISPATCH + dispatch_semaphore_t queue_sem; + #endif #endif double at_second; double music_duration; @@ -279,7 +319,7 @@ static void inline adjustVolume(AO_Handle *handle, char *_buf, int buf_size, int } } -#ifdef USE_PTHREADS +#if defined(USE_PTHREADS) || defined(USE_DISPATCH) static void *run(void *arg) #endif #ifdef USE_WINDOWS_THREADS @@ -317,7 +357,7 @@ static DWORD run(LPVOID arg) } } -#ifdef USE_PTHREADS +#if defined(USE_PTHREADS) || defined(USE_DISPATCH) return NULL; #endif #ifdef USE_WINDOWS_THREADS @@ -514,17 +554,23 @@ void *ao_create_async(int bits, int rate, int channels, int byte_format, const c handle->paused = (1 == 0); -#ifdef USE_PTHREADS +#if defined(USE_PTHREADS) || defined(USE_DISPATCH) 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; handle->mutex = m; +#ifdef USE_PTHREADS sem_init(&handle->queue_sem, 0, 0); +#endif +#ifdef USE_DISPATCH + handle->queue_sem = dispatch_semaphore_create(0); +#endif pthread_create(&handle->thread, NULL, run, handle); #endif + #ifdef USE_WINDOWS_THREADS handle->mutex = CreateMutex(NULL, // default security attributes FALSE, // initially not owned @@ -562,10 +608,19 @@ void ao_stop_async(void *ao_handle) fprintf(stderr, "stop command queued\n"); -#ifdef USE_PTHREADS +#if defined(USE_PTHREADS) || defined(USE_DISPATCH) void *retval; pthread_join(h->thread, &retval); + + #ifdef USE_PTHREADS + sem_destroy(&h->queue_sem); + #endif + + pthread_mutex_destroy(&h->pause_mutex); + pthread_mutex_destroy(&h->clear_mutex); + pthread_mutex_destroy(&h->mutex); #endif + #ifdef USE_WINDOWS_THREADS WaitForSingleObject(h->thread, INFINITE); CloseHandle(h->thread); @@ -708,3 +763,5 @@ int ao_real_output_bits_async(void *handle) AO_Handle *h = (AO_Handle *) handle; return h->dev_bits_per_sample; } + + diff --git a/ffmpeg-audio/CMakeLists.txt b/ffmpeg-audio/CMakeLists.txt index db2c3dd..6814231 100644 --- a/ffmpeg-audio/CMakeLists.txt +++ b/ffmpeg-audio/CMakeLists.txt @@ -22,6 +22,11 @@ if(WIN32) target_link_directories(ffmpeg_audio PRIVATE ${FFMPEG_LIB}) set(FFMPEG_LIBRARIES avcodec.lib avformat.lib swresample.lib avutil.lib avdevice.lib avfilter.lib swscale.lib) target_link_directories(demo_ffmpeg_audio PRIVATE ${FFMPEG_LIB}) +elseif(APPLE) + target_link_directories(ffmpeg_audio PRIVATE /opt/homebrew/opt/ffmpeg-full/lib) + include_directories(/opt/homebrew/opt/ffmpeg-full/include) + set(FFMPEG_LIBRARIES avcodec avformat swresample avutil avdevice avfilter swscale) + target_link_directories(demo_ffmpeg_audio PRIVATE /opt/homebrew/opt/ffmpeg-full/lib) else() set(FFMPEG_LIBRARIES avcodec avformat swresample avutil avdevice avfilter swscale) endif() diff --git a/lib/Building Win32.txt b/lib/Building Win32.txt new file mode 100644 index 0000000..b97d7e5 --- /dev/null +++ b/lib/Building Win32.txt @@ -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_/ + + + diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000..e76a88b --- /dev/null +++ b/lib/Makefile @@ -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 diff --git a/lib/macosx-aarch64.zip b/lib/macosx-aarch64.zip new file mode 100644 index 0000000..5a55694 Binary files /dev/null and b/lib/macosx-aarch64.zip differ diff --git a/lib/taglib-2.2.1.tar.gz b/lib/taglib-2.2.1.tar.gz new file mode 100644 index 0000000..17d68f5 Binary files /dev/null and b/lib/taglib-2.2.1.tar.gz differ