diff --git a/extra/flac/bitstream/bitstream.factor b/extra/flac/bitstream/bitstream.factor index 81ec4d1697..e6a5c376a0 100644 --- a/extra/flac/bitstream/bitstream.factor +++ b/extra/flac/bitstream/bitstream.factor @@ -30,6 +30,10 @@ M: flac-stream-reader dispose stream>> dispose ; dup bytes>> swap [ prepend ] dip swap >>bytes drop ] while flac-input-stream get bitstream>> bitstreams:read ; +: flac-read-sint ( n -- n ) + ! TODO: this isn't rightt + dup flac-read-uint dup . dup 1 - neg shift swap shift ; + : with-flac-stream-reader* ( flac-bitstream quot -- ) flac-input-stream swap with-variable ; inline diff --git a/extra/flac/decoder/decoder.factor b/extra/flac/decoder/decoder.factor index bccd91eee3..fbf9169ebc 100644 --- a/extra/flac/decoder/decoder.factor +++ b/extra/flac/decoder/decoder.factor @@ -6,23 +6,6 @@ USING: flac.bitstream flac.metadata flac.format ; IN: flac.decoder -CONSTANT: sync-code 16382 - -ERROR: sync-code-error ; -ERROR: invalid-channel-assignment ; -ERROR: reserved-block-size ; -ERROR: invalid-sample-rate ; -ERROR: reserved-subframe-type ; -ERROR: invalid-subframe-sync ; - -: 0xxxxxxx? ( n -- ? ) 0x80 mask? not ; -: 110xxxxx? ( n -- ? ) [ 0xc0 mask? ] [ 0x20 mask? not ] bi and ; -: 1110xxxx? ( n -- ? ) [ 0xe0 mask? ] [ 0x10 mask? not ] bi and ; -: 11110xxx? ( n -- ? ) [ 0xf0 mask? ] [ 0x08 mask? not ] bi and ; -: 111110xx? ( n -- ? ) [ 0xf8 mask? ] [ 0x04 mask? not ] bi and ; -: 1111110x? ( n -- ? ) [ 0xfc mask? ] [ 0x02 mask? not ] bi and ; -: 11111110? ( n -- ? ) [ 0xfe mask? ] [ 0x01 mask? not ] bi and ; - : read-utf8-uint ( -- n ) 0 [ 1 flac-read-uint 1 = ] [ 1 + ] while dup [ 7 swap - flac-read-uint ] dip @@ -86,10 +69,27 @@ ERROR: invalid-subframe-sync ; : read-flac-subframe-constant ( frame-header subframe-header -- constant-subframe ) drop bits-per-sample>> flac-read-uint flac-subframe-constant boa ; -: read-flac-subframe-fixed ( frame-header subframe-header -- fixed-subframe ) - 2drop flac-subframe-fixed new ; +! : read-flac-residuals ( block-size - seq ) +! 2 flac-read-uint +! dup +! { +! { [ 0 1 between? ] [ ] } +! [ drop reserved-residual-coding ] +! } cond-case +! 4 flac-read-uint +! ; -: decode-flac-subframe-type ( n -- order type ) +: read-flac-residuals ( block-size -- seq ) + ; + +: read-flac-subframe-fixed ( frame-header subframe-header -- fixed-subframe ) + [ [ blocksize>> ] [ bits-per-sample>> ] bi ] dip + pre-order>> swap [ flac-read-sint ] map ! warm up samples + [ read-flac-residuals ] dip +! swap read-flac-redisduals + flac-subframe-fixed new swap >>warmup swap drop ; + +: decode-flac-subframe-type ( n -- type order ) dup { { [ 0 = ] [ drop f 0 ] } @@ -103,7 +103,7 @@ ERROR: invalid-subframe-sync ; : read-flac-subframe-header ( -- subframe-header ) 1 flac-read-uint 1 = [ invalid-subframe-sync ] when 6 flac-read-uint decode-flac-subframe-type - 1 flac-read-uint ! TODO: handle wasted bits + 1 flac-read-uint flac-subframe-header boa ; : read-flac-subframe ( frame-header -- subframe ) @@ -142,12 +142,21 @@ ERROR: invalid-subframe-sync ; 8 flac-read-uint flac-frame-header boa ; +: read-flac-frame-footer ( -- frame-footer ) + 16 flac-read-uint flac-frame-footer boa ; + : read-flac-frame ( -- frame ) - read-flac-frame-header - read-flac-subframes ; + read-flac-frame-header dup + read-flac-subframes + read-flac-frame-footer + flac-frame boa ; : read-flac-file ( filename -- flac-stream ) [ read-flac-metadata drop + read-flac-frame drop + read-flac-frame drop + read-flac-frame drop read-flac-frame + ] with-flac-file-reader ; diff --git a/extra/flac/format/format.factor b/extra/flac/format/format.factor index fa10f94aaa..f2d2d8b8b4 100644 --- a/extra/flac/format/format.factor +++ b/extra/flac/format/format.factor @@ -5,6 +5,7 @@ USING: alien.syntax math byte-arrays sequences kernel strings arrays assocs ; IN: flac.format CONSTANT: FLAC-MAGIC 0x664c6143 ! fLaC +CONSTANT: sync-code 0b11111111111110 CONSTANT: MIN-BLOCK-SIZE 16 CONSTANT: MAX-BLOCK-SIZE 65535 @@ -20,6 +21,12 @@ CONSTANT: MAX-FIXED-ORDER 4 CONSTANT: MAX-RICE-PARTITION-ORDER 15 ERROR: not-a-flac-file ; +ERROR: sync-code-error ; +ERROR: invalid-channel-assignment ; +ERROR: reserved-block-size ; +ERROR: invalid-sample-rate ; +ERROR: reserved-subframe-type ; +ERROR: invalid-subframe-sync ; ENUM: flac-frame-number-type frame-number-type-frame @@ -69,14 +76,6 @@ ENUM: flac-entropy-coding-method-type entropy-coding-partioned-rice entropy-coding-partioned-rice2 ; -TUPLE: flac-subframe-header - { subframe-type maybe{ subframe-type-constant - subframe-type-verbatim - subframe-type-fixed - subframe-type-lpc } } - { order maybe{ integer } } - { wasted-bits integer } ; - TUPLE: flac-entropy-coding-method-partioned-rice-contents { parameters integer } { raw-bits integer } @@ -98,8 +97,8 @@ TUPLE: flac-subframe-verbatim { data byte-array } ; TUPLE: flac-subframe-fixed - { entropy-coding-method flac-entropy-coding-method } { warmup sequence } + { entropy-coding-method flac-entropy-coding-method } residual ; TUPLE: flac-subframe-lpc @@ -111,8 +110,16 @@ TUPLE: flac-subframe-lpc { warmup integer } residual ; +TUPLE: flac-subframe-header + { subframe-type maybe{ subframe-type-constant + subframe-type-verbatim + subframe-type-fixed + subframe-type-lpc } } + { pre-order maybe{ integer } } + { wasted-bits integer } ; + TUPLE: flac-subframe - { subframe-header flac-subframe-header } + { header flac-subframe-header } { data maybe{ flac-subframe-constant flac-subframe-verbatim flac-subframe-fixed