USING: kernel namespaces accessors sequences destructors io io.files io.encodings.binary math math.functions math.bitwise ; FROM: flac.format => FLAC-MAGIC not-a-flac-stream ; QUALIFIED: bitstreams QUALIFIED: io IN: flac.stream SYMBOL: flac-input-stream TUPLE: flac-stream-reader stream buffer buffer-length ; M: flac-stream-reader dispose stream>> dispose ; : flac-input-stream> ( -- flac-input-stream ) flac-input-stream get ; : flac-input-stream-stream> ( -- stream ) flac-input-stream> stream>> ; : flac-input-stream-buffer> ( -- buffer ) flac-input-stream> buffer>> ; : flac-input-stream-buffer-length> ( -- buffer-length ) flac-input-stream> buffer-length>> ; : ( stream -- flac-stream-reader ) 0 0 flac-stream-reader boa ; :: flac-read-uint ( num-bits -- uint ) flac-input-stream> [ buffer-length>> num-bits < ] [ flac-input-stream> flac-input-stream-stream> io:stream-read1 flac-input-stream-buffer> 8 shift bitor >>buffer flac-input-stream-buffer-length> 8 + >>buffer-length ] while flac-input-stream> flac-input-stream-buffer-length> num-bits - >>buffer-length flac-input-stream-buffer> flac-input-stream-buffer-length> neg shift 1 num-bits shift 1 - bitand [ flac-input-stream-buffer> 1 flac-input-stream-buffer-length> shift 1 - bitand >>buffer drop ] dip ; : flac-read-sint ( num-bits -- sint ) dup flac-read-uint swap >signed ; ! flac-input-stream> buffer-length>> n - >>buffer-length ! flac-input-stream> buffer>> flac-input-stream buffer-length>> neg ! 1 n shift 1 - ! [ flac-input-stream> buffer>> 1 flac-input-stream buffer-length>> shift 1 - bitand ] keep ; ! : flac-read ( n -- m ) ! [ 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 -- ) ! [ 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:seek ; ! ! : flac-align-to-byte ( -- ) ! 8 flac-input-stream get bitstream>> bitstreams:align ; ! ! : flac-read-int ( n -- m ) ! dup flac-read swap >signed ; ! ! : flac-read-rice-signed-int ( param -- n ) ! [ 0 [ 1 flac-read 0 = ] [ 1 + ] while ] dip ! [ shift ] keep flac-read bitor ! [ -1 shift ] [ 1 bitand -1 * ] bi bitxor ; ! ! : flac-read-coded-number ( -- n ) ! 8 flac-read ! [ dup 0b11000000 >= ] [ 8 flac-read drop 2^ 0xff bitand ] while ; : (with-flac-stream-reader) ( stream quot -- ) flac-input-stream swap with-variable ; inline : with-flac-stream-reader ( stream quot -- ) [ ] dip [ (with-flac-stream-reader) ] curry with-disposal ; inline : with-flac-file-reader ( path quot -- ) [ binary ] dip with-flac-stream-reader ; inline : read/assert-flac-magic ( -- ) 32 flac-read-uint FLAC-MAGIC = [ not-a-flac-stream ] unless ;