From be4f0ff9dd801a1b91c1cec070bf7d863d0091e7 Mon Sep 17 00:00:00 2001 From: Hans Dijkema Date: Fri, 10 Apr 2026 08:32:06 +0200 Subject: [PATCH] - --- Makefile | 4 +- ao-play-async/ao_playasync.c | 136 ++++++++++++++++++++++++++++++++++- ao-play-async/ao_playasync.h | 20 +++++- lib/linux-x86_64.zip | Bin 664782 -> 665647 bytes 4 files changed, 155 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index c1da169..9505770 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ all: cmake -S ao-play-async -B build (cd build; make) -install: +install: all SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \ mkdir -p lib/$$SUBDIR SUBDIR=`racket -e "(display (format \"~a-~a\" (system-type 'os*) (system-type 'arch)))"`; \ @@ -13,7 +13,7 @@ install: 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 -zip: +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)))"`; \ diff --git a/ao-play-async/ao_playasync.c b/ao-play-async/ao_playasync.c index e35dae2..9557eef 100644 --- a/ao-play-async/ao_playasync.c +++ b/ao-play-async/ao_playasync.c @@ -30,12 +30,14 @@ #include #include #include +#include typedef enum { PLAY = 1, STOP = 2 } Command_t; + typedef void * ao_device; typedef struct _queue_ { @@ -189,6 +191,11 @@ static DWORD run(LPVOID arg) #endif } +int ao_async_version() +{ + return VERSION; +} + void *ao_create_async(void *ao_device_yeah, void *ao_play_f) { //if (ao_play == NULL) { get_ao_play(); } @@ -242,10 +249,135 @@ void ao_stop_async(void *ao_handle) free(h); } -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, double at_second, double music_duration, int buf_size, void *mem, BufferInfo_t info) { AO_Handle *h = (AO_Handle *) ao_handle; - Queue_t *q = new_elem(PLAY, at_second, music_duration, buf_size, mem); + + fprintf(stderr, "ao_play_async: %lf %lf %d %d\n", at_second, music_duration, buf_size, info.type); + + 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, at_second, music_duration, store_size, store_mem); + free(store_mem); + fprintf(stderr, "flac made\n"); + } + break; + case ao: { + q = new_elem(PLAY, 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; + } + MUTEX_LOCK(h->mutex); add(h, q); MUTEX_UNLOCK(h->mutex); diff --git a/ao-play-async/ao_playasync.h b/ao-play-async/ao_playasync.h index 4352ed9..a0b69d0 100644 --- a/ao-play-async/ao_playasync.h +++ b/ao-play-async/ao_playasync.h @@ -11,9 +11,27 @@ #define AOPLAYASYNC_EXPORT extern #endif +#define VERSION 1 + +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(void *ao_handle, void *ao_play_f); 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, 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); diff --git a/lib/linux-x86_64.zip b/lib/linux-x86_64.zip index 13998251c8edb222c244785cdf9116899cf6b77f..541413f823a833897f7494d38235babdfe243a7b 100644 GIT binary patch delta 4924 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