Exposed-Modules:
Sound.EsounD
+ Sound.EsounD.Player
+ Sound.EsounD.Types
Other-Modules:
Sound.EsounD.Internals
-- | Type-safe bindings to EsounD with monadic regions.
module Sound.EsounD
- ( Frame
-
- , Channels
- , Mono
- , Stereo
-
- , Player
- , openPlayer
+ ( module Sound.EsounD.Types
+ , module Sound.EsounD.Player
)
where
-import Bindings.EsounD
-import Control.Monad.IO.Class
-import Control.Monad.Trans.Region
-import Control.Monad.Trans.Region.OnExit
-import Control.Monad.Unicode
-import Data.Bits
-import Data.Int
-import Foreign.C.String
-import Network
-import Prelude.Unicode
-import Sound.EsounD.Internals
-import System.IO
-import System.IO.SaferFileHandles.Unsafe
-
-class Frame fr where
- frameFmt ∷ fr → C'esd_format_t
-
-instance Frame Int8 where
- frameFmt _ = c'ESD_BITS8
-
-instance Frame Int16 where
- frameFmt _ = c'ESD_BITS16
-
-class Channels ch where
- channelFmt ∷ ch → C'esd_format_t
-
-data Mono
-instance Channels Mono where
- channelFmt _ = c'ESD_MONO
-
-data Stereo
-instance Channels Stereo where
- channelFmt _ = c'ESD_STEREO
-
-
--- ^ An ESD handle for playing a stream.
-data Player fr ch (r ∷ * → *)
- = Player {
- plRate ∷ !Int
- -- THINKME: We really want to use RegionalFileHandle but we
- -- can't, because safer-file-handles currently provides no ways
- -- to wrap ordinary handles.
- , plHandle ∷ !Handle
- , plCloseH ∷ !(CloseHandle r)
- }
-
-instance Dup (Player fr ch) where
- dup pl = do ch' ← dup (plCloseH pl)
- return pl { plCloseH = ch' }
-
--- | Open an ESD handle for playing a stream.
-openPlayer ∷ ∀fr ch s pr.
- ( Frame fr
- , Channels ch
- , MonadIO pr
- )
- ⇒ Int -- ^ sample rate for the stream.
- → HostName -- ^ host to connect to.
- → Maybe String -- ^ name used to identify this stream to
- -- ESD (if any).
- → RegionT s pr (Player fr ch (RegionT s pr))
-openPlayer rate host name
- = do h ← liftIO openSocket
- ch ← onExit $ sanitizeIOError $ closeSocket h
- return Player {
- plRate = rate
- , plHandle = h
- , plCloseH = ch
- }
- where
- fmt :: C'esd_format_t
- fmt = frameFmt ((⊥) ∷ fr) .&.
- channelFmt ((⊥) ∷ ch) .&.
- c'ESD_STREAM .&.
- c'ESD_PLAY
-
- openSocket :: IO Handle
- openSocket = withCString host $ \hostPtr →
- withCStrOrNull name $ \namePtr →
- c'esd_play_stream
- fmt
- (fromIntegral rate)
- hostPtr
- namePtr
- ≫= wrapSocket "esd_play_stream() returned an error"
+import Sound.EsounD.Types
+import Sound.EsounD.Player
module Sound.EsounD.Internals
- ( wrapSocket
+ ( Frame(..)
+
+ , Channels(..)
+ , Mono
+ , Stereo
+
+ , wrapSocket
, closeSocket
, withCStrOrNull
)
where
import Bindings.EsounD
+import Data.Int
import Foreign.C.String
import Foreign.C.Types
import Foreign.Ptr
import System.Posix.IO
import System.Posix.Types
+class Frame fr where
+ frameFmt ∷ fr → C'esd_format_t
+
+instance Frame Int8 where
+ frameFmt _ = c'ESD_BITS8
+
+instance Frame Int16 where
+ frameFmt _ = c'ESD_BITS16
+
+class Channels ch where
+ channelFmt ∷ ch → C'esd_format_t
+
+data Mono
+instance Channels Mono where
+ channelFmt _ = c'ESD_MONO
+
+data Stereo
+instance Channels Stereo where
+ channelFmt _ = c'ESD_STEREO
+
+
wrapSocket :: String -> CInt → IO Handle
wrapSocket e (-1) = fail e
wrapSocket _ fd = fdToHandle (Fd fd)
--- /dev/null
+-- | EsounD player streams.
+module Sound.EsounD.Player
+ ( Player
+ , openPlayer
+ )
+ where
+
+import Bindings.EsounD
+import Control.Monad.IO.Class
+import Control.Monad.Trans.Region
+import Control.Monad.Trans.Region.OnExit
+import Control.Monad.Unicode
+import Data.Bits
+import Foreign.C.String
+import Network
+import Prelude.Unicode
+import Sound.EsounD.Internals
+import System.IO
+import System.IO.SaferFileHandles.Unsafe
+
+
+-- ^ An opaque ESD handle for playing a stream.
+data Player fr ch (r ∷ * → *)
+ = Player {
+ plRate ∷ !Int
+ -- THINKME: We really want to use RegionalFileHandle but we
+ -- can't, because safer-file-handles currently provides no ways
+ -- to wrap ordinary handles.
+ , plHandle ∷ !Handle
+ , plCloseH ∷ !(CloseHandle r)
+ }
+
+instance Dup (Player fr ch) where
+ dup pl = do ch' ← dup (plCloseH pl)
+ return pl { plCloseH = ch' }
+
+-- | Open an ESD handle for playing a stream.
+openPlayer ∷ ∀fr ch s pr.
+ ( Frame fr
+ , Channels ch
+ , MonadIO pr
+ )
+ ⇒ Int -- ^ sample rate for the stream.
+ → HostName -- ^ host to connect to.
+ → Maybe String -- ^ name used to identify this stream to
+ -- ESD (if any).
+ → RegionT s pr (Player fr ch (RegionT s pr))
+openPlayer rate host name
+ = do h ← liftIO openSocket
+ ch ← onExit $ sanitizeIOError $ closeSocket h
+ return Player {
+ plRate = rate
+ , plHandle = h
+ , plCloseH = ch
+ }
+ where
+ fmt :: C'esd_format_t
+ fmt = frameFmt ((⊥) ∷ fr) .&.
+ channelFmt ((⊥) ∷ ch) .&.
+ c'ESD_STREAM .&.
+ c'ESD_PLAY
+
+ openSocket :: IO Handle
+ openSocket = withCString host $ \hostPtr →
+ withCStrOrNull name $ \namePtr →
+ c'esd_play_stream
+ fmt
+ (fromIntegral rate)
+ hostPtr
+ namePtr
+ ≫= wrapSocket "esd_play_stream() returned an error"
--- /dev/null
+module Sound.EsounD.Types
+ ( Frame
+
+ , Channels
+ , Mono
+ , Stereo
+ )
+ where
+
+import Sound.EsounD.Internals