5 , MultiParamTypeClasses
9 -- | EsounD controlling handles.
10 module Sound.EsounD.Controller
18 import Bindings.EsounD
19 import Control.Exception.Peel
20 import Control.Monad.IO.Class
21 import Control.Monad.IO.Peel
22 import Control.Monad.Trans.Region
23 import Control.Monad.Trans.Region.OnExit
24 import Control.Monad.Unicode
25 import Foreign.C.Types
27 import Sound.EsounD.Internals
28 import System.IO.SaferFileHandles.Unsafe
29 import System.Posix.Types
32 -- ^ An opaque ESD handle for controlling ESD.
33 data Controller (r ∷ ★ → ★)
36 , coCloseH ∷ !(FinalizerHandle r)
39 instance Dup Controller where
40 dup co = do ch' ← dup (coCloseH co)
41 return co { coCloseH = ch' }
43 -- | Open an ESD handle for controlling ESD.
44 openController ∷ MonadPeelIO pr
45 ⇒ Maybe HostName -- ^ host to connect to.
46 → RegionT s pr (Controller (RegionT s pr))
49 do s ← liftIO openSocket
50 ch ← onExit $ sanitizeIOError $ closeSocket' s
57 openSocket = withCStrOrNull host $ \hostPtr →
58 c'esd_open_sound hostPtr
61 wrapSocket' ∷ Monad m ⇒ CInt → m Fd
62 wrapSocket' (-1) = fail ( printf "esd_open_sound(%s) returned an error"
65 wrapSocket' fd = return $ Fd fd
67 closeSocket' ∷ Fd → IO ()
69 = do _ ← c'esd_close $ fdToCInt fd
73 fdToCInt (Fd fd) = fromIntegral fd
75 -- | Lock the ESD so that it won't accept connections from remote
77 lock ∷ ( AncestorRegion pr cr
85 c'esd_lock (fdToCInt $ coSocket co)
86 ≫= failOnError "esd_lock(fd) returned an error"
88 -- | Unlock the ESD so that it will accept connections from remote
90 unlock ∷ ( AncestorRegion pr cr
98 c'esd_unlock (fdToCInt $ coSocket co)
99 ≫= failOnError "esd_unlock(fd) returned an error"