 M: audio-listener audio-velocity velocity>> ; inline
 M: audio-listener audio-orientation orientation>> ; inline
 
+GENERIC# generate-audio 1 ( generator buffer-size -- c-ptr )
+GENERIC: generator-audio-format ( generator -- channels sample-bits sample-rate )
+
 TUPLE: audio-engine < disposable
     { voice-count integer }
-    { buffer-size integer }
-    { buffer-count integer }
     { al-device c-ptr }
     { al-context c-ptr }
     al-sources

            voice-count >>voice-count
            al-device >>al-device
            al-context >>al-context
            buffer-size >>buffer-size
            buffer-count >>buffer-count
    ] with-destructors ;

: <standard-audio-engine> ( -- engine )
    f 16 8192 2 <audio-engine> ;

<PRIVATE


        [ AL_ROLLOFF_FACTOR swap audio-rolloff alSourcef ]
    } 2cleave ;

GENERIC: (update-audio-clip) ( audio-clip -- )

M: static-audio-clip (update-audio-clip)
    drop ;

M:: streaming-audio-clip (update-audio-clip) ( audio-clip -- )
    audio-clip al-source>> :> al-source
    0 c:<uint> :> buffer
    al-source AL_BUFFERS_PROCESSED get-source-param [
        al-source 1 buffer alSourceUnqueueBuffers
        audio-clip buffer c:*uint queue-clip-buffer
    ] times ;

: update-audio-clip ( audio-clip -- )
    [ update-source ] [
        dup al-source>> AL_SOURCE_STATE get-source-param AL_STOPPED = 
        [ dispose ] [ (update-audio-clip) ] if
    ] bi ;

: clip-al-sources ( clips -- length sources )
    [ length ] [ [ al-source>> ] uint-array{ } map-as ] bi ;
