{-# Language CPP #-}
module Csound.Typed.GlobalState.Options (
    Options(..),
    defGain, defSampleRate, defBlockSize, defTabFi, defScaleUI,
    -- * Table fidelity
    TabFi(..), fineFi, coarseFi,
    -- ** Gen identifiers
    -- | Low level Csound integer identifiers for tables. These names can be used in the function 'Csound.Base.fineFi'
    -- *** Integer identifiers
    idWavs, idMp3s, idDoubles, idSines, idSines3, idSines2,
    idPartials, idSines4, idBuzzes, idConsts, idLins, idCubes,
    idExps, idSplines, idStartEnds,  idPolys, idChebs1, idChebs2, idBessels, idWins,
    idTabHarmonics, idMixOnTab, idMixTabs,
    idNormTab, idPolynomFuns, idLinTab, idRandDists, idReadNumFile, idReadNumTab,
    idExpsBreakPoints, idLinsBreakPoints, idReadTrajectoryFile, idMixSines1, idMixSines2,
    idRandHist, idRandPairs, idRandRanges, idPvocex, idTuning, idMultichannel,
    -- *** String identifiers
    idPadsynth, idTanh, idExp, idSone, idFarey, idWave,
    -- * Jacko
    Jacko(..), JackoConnect, renderJacko,
    -- * Debug trace
    csdNeedTrace
) where

import Control.Applicative
import Data.Default
import Data.Maybe

import qualified Data.IntMap as IM
import qualified Data.Map    as M
import Data.Text (Text)
import Data.Text qualified as Text

import Csound.Dynamic hiding (csdFlags)

-- | Csound options. The default values are
--
-- > flags      = def     -- the only flag set by default is "no-displays"
-- >                      -- to supress the display of the tables
-- > sampleRate = 44100
-- > blockSize  = 64
-- > gain       = 0.5
-- > tabFi      = fineFi 13 [(idLins, 11), (idExps, 11), (idConsts, 9), (idSplines, 11), (idStartEnds, 12)] }
-- > scaleUI    = (1, 1)
data Options = Options
    { Options -> Flags
csdFlags          :: Flags                    -- ^ Csound command line flags
    , Options -> Maybe Int
csdSampleRate     :: Maybe Int                -- ^ The sample rate
    , Options -> Maybe Int
csdBlockSize      :: Maybe Int                -- ^ The number of audio samples in one control step
    , Options -> Maybe Double
csdGain           :: Maybe Double             -- ^ A gain of the final output
    , Options -> Maybe TabFi
csdTabFi          :: Maybe TabFi              -- ^ Default fidelity of the arrays
    , Options -> Maybe (Double, Double)
csdScaleUI        :: Maybe (Double, Double)   -- ^ Scale factors for UI-window
    , Options -> Maybe Jacko
csdJacko          :: Maybe Jacko
    , Options -> Maybe [(Text, Text)]
csdJackConnect    :: Maybe [(Text, Text)] -- ^ list of jack connections to make after csound app is launched (Linux only)
    , Options -> Maybe Bool
csdTrace          :: Maybe Bool               -- ^ Do we need debug-trace, default is False
    , Options -> Maybe RenderOptions
csdRender         :: Maybe RenderOptions
    } deriving (Options -> Options -> Bool
(Options -> Options -> Bool)
-> (Options -> Options -> Bool) -> Eq Options
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Options -> Options -> Bool
== :: Options -> Options -> Bool
$c/= :: Options -> Options -> Bool
/= :: Options -> Options -> Bool
Eq, Int -> Options -> ShowS
[Options] -> ShowS
Options -> String
(Int -> Options -> ShowS)
-> (Options -> String) -> ([Options] -> ShowS) -> Show Options
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Options -> ShowS
showsPrec :: Int -> Options -> ShowS
$cshow :: Options -> String
show :: Options -> String
$cshowList :: [Options] -> ShowS
showList :: [Options] -> ShowS
Show, ReadPrec [Options]
ReadPrec Options
Int -> ReadS Options
ReadS [Options]
(Int -> ReadS Options)
-> ReadS [Options]
-> ReadPrec Options
-> ReadPrec [Options]
-> Read Options
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Options
readsPrec :: Int -> ReadS Options
$creadList :: ReadS [Options]
readList :: ReadS [Options]
$creadPrec :: ReadPrec Options
readPrec :: ReadPrec Options
$creadListPrec :: ReadPrec [Options]
readListPrec :: ReadPrec [Options]
Read)

