racket version of async C backend
This commit is contained in:
+1
-1
@@ -43,7 +43,7 @@
|
|||||||
flac-read
|
flac-read
|
||||||
flac-seek
|
flac-seek
|
||||||
flac-stop
|
flac-stop
|
||||||
'flac))
|
'ao))
|
||||||
|
|
||||||
;; MP3
|
;; MP3
|
||||||
(hash-set! audio-readers
|
(hash-set! audio-readers
|
||||||
|
|||||||
+61
-15
@@ -43,25 +43,70 @@
|
|||||||
(define kinds (make-hash))
|
(define kinds (make-hash))
|
||||||
(define last-buffer #f)
|
(define last-buffer #f)
|
||||||
(define last-buf-len #f)
|
(define last-buf-len #f)
|
||||||
|
|
||||||
|
(define (endian-little? e)
|
||||||
|
(cond [(eq? e 'little-endian) #t]
|
||||||
|
[(eq? e 'big-endian) #f]
|
||||||
|
[(eq? e 'native-endian) (not (system-big-endian?))]
|
||||||
|
[else (error (format "unknown endian value: ~a" e))]))
|
||||||
|
|
||||||
|
(define (flac-channels->interleaved-buffer buffer block-size channels bits endianness)
|
||||||
|
(let* ([bytes (quotient bits 8)]
|
||||||
|
[little? (endian-little? endianness)]
|
||||||
|
[buf-size (* block-size channels bytes)]
|
||||||
|
[mem-out (malloc buf-size 'atomic)]
|
||||||
|
[out-pos 0])
|
||||||
|
|
||||||
|
(for ([k (in-range block-size)])
|
||||||
|
(for ([channel (in-range channels)])
|
||||||
|
(let* ([channel-ptr (ptr-ref buffer _pointer channel)]
|
||||||
|
[sample (ptr-ref channel-ptr _int32 k)])
|
||||||
|
|
||||||
|
(if little?
|
||||||
|
(for ([j (in-range bytes)])
|
||||||
|
(ptr-set! mem-out _uint8 (+ out-pos j)
|
||||||
|
(bitwise-and
|
||||||
|
(arithmetic-shift sample (* -8 j))
|
||||||
|
#xff)))
|
||||||
|
(for ([j (in-range bytes)])
|
||||||
|
(ptr-set! mem-out _uint8 (+ out-pos j)
|
||||||
|
(bitwise-and
|
||||||
|
(arithmetic-shift sample
|
||||||
|
(* -8 (- bytes j 1)))
|
||||||
|
#xff))))
|
||||||
|
|
||||||
|
(set! out-pos (+ out-pos bytes)))))
|
||||||
|
|
||||||
|
(list mem-out buf-size)))
|
||||||
|
|
||||||
(define (process-frame handle frame buffer)
|
(define (process-frame handle frame buffer)
|
||||||
(let* ((h (flac-ffi-frame-header frame))
|
(let* ([h (flac-ffi-frame-header frame)]
|
||||||
(cb-audio (flac-handle-cb-audio handle))
|
[cb-audio (flac-handle-cb-audio handle)]
|
||||||
(ffi (flac-handle-ffi-decoder-handler handle))
|
[type (hash-ref h 'number-type)]
|
||||||
(type (hash-ref h 'number-type))
|
[channels (hash-ref h 'channels)]
|
||||||
(channels (hash-ref h 'channels))
|
[block-size (hash-ref h 'blocksize)]
|
||||||
(block-size (hash-ref h 'blocksize)))
|
[bits (hash-ref h 'bits-per-sample)]
|
||||||
|
[endianness 'native-endian]
|
||||||
|
[result (flac-channels->interleaved-buffer
|
||||||
|
buffer block-size channels bits endianness)]
|
||||||
|
[mem-out (car result)]
|
||||||
|
[buf-size (cadr result)])
|
||||||
|
|
||||||
(hash-set! h 'duration (flac-duration handle))
|
(hash-set! h 'duration (flac-duration handle))
|
||||||
(let ((sample (hash-ref h 'number)))
|
(hash-set! h 'sample (hash-ref h 'number))
|
||||||
(hash-set! h 'sample sample))
|
(hash-set! h 'type 'interleaved)
|
||||||
(set! last-buffer buffer)
|
(hash-set! h 'endianness endianness)
|
||||||
(set! last-buf-len block-size)
|
(hash-set! h 'bits-per-sample bits)
|
||||||
|
|
||||||
|
(set! last-buffer mem-out)
|
||||||
|
(set! last-buf-len buf-size)
|
||||||
|
|
||||||
(hash-set! kinds type #t)
|
(hash-set! kinds type #t)
|
||||||
|
|
||||||
(when (procedure? cb-audio)
|
(when (procedure? cb-audio)
|
||||||
(cb-audio h buffer block-size))
|
(cb-audio h mem-out buf-size))
|
||||||
)
|
|
||||||
#t
|
#t))
|
||||||
)
|
|
||||||
|
|
||||||
(define (process-meta handle meta)
|
(define (process-meta handle meta)
|
||||||
(let ((type (FLAC__StreamMetadata-type meta)))
|
(let ((type (FLAC__StreamMetadata-type meta)))
|
||||||
@@ -74,13 +119,14 @@
|
|||||||
(hash-ref mh 'min-framesize) (hash-ref mh 'max-framesize)
|
(hash-ref mh 'min-framesize) (hash-ref mh 'max-framesize)
|
||||||
(hash-ref mh 'sample-rate)
|
(hash-ref mh 'sample-rate)
|
||||||
(hash-ref mh 'channels)
|
(hash-ref mh 'channels)
|
||||||
(hash-ref mh 'bits-per-sample)
|
32 ; (hash-ref mh 'bits-per-sample)
|
||||||
(hash-ref mh 'total-samples))))
|
(hash-ref mh 'total-samples))))
|
||||||
(let ((duration (exact->inexact
|
(let ((duration (exact->inexact
|
||||||
(/ (hash-ref mh 'total-samples)
|
(/ (hash-ref mh 'total-samples)
|
||||||
(hash-ref mh 'sample-rate)))))
|
(hash-ref mh 'sample-rate)))))
|
||||||
(hash-set! mh 'duration duration))
|
(hash-set! mh 'duration duration))
|
||||||
(set-flac-handle-stream-info! handle si)
|
(set-flac-handle-stream-info! handle si)
|
||||||
|
(hash-set! mh 'bits-per-sample 32) ; Flac works internally 32 bits.
|
||||||
(let ((cb (flac-handle-cb-stream-info handle)))
|
(let ((cb (flac-handle-cb-stream-info handle)))
|
||||||
(when (procedure? cb)
|
(when (procedure? cb)
|
||||||
(cb mh))))))
|
(cb mh))))))
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
#lang racket/base
|
#lang racket/base
|
||||||
|
|
||||||
(require (prefix-in fin: finalizer)
|
(require (prefix-in fin: finalizer)
|
||||||
(prefix-in ffi: "libao-async-ffi.rkt")
|
(prefix-in ffi: "libao-async-ffi-racket.rkt")
|
||||||
ffi/unsafe
|
ffi/unsafe
|
||||||
ffi/unsafe/custodian
|
ffi/unsafe/custodian
|
||||||
data/queue
|
data/queue
|
||||||
|
|||||||
+17
-13
@@ -21,8 +21,8 @@
|
|||||||
(set! test-file4 (build-path tests "mahler-2.ogg"))
|
(set! test-file4 (build-path tests "mahler-2.ogg"))
|
||||||
)
|
)
|
||||||
(when (eq? os 'windows)
|
(when (eq? os 'windows)
|
||||||
(set! test-file3 (build-path tests "mahler-1.ogg"))
|
(set! test-file3 (build-path tests "idyll.flac"))
|
||||||
(set! test-file4 (build-path tests "mahler-2.ogg"))
|
(set! test-file4 (build-path tests "idyll.flac"))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
(define seeked #f)
|
(define seeked #f)
|
||||||
|
|
||||||
(define (audio-play type ao-type handle buf-info buffer buf-len)
|
(define (audio-play type ao-type handle buf-info buffer buf-len)
|
||||||
|
;(dbg-sound "~a ~a ~a ~a ~a" type ao-type handle buf-info buf-len)
|
||||||
(let* ((sample (hash-ref buf-info 'sample))
|
(let* ((sample (hash-ref buf-info 'sample))
|
||||||
(rate (hash-ref buf-info 'sample-rate))
|
(rate (hash-ref buf-info 'sample-rate))
|
||||||
(second (/ (* sample 1.0) (* rate 1.0)))
|
(second (/ (* sample 1.0) (* rate 1.0)))
|
||||||
@@ -58,8 +59,19 @@
|
|||||||
(let ((perc (exact->inexact (* (/ (- duration 15) duration) 100.0))))
|
(let ((perc (exact->inexact (* (/ (- duration 15) duration) 100.0))))
|
||||||
(info-sound "Seeking to ~a%" perc)
|
(info-sound "Seeking to ~a%" perc)
|
||||||
(audio-seek current-audio-h perc))))))
|
(audio-seek current-audio-h perc))))))
|
||||||
|
(cond-volume (λ ()
|
||||||
|
(when (= (round current-seconds) 20)
|
||||||
|
(ao-set-volume! ao-h 70.0))
|
||||||
|
(when (= (round current-seconds) 25)
|
||||||
|
(ao-set-volume! ao-h 30))
|
||||||
|
(when (= (round current-seconds) 30)
|
||||||
|
(ao-set-volume! ao-h 100))
|
||||||
|
(when (= (round current-seconds) 35)
|
||||||
|
(ao-set-volume! ao-h 150))
|
||||||
|
(when (= (round current-seconds) 40)
|
||||||
|
(ao-set-volume! ao-h 100))))
|
||||||
)
|
)
|
||||||
|
|
||||||
(when (not (eq? ao-h #f))
|
(when (not (eq? ao-h #f))
|
||||||
(when (not (and
|
(when (not (and
|
||||||
(= current-bits bits-per-sample)
|
(= current-bits bits-per-sample)
|
||||||
@@ -116,6 +128,7 @@
|
|||||||
(buf-seconds (exact->inexact (/ buf-size bytes-per-sample-all-channels rate))))
|
(buf-seconds (exact->inexact (/ buf-size bytes-per-sample-all-channels rate))))
|
||||||
(second-printer buf-seconds)
|
(second-printer buf-seconds)
|
||||||
(cond-seek)
|
(cond-seek)
|
||||||
|
(cond-volume)
|
||||||
(when (> buf-seconds 5)
|
(when (> buf-seconds 5)
|
||||||
(letrec ((waiter (λ ()
|
(letrec ((waiter (λ ()
|
||||||
(let ((buf-seconds-left (exact->inexact
|
(let ((buf-seconds-left (exact->inexact
|
||||||
@@ -127,16 +140,7 @@
|
|||||||
(begin
|
(begin
|
||||||
(sleep 0.5)
|
(sleep 0.5)
|
||||||
(second-printer buf-seconds)
|
(second-printer buf-seconds)
|
||||||
(when (= (round current-seconds) 20)
|
(cond-volume)
|
||||||
(ao-set-volume! ao-h 70.0))
|
|
||||||
(when (= (round current-seconds) 25)
|
|
||||||
(ao-set-volume! ao-h 30))
|
|
||||||
(when (= (round current-seconds) 30)
|
|
||||||
(ao-set-volume! ao-h 100))
|
|
||||||
(when (= (round current-seconds) 35)
|
|
||||||
(ao-set-volume! ao-h 150))
|
|
||||||
(when (= (round current-seconds) 40)
|
|
||||||
(ao-set-volume! ao-h 100))
|
|
||||||
(cond-seek)
|
(cond-seek)
|
||||||
(waiter)))))
|
(waiter)))))
|
||||||
))
|
))
|
||||||
|
|||||||
Reference in New Issue
Block a user