1 ! Copyright (C) 2007 Adam Wendt.
\r
2 ! See http://factorcode.org/license.txt for BSD license.
\r
3 USING: alien alien.c-types byte-arrays io io.binary io.files kernel mad
\r
4 namespaces prettyprint sbufs sequences tools.interpreter vars
\r
5 io.encodings.binary ;
\r
8 VARS: buffer-start buffer-length output-callback-var ;
\r
10 : create-mad-callback-generic ( sequence parameters -- alien )
\r
11 swap >r >r "mad_flow" r> "cdecl" r> alien-callback ; inline
\r
13 : create-input-callback ( sequence -- alien )
\r
14 { "void*" "mad_stream*" } create-mad-callback-generic ; inline
\r
16 : create-header-callback ( sequence -- alien )
\r
17 { "void*" "mad_header*" } create-mad-callback-generic ; inline
\r
19 : create-filter-callback ( sequence -- alien )
\r
20 { "void*" "mad_stream*" "mad_frame*" } create-mad-callback-generic ; inline
\r
22 : create-output-callback ( sequence -- alien )
\r
23 { "void*" "mad_header*" "mad_pcm*" } create-mad-callback-generic ; inline
\r
25 : create-error-callback ( sequence -- alien )
\r
26 { "void*" "mad_stream*" "mad_frame*" } create-mad-callback-generic ; inline
\r
28 : create-message-callback ( sequence -- alien )
\r
29 { "void*" "void*" "uint*" } create-mad-callback-generic ; inline
\r
31 : input ( buffer mad_stream -- mad_flow )
\r
34 buffer-start get ! mad_stream start
\r
35 buffer-length get ! mad_stream start length
\r
36 dup 0 = ! mad-stream start length bool
\r
37 [ 3drop MAD_FLOW_STOP ] ! mad_flow
\r
38 [ mad_stream_buffer !
\r
39 0 buffer-length set !
\r
40 MAD_FLOW_CONTINUE ] if ; ! mad_flow
\r
42 : input-callback ( -- callback )
\r
43 [ input ] create-input-callback ;
\r
45 : header-callback ( -- callback )
\r
46 [ "header" print flush drop drop MAD_FLOW_CONTINUE ] create-header-callback ;
\r
48 : filter-callback ( -- callback )
\r
49 [ "filter" print flush 3drop MAD_FLOW_CONTINUE ] create-filter-callback ;
\r
51 : write-sample ( sample -- )
\r
54 : output ( data header pcm -- mad_flow )
\r
56 -rot 2drop output-callback-var> call
\r
57 [ MAD_FLOW_CONTINUE ] [ MAD_FLOW_STOP ] if ;
\r
59 : output-stdout ( pcm -- ? )
\r
60 [ mad_pcm-channels ] keep
\r
61 [ mad_pcm-length ] keep swap
\r
63 [ mad_pcm-sample-right ] 2keep
\r
64 [ mad_pcm-sample-left ] 2keep
\r
65 drop -rot write-sample pick
\r
66 2 = [ write-sample ] [ drop ] if
\r
69 : output-callback ( -- callback )
\r
70 [ output ] create-output-callback ;
\r
72 : error-callback ( -- callback )
\r
73 [ "error" print flush drop drop drop MAD_FLOW_CONTINUE ] create-error-callback ;
\r
75 : message-callback ( -- callback )
\r
76 [ "message" print flush drop drop drop MAD_FLOW_CONTINUE ] create-message-callback ;
\r
78 : mad-init ( decoder -- )
\r
79 0 <alien> input-callback 0 <alien> 0 <alien> output-callback error-callback message-callback mad_decoder_init ;
\r
81 : make-decoder ( -- decoder )
\r
82 "mad_decoder" malloc-object ;
\r
84 : mad-run ( -- int )
\r
85 make-decoder [ mad-init ] keep MAD_DECODER_MODE_SYNC mad_decoder_run ;
\r
87 : init-vars ( alien length -- )
\r
88 buffer-length set buffer-start set ;
\r
90 : decode-mp3 ( filename -- results )
\r
91 [ malloc-file-contents ] keep file-length init-vars mad-run ;
\r
93 : mad-test ( -- results )
\r
94 [ output-stdout ] >output-callback-var
\r
95 "/home/adam/download/mp3/Misc/wutbf.mp3" decode-mp3 ;
\r