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)...

   Keean.

Sebastian Sylvan wrote:

On Thu, 16 Dec 2004 09:46:34 +0000, Keean Schupke
<[EMAIL PROTECTED]> 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
memory
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
finalizer.



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

where:
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.

/S




_______________________________________________ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to