diff --git a/README.md b/README.md index 0885495..c1e7714 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,14 @@ # racket-audio -Integration of common audio libraries in racket \ No newline at end of file +Integration of common audio libraries in racket. + +## Mac OS X + +Make sure you have libao, libFLAC, mpg123 and ffmpeg-full installed using brew. + +% brew install libao +% brew install flac +% brew install mpg123 +% brew install ffmpeg-full + + diff --git a/libao-async-ffi-racket.rkt b/libao-async-ffi-racket.rkt index 9c4360b..7e5753f 100644 --- a/libao-async-ffi-racket.rkt +++ b/libao-async-ffi-racket.rkt @@ -28,6 +28,7 @@ ao_pause_async ao_set_volume_async ao_volume_async + ao_reuse_buf_len make-buffer-info make-BufferInfo_t ) @@ -144,6 +145,8 @@ volume-in-10000 valid + + bufs ) #:mutable ) @@ -202,6 +205,36 @@ (let ((le-a (is-little-endian? a)) (le-b (is-little-endian? b))) (eq? le-a le-b))) + + +(define (alloc-buf h size) + (let ((entry #f)) + (letrec ((f (λ (entries) + (if (null? entries) + '() + (let ((e (car entries))) + (if (< size (car e)) + (begin + (set! entry e) + (cdr entries)) + (begin + (cons e (f (cdr entries)))) + ) + ) + ) + ) + )) + (set-ao-handle-bufs! h (f (ao-handle-bufs h))) + (if (eq? entry #f) + (list size (make-bytes size)) + entry) + ) + ) + ) + +(define (reuse-buf h buf size) + (set-ao-handle-bufs! h (cons (list size buf) (ao-handle-bufs h))) + ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Converters @@ -209,8 +242,6 @@ ;;; Volume - - (define (adjust-volume h bs buf-size volume-in-10000) ;; bs: bytes ;; buf-size: aantal geldige bytes in bs @@ -237,7 +268,7 @@ ;;; planar -> intereleaved -(define (planar-to-interleaved mem buf-size info) +(define (planar-to-interleaved h mem buf-size info) ;; mem: bytes ;; result: (list bytes output-size) @@ -246,7 +277,8 @@ [channels (buffer-info-channels info)] [bytes (arithmetic-shift bits -3)] [out-size buf-size] - [out (make-bytes out-size)]) + [out (cadr (alloc-buf h out-size))] + ) (unless (or (eq? type 'planar) (eq? type 'flac)) (error (format "expected planar buffer, got: ~a" type))) @@ -272,7 +304,7 @@ ;;; requested bits to device bits -(define (convert-bits buf buf-size in-bits in-endianness out-bits out-endianness) +(define (convert-bits h buf buf-size in-bits in-endianness out-bits out-endianness) ;; buf: bytes ;; returns: (list out-bytes out-size) @@ -280,7 +312,7 @@ [out-bytes (arithmetic-shift out-bits -3)] [samples (quotient buf-size in-bytes)] [out-size (* samples out-bytes)] - [out (make-bytes out-size)] + [out (cadr (alloc-buf h out-size))] [shift (- out-bits in-bits)] [in-big? (is-big-endian? in-endianness)] [out-big? (is-big-endian? out-endianness)]) @@ -292,13 +324,13 @@ [converted (arithmetic-shift sample shift)]) (integer->int-bytes converted out-bytes #t out-big? out out-pos))) - (list out out-size))) + (list out out-size #t))) (define (convert-req-bits-to-dev-bits h mem buf-size info) (if (and (= (buffer-info-sample-bits info) (ao-handle-dev-bits-per-sample h)) (endian-eq? (buffer-info-endianness info) (ao-handle-dev-endianness h))) - (list mem buf-size) - (convert-bits mem buf-size + (list mem buf-size #f) + (convert-bits h mem buf-size (buffer-info-sample-bits info) (buffer-info-endianness info) (ao-handle-dev-bits-per-sample h) @@ -442,6 +474,7 @@ 10000 ; volume-in-10000 #t ; valid handle + '() ; reuse buffer ))) (let ((ao-dev-bits (try-open-device bits rate channels byte-format wav-output-file))) @@ -495,6 +528,7 @@ (when (or (eq? type 'planar) (eq? type 'flac)) (dbg-sound "Converting from planar to interleaved") (let ((m (planar-to-interleaved mem buf-size info))) + (reuse-buf h mem buf-size) (set! mem (car m)) (set! buf-size (cadr m))) ) @@ -502,8 +536,10 @@ (let ((ao-size buf-size) (ao-mem mem)) (let ((m (convert-req-bits-to-dev-bits h mem buf-size info))) - (set! ao-mem (car m)) - (set! ao-size (cadr m))) + (when (eq? (caddr m) #t) + (reuse-buf h mem buf-size) + (set! ao-mem (car m)) + (set! ao-size (cadr m)))) (unless (bytes? ao-mem) (error "Hey! this was unexpected!")) @@ -560,3 +596,5 @@ (define (ao_real_output_bits_async h) (ao-handle-dev-bits-per-sample h)) +(define (ao_reuse_buf_len h) + (length (ao-handle-bufs h))) \ No newline at end of file diff --git a/libao-async-ffi.rkt b/libao-async-ffi.rkt index 940b5a0..1a84993 100644 --- a/libao-async-ffi.rkt +++ b/libao-async-ffi.rkt @@ -15,6 +15,7 @@ ao_is_at_second_async ao_music_duration_async ao_bufsize_async + ao_reuse_buf_len ao_clear_async ao_pause_async ao_set_volume_async @@ -109,3 +110,6 @@ ;extern double ao_volume_async(void *handle) (define-libao-async ao_volume_async (_fun _libao-async-handle-pointer -> _double)) + +(define (ao_reuse_buf_len h) -1) + \ No newline at end of file diff --git a/libao.rkt b/libao.rkt index e5cc1ca..15f8af1 100644 --- a/libao.rkt +++ b/libao.rkt @@ -18,6 +18,7 @@ ao-music-duration ao-at-music-id ao-bufsize-async + ao-reuse-buf-len-async ao-clear-async ao-pause ao-set-volume! @@ -200,6 +201,11 @@ (ffi:ao_bufsize_async (ao-handle-async-player handle)) ) +(rc:define/contract (ao-reuse-buf-len-async handle) + (rc:-> ao-handle? integer?) + (ffi:ao_reuse_buf_len (ao-handle-async-player handle)) + ) + (rc:define/contract (ao-set-volume! handle percentage) (rc:-> ao-handle? number? void?) (ffi:ao_set_volume_async (ao-handle-async-player handle) diff --git a/play-test.rkt b/play-test.rkt index 2b382e8..93502b9 100644 --- a/play-test.rkt +++ b/play-test.rkt @@ -123,6 +123,7 @@ (cond-seek) (cond-volume) (when (> buf-seconds 5) + (info-sound "Reuse buf: ~a" (ao-reuse-buf-len-async ao-h)) (letrec ((waiter (λ () (let ((buf-seconds-left (exact->inexact (/ (ao-bufsize-async ao-h) @@ -137,7 +138,9 @@ (cond-seek) (waiter))))) )) - (waiter)))) + (waiter) + (info-sound "Reuse buf: ~a" (ao-reuse-buf-len-async ao-h)) + ))) ) ) )