instance Default Options where
    def :: Options
def = Flags
-> Maybe Int
-> Maybe Int
-> Maybe Double
-> Maybe TabFi
-> Maybe (Double, Double)
-> Maybe Jacko
-> Maybe [(Text, Text)]
-> Maybe Bool
-> Maybe RenderOptions
-> Options
Options Flags
forall a. Default a => a
def Maybe Int
forall a. Default a => a
def Maybe Int
forall a. Default a => a
def Maybe Double
forall a. Default a => a
def Maybe TabFi
forall a. Default a => a
def Maybe (Double, Double)
forall a. Default a => a
def Maybe Jacko
forall a. Default a => a
def Maybe [(Text, Text)]
forall a. Default a => a
def Maybe Bool
forall a. Default a => a
def Maybe RenderOptions
forall a. Default a => a
def

#if MIN_VERSION_base(4,11,0)
instance Semigroup Options where
    <> :: Options -> Options -> Options
(<>) = Options -> Options -> Options
mappendOptions

instance Monoid Options where
    mempty :: Options
mempty  = Options
forall a. Default a => a
def

#else

instance Monoid Options where
    mempty  = def
    mappend = mappendOptions

#endif

mappendOptions :: Options -> Options -> Options
mappendOptions :: Options -> Options -> Options
mappendOptions Options
a Options
b = Options
    { csdFlags :: Flags
csdFlags          = Flags -> Flags -> Flags
forall a. Monoid a => a -> a -> a
mappend (Options -> Flags
csdFlags Options
a) (Options -> Flags
csdFlags Options
b)
    , csdSampleRate :: Maybe Int
csdSampleRate     = Options -> Maybe Int
csdSampleRate Options
a Maybe Int -> Maybe Int -> Maybe Int
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Options -> Maybe Int
csdSampleRate Options
b
    , csdBlockSize :: Maybe Int
csdBlockSize      = Options -> Maybe Int
csdBlockSize Options
a Maybe Int -> Maybe Int -> Maybe Int
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Options -> Maybe Int
csdBlockSize Options
b
    , csdGain :: Maybe Double
csdGain           = Options -> Maybe Double
csdGain Options
a Maybe Double -> Maybe Double -> Maybe Double
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Options -> Maybe Double
csdGain Options
b
    , csdTabFi :: Maybe TabFi
csdTabFi          = Options -> Maybe TabFi
csdTabFi Options
a Maybe TabFi -> Maybe TabFi -> Maybe TabFi
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Options -> Maybe TabFi
csdTabFi Options
b
    , csdScaleUI :: Maybe (Double, Double)
csdScaleUI        = Options -> Maybe (Double, Double)
csdScaleUI Options
a Maybe (Double, Double)
-> Maybe (Double, Double) -> Maybe (Double, Double)
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Options -> Maybe (Double, Double)
csdScaleUI Options
b
    , csdJacko :: Maybe Jacko
csdJacko          = Options -> Maybe Jacko
csdJacko Options
a Maybe Jacko -> Maybe Jacko -> Maybe Jacko
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Options -> Maybe Jacko
csdJacko Options
b
    , csdJackConnect :: Maybe [(Text, Text)]
csdJackConnect    = Maybe [(Text, Text)]
-> Maybe [(Text, Text)] -> Maybe [(Text, Text)]
forall a. Monoid a => a -> a -> a
mappend (Options -> Maybe [(Text, Text)]
csdJackConnect Options
a) (Options -> Maybe [(Text, Text)]
csdJackConnect Options
b)
    , csdTrace :: Maybe Bool
csdTrace          = Options -> Maybe Bool
csdTrace Options
a Maybe Bool -> Maybe Bool -> Maybe Bool
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Options -> Maybe Bool
csdTrace Options
b
    , csdRender :: Maybe RenderOptions
csdRender         = Options -> Maybe RenderOptions
csdRender Options
a Maybe RenderOptions -> Maybe RenderOptions -> Maybe RenderOptions
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Options -> Maybe RenderOptions
csdRender Options
b
    }

