5 , MultiParamTypeClasses
9 -- | EsounD filtering streams.
10 module Sound.EsounD.Filter
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 filtering sound produced by ESD.
35 -- Reading from the stream will give a block of audio frames, which is
36 -- the mixed output from other players and filters. The filter is free
37 -- to process this block as it likes, but must then write an
38 -- identically sized block to the stream. The frames so returned is
39 -- played by the ESD, possibly after applying more filters to it.
40 data Filter fr ch (r ∷ ★ → ★)
44 , fiCloseH ∷ !(FinalizerHandle r)
47 instance Dup (Filter fr ch) where
48 dup fi = do ch' ← dup (fiCloseH fi)
49 return fi { fiCloseH = ch' }
51 instance Stream (Filter fr ch) where
52 streamSampleRate = fiRate
54 instance Frame fr ⇒ ReadableStream (Filter fr Mono) (L.Vector fr) where
59 S.hGet (fiHandle fi) nFrames
61 instance Frame fr ⇒ ReadableStream (Filter fr Stereo) (L.Vector fr, L.Vector fr) where
65 fmap (deinterleave ∘ toLSV) $
66 S.hGet (fiHandle fi) nFrames
68 instance Frame fr ⇒ WritableStream (Filter fr Mono) (L.Vector fr) where
70 = liftIO $ sanitizeIOError $ L.hPut (fiHandle fi) v
72 instance Frame fr ⇒ WritableStream (Filter fr Stereo) (L.Vector fr, L.Vector fr) where
74 = liftIO $ sanitizeIOError $ L.hPut (fiHandle fi) (interleave l r)
76 -- | Open an ESD handle for filtering sound produced by ESD.
78 -- The new filter will be placed at the head of the list of filters:
79 -- i.e. it will receive data for processing first, and the next filter
80 -- will receive the resultant processed data.
81 openFilter ∷ ∀fr ch s pr.
86 ⇒ Int -- ^ sample rate for the stream.
87 → Maybe HostName -- ^ host to connect to.
88 → Maybe String -- ^ name used to identify this stream to
90 → RegionT s pr (Filter fr ch (RegionT s pr))
91 openFilter rate host name
93 do h ← liftIO openSocket
94 ch ← onExit $ sanitizeIOError $ closeSocket h
102 fmt = frameFmt ((⊥) ∷ fr) .|.
103 channelFmt ((⊥) ∷ ch) .|.
106 openSocket ∷ IO Handle
107 openSocket = withCStrOrNull host $ \hostPtr →
108 withCStrOrNull name $ \namePtr →
115 ( printf "esd_filter_stream(%s, %s, %s, %s) returned an error"