]> gitweb.factorcode.org Git - factor.git/blobdiff - extra/audio/engine/engine.factor
factor: trim using lists
[factor.git] / extra / audio / engine / engine.factor
index 16efe8e56a3b9ef7dbe20825e0f5f43916b006c4..efc71cc34dab4605d9e2999de8ad966250bae8f4 100644 (file)
@@ -1,7 +1,9 @@
-! (c)2009 Joe Groff bsd license
-USING: accessors alien audio classes.struct fry calendar alarms
-combinators combinators.short-circuit destructors generalizations
-kernel literals locals math openal sequences specialized-arrays strings ;
+! Copyright (C) 2009 Joe Groff.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors alien alien.data audio calendar
+combinators combinators.short-circuit destructors kernel
+literals math openal sequences sequences.generalizations
+specialized-arrays timers ;
 QUALIFIED-WITH: alien.c-types c
 SPECIALIZED-ARRAYS: c:float c:uchar c:uint ;
 IN: audio.engine
@@ -14,11 +16,11 @@ TUPLE: audio-source
     { distance float initial: 1.0 }
     { rolloff float initial: 1.0 } ;
 
-TUPLE: audio-orientation
+TUPLE: audio-orientation-state
     { forward initial: { 0.0 0.0 -1.0 } }
     { up initial: { 0.0 1.0 0.0 } } ;
 
-C: <audio-orientation> audio-orientation
+C: <audio-orientation-state> audio-orientation-state
 
 : orientation>float-array ( orientation -- float-array )
     [ forward>> first3 ]
@@ -28,7 +30,7 @@ TUPLE: audio-listener
     { position initial: { 0.0 0.0 0.0 } }
     { gain float initial: 1.0 }
     { velocity initial: { 0.0 0.0 0.0 } }
-    { orientation initial: T{ audio-orientation } } ;
+    { orientation initial: T{ audio-orientation-state } } ;
 
 GENERIC: audio-position ( source/listener -- position )
 GENERIC: audio-gain ( source/listener -- gain )
@@ -44,7 +46,7 @@ M: object audio-velocity drop { 0.0 0.0 0.0 } ; inline
 M: object audio-relative? drop f ; inline
 M: object audio-distance drop 1.0 ; inline
 M: object audio-rolloff drop 1.0 ; inline
-M: object audio-orientation drop T{ audio-orientation } ; inline
+M: object audio-orientation drop T{ audio-orientation-state } ; inline
 
 M: audio-source audio-position position>> ; inline
 M: audio-source audio-gain gain>> ; inline
@@ -69,7 +71,7 @@ TUPLE: audio-engine < disposable
     listener
     { next-source integer }
     clips
-    update-alarm ;
+    update-timer ;
 
 TUPLE: audio-clip < disposable
     { audio-engine audio-engine }
@@ -84,7 +86,8 @@ TUPLE: streaming-audio-clip < audio-clip
     { channels integer }
     { sample-bits integer }
     { sample-rate integer }
-    { al-buffers uint-array } ;
+    { al-buffers uint-array }
+    { done? boolean } ;
 
 ERROR: audio-device-not-found device-name ;
 ERROR: audio-context-not-available device-name ;
@@ -116,11 +119,11 @@ ERROR: audio-context-not-available device-name ;
     al-context>> alcMakeContextCurrent drop ; inline
 
 : allocate-sources ( audio-engine -- sources )
-    voice-count>> dup (uint-array) [ alGenSources ] keep ; inline
+    voice-count>> dup c:uint (c-array) [ alGenSources ] keep ; inline
 
 :: flush-source ( al-source -- )
     al-source alSourceStop
-    0 c:<uint> :> dummy-buffer
+    0 c:uint <ref> :> dummy-buffer
     al-source AL_BUFFERS_PROCESSED get-source-param [
         al-source 1 dummy-buffer alSourceUnqueueBuffers
     ] times
@@ -150,14 +153,18 @@ ERROR: audio-context-not-available device-name ;
     al-source ;
 
 :: queue-clip-buffer ( audio-clip al-buffer -- )