defScaleUI :: Options -> (Double, Double)
defScaleUI :: Options -> (Double, Double)
defScaleUI = (Double, Double)
-> ((Double, Double) -> (Double, Double))
-> Maybe (Double, Double)
-> (Double, Double)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Double
1, Double
1) (Double, Double) -> (Double, Double)
forall a. a -> a
id (Maybe (Double, Double) -> (Double, Double))
-> (Options -> Maybe (Double, Double))
-> Options
-> (Double, Double)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options -> Maybe (Double, Double)
csdScaleUI

defGain :: Options -> Double
defGain :: Options -> Double
defGain = Double -> (Double -> Double) -> Maybe Double -> Double
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Double
0.8 Double -> Double
forall a. a -> a
id (Maybe Double -> Double)
-> (Options -> Maybe Double) -> Options -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options -> Maybe Double
csdGain

defSampleRate :: Options -> Int
defSampleRate :: Options -> Int
defSampleRate = Int -> (Int -> Int) -> Maybe Int -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
44100 Int -> Int
forall a. a -> a
id (Maybe Int -> Int) -> (Options -> Maybe Int) -> Options -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options -> Maybe Int
csdSampleRate

defBlockSize :: Options -> Int
defBlockSize :: Options -> Int
defBlockSize = Int -> (Int -> Int) -> Maybe Int -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
64 Int -> Int
forall a. a -> a
id (Maybe Int -> Int) -> (Options -> Maybe Int) -> Options -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options -> Maybe Int
csdBlockSize

defTabFi :: Options -> TabFi
defTabFi :: Options -> TabFi
defTabFi = TabFi -> (TabFi -> TabFi) -> Maybe TabFi -> TabFi
forall b a. b -> (a -> b) -> Maybe a -> b
maybe TabFi
forall a. Default a => a
def TabFi -> TabFi
forall a. a -> a
id (Maybe TabFi -> TabFi)
-> (Options -> Maybe TabFi) -> Options -> TabFi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options -> Maybe TabFi
csdTabFi

-- | Table size fidelity (how many points in the table by default).
data TabFi = TabFi
    { TabFi -> Int
tabFiBase   :: Int
    , TabFi -> IntMap Int
tabFiGens   :: IM.IntMap Int
    , TabFi -> Map Text Int
tabNamedFiGens :: M.Map Text Int
    } deriving (TabFi -> TabFi -> Bool
(TabFi -> TabFi -> Bool) -> (TabFi -> TabFi -> Bool) -> Eq TabFi
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TabFi -> TabFi -> Bool
== :: TabFi -> TabFi -> Bool
$c/= :: TabFi -> TabFi -> Bool
/= :: TabFi -> TabFi -> Bool
Eq, Int -> TabFi -> ShowS
[TabFi] -> ShowS
TabFi -> String
(Int -> TabFi -> ShowS)
-> (TabFi -> String) -> ([TabFi] -> ShowS) -> Show TabFi
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TabFi -> ShowS
showsPrec :: Int -> TabFi -> ShowS
$cshow :: TabFi -> String
show :: TabFi -> String
$cshowList :: [TabFi] -> ShowS
showList :: [TabFi] -> ShowS
Show, ReadPrec [TabFi]
ReadPrec TabFi
Int -> ReadS TabFi
ReadS [TabFi]
(Int -> ReadS TabFi)
-> ReadS [TabFi]
-> ReadPrec TabFi
-> ReadPrec [TabFi]
-> Read TabFi
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS TabFi
readsPrec :: Int -> ReadS TabFi
$creadList :: ReadS [TabFi]
readList :: ReadS [TabFi]
$creadPrec :: ReadPrec TabFi
readPrec :: ReadPrec TabFi
$creadListPrec :: ReadPrec [TabFi]
readListPrec :: ReadPrec [TabFi]
Read)

