
On Thu, 16 Dec 2004 09:46:34 +0000, Keean Schupke
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 -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862