-    audio-clip al-source>> :> al-source
-    audio-clip generator>> :> generator
-    generator generate-audio :> ( data size )
-
-    data [
-        al-buffer audio-clip openal-format data size audio-clip sample-rate>> alBufferData
-        al-source 1 al-buffer c:<uint> alSourceQueueBuffers
-    ] when ;
+    audio-clip done?>> [
+        audio-clip al-source>> :> al-source
+        audio-clip generator>> :> generator
+        generator generate-audio :> ( data size )
+
+        size { [ not ] [ zero? ] } 1|| [
+            audio-clip t >>done? drop
+        ] [
+            al-buffer audio-clip openal-format data size audio-clip sample-rate>> alBufferData
+            al-source 1 al-buffer c:uint <ref> alSourceQueueBuffers
+        ] if
+    ] unless ;
 
 : update-listener ( audio-engine -- )
     listener>> {
@@ -184,15 +191,15 @@ M: static-audio-clip (update-audio-clip)
 
 M:: streaming-audio-clip (update-audio-clip) ( audio-clip -- )
     audio-clip al-source>> :> al-source
-    0 c:<uint> :> buffer
+    0 c:uint <ref> :> buffer
     al-source AL_BUFFERS_PROCESSED get-source-param [
         al-source 1 buffer alSourceUnqueueBuffers
-        audio-clip buffer c:*uint queue-clip-buffer
+        audio-clip buffer c:uint deref queue-clip-buffer
     ] times ;
 
 : update-audio-clip ( audio-clip -- )
     [ update-source ] [
-        dup al-source>> AL_SOURCE_STATE get-source-param AL_STOPPED = 
+        dup al-source>> AL_SOURCE_STATE get-source-param AL_STOPPED =
         [ dispose ] [ (update-audio-clip) ] if
     ] bi ;
 
@@ -220,20 +227,20 @@ DEFER: update-audio
 
 : start-audio ( audio-engine -- )
     dup start-audio*
-    dup '[ _ update-audio ] 20 milliseconds every >>update-alarm
+    dup '[ _ update-audio ] 20 milliseconds every >>update-timer
     drop ;
 
 : stop-audio ( audio-engine -- )
     dup al-sources>> [
         {
             [ make-engine-current ]
-            [ update-alarm>> [ cancel-alarm ] when* ]
+            [ update-timer>> [ stop-timer ] when* ]
             [ clips>> clone [ dispose ] each ]
             [ al-sources>> free-sources ]
             [
                 f >>al-sources
                 f >>clips
-                f >>update-alarm
+                f >>update-timer
                 drop
             ]
             [ al-context>> alcSuspendContext ]
@@ -250,7 +257,7 @@ M: audio-engine dispose*
     audio-engine get-available-source :> al-source
 
     al-source [
-        1 0 c:<uint> [ alGenBuffers ] keep c:*uint :> al-buffer
+        1 0 c:uint <ref> [ alGenBuffers ] keep c:uint deref :> al-buffer
         al-buffer audio { [ openal-format ] [ data>> ] [ size>> ] [ sample-rate>> ] } cleave
             alBufferData
 
@@ -271,7 +278,7 @@ M: audio-engine dispose*
     audio-engine get-available-source :> al-source
 
     al-source [
-        buffer-count dup (uint-array) [ alGenBuffers ] keep :> al-buffers
+        buffer-count dup c:uint (c-array) [ alGenBuffers ] keep :> al-buffers
         generator generator-audio-format :> ( channels sample-bits sample-rate )
 
         streaming-audio-clip new-disposable
@@ -295,7 +302,7 @@ M: audio-clip dispose*
 
 M: static-audio-clip dispose*
     [ call-next-method ]
-    [ [ 1 ] dip al-buffer>> c:<uint> alDeleteBuffers ] bi ;
+    [ [ 1 ] dip al-buffer>> c:uint <ref> alDeleteBuffers ] bi ;
 
 M: streaming-audio-clip dispose*
     [ call-next-method ]
@@ -313,7 +320,7 @@ M: streaming-audio-clip dispose*
 : 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-count -- audio-clip/f ) 
+: play-streaming-audio-clip ( audio-engine source generator buffer-count -- audio-clip/f )
     <streaming-audio-clip> dup [ play-clip ] when* ;
 
 : pause-clip ( audio-clip -- )
@@ -335,4 +342,3 @@ M: streaming-audio-clip dispose*
         [ update-listener ]
         [ clips>> clone [ update-audio-clip ] each ]
     } cleave ;
-