instance Default TabFi where
    def :: TabFi
def = Int -> [(Int, Int)] -> [(Text, Int)] -> TabFi
fineFi Int
13
                [(Int
idLins, Int
11), (Int
idExps, Int
11), (Int
idConsts, Int
9), (Int
idSplines, Int
11), (Int
idStartEnds, Int
12), (Int
idExpsBreakPoints, Int
11), (Int
idLinsBreakPoints, Int
11), (Int
idRandDists, Int
6)]
                [(Text
idPadsynth, Int
18), (Text
idSone, Int
14), (Text
idTanh, Int
13), (Text
idExp, Int
13)]


-- | Sets different table size for different GEN-routines.
--
-- > fineFi n ps
--
-- where
--
-- * @n@ is the default value for table size (size is a @n@ power of 2) for all gen routines that are not listed in the next argument @ps@.
--
-- * @ps@ is a list of pairs @(genRoutineId, tableSizeDegreeOf2)@ that sets the given table size for a
--   given GEN-routine.
--
-- with this function we can set lower table sizes for tables that are usually used in the envelopes.
fineFi :: Int -> [(Int, Int)] -> [(Text, Int)] -> TabFi
fineFi :: Int -> [(Int, Int)] -> [(Text, Int)] -> TabFi
fineFi Int
n [(Int, Int)]
xs [(Text, Int)]
ys = Int -> IntMap Int -> Map Text Int -> TabFi
TabFi Int
n ([(Int, Int)] -> IntMap Int
forall a. [(Int, a)] -> IntMap a
IM.fromList [(Int, Int)]
xs) ([(Text, Int)] -> Map Text Int
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(Text, Int)]
ys)

-- | Sets the same table size for all tables.
--
-- > coarseFi n
--
-- where @n@  is a degree of 2. For example, @n = 10@ sets size to 1024 points for all tables by default.
coarseFi :: Int -> TabFi
coarseFi :: Int -> TabFi
coarseFi Int
n = Int -> IntMap Int -> Map Text Int -> TabFi
TabFi Int
n IntMap Int
forall a. IntMap a
IM.empty Map Text Int
forall k a. Map k a
M.empty

idWavs, idMp3s, idDoubles, idSines, idSines3, idSines2,
    idPartials, idSines4, idBuzzes, idConsts, idLins, idCubes,
    idExps, idSplines, idStartEnds,  idPolys, idChebs1, idChebs2, idBessels, idWins,
    idTabHarmonics, idMixOnTab, idMixTabs,
    idNormTab, idPolynomFuns, idLinTab, idRandDists, idReadNumFile, idReadNumTab,
    idExpsBreakPoints, idLinsBreakPoints, idReadTrajectoryFile, idMixSines1, idMixSines2,
    idRandHist, idRandPairs, idRandRanges, idPvocex, idTuning, idMultichannel :: Int

-- Human readable Csound identifiers for GEN-routines

idWavs :: Int
idWavs = Int
1
idDoubles :: Int
idDoubles = Int
2
idSines :: Int
idSines = Int
10
idSines3 :: Int
idSines3 = Int
9
idSines2 :: Int
idSines2 = Int
9
idPartials :: Int
idPartials = Int
9
idSines4 :: Int
idSines4 = Int
19
idBuzzes :: Int
idBuzzes = Int
11
idConsts :: Int
idConsts = Int
17
idLins :: Int
idLins = Int
7
idCubes :: Int
idCubes = Int
6
idExps :: Int
idExps = Int
5
idStartEnds :: Int
idStartEnds = Int
16
idSplines :: Int
idSplines = Int
8
idPolys :: Int
idPolys = Int
3
idChebs1 :: Int
idChebs1 = Int
13
idChebs2 :: Int
idChebs2 = Int
14
idBessels :: Int
idBessels = Int
12
idWins :: Int
idWins = Int
20
idMp3s :: Int
idMp3s = Int
49
idTabHarmonics :: Int
idTabHarmonics = Int
30
idMixOnTab :: Int
idMixOnTab = Int
31
idMixTabs :: Int
idMixTabs = Int
32

