     dup #vorbis-headers>> zero?
     [ no-vorbis-in-ogg ]
     [ init-vorbis-codec ] if ;
+
+: get-pending-decoded-audio ( vorbis-stream -- pcm len )
+    dsp-state>> f <void*> [ vorbis_synthesis_pcmout ] keep *void* swap ;
+
+:: make-pcm-buffer ( vorbis-stream pcm len -- short-array )
+    vorbis-stream info>> channels>> :> #channels
+    pcm #channels <direct-void*-array> :> channel*s
+    #channels len * <short-vector> :> output
+
+    len iota [| sample |
+        #channels iota [| channel |
+            channel channel*s nth len <direct-float-array> :> samples
+            sample samples nth
+            -32767.0 * >integer -32767 32767 clamp
+            output push
+        ] each
+    ] each
+    output >short-array ; inline
+
+: read-samples ( vorbis-stream pcm len -- )
+    [ dsp-state>> ] [ drop ] [ ] tri* vorbis_synthesis_read drop ; inline
+
+: queue-audio ( vorbis-stream -- ? )
+    dup [ stream-state>> ] [ packet>> ] bi ogg_stream_packetout 0 > [
+        dup [ block>> ] [ packet>> ] bi vorbis_synthesis 0 = [
+            [ dsp-state>> ] [ block>> ] bi vorbis_synthesis_blockin drop
+        ] [ drop ] if t
+    ] [ drop f ] if ;
+
+: decode-audio ( vorbis-stream -- short-array/f length/f )
+    dup get-pending-decoded-audio dup 0 > [
+        [ make-pcm-buffer dup byte-length ] [ read-samples ] 3bi
+    ] [
+        2drop dup queue-audio [ decode-audio ] [ drop f f ] if
+    ] if ;
 PRIVATE>
 
 : <vorbis-stream> ( stream -- vorbis-stream )

M: vorbis-stream generator-audio-format
    [ info>> channels>> ] [ drop 16 ] [ info>> rate>> ] tri ;
M: vorbis-stream generate-audio
    drop f f ;

! (c)2007, 2010 Chris Double, Joe Groff bsd license
USING: accessors alien.c-types audio.engine byte-arrays classes.struct
combinators destructors fry gpu.buffers io io.files io.encodings.binary
kernel libc locals make math math.order math.parser ogg ogg.vorbis
sequences specialized-arrays specialized-vectors ;
FROM: alien.c-types => float short void* ;
SPECIALIZED-ARRAYS: float void* ;
SPECIALIZED-VECTOR: short
IN: audio.vorbis

TUPLE: vorbis-stream < disposable
