 : allocate-sources ( audio-engine -- sources )
     voice-count>> dup (uint-array) [ alGenSources ] keep ; inline
 
-:: flush-source ( source -- )
-    source alSourceStop
+:: flush-source ( al-source -- )
+    al-source alSourceStop
     0 c:<uint> :> dummy-buffer
-    source AL_BUFFERS_PROCESSED get-source-param [
-        source 1 dummy-buffer alSourceUnqueueBuffers
-    ] times ;
+    al-source AL_BUFFERS_PROCESSED get-source-param [
+        al-source 1 dummy-buffer alSourceUnqueueBuffers
+    ] times
+    al-source AL_BUFFER 0 alSourcei ;
 
 : free-sources ( sources -- )
     [ length ] keep alDeleteSources ; inline

    [ [ alcCloseDevice*   ] when* f ] change-al-device
    drop ;

:: (audio-clip) ( audio-engine audio source loop? -- audio-clip/f )
    audio-engine get-available-source :> al-source

    al-source [
        audio-engine buffer-count>> :> buffer-count
        buffer-count dup (uint-array) [ alGenBuffers ] keep :> al-buffers

        audio-clip new-disposable
            audio-engine >>audio-engine
            audio >>audio
            source >>source
            loop? >>loop?
            al-source >>al-source
            al-buffers >>al-buffers
            0 >>next-data-offset :> clip
        al-buffers [ clip swap queue-clip-buffer ] each
        clip audio-engine clips>> push

        clip
    ] [ f ] if ;

M: audio-clip dispose*
    {
        [ al-source>> flush-source ]
        [ al-buffers>> [ length ] keep alDeleteBuffers ]
        [ dup audio-engine>> clips>> remove! drop ]
    } cleave ;

: play-clip ( audio-clip -- )
    [ update-source ]

    [ [ update-source ] each ]
    [ clip-al-sources alSourcePlayv ] bi ;

: play-static-audio-clip ( audio-engine source audio loop? -- audio-clip/f )
    <static-audio-clip> dup [ play-clip ] when* ;

: play-streaming-audio-clip ( audio-engine source generator buffer-size buffer-count -- audio-clip/f ) 
    <streaming-audio-clip> dup [ play-clip ] when* ;

: pause-clip ( audio-clip -- )
    al-source>> alSourcePause ;