idNormTab :: Int
idNormTab = Int
4
idLinTab :: Int
idLinTab = Int
18

idRandDists :: Int
idRandDists = Int
21
idReadNumFile :: Int
idReadNumFile = Int
23
idReadNumTab :: Int
idReadNumTab = Int
24
idExpsBreakPoints :: Int
idExpsBreakPoints = Int
25
idLinsBreakPoints :: Int
idLinsBreakPoints = Int
27
idReadTrajectoryFile :: Int
idReadTrajectoryFile = Int
28
idMixSines1 :: Int
idMixSines1 = Int
33
idMixSines2 :: Int
idMixSines2 = Int
34
idRandHist :: Int
idRandHist = Int
40
idRandPairs :: Int
idRandPairs = Int
41
idRandRanges :: Int
idRandRanges = Int
42
idPvocex :: Int
idPvocex = Int
43
idTuning :: Int
idTuning = Int
51
idMultichannel :: Int
idMultichannel = Int
52

idTanh :: Text
idTanh     = Text
"tanh"
idExp :: Text
idExp      = Text
"exp"
idSone :: Text
idSone     = Text
"sone"
idFarey :: Text
idFarey    = Text
"farey"
idWave :: Text
idWave     = Text
"wave"

-- Identifiers for named GEN-routines

idPadsynth, idTanh, idExp, idSone, idFarey, idWave :: Text

idPadsynth :: Text
idPadsynth = Text
"padsynth"

---------------------------------------------
-- not implemented yet (hard to implement within the current model)

idPolynomFuns :: Int
idPolynomFuns = Int
15


----------------------------------------------------------
-- Jacko

type JackoConnect = (Text, Text)

-- | Describes the Jacko header. All information that is going to be set in the global settings for Jacko opcodes.
-- The jacko opcodes allows us to easily turn our app into Jack-client. We can also do it with command line flags.
-- But the Jacko opcodes provide more options.
--
-- see the Csound docs for details: <http://csound.github.io/docs/manual/JackoOpcodes.html>
data Jacko = Jacko
    { Jacko -> Text
jackoClient       :: Text
    , Jacko -> Text
jackoServer       :: Text
    , Jacko -> [(Text, Text)]
jackoAudioIns     :: [JackoConnect]
    , Jacko -> [(Text, Text)]
jackoAudioOuts    :: [JackoConnect]
    , Jacko -> [(Text, Text)]
jackoMidiIns      :: [JackoConnect]
    , Jacko -> [(Text, Text)]
jackoMidiOuts     :: [JackoConnect]
    , Jacko -> Bool
jackoFreewheel    :: Bool
    , Jacko -> Bool
jackoInfo         :: Bool
    } deriving (Jacko -> Jacko -> Bool
(Jacko -> Jacko -> Bool) -> (Jacko -> Jacko -> Bool) -> Eq Jacko
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Jacko -> Jacko -> Bool
== :: Jacko -> Jacko -> Bool
$c/= :: Jacko -> Jacko -> Bool
/= :: Jacko -> Jacko -> Bool
Eq, Int -> Jacko -> ShowS
[Jacko] -> ShowS
Jacko -> String
(Int -> Jacko -> ShowS)
-> (Jacko -> String) -> ([Jacko] -> ShowS) -> Show Jacko
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Jacko -> ShowS
showsPrec :: Int -> Jacko -> ShowS
$cshow :: Jacko -> String
show :: Jacko -> String
$cshowList :: [Jacko] -> ShowS
showList :: [Jacko] -> ShowS
Show, ReadPrec [Jacko]
ReadPrec Jacko
Int -> ReadS Jacko
ReadS [Jacko]
(Int -> ReadS Jacko)
-> ReadS [Jacko]
-> ReadPrec Jacko
-> ReadPrec [Jacko]
-> Read Jacko
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Jacko
readsPrec :: Int -> ReadS Jacko
$creadList :: ReadS [Jacko]
readList :: ReadS [Jacko]
$creadPrec :: ReadPrec Jacko
readPrec :: ReadPrec Jacko
$creadListPrec :: ReadPrec [Jacko]
readListPrec :: ReadPrec [Jacko]
Read)

