! Copyright (C) 2009 Daniel Ehrenberg ! See http://factorcode.org/license.txt for BSD license. USING: kernel system destructors accessors byte-arrays math math.functions locals io.files io.encodings.binary combinators sequences namespaces ; QUALIFIED: bitstreams QUALIFIED: io USING: prettyprint ; IN: flac.bitstream CONSTANT: default-bitreader-capacity 65536 SYMBOL: flac-input-stream TUPLE: flac-stream-reader stream bitstream ; GENERIC: read-uint ( n flac-stream-reader -- n ) GENERIC: align-to-byte ( flac-stream-reader -- ) : ( path -- flac-stream-reader ) binary B{ } bitstreams: flac-stream-reader boa ; M: flac-stream-reader dispose stream>> dispose ; : flac-align-to-byte ( -- ) 8 flac-input-stream get bitstream>> bitstreams:align ; : flac-read-uint ( n -- n ) [ dup flac-input-stream get bitstream>> bitstreams:enough-bits? not ] [ flac-input-stream get [ stream>> default-bitreader-capacity swap io:stream-read ] [ bitstream>> ] bi dup bytes>> swap [ prepend ] dip swap >>bytes drop ] while flac-input-stream get bitstream>> bitstreams:read ; : flac-seek ( n -- ) [ 8 * flac-input-stream get bitstream>> bitstreams:seek ] [ io:seek-relative flac-input-stream get stream>> io:stream-seek ] bi ; :: flac-read-sint ( n -- n ) n flac-read-uint :> val val val n 1 - neg shift n shift - ; : flac-read-utf8-uint ( -- n ) 8 flac-read-uint [ dup 0b11000000 >= ] [ 8 flac-read-uint drop 2^ 0xff bitand ] while ; : flac-read-rice-sint ( param -- n ) 0 [ 1 flac-read-uint 0 = ] [ 1 + ] while [ swap shift ] [ flac-read-uint ] bi bitor [ -1 shift ] [ 1 bitand neg ] bi ^ ; : with-flac-stream-reader* ( flac-bitstream quot -- ) flac-input-stream swap with-variable ; inline : with-flac-stream-reader ( flac-bitstream quot -- ) [ with-flac-stream-reader* ] curry with-disposal ; inline : with-flac-file-reader ( filename quot -- ) [ ] dip with-flac-stream-reader ; inline