flac
Steve Ayerhart 2020-05-02 15:58:16 -05:00
parent c91134d0ba
commit 1b67ebac16
No known key found for this signature in database
GPG Key ID: 5BFD39C5359E967D
2 changed files with 70 additions and 132 deletions

View File

@ -17,6 +17,7 @@ GENERIC: align-to-byte ( flac-stream-reader -- )
: <flac-stream-reader> ( path -- flac-stream-reader ) : <flac-stream-reader> ( path -- flac-stream-reader )
binary <file-reader> B{ } bitstreams:<msb0-bit-reader> flac-stream-reader boa ; binary <file-reader> B{ } bitstreams:<msb0-bit-reader> flac-stream-reader boa ;
M: flac-stream-reader dispose stream>> dispose ; M: flac-stream-reader dispose stream>> dispose ;
: flac-align-to-byte ( -- ) : flac-align-to-byte ( -- )
@ -35,5 +36,5 @@ M: flac-stream-reader dispose stream>> dispose ;
: with-flac-stream-reader ( flac-bitstream quot -- ) : with-flac-stream-reader ( flac-bitstream quot -- )
[ with-flac-stream-reader* ] curry with-disposal ; inline [ with-flac-stream-reader* ] curry with-disposal ; inline
: with-flac-file-reader ( filename quote -- ) : with-flac-file-reader ( filename quot -- )
[ <flac-stream-reader> ] dip with-flac-stream-reader ; inline [ <flac-stream-reader> ] dip with-flac-stream-reader ; inline

View File

