5 , MultiParamTypeClasses
9 -- | EsounD recording streams.
10 module Sound.EsounD.Recorder
15 import Bindings.EsounD
16 import Control.Exception.Peel
17 import Control.Monad.IO.Class
18 import Control.Monad.IO.Peel
19 import Control.Monad.Trans.Region
20 import Control.Monad.Trans.Region.OnExit
21 import Control.Monad.Unicode
23 import Data.StorableVector as S
24 import Data.StorableVector.Lazy as L
26 import Prelude.Unicode
27 import Sound.EsounD.Streams
28 import Sound.EsounD.Internals
30 import System.IO.SaferFileHandles.Unsafe
33 -- ^ An opaque ESD handle for recording data from the soundcard via ESD.
34 data Recorder fr ch (r ∷ ★ → ★)
38 , reCloseH ∷ !(FinalizerHandle r)
41 instance Dup (Recorder fr ch) where
42 dup re = do ch' ← dup (reCloseH re)
43 return re { reCloseH = ch' }
45 instance Stream (Recorder fr ch) where
46 streamSampleRate = reRate
48 instance Frame fr ⇒ ReadableStream (Recorder fr Mono) (L.Vector fr) where
53 S.hGet (reHandle re) nFrames
55 instance Frame fr ⇒ ReadableStream (Recorder fr Stereo) (L.Vector fr, L.Vector fr) where
59 fmap (deinterleave ∘ toLSV) $
60 S.hGet (reHandle re) nFrames
62 -- | Open an ESD handle for recording data from the soundcard via ESD.
63 openRecorder ∷ ∀fr ch s pr.
68 ⇒ Int -- ^ sample rate for the stream.
69 → Maybe HostName -- ^ host to connect to.
70 → Maybe String -- ^ name used to identify this stream
72 → RegionT s pr (Recorder fr ch (RegionT s pr))
73 openRecorder rate host name
75 do h ← liftIO openSocket
76 ch ← onExit $ sanitizeIOError $ closeSocket h
84 fmt = frameFmt ((⊥) ∷ fr) .|.
85 channelFmt ((⊥) ∷ ch) .|.
89 openSocket ∷ IO Handle
90 openSocket = withCStrOrNull host $ \hostPtr →
91 withCStrOrNull name $ \namePtr →
98 ( printf "esd_record_stream(%s, %s, %s, %s) returned an error"