1 -- | EsounD player streams.
2 module Sound.EsounD.Player
9 import Control.Monad.IO.Class
10 import Control.Monad.Trans.Region
11 import Control.Monad.Trans.Region.OnExit
12 import Control.Monad.Unicode
14 import Foreign.C.String
16 import Prelude.Unicode
17 import Sound.EsounD.Internals
19 import System.IO.SaferFileHandles.Unsafe
22 -- ^ An opaque ESD handle for playing a stream.
23 data Player fr ch (r ∷ * → *)
26 -- THINKME: We really want to use RegionalFileHandle but we
27 -- can't, because safer-file-handles currently provides no ways
28 -- to wrap ordinary handles into safer handles.
30 , plCloseH ∷ !(FinalizerHandle r)
33 instance Dup (Player fr ch) where
34 dup pl = do ch' ← dup (plCloseH pl)
35 return pl { plCloseH = ch' }
37 -- | Open an ESD handle for playing a stream.
38 openPlayer ∷ ∀fr ch s pr.
43 ⇒ Int -- ^ sample rate for the stream.
44 → HostName -- ^ host to connect to.
45 → Maybe String -- ^ name used to identify this stream to
47 → RegionT s pr (Player fr ch (RegionT s pr))
48 openPlayer rate host name
49 = do h ← liftIO openSocket
50 ch ← onExit $ sanitizeIOError $ closeSocket h
58 fmt = frameFmt ((⊥) ∷ fr) .&.
59 channelFmt ((⊥) ∷ ch) .&.
63 openSocket :: IO Handle
64 openSocket = withCString host $ \hostPtr →
65 withCStrOrNull name $ \namePtr →
71 ≫= wrapSocket "esd_play_stream() returned an error"