packages feed

csound-expression-typed 0.0.5.2 → 0.0.5.3

raw patch · 12 files changed

+204/−28 lines, 12 filesdep ~csound-expression-dynamicPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: csound-expression-dynamic

API changes (from Hackage documentation)

- Csound.Typed.Gui: value :: String -> Double -> Sink Sig
+ Csound.Typed.Control: data OscRef
+ Csound.Typed.Control: globalSensorsSE :: Tuple a => a -> SE (SE a, a -> SE ())
+ Csound.Typed.Control: initMidiCtrl :: D -> D -> D -> SE ()
+ Csound.Typed.Control: initOsc :: OscPort -> SE OscRef
+ Csound.Typed.Control: listenOsc :: Tuple a => OscRef -> OscAddress -> OscType -> Evt a
+ Csound.Typed.Control: newGlobalSERef :: Tuple a => a -> SE (SERef a)
+ Csound.Typed.Control: newGlobalVars :: [Rate] -> GE [E] -> SE [Var]
+ Csound.Typed.Control: sendOsc :: Tuple a => OscHost -> OscPort -> OscAddress -> OscType -> Evt a -> SE ()
+ Csound.Typed.Control: type OscAddress = String
+ Csound.Typed.Control: type OscHost = String
+ Csound.Typed.Control: type OscPort = Int
+ Csound.Typed.Control: type OscType = String
+ Csound.Typed.Gui: setNumeric :: String -> ValDiap -> ValStep -> Double -> Sink Sig
+ Csound.Typed.Types.Prim: untilDo :: BoolSig -> SE () -> SE ()
+ Csound.Typed.Types.Prim: whileDo :: BoolSig -> SE () -> SE ()

Files