@ -23,38 +23,14 @@ ERROR: invalid-subframe-sync ;
: 1111110x? ( n -- ? ) [ 0xfc mask? ] [ 0x02 mask? not ] bi and ; : 1111110x? ( n -- ? ) [ 0xfc mask? ] [ 0x02 mask? not ] bi and ;
: 11111110? ( n -- ? ) [ 0xfe mask? ] [ 0x01 mask? not ] bi and ; : 11111110? ( n -- ? ) [ 0xfe mask? ] [ 0x01 mask? not ] bi and ;
: remaining-bytes ( n -- n )
{
{ [ 110xxxxx? ] [ 1 ] }
{ [ 1110xxxx? ] [ 2 ] }
{ [ 11110xxx? ] [ 3 ] }
{ [ 111110xx? ] [ 4 ] }
{ [ 1111110x? ] [ 5 ] }
{ [ 11111110? ] [ 6 ] }
} cond-case ;
! :: decode-utf8-uint ( frame-length bitstream -- n )
! frame-length 7 -
! bitstream read-bit
! frame-length <iota> [
! drop
! 2 bitstream read-bit drop
! 6 shift 6 bitstream read-bit bitor
! ] each ;
: read-utf8-uint ( -- n ) : read-utf8-uint ( -- n )
8 flac-read-uint dup 0 [ 1 flac-read-uint 1 = ] [ 1 + ] while
[ 0b11000000 <= ] dup [ 7 swap - flac-read-uint ] dip
[ <iota> [
8 flac-read-uint drop drop
1 shift 0xff bitand 2 flac-read-uint drop
] while ; 6 shift 6 flac-read-uint bitor
] each ;
! : read-utf8-uint ( -- n )
! 1 read dup
! be> 0xxxxxxx?
! [ be> ]
! [ dup be> remaining-bytes read B{ } append-as be> ] if ;
: decode-block-size ( n -- n ) : decode-block-size ( n -- n )
dup dup
@ -107,110 +83,71 @@ ERROR: invalid-subframe-sync ;
} cond swap } cond swap
<flac-channel-assignment> ; <flac-channel-assignment> ;
! :: decode-header ( bitstream -- frame-header ) : read-flac-subframe-constant ( frame-header subframe-header -- constant-subframe )
! [ drop bits-per-sample>> flac-read-uint flac-subframe-constant boa ;
! 14 bitstream read-bit drop ! ignore sync
! 1 bitstream read-bit drop ! reserved : read-flac-subframe-fixed ( frame-header subframe-header -- fixed-subframe )
! 1 bitstream read-bit 2drop flac-subframe-fixed new ;
! 4 bitstream read-bit
! 4 bitstream read-bit : decode-flac-subframe-type ( n -- order type )
! 4 bitstream read-bit dup
! 3 bitstream read-bit {
! 1 bitstream read-bit drop ! ignore magic sync { [ 0 = ] [ drop f 0 ] }
! read-utf8-uint { [ 1 = ] [ drop f 1 ] }
! [ { [ 8 12 between? ] [ -1 shift 7 bitand 2 ] }
! { { [ 32 63 between? ] [ -1 shift 31 bitand 3 ] }
! [ <flac-frame-number-type> ] [ drop reserved-subframe-type ]
! [ decode-block-size ] } cond-case
! [ decode-sample-rate ] <flac-subframe-type> swap ;
! [ decode-channels ]
! [ decode-bits-per-sample ] : read-flac-subframe-header ( -- subframe-header )
! } spread 1 flac-read-uint 1 = [ invalid-subframe-sync ] when
! ] dip 6 flac-read-uint decode-flac-subframe-type
! 1 read be> 1 flac-read-uint ! TODO: handle wasted bits
! ] with-big-endian flac-subframe-header boa ;
! flac-frame-header boa ;
! : read-flac-subframe ( frame-header -- subframe )
! : decode-subframe-type ( n -- order type ) read-flac-subframe-header dup dup
! dup [
! { subframe-type>>
! { [ 0 = ] [ drop f 0 ] } {
! { [ 1 = ] [ drop f 1 ] } { subframe-type-constant [ read-flac-subframe-constant ] }
! { [ 8 12 between? ] [ -1 shift 7 bitand 2 ] } { subframe-type-fixed [ read-flac-subframe-fixed ] }
! { [ 32 63 between? ] [ -1 shift 31 bitand 3 ] } } case
! [ drop reserved-subframe-type ] ] dip swap
! } cond-case <flac-subframe-type> swap ; flac-subframe boa ;
!
! : read-residual ( order -- residual ) : read-flac-subframes ( frame-header -- seq )
! drop "TODO" ; dup channels>> swap <repetition> [ read-flac-subframe ] map ;
!
! : read-constant-subframe ( frame-header subframe-header -- constant-subframe )
! drop bits-per-sample>> 8 / read be> flac-subframe-constant boa ;
!
! : read-fixed-subframe ( fame-header subframe-header -- fixed-subframe )
! order>> swap bits-per-sample>> <repetition> [
! 8 / read be>
! ] map flac-subframe-fixed new swap >>warmup dup . ;
!
! : read-lpc-subframe ( predictive-order -- lpc-subframe )
! drop "TODO" ;
!
! :: decode-subframe-header ( bitstream -- subframe-header )
! 1 bitstream read-bit 1 = [ invalid-subframe-sync ] when
! 6 bitstream read-bit decode-subframe-type
! 1 bitstream read-bit ! TODO: wasted-bits: 0 for now..
! flac-subframe-header boa ;
!
! ! TODO: actually decode based on subframe type
! ! TODO: handle wasted bits assuming 1 byte for now :/
! : read-subframe ( frame-header -- subframe )
! 1 read bitstreams:<msb0-bit-reader> decode-subframe-header dup dup
! [
! subframe-type>>
! {
! { subframe-type-constant [ read-constant-subframe ] }
! { subframe-type-fixed [ read-fixed-subframe ] }
! } case
! ] dip swap flac-subframe boa ;
!
! : read-subframes ( frame-header -- seq )
! dup channels>> swap <repetition> [ dup . read-subframe ] map ;
!
! : read-frame-header ( -- frame-header )
! 4 read bitstreams:<msb0-bit-reader> decode-header ;
!
! : read-frame-footer ( -- frame-footer )
! 2 read be> flac-frame-footer boa ;
!
! : read-frame ( -- frame )
! read-frame-header dup
! read-subframes
! read-frame-footer
! flac-frame boa ;
!
! : read-flac-file ( filename -- something )
! binary
! [
! read-flac-magic [ not-a-flac-file ] unless
! read-stream-info .
! skip-metadata
! ! 51448296 seek-absolute seek-input
! 4 <iota> [ drop read-frame ] map
! ] with-file-reader ;
: read-flac-frame-header ( -- frame-header ) : read-flac-frame-header ( -- frame-header )
14 flac-read-uint drop 14 flac-read-uint drop ! ignore sync
1 flac-read-uint drop 1 flac-read-uint drop ! reserved
1 flac-read-uint <flac-frame-number-type> 1 flac-read-uint
4 flac-read-uint decode-block-size 4 flac-read-uint
4 flac-read-uint decode-sample-rate 4 flac-read-uint
4 flac-read-uint decode-channels 4 flac-read-uint
3 flac-read-uint decode-bits-per-sample 3 flac-read-uint
1 flac-read-uint drop 1 flac-read-uint drop ! ignore magic sync for now
read-utf8-uint read-utf8-uint
[
{
[ <flac-frame-number-type> ]
[ decode-block-size ]
[ decode-sample-rate ]
[ decode-channels ]
[ decode-bits-per-sample ]
} spread
] dip
8 flac-read-uint
flac-frame-header boa ; flac-frame-header boa ;
: read-flac-frame ( -- frame )
read-flac-frame-header
read-flac-subframes ;
: read-flac-file ( filename -- flac-stream ) : read-flac-file ( filename -- flac-stream )
[ [
read-flac-metadata read-flac-metadata drop
] with-flac-stream-reader ; read-flac-frame
] with-flac-file-reader ;