factor-work/flac/flac.factor

50 lines
1.8 KiB
Factor

USING: kernel audio.wav io io.files io.encodings.ascii io.encodings.binary io.encodings.string endian accessors math sequences ;
USING: flac.decoder flac.stream flac.metadata ;
USING: specialized-arrays alien.c-types prettyprint io.encodings.utf8 ;
IN: flac
:: wav-header ( stream-info -- byte-array )
RIFF-MAGIC ascii encode
stream-info samples>> stream-info channels>> stream-info bits-per-sample>> 8 /i * * 36 + 4 >le
WAVE-MAGIC ascii encode
FMT-MAGIC ascii encode
16 4 >le
1 2 >le
stream-info channels>> 2 >le
stream-info sample-rate>> 4 >le
stream-info sample-rate>> stream-info channels>> stream-info bits-per-sample>> 8 /i * * 4 >le
stream-info channels>> stream-info bits-per-sample>> 8 /i * 2 >le
stream-info bits-per-sample>> 2 >le
DATA-MAGIC ascii encode
stream-info samples>> stream-info channels>> stream-info bits-per-sample>> 8 /i * * 4 >le
'{ _ _ _ _ _ _ _ _ _ _ _ _ _ } B{ } concat-as ;
:: write-frame ( sample-depth channels blocksize samples -- )
sample-depth 8 /i :> sample-bytes
sample-depth 8 = [ 128 ] [ 0 ] if :> addend
blocksize <iota> [| block |
channels <iota> [| channel |
block channel samples nth nth addend + sample-bytes >le write
] each
] each ;
! TODO: actually write good code
: decode-file ( flac-file -- )
[
"/home/steve/FACTOR.wav" binary [
read-stream-info/seek-data
dup
[ wav-header write ]
[ samples>> ] bi
swap <repetition>
[
[ [ bits-per-sample>> ] [ channels>> ] bi ]
[ read-flac-frame ] bi
[ header>> blocksize>> ] [ samples>> ] bi
write-frame
] each
] with-file-writer
] with-flac-file-reader ;