instance Default Jacko where
    def :: Jacko
def = Jacko
        { jackoClient :: Text
jackoClient       = Text
"csound-exp"
        , jackoServer :: Text
jackoServer       = Text
"default"
        , jackoAudioIns :: [(Text, Text)]
jackoAudioIns     = []
        , jackoAudioOuts :: [(Text, Text)]
jackoAudioOuts    = []
        , jackoMidiIns :: [(Text, Text)]
jackoMidiIns      = []
        , jackoMidiOuts :: [(Text, Text)]
jackoMidiOuts     = []
        , jackoFreewheel :: Bool
jackoFreewheel    = Bool
False
        , jackoInfo :: Bool
jackoInfo         = Bool
False }

renderJacko :: Jacko -> Text
renderJacko :: Jacko -> Text
renderJacko Jacko
spec = [Text] -> Text
Text.unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter ( Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"")
    [ Text
"JackoInit " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Text -> String
forall a. Show a => a -> String
show (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Jacko -> Text
jackoServer Jacko
spec) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ Text -> String
forall a. Show a => a -> String
show (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Jacko -> Text
jackoClient Jacko
spec)
    , if (Jacko -> Bool
jackoFreewheel Jacko
spec) then Text
"JackoFreewheel 1" else Text
""
    , if (Jacko -> Bool
jackoInfo Jacko
spec) then Text
"JackoInfo" else Text
""
    , Text -> [(Text, Text)] -> Text
forall {a} {a}. (Show a, Show a) => Text -> [(a, a)] -> Text
renderConnections Text
"JackoAudioInConnect" ([(Text, Text)] -> Text) -> [(Text, Text)] -> Text
forall a b. (a -> b) -> a -> b
$ Jacko -> [(Text, Text)]
jackoAudioIns Jacko
spec
    , Text -> [(Text, Text)] -> Text
forall {a} {a}. (Show a, Show a) => Text -> [(a, a)] -> Text
renderConnections Text
"JackoAudioOutConnect" ([(Text, Text)] -> Text) -> [(Text, Text)] -> Text
forall a b. (a -> b) -> a -> b
$ Jacko -> [(Text, Text)]
jackoAudioOuts Jacko
spec
    , Text -> [(Text, Text)] -> Text
forall {a} {a}. (Show a, Show a) => Text -> [(a, a)] -> Text
renderConnections Text
"JackoMidiInConnect" ([(Text, Text)] -> Text) -> [(Text, Text)] -> Text
forall a b. (a -> b) -> a -> b
$ Jacko -> [(Text, Text)]
jackoMidiIns Jacko
spec
    , Text -> [(Text, Text)] -> Text
forall {a} {a}. (Show a, Show a) => Text -> [(a, a)] -> Text
renderConnections Text
"JackoMidiOutConnect" ([(Text, Text)] -> Text) -> [(Text, Text)] -> Text
forall a b. (a -> b) -> a -> b
$ Jacko -> [(Text, Text)]
jackoMidiOuts Jacko
spec
    , Text
"JackoOn" ]
    where
        renderConnections :: Text -> [(a, a)] -> Text
renderConnections Text
name [(a, a)]
links = [Text] -> Text
Text.unlines ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ ((a, a) -> Text) -> [(a, a)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Text -> (a, a) -> Text
forall {a} {a}. (Show a, Show a) => Text -> (a, a) -> Text
renderLink Text
name) [(a, a)]
links

        renderLink :: Text -> (a, a) -> Text
renderLink Text
name (a
a, a
b) = Text
name Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (a -> String
forall a. Show a => a -> String
show a
a) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (a -> String
forall a. Show a => a -> String
show a
b)


csdNeedTrace :: Options -> Bool
csdNeedTrace :: Options -> Bool
csdNeedTrace Options
opt = Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False (Maybe Bool -> Bool) -> Maybe Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Options -> Maybe Bool
csdTrace Options
opt