summaryrefslogtreecommitdiff
path: root/src/Trivstream
diff options
context:
space:
mode:
authorGregor Kleen <pngwjpgh@users.noreply.github.com>2016-08-02 22:42:52 +0200
committerGregor Kleen <pngwjpgh@users.noreply.github.com>2016-08-02 22:42:52 +0200
commitf31a65bcd1642b3f042bd906674f4064cfc9362c (patch)
treeb99f2180b38a2a3280f63dc9f521785fe3736578 /src/Trivstream
parentd6647e7fc48c6436dc74c99b4614aa2bb557ea75 (diff)
downloadtrivstream-f31a65bcd1642b3f042bd906674f4064cfc9362c.tar
trivstream-f31a65bcd1642b3f042bd906674f4064cfc9362c.tar.gz
trivstream-f31a65bcd1642b3f042bd906674f4064cfc9362c.tar.bz2
trivstream-f31a65bcd1642b3f042bd906674f4064cfc9362c.tar.xz
trivstream-f31a65bcd1642b3f042bd906674f4064cfc9362c.zip
Inital work on option parsing
Diffstat (limited to 'src/Trivstream')
-rw-r--r--src/Trivstream/Options.hs37
-rw-r--r--src/Trivstream/Options/Utils.hs32
-rw-r--r--src/Trivstream/Types.hs92
3 files changed, 161 insertions, 0 deletions
diff --git a/src/Trivstream/Options.hs b/src/Trivstream/Options.hs
new file mode 100644
index 0000000..a777942
--- /dev/null
+++ b/src/Trivstream/Options.hs
@@ -0,0 +1,37 @@
1{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
2
3module Trivstream.Options
4 ( withOptions
5 ) where
6
7
8import Trivstream.Types
9import Trivstream.Options.Utils
10import Paths_trivstream (version)
11
12
13import Options.Applicative
14
15import Control.Monad.Reader
16import Control.Monad.IO.Class
17
18
19withOptions :: MonadIO m => ReaderT Configuration a -> IO a
20withOptions f = liftIO (execParser options) >>= runReaderT f
21 where
22 options = options' `info` mconcat [ header $ concat [ "trivstream "
23 , show version
24 , " - "
25 , "A trivial client & server for streaming audio between pulseaudio and jack over udp/tcp"
26 ]
27 , footer $ concat [ "trivstream "
28 , show version
29 , " (", $(gitBranch), "@", $(gitHash), (if $(gitDirty) then "*" else ""), ")"
30 ]
31 ]
32 options' = Configuration <$> argument rCI (help "Mode of operation" <> value def <> showDefault <> metavar "MODE")
33 <*> optional ( undefined
34 )
35 <*> audioOptions
36
37 audioOptions = undefined
diff --git a/src/Trivstream/Options/Utils.hs b/src/Trivstream/Options/Utils.hs
new file mode 100644
index 0000000..30694d8
--- /dev/null
+++ b/src/Trivstream/Options/Utils.hs
@@ -0,0 +1,32 @@
1{-# LANGUAGE StandaloneDeriving #-}
2
3module Trivstream.Options.Utils
4 ( rCI
5 ) where
6
7import Options.Applicative
8
9import Data.Char
10import Data.Maybe
11
12import Network.Socket
13
14
15deriving instance Enum Family
16deriving instance Bounded Family
17
18
19rCI :: (Show a, Read a) => ReadM a
20rCI = eitherReader rRep'
21 where
22 rRep' str = case mapMaybe readMaybe $ cases str of
23 [] -> Left $ "Could not parse `" ++ str ++ "'"
24 [x] -> Right x
25 xs -> Left $ "Ambiguous parse for `" ++ str ++ "': " ++ show xs
26 cases [] = [[]]
27 cases (c:cs) = [(c':cs') | c' <- [toLower c, c, toUpper c], cs' <- cases cs]
28
29rFamily :: ReadM Family
30rFamily = undefined
31 where
32 families = filter isSupportedFamily [minBound..maxBound]
diff --git a/src/Trivstream/Types.hs b/src/Trivstream/Types.hs
new file mode 100644
index 0000000..8cdd592
--- /dev/null
+++ b/src/Trivstream/Types.hs
@@ -0,0 +1,92 @@
1{-# LANGUAGE TemplateHaskell #-}
2{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving, DeriveGeneric #-}
3
4module Trivstream.Types
5 ( AudioConfig(..)
6 , AudioBackend(..)
7 , SampleRate(..)
8 , Configuration(..)
9 , Mode (..)
10 ) where
11
12
13import Control.Lens
14import Control.Lens.TH
15import Data.Default.Class (Default(..))
16import Data.Serialize (Serialize)
17import GHC.Generics (Generic)
18
19import Foreign.C.Types (CInt(..))
20
21import Sound.Pulse.Simple (ChannelPosition(..), ChannelPan(..))
22import Sound.JACK ()
23
24import Network.Socket (Family(..), SocketType(..), ProtocolNumber(..), SockAddr(..))
25
26
27deriving instance Generic ChannelPan
28instance Serialize ChannelPan
29
30deriving instance Generic ChannelPosition
31instance Serialize ChannelPosition
32
33
34data AudioBackend = Pulse | Jack
35 deriving (Enum, Eq, Generic)
36
37instance Default AudioBackend where
38 def = Pulse
39
40instance Serialize AudioBackend
41
42
43-- | Numeric instances consider this value to be in `kHz`
44newtype SampleRate = SampleRate Int
45 deriving (Eq, Ord, Enum, Num, Real, Integral, Generic)
46makePrisms ''SampleRate
47
48instance Default SampleRate where
49 def = 44100
50
51instance Serialize SampleRate
52
53
54data AudioConfig = AudioConfig
55 { _aBackend :: AudioBackend
56 , _aChannels :: [Maybe ChannelPosition]
57 , _aRate :: SampleRate
58 } deriving (Generic)
59makeLenses ''AudioConfig
60
61instance Default AudioConfig where
62 def = AudioConfig
63 { _aBackend = def
64 , _aChannels = [Just $ ChannelNormal PanLeft, Just $ ChannelNormal PanRight]
65 , _aRate = def
66 }
67
68instance Serialize AudioConfig
69
70
71data Mode = Server | Client
72 deriving (Enum, Eq, Generic, Show)
73
74instance Default Mode where
75 def = Server
76
77instance Serialize Mode
78
79
80data Configuration = Configuration
81 { _cMode :: Mode
82 , _cSocketDesc :: Maybe (Family, SocketType, ProtocolNumber, SockAddr)
83 , _cAudio :: AudioConfig
84 } deriving (Generic)
85makeLenses ''Configuration
86
87instance Default Configuration where
88 def = Configuration
89 { _cMode = def
90 , _cSocketDesc = Nothing
91 , _cAudio = def
92 }