csound-expression-typed.cabal view
@@ -1,5 +1,5 @@ Name:          csound-expression-typed-Version:       0.0.5.2+Version:       0.0.5.3 Cabal-Version: >= 1.6 License:       BSD3 License-file:  LICENSE@@ -25,7 +25,7 @@   Ghc-Options:    -Wall   Build-Depends:         base >= 4, base < 5, ghc-prim, containers, transformers >= 0.3, Boolean >= 0.1.0, colour >= 2.3, data-default,-        wl-pprint, stable-maps >= 0.0.3.3, csound-expression-dynamic >= 0.0.5+        wl-pprint, stable-maps >= 0.0.3.3, csound-expression-dynamic >= 0.0.6   Hs-Source-Dirs:      src/   Exposed-Modules:     Csound.Typed@@ -58,6 +58,7 @@     Csound.Typed.Control.Vco     Csound.Typed.Control.Mix     Csound.Typed.Control.Midi+    Csound.Typed.Control.Osc     Csound.Typed.Control.SERef     Csound.Typed.Control.Instr 
src/Csound/Typed/Control.hs view
@@ -9,6 +9,8 @@     module Csound.Typed.Control.Mix,     -- * Midi     module Csound.Typed.Control.Midi,+    -- * OSC+    module Csound.Typed.Control.Osc,     -- * Events     module Csound.Typed.Control.Evt,     -- * Band-limited oscillators@@ -22,6 +24,7 @@ import Csound.Typed.Control.Evt import Csound.Typed.Control.Mix import Csound.Typed.Control.Midi+import Csound.Typed.Control.Osc import Csound.Typed.Control.Vco  import Csound.Typed.Types
src/Csound/Typed/Control/Midi.hs view
@@ -2,7 +2,8 @@ module Csound.Typed.Control.Midi(     Msg, Channel,     midi, midin, pgmidi, -    midi_, midin_, pgmidi_+    midi_, midin_, pgmidi_,+    initMidiCtrl ) where  import System.Mem.StableName@@ -57,4 +58,11 @@  midiKey :: MidiType -> Channel -> a -> GE MidiKey midiKey ty chn a = liftIO $ MidiKey ty chn . hashStableName <$> makeStableName a  ++-----------------------------------------------------------------+-- midi ctrls++initMidiCtrl :: D -> D -> D -> SE ()+initMidiCtrl chno ctrlno val = geToSe $ +    saveMidiCtrl =<< (MidiCtrl <$> toGE chno <*> toGE ctrlno <*> toGE val) 
+ src/Csound/Typed/Control/Osc.hs view
@@ -0,0 +1,98 @@+-- | Open sound control +{-# Language ScopedTypeVariables #-}+module Csound.Typed.Control.Osc(+    OscRef, OscHost, OscPort, OscAddress, OscType, +    initOsc, listenOsc, sendOsc+) where++import Data.Boolean ((==*))++import Csound.Typed.Types+import Csound.Typed.GlobalState hiding (oscInit, oscListen, oscSend)+import qualified Csound.Typed.GlobalState as C(oscInit, oscListen, oscSend)++import Csound.Typed.Control.SERef+++newtype OscRef = OscRef { unOscRef :: D }++-- | Port to listen OSC-messages.+type OscPort = Int++-- | Path-like string ("/foo/bar/baz")+type OscAddress = String++ +-- | The string specifies the type of expected arguments. +-- The string can contain the characters "bcdfilmst" which stand for +-- Boolean, character, double, float, 32-bit integer, 64-bit integer, MIDI, +-- string and timestamp.+type OscType = String++-- | The hostname of the computer. An empty string is for local machine.+type OscHost = String++-- | Initializes host client. The process starts to run in the background.+initOsc :: OscPort -> SE OscRef+initOsc port = do+    oscRef <- fmap fromGE $ fromDep $ C.oscInit (fromIntegral port)+    varRef <- newGlobalSERef (0 :: D)+    writeSERef varRef oscRef+    ihandle <- readSERef varRef+    return $ OscRef ihandle++-- | Listens for the OSC-messages. The first argument is OSC-reference.+-- We can create it with the function @oscInit@. The next two arguments are strings.+-- The former specifies the path-like address to listen the messages. It can be:+--+-- > /foo/bar/baz+--+-- The latter specifies the type of expected arguments. +-- The string can contain the characters "bcdfilmst" which stand for +-- Boolean, character, double, float, 32-bit integer, 64-bit integer, MIDI, +-- string and timestamp.+--+-- The result is an event of messages. We can run a callback on it+-- with standard function @runEvt@:+--+-- > runEvt :: Evt a -> (a -> SE ()) -> SE ()+listenOsc :: forall a . Tuple a => OscRef -> OscAddress -> OscType -> Evt a+listenOsc oscRef oscAddr oscType = Evt $ \bam -> do+    (readCond, writeCond) <- sensorsSE (0 :: Sig)+    resRef <- newSERef (defTuple :: a)+    writeCond =<< listen resRef+    readCond >>= (\cond -> whileDo (cond ==* 1) $ do+        bam =<< readSERef resRef+        writeCond =<< listen resRef)+    where+        listen :: Tuple a => SERef a -> SE Sig+        listen ref = csdOscListen ref oscRef oscAddr oscType++        csdOscListen :: Tuple a => SERef a -> OscRef -> OscAddress -> OscType -> SE Sig+        csdOscListen resRef oscHandle addr ty = do+            args <- readSERef resRef+            res  <- fmap fromGE $ fromDep $ hideGEinDep $ do +                expArgs <- fromTuple args+                expOscHandle <- toGE $ unOscRef oscHandle+                expAddr <- toGE $ text addr+                expOscType <- toGE $ text ty+                return $ C.oscListen $ expOscHandle : expAddr : expOscType : expArgs+            writeSERef resRef args+            return res++-- | Sends OSC-messages. It takes in a name of the host computer +-- (empty string is alocal machine), port on which the target +-- machine is listening, OSC-addres and type. The last argument+-- produces the values for OSC-messages.+sendOsc :: forall a . Tuple a => OscHost -> OscPort -> OscAddress -> OscType -> Evt a -> SE ()+sendOsc host port addr ty evts = runEvt evts send+    where +        send :: Tuple a => a -> SE ()+        send as = SE $ hideGEinDep $ do+            args <- fromTuple as+            expHost <- toGE $ text $ host+            expPort <- toGE $ int  $ port+            expAddr <- toGE $ text $ addr+            expTy   <- toGE $ text $ ty+            return $ C.oscSend $ 1 : expHost : expPort : expAddr : expTy : args+
src/Csound/Typed/Control/SERef.hs view
@@ -12,7 +12,7 @@     { writeSERef :: a -> SE ()     , readSERef  :: SE a } --- | Allocates a new mutable value and initializes it with value. +-- | Allocates a new local (it is visible within the instrument) mutable value and initializes it with value.  -- A reference can contain a tuple of variables. newSERef :: Tuple a => a -> SE (SERef a) newSERef t = do@@ -28,3 +28,18 @@     ref <- newSERef a     return $ (readSERef ref, writeSERef ref) +-- | Allocates a new global mutable value and initializes it with value. +-- A reference can contain a tuple of variables.+newGlobalSERef :: Tuple a => a -> SE (SERef a)+newGlobalSERef t = do+    vars <- newGlobalVars (tupleRates t) (fromTuple t)+    let wr a = fromDep_ $ (zipWithM_ writeVar vars) =<< lift (fromTuple a)+        re   = fmap toTuple $ fromDep $ mapM readVar vars+    return (SERef wr re)++-- | An alias for the function @newSERef@. It returns not the reference+-- to mutable value but a pair of reader and writer functions.+globalSensorsSE :: Tuple a => a -> SE (SE a, a -> SE ())+globalSensorsSE a = do+    ref <- newSERef a+    return $ (readSERef ref, writeSERef ref)
src/Csound/Typed/GlobalState.hs view
@@ -7,7 +7,8 @@     -- * Reexports dynamic     BandLimited(..), readBandLimited, renderBandLimited,     Instrs(..), IdMap(..), getInstrIds,-    getIn, chnUpdateUdo, renderGlobals, turnoff, turnoff2, exitnow+    getIn, chnUpdateUdo, renderGlobals, turnoff, turnoff2, exitnow,+    oscListen, oscInit, oscSend ) where  import Csound.Typed.GlobalState.Options
src/Csound/Typed/GlobalState/GE.hs view
@@ -2,9 +2,10 @@     GE, Dep, History(..), withOptions, withHistory, getOptions, evalGE, execGE,     getHistory, putHistory,     -- * Globals-    onGlobals, +    onGlobals,     -- * Midi     MidiAssign(..), Msg(..), renderMidiAssign, saveMidi,  +    MidiCtrl(..), saveMidiCtrl, renderMidiCtrl,     -- * Instruments     saveAlwaysOnInstr, onInstr, saveUserInstr0, getSysExpr,     -- * Total duration@@ -81,6 +82,7 @@     , globals           :: Globals     , instrs            :: Instrs     , midis             :: [MidiAssign]+    , midiCtrls         :: [MidiCtrl]     , totalDur          :: Maybe TotalDur     , alwaysOnInstrs    :: [InstrId]     , notes             :: [(InstrId, CsdEvent Note)]@@ -90,11 +92,12 @@     , guis              :: Guis }  instance Default History where-    def = History def def def def def def def def (return ()) def def def+    def = History def def def def def def def def def (return ()) def def def  data Msg = Msg data MidiAssign = MidiAssign MidiType Channel InstrId-            +data MidiCtrl   = MidiCtrl E E E+ renderMidiAssign :: Monad m => MidiAssign -> DepT m () renderMidiAssign (MidiAssign ty chn instrId) = case ty of     Massign         -> massign chn instrId@@ -103,12 +106,15 @@         massign n instr = depT_ $ opcs "massign" [(Xr, [Ir,Ir])] [int n, prim $ PrimInstrId instr]         pgmassign pgm instr mchn = depT_ $ opcs "pgmassign" [(Xr, [Ir,Ir,Ir])] ([int pgm, prim $ PrimInstrId instr] ++ maybe [] (return . int) mchn) +renderMidiCtrl :: Monad m => MidiCtrl -> DepT m ()+renderMidiCtrl (MidiCtrl chno ctrlno val) = initc7 chno ctrlno val+    where +        initc7 :: Monad m => E -> E -> E -> DepT m ()+        initc7 a b c = depT_ $ opcs "initc7" [(Xr, [Ir, Ir, Ir])] [a, b, c]+ data TotalDur = ExpDur E | NumDur Double | InfiniteDur     deriving (Eq, Ord) -getTotalDurForF0 :: GE Double-getTotalDurForF0 = fmap (pureGetTotalDurForF0 . totalDur) getHistory- getTotalDurForTerminator :: GE E getTotalDurForTerminator = fmap (getTotalDurForTerminator' . totalDur) getHistory @@ -160,6 +166,10 @@ saveMidi ma = onMidis $ modify (ma: )     where onMidis = onHistory midis (\a h -> h { midis = a }) +saveMidiCtrl :: MidiCtrl -> GE ()+saveMidiCtrl ma = onMidis $ modify (ma: )+    where onMidis = onHistory midiCtrls (\a h -> h { midiCtrls = a })+ saveUserInstr0 :: Dep () -> GE () saveUserInstr0 expr = onUserInstr0 $ modify ( >> expr)     where onUserInstr0 = onHistory userInstr0 (\a h -> h { userInstr0 = a })@@ -441,4 +451,5 @@             saveAlwaysOnInstr keyEventInstrId             body <- keyEventInstrBody $ guiKeyEvents $ guis h             return $ Just (Instr keyEventInstrId body)+ 
src/Csound/Typed/GlobalState/Opcodes.hs view
@@ -9,6 +9,8 @@     out, outs, safeOut, autoOff, turnoff, turnoff2, exitnow,     -- * vco2     oscili, oscilikt, vco2ft, vco2ift, vco2init, ftgen,+    -- * OSC+    oscInit, oscListen, oscSend,     -- * times     times ) where@@ -198,7 +200,19 @@ vco2init :: [E] -> E vco2init = opcs "vco2init" [(Ir, repeat Ir)] -----------------------+-----------------------------------------------------------+-- OSC++oscInit :: Monad m => E -> DepT m E+oscInit port = depT $ opcs "OSCinit" [(Ir, [Ir])] [port]++oscListen :: Monad m => [E] -> DepT m E+oscListen args = depT $ opcs "OSClisten" [(Kr, Ir:Ir:Ir:repeat Xr)] args++oscSend :: Monad m => [E] -> DepT m ()+oscSend args = depT_ $ opcs "OSCsend" [(Xr, Kr:Ir:Ir:Ir:Ir:repeat Xr)] args++----------------------------------------------------------- -- times  times :: Monad m => DepT m E
src/Csound/Typed/GlobalState/SE.hs view
@@ -2,7 +2,7 @@     SE(..), LocalHistory(..),      runSE, execSE, evalSE, execGEinSE, hideGEinDep,      fromDep, fromDep_, geToSe,-    newLocalVar, newLocalVars        +    newLocalVar, newLocalVars, newGlobalVars ) where  import Control.Applicative@@ -12,6 +12,7 @@ import Csound.Dynamic hiding (newLocalVar, newLocalVars) import qualified Csound.Dynamic as D(newLocalVar, newLocalVars) import Csound.Typed.GlobalState.GE+import Csound.Typed.GlobalState.Elements(newPersistentGlobalVar)  -- | The Csound's @IO@-monad. All values that produce side effects are wrapped -- in the @SE@-monad.@@ -35,10 +36,13 @@ execSE a = execDepT $ unSE a  execGEinSE :: SE (GE a) -> SE a-execGEinSE (SE sa) = SE $ do+execGEinSE a = geToSe =<< a+{-+(SE sa) = SE $ do     ga <- sa     a  <- lift ga     return a+-}  hideGEinDep :: GE (Dep a) -> Dep a hideGEinDep = join . lift@@ -63,4 +67,12 @@  newLocalVar :: Rate -> GE E -> SE Var newLocalVar rate val = SE $ D.newLocalVar rate val++----------------------------------------------------------------------+-- allocation of the global vars++newGlobalVars :: [Rate] -> GE [E] -> SE [Var]+newGlobalVars rs vs = geToSe $ zipWithM f rs =<< vs+    where f r v = onGlobals $ newPersistentGlobalVar r v+ 
src/Csound/Typed/Gui/Widget.hs view
@@ -11,7 +11,7 @@     -- * Widgets     count, countSig, joy, knob, roller, slider, sliderBank, numeric, meter, box,     button, butBank, butBankSig, butBank1, butBankSig1, toggle, toggleSig,-    value, +    setNumeric,      -- * Transformers     setTitle,     -- * Keyboard    @@ -199,10 +199,10 @@  singleIn :: (GuiHandle -> Output Sig) -> Maybe Double -> Elem -> Sink Sig  singleIn outs v0 el = geToSe $ do-    (_, handle) <- newGuiVar+    (var, handle) <- newGuiVar     let handleVar = guiHandleToVar handle                 inits = maybe [] (return . InitMe handleVar) v0-        gui = fromElem [handleVar] inits el+        gui = fromElem [var, handleVar] inits el     appendToGui (GuiNode gui handle) (unSE noInner)     return (fromGuiHandle handle, outs handle) @@ -374,13 +374,9 @@ butBankSig1 name xn yn (x0, y0) = setSourceTitle name $ singleOut (Just n) $ ButBank xn yn     where n = fromIntegral $ y0 + x0 * yn --- | FLvalue shows current the value of a valuator in a text field.------ > value initVal------ doc: <http://www.csounds.com/manual/html/FLvalue.html>-value :: String -> Double -> Sink Sig -value name v = setLabelSink name $ singleIn printk2 (Just v) Value+-- |  FLtext that is sink shows current the value of a valuator in a text field.+setNumeric :: String -> ValDiap -> ValStep -> Double -> Sink Sig+setNumeric name diap step v0 = setLabelSource name $ singleIn printk2 (Just v0) $ Text diap step   -- | A slider that serves as indicator. It consumes values instead of producing. --
src/Csound/Typed/Render.hs view
@@ -72,6 +72,7 @@ getInstr0 nchnls opt hist = do     globalConstants     midiAssigns+    midiInitCtrls     initGlobals     renderBandLimited (genMap hist) (bandLimitedMap hist)     userInstr0 hist@@ -84,7 +85,8 @@             setNchnls   (max 1 nchnls)             setZeroDbfs 1 -        midiAssigns = mapM_ renderMidiAssign $ midis hist+        midiAssigns   = mapM_ renderMidiAssign $ midis hist+        midiInitCtrls = mapM_ renderMidiCtrl   $ midiCtrls hist          initGlobals = fst $ renderGlobals $ globals $ hist 
src/Csound/Typed/Types/Prim.hs view
@@ -23,7 +23,7 @@     quot', rem', div', mod', ceil', floor', round', int', frac',         -- ** logic funs-    when1, whens, boolSig+    when1, whens, untilDo, whileDo, boolSig ) where  import Control.Applicative hiding ((<*))@@ -35,8 +35,8 @@ import Data.Default import Data.Boolean -import Csound.Dynamic hiding (double, int, str, when1, whens, ifBegin, ifEnd, elseBegin, elseIfBegin)-import qualified Csound.Dynamic as D(double, int, str, ifBegin, ifEnd, elseBegin, elseIfBegin)+import Csound.Dynamic hiding (double, int, str, when1, whens, ifBegin, ifEnd, elseBegin, elseIfBegin, untilBegin, untilEnd, untilDo)+import qualified Csound.Dynamic as D(double, int, str, ifBegin, ifEnd, elseBegin, elseIfBegin, untilBegin, untilEnd) import Csound.Typed.GlobalState  -- | Signals@@ -408,6 +408,21 @@  elseIfBegin :: BoolSig -> SE () elseIfBegin a = fromDep_ $ D.elseIfBegin =<< lift (toGE a)++untilDo :: BoolSig -> SE () -> SE ()+untilDo p body = do+    untilBegin p+    body+    untilEnd++whileDo :: BoolSig -> SE () -> SE ()+whileDo p = untilDo (notB p) ++untilBegin :: BoolSig -> SE ()+untilBegin a = fromDep_ $ D.untilBegin =<< lift (toGE a)++untilEnd :: SE ()+untilEnd = fromDep_ D.untilEnd  -- | Creates a constant boolean signal. boolSig :: BoolD -> BoolSig