[Haskell-cafe] FFI woes!
Sebastian Sylvan
sebastian.sylvan at gmail.com
Mon Dec 20 02:27:48 EST 2004
On Sat, 18 Dec 2004 20:24:47 -0500, Robert Dockins
<robdockins at fastmail.fm> wrote:
>
> > Well that shouldn't affect the functionality. The weak pointer was
> > only a way of attatching a finalizer to the Playback object. It is
> > true that I should probably wrap up the the SoundPlaybackRaw inside
> > the SoundPlayback as well, to save CPU, but it shouldn't matter for
> > the core functionality.
>
> I'm not sure I understand.
>
Well not including the SamplePlaybackRaw in the SamplePlayback
datatype means that the SamplePlaybackRaw might get prematurely GC'd,
but if the finalizer had worked that wouldn't have mattered, it
would've only meant that the keep-alive loop might have been started
earlier.
Anyway, the reason for not wanting to do polling-loops was simply a
performance issue. FMOD is one of the fastest, if not THE fastest,
sound libraries out there so I didn't want to "ruin it" by attatching
too much extra "fluff".
That's why I wanted to start a polling loop ony when it was absolutely
necessary, ie only when the Playback object was being GC'd (which
meant that GC'ing of the sound data might be imminent).
But anyway, I decided to bite the bullet and do it "the easy way".
Here's the final, short-n-sweet (albeit slightly inefficient),
solution:
-- A playback of a sample resource
newtype SamplePlayback = SP (MVar CInt)
-- play, and keep data alive until playback is done
samplePlay' :: MVar CInt -> SoundSample -> IO ()
samplePlay' var s = do ch <- withForeignPtr s (fsound_PlaySound (-1))
putMVar var ch
let loop = do b <- isPlaying (SP var)
case b of
True -> do touchForeignPtr s
threadDelay 1000000
-- wait one second
loop
False -> return ()
loop
-- asynchronous playback action
samplePlay :: SoundSample -> IO SamplePlayback
samplePlay s = do var <- newEmptyMVar
-- spawn a new playback thread
forkIO (samplePlay' var s)
-- wait for the MVar to get filled in
let loop = do yield
b <- isEmptyMVar var
if b then loop else return ()
loop
return (SP var)
isPlaying :: SamplePlayback -> IO Bool
isPlaying (SP var) = do b <- withMVar var (fsound_IsPlaying)
return (cscharToBool b)
--
Sebastian Sylvan
+46(0)736-818655
UIN: 44640862
More information about the Haskell-Cafe
mailing list