guile-flac/src/flac/reader.scm

73 lines
2.6 KiB
Scheme
Raw Normal View History

2022-07-13 19:25:12 -04:00
(define-module (flac reader)
#:use-module (flac format)
#:use-module (srfi srfi-9)
#:use-module (ice-9 binary-ports)
#:use-module (rnrs bytevectors)
#:use-module (rnrs arithmetic bitwise)
#:export (flac-read-uint
flac-read-bytes
flac-read-coded-number
with-flac-input-port
new-flac-reader
make-flac-reader
flac-read/assert-magic
current-flac-reader))
(define current-flac-reader (make-parameter #f))
(define-record-type <flac-reader>
(make-flac-reader port bit-buffer bit-buffer-length)
flac-reader?
(port flac-reader-port)
(bit-buffer flac-reader-bit-buffer set-flac-reader-bit-buffer!)
(bit-buffer-length flac-reader-bit-buffer-length set-flac-reader-bit-buffer-length!))
(define (with-flac-input-port port thunk)
(with-input-from-port port
(λ ()
(parameterize ((current-flac-reader (make-flac-reader (current-input-port) 0 0)))
(thunk)))))
(define (new-flac-reader port)
(current-flac-reader (make-flac-reader port 0 0))
(current-flac-reader))
(define (flac-read-bits reader bits)
(while
(< (flac-reader-bit-buffer-length reader) bits)
(let ((byte-read (get-u8 (flac-reader-port reader))))
(set-flac-reader-bit-buffer! reader
(bitwise-ior (bitwise-arithmetic-shift (flac-reader-bit-buffer reader) 8)
byte-read))
(set-flac-reader-bit-buffer-length! reader (+ (flac-reader-bit-buffer-length reader) 8))))
(set-flac-reader-bit-buffer-length! reader (- (flac-reader-bit-buffer-length reader) bits))
(let ((uint (bitwise-and (bitwise-arithmetic-shift-right
(flac-reader-bit-buffer reader) (flac-reader-bit-buffer-length reader))
(- (bitwise-arithmetic-shift 1 bits) 1))))
(set-flac-reader-bit-buffer! reader
(bitwise-and
(flac-reader-bit-buffer reader)
(- (bitwise-arithmetic-shift 1 (flac-reader-bit-buffer-length reader)) 1)))
uint))
(define (flac-read-bytes n)
(u8-list->bytevector (map (λ (_) (flac-read-uint 8)) (iota n))))
(define (flac-read-uint bits)
(flac-read-bits (current-flac-reader) bits))
(define (flac-read/assert-magic)
(unless (= FLAC-MAGIC (flac-read-uint 32))
#f))
(define (flac-read-coded-number)
(let coded-number-loop ((coded-sample-number (flac-read-uint 8)))
(if (< coded-sample-number #b11000000)
coded-sample-number
(coded-number-loop (bitwise-and (bitwise-arithmetic-shift coded-sample-number 1) #xff)))))