50 lines
1.8 KiB
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 ;
|