[Haskell-cafe] FFI woes!

Keean Schupke k.schupke at imperial.ac.uk
Thu Dec 16 07:35:55 EST 2004

Okay, you want to poll to see if the sound is still playing... This is 
not very
easy to do...

You really want to use the low-buffer callback from the soundcard
driver to load the next sample into the buffer using DMA. (IE you
can pass a function to the driver to call when you sample has been
copied completely to the sound-cards memory). This is the way to
do it...

    play_then_free = do
        set_callback (free_sample my_sample)
        play_sample my_sample

You can see that this provides the interface you want to the user (IE
samples are freed once they are finished with)...


Sebastian Sylvan wrote:

>On Thu, 16 Dec 2004 09:46:34 +0000, Keean Schupke
><k.schupke at imperial.ac.uk> wrote:
>>What about using a StablePtr? If you're dealing with hardware you would
>>get the
>>end-of-sample interrupt to free the buffer... Either way you either have
>>to delay GC
>>until the sample playback has finished... (well technically until the
>>soundcard DMA
>>has transferred the sample to the soundcards onboard memory) or free the
>>when playback has finished. These ammount to the same thing... but using
>>a StablePtr
>>and explicit free seems much nicer than hacking strange stuff into a
>Explicitly freeing works as it is. I was just hoping to get a higher
>level abstraction on top of this so that the user could just create a
>sound resource, and then play it back all over the place (even in
>functions with short-lifespans) and have the system "Do The Right
>Thing" with regards to cleaning up once nothing references the sound
>resource, or the channels playing it, anymore..
>Of couse, as stated, the problem comes in with the fact that channels
>will get cleaned up even if they are currently playing stuff.
>It would be ideal if one could just attatch a "guard" against the GC
>to a value so that each time the GC wants to collect unreferenced
>stuff it will first apply the guard-function, if there is one, to the
>value and only free it up if that returns True (this would be tested
>every time the GC does a "collection sweep").
>Then I could just do something like the following each time a playback
>is started:
>attatchGCGuard playback isPlaying
>isPlaying :: Playback -> IO Bool
>attatchGCGuard :: a -> (a -> IO Bool) -> IO ()
>This would mean that the playback won't get cleaned up if it's
>currently playing something. And since the Playback value has a
>reference to the "ForeignPtr CSoundSample" where the sound data lies,
>that won't get freed up either (freeing of that resource happens in
>the finalizer for that ForeignPtr).
>Maybe that's not possible for reasons beyond my understanding, but
>perhaps it illustrates my problem in a clearer way.

More information about the Haskell-Cafe mailing list