conductive-base 0.2 → 0.3
raw patch · 13 files changed
+597/−942 lines, 13 filesdep +arraydep +randomdep +stmdep −MissingHdep ~basedep ~containersdep ~timePVP ok
version bump matches the API change (PVP)
Dependencies added: array, random, stm
Dependencies removed: MissingH
Dependency ranges changed: base, containers, time
API changes (from Hackage documentation)
- Sound.Conductive.ConductiveBaseData: Generator :: MVar [a] -> IORef Int -> IORef Int -> Generator a
- Sound.Conductive.ConductiveBaseData: data Generator a
- Sound.Conductive.ConductiveBaseData: doubleGeneratorStore :: MusicalEnvironment -> Map String (Generator Double)
- Sound.Conductive.ConductiveBaseData: generatorCounter :: Generator a -> IORef Int
- Sound.Conductive.ConductiveBaseData: generatorSource :: Generator a -> MVar [a]
- Sound.Conductive.ConductiveBaseData: iOIListStore :: MusicalEnvironment -> Map String [Double]
- Sound.Conductive.ConductiveBaseData: sourceLength :: Generator a -> IORef Int
- Sound.Conductive.ConductiveDefaults: defaultIOI :: MVar MusicalEnvironment -> Player -> IO Double
- Sound.Conductive.ConductiveDefaults: defaultIOIListStore :: Map [Char] [Double]
- Sound.Conductive.Generator: defaultGeneratorStore :: IO (Map [Char] (Generator Double))
- Sound.Conductive.Generator: getCount :: Generator a -> IO Int
- Sound.Conductive.Generator: getGeneratorSource :: Generator a -> IO [a]
- Sound.Conductive.Generator: newCounter :: IO (IORef Int)
- Sound.Conductive.Generator: newGenerator :: [a] -> IO (Generator a)
- Sound.Conductive.Generator: newGeneratorStore :: Ord t => (t, [a]) -> IO (Map t (Generator a))
- Sound.Conductive.Generator: next :: Generator a -> IO a
- Sound.Conductive.Generator: nextWithOffset :: Int -> Generator a -> IO a
- Sound.Conductive.Generator: nexts :: [Generator b] -> IO [b]
- Sound.Conductive.Generator: resetCounter :: Generator a -> IO ()
- Sound.Conductive.Generator: swapGenerator :: Generator a -> [a] -> IO [a]
- Sound.Conductive.Generator: withNext :: Generator a -> (a -> b) -> IO b
- Sound.Conductive.IOI: iOIFromList :: MVar MusicalEnvironment -> Player -> String -> IO Double
- Sound.Conductive.IOI: makeIOIList :: Num a => a -> [a] -> [a]
- Sound.Conductive.IOI: newIOIFunctionAndIOIList :: MVar MusicalEnvironment -> String -> Double -> [Double] -> IO MusicalEnvironment
- Sound.Conductive.MVarUtils: wIOm :: MVar a -> (a -> IO b) -> IO b
- Sound.Conductive.MVarUtils: wcm :: MVar a -> (a -> a) -> IO a
- Sound.Conductive.MVarUtils: withChangeToMVar :: MVar a -> (a -> a) -> IO a
- Sound.Conductive.MVarUtils: wm :: MVar a -> (a -> a1) -> IO a1
- Sound.Conductive.MusicalEnvironment: addAction :: MVar MusicalEnvironment -> (String, MVar MusicalEnvironment -> Player -> IO ()) -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: addDoubleGenerator :: MVar MusicalEnvironment -> (String, Generator Double) -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: addIOI :: MVar MusicalEnvironment -> (String, MVar MusicalEnvironment -> Player -> IO Double) -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: addIOIList :: MVar MusicalEnvironment -> (String, [Double]) -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: addInterrupt :: MVar MusicalEnvironment -> (String, [IO ()]) -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: addNewGenerator :: MVar MusicalEnvironment -> (String, [Double]) -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: addPlayer :: MVar MusicalEnvironment -> (String, Player) -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: addTempoClock :: MVar MusicalEnvironment -> (String, TempoClock) -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: changeActions :: (Map String (MVar MusicalEnvironment -> Player -> IO ()) -> Map String (MVar MusicalEnvironment -> Player -> IO ())) -> MusicalEnvironment -> MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: changeDoubleGenerators :: (Map String (Generator Double) -> Map String (Generator Double)) -> MusicalEnvironment -> MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: changeEnvironment :: MVar a -> (a -> a) -> IO a
- Sound.Conductive.MusicalEnvironment: changeIOILists :: (Map String [Double] -> Map String [Double]) -> MusicalEnvironment -> MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: changeIOIs :: (Map String (MVar MusicalEnvironment -> Player -> IO Double) -> Map String (MVar MusicalEnvironment -> Player -> IO Double)) -> MusicalEnvironment -> MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: changeInterrupts :: (Map String [IO ()] -> Map String [IO ()]) -> MusicalEnvironment -> MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: changePlayers :: (Map String Player -> Map String Player) -> MusicalEnvironment -> MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: changeTempoClocks :: (Map String TempoClock -> Map String TempoClock) -> MusicalEnvironment -> MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: deleteAction :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: deleteDoubleGenerator :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: deleteIOI :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: deleteIOIList :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: deleteInterrupt :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: deletePlayer :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: deleteTempoClock :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment
- Sound.Conductive.MusicalEnvironment: doubleGenerators :: MVar MusicalEnvironment -> IO [String]
- Sound.Conductive.MusicalEnvironment: eCurrentTempo :: MVar MusicalEnvironment -> String -> IO Double
- Sound.Conductive.MusicalEnvironment: eCurrentTimeSignature :: MVar MusicalEnvironment -> String -> IO Int
- Sound.Conductive.MusicalEnvironment: eElapsedBeats :: MVar MusicalEnvironment -> String -> IO Double
- Sound.Conductive.MusicalEnvironment: eElapsedTime :: MVar MusicalEnvironment -> String -> IO Double
- Sound.Conductive.MusicalEnvironment: getAction :: MVar MusicalEnvironment -> String -> IO (MVar MusicalEnvironment -> Player -> IO ())
- Sound.Conductive.MusicalEnvironment: getCurrentTime :: MVar MusicalEnvironment -> String -> IO MusicalTime
- Sound.Conductive.MusicalEnvironment: getDoubleGenerator :: MVar MusicalEnvironment -> String -> IO (Generator Double)
- Sound.Conductive.MusicalEnvironment: getIOI :: MVar MusicalEnvironment -> String -> IO (MVar MusicalEnvironment -> Player -> IO Double)
- Sound.Conductive.MusicalEnvironment: getIOIList :: MVar MusicalEnvironment -> String -> IO [Double]
- Sound.Conductive.MusicalEnvironment: getInterrupt :: MVar MusicalEnvironment -> String -> IO [IO ()]
- Sound.Conductive.MusicalEnvironment: getPlayer :: MVar MusicalEnvironment -> String -> IO Player
- Sound.Conductive.MusicalEnvironment: getTempoClock :: MVar MusicalEnvironment -> String -> IO TempoClock
- Sound.Conductive.MusicalEnvironment: iOILists :: MVar MusicalEnvironment -> IO [String]
- Sound.Conductive.MusicalEnvironment: showCurrentTime :: MVar MusicalEnvironment -> String -> IO [Char]
- Sound.Conductive.MusicalEnvironment: withDoubleGenerator :: (Generator Double -> IO b) -> MVar MusicalEnvironment -> String -> IO b
- Sound.Conductive.MusicalEnvironment: withEnvironment :: MVar a -> (a -> a1) -> IO a1
- Sound.Conductive.MusicalEnvironment: withIOIList :: ([Double] -> IO b) -> MVar MusicalEnvironment -> String -> IO b
- Sound.Conductive.Player: playAllAt :: MVar MusicalEnvironment -> [Char] -> IO ()
- Sound.Conductive.Player: playNAt :: MVar MusicalEnvironment -> [Char] -> [String] -> IO ()
- Sound.Conductive.Player: timeDiff :: TempoClock -> Double -> IO Double
+ Sound.Conductive.MiscListUtils: coin :: IO Bool
+ Sound.Conductive.MiscListUtils: diff_select :: Int -> Int -> IO [Int]
+ Sound.Conductive.MiscListUtils: diff_select' :: (Eq a, Num a) => a -> [a1] -> IO [a1]
+ Sound.Conductive.MiscListUtils: getSeed :: IO Integer
+ Sound.Conductive.MiscListUtils: joinVals :: Num a => Int -> Int -> [a] -> [a]
+ Sound.Conductive.MiscListUtils: lace :: [[a]] -> Int -> [a]
+ Sound.Conductive.MiscListUtils: lerp :: Fractional a => (a, a) -> (a, a) -> a -> a
+ Sound.Conductive.MiscListUtils: normalize :: (Fractional b, Ord b) => [b] -> [b]
+ Sound.Conductive.MiscListUtils: normalizeTo :: (Fractional b, Ord b) => b -> [b] -> [b]
+ Sound.Conductive.MiscListUtils: npletAt :: Fractional a => Int -> Int -> [a] -> [a]
+ Sound.Conductive.MiscListUtils: odds :: Int -> Int -> IO Bool
+ Sound.Conductive.MiscListUtils: pick :: [a] -> IO a
+ Sound.Conductive.MiscListUtils: pick' :: (Eq t, Num t, Random t) => a -> [a] -> t -> IO a
+ Sound.Conductive.MiscListUtils: pickN :: (Num a, Enum a) => a -> [b] -> IO [b]
+ Sound.Conductive.MiscListUtils: rList :: Int -> IO [Int]
+ Sound.Conductive.MiscListUtils: randomList :: Int -> StdGen -> [Int]
+ Sound.Conductive.MiscListUtils: randomSubset :: [b] -> Int -> IO [b]
+ Sound.Conductive.MiscListUtils: replaceAt :: Int -> [a] -> [a] -> [a]
+ Sound.Conductive.MiscListUtils: replicator :: [(Int, b)] -> [b]
+ Sound.Conductive.MiscListUtils: rotate :: [a] -> Int -> [a]
+ Sound.Conductive.MiscListUtils: shuffle :: [a] -> IO [a]
+ Sound.Conductive.MiscListUtils: shuffle' :: [a] -> StdGen -> ([a], StdGen)
+ Sound.Conductive.MiscListUtils: slice :: [a] -> [Int] -> [a]
+ Sound.Conductive.MiscListUtils: stutter :: Int -> Int -> Int -> [a] -> [a]
+ Sound.Conductive.MiscListUtils: takeToValue :: (Num a, Ord a) => a -> [a] -> [a]
+ Sound.Conductive.MiscListUtils: takeToValue' :: (Ord a, Num a) => [a] -> a -> a -> [a] -> [a]
+ Sound.Conductive.MiscListUtils: unconcat :: [t] -> [[t]]
+ Sound.Conductive.MiscListUtils: weightedList :: [(Int, b)] -> [b]
+ Sound.Conductive.MutableMap: (+@) :: Ord k => TVar (Map k a) -> (k, a) -> IO ()
+ Sound.Conductive.MutableMap: (-@) :: Ord k => TVar (Map k a) -> k -> IO ()
+ Sound.Conductive.MutableMap: (?@) :: Ord k => TVar (Map k a) -> k -> IO (Maybe a)
+ Sound.Conductive.MutableMap: addVal :: Ord k => TVar (Map k a) -> (k, a) -> IO ()
+ Sound.Conductive.MutableMap: addVals :: Ord k => TVar (Map k a) -> [(k, a)] -> IO ()
+ Sound.Conductive.MutableMap: changeKey :: Ord k => TVar (Map k a) -> k -> k -> IO ()
+ Sound.Conductive.MutableMap: changeVal :: Ord k => TVar (Map k a) -> (k, a) -> IO ()
+ Sound.Conductive.MutableMap: copyVal :: Ord k => TVar (Map k a) -> k -> k -> IO ()
+ Sound.Conductive.MutableMap: deleteVal :: Ord k => TVar (Map k a) -> k -> IO ()
+ Sound.Conductive.MutableMap: elems :: TVar (Map k a) -> IO [a]
+ Sound.Conductive.MutableMap: keys :: TVar (Map k a) -> IO [k]
+ Sound.Conductive.MutableMap: mapMMapIO_ :: TVar (Map k a) -> ((k, a) -> IO b) -> IO ()
+ Sound.Conductive.MutableMap: modifyMMap :: TVar a -> (a -> a) -> IO ()
+ Sound.Conductive.MutableMap: newMMap :: Ord k => [(k, a)] -> IO (TVar (Map k a))
+ Sound.Conductive.MutableMap: newMMapSingleton :: Ord k => (k, a) -> IO (TVar (Map k a))
+ Sound.Conductive.MutableMap: toMap :: TVar a -> IO a
+ Sound.Conductive.MutableMap: type MutableMap t t1 = TVar (Map t t1)
+ Sound.Conductive.MutableMap: withKey :: Ord k => TVar (Map k t) -> (t -> a) -> k -> IO (Maybe a)
+ Sound.Conductive.MutableMap: withKeys :: Ord a => TVar (Map a t) -> (t -> a1) -> [a] -> IO [Maybe a1]
+ Sound.Conductive.MutableMap: withKeys_ :: Ord a => TVar (Map a t) -> (t -> a1) -> [a] -> IO ()
+ Sound.Conductive.MutableMap: withMMap :: TVar t -> (t -> b) -> IO b
+ Sound.Conductive.Player: basicPlay :: MusicalEnvironment -> String -> PlayerStatus -> IO ()
+ Sound.Conductive.Player: playAtStartOfNMeasure :: MusicalEnvironment -> Int -> String -> IO ()
+ Sound.Conductive.Player: playNow :: MusicalEnvironment -> String -> IO ()
+ Sound.Conductive.Player: withPlayers :: MusicalEnvironment -> (Player -> a1) -> [String] -> IO [Maybe a1]
- Sound.Conductive.ConductiveBaseData: MusicalEnvironment :: String -> Map String Player -> Map String TempoClock -> Map String (MVar MusicalEnvironment -> Player -> IO Double) -> Map String (MVar MusicalEnvironment -> Player -> IO ()) -> Map String ([IO ()]) -> Map String (Generator Double) -> Map String [Double] -> MusicalEnvironment
+ Sound.Conductive.ConductiveBaseData: MusicalEnvironment :: String -> MutableMap String Player -> MutableMap String TempoClock -> MutableMap String (MusicalEnvironment -> Player -> Double -> Double -> IO Double) -> MutableMap String (MusicalEnvironment -> Player -> Double -> Double -> IO ()) -> MutableMap String ([IO ()]) -> MusicalEnvironment
- Sound.Conductive.ConductiveBaseData: actionStore :: MusicalEnvironment -> Map String (MVar MusicalEnvironment -> Player -> IO ())
+ Sound.Conductive.ConductiveBaseData: actionStore :: MusicalEnvironment -> MutableMap String (MusicalEnvironment -> Player -> Double -> Double -> IO ())
- Sound.Conductive.ConductiveBaseData: iOIStore :: MusicalEnvironment -> Map String (MVar MusicalEnvironment -> Player -> IO Double)
+ Sound.Conductive.ConductiveBaseData: iOIStore :: MusicalEnvironment -> MutableMap String (MusicalEnvironment -> Player -> Double -> Double -> IO Double)
- Sound.Conductive.ConductiveBaseData: interruptStore :: MusicalEnvironment -> Map String ([IO ()])
+ Sound.Conductive.ConductiveBaseData: interruptStore :: MusicalEnvironment -> MutableMap String ([IO ()])
- Sound.Conductive.ConductiveBaseData: playerStore :: MusicalEnvironment -> Map String Player
+ Sound.Conductive.ConductiveBaseData: playerStore :: MusicalEnvironment -> MutableMap String Player
- Sound.Conductive.ConductiveBaseData: tempoClockStore :: MusicalEnvironment -> Map String TempoClock
+ Sound.Conductive.ConductiveBaseData: tempoClockStore :: MusicalEnvironment -> MutableMap String TempoClock
- Sound.Conductive.ConductiveDefaults: defaultActionStore :: Map [Char] (t -> t1 -> IO ())
+ Sound.Conductive.ConductiveDefaults: defaultActionStore :: IO (TVar (Map [Char] (t -> t1 -> t2 -> t3 -> IO ())))
- Sound.Conductive.ConductiveDefaults: defaultIOIStore :: Map [Char] (MVar MusicalEnvironment -> Player -> IO Double)
+ Sound.Conductive.ConductiveDefaults: defaultIOIStore :: IO (TVar (Map [Char] a))
- Sound.Conductive.ConductiveDefaults: defaultInterruptStore :: Map [Char] [IO ()]
+ Sound.Conductive.ConductiveDefaults: defaultInterruptStore :: IO (TVar (Map [Char] [IO ()]))
- Sound.Conductive.ConductiveDefaults: defaultMusicalEnvironment :: IO (MVar MusicalEnvironment)
+ Sound.Conductive.ConductiveDefaults: defaultMusicalEnvironment :: IO MusicalEnvironment
- Sound.Conductive.ConductiveDefaults: defaultPlayerStore :: Map String Player
+ Sound.Conductive.ConductiveDefaults: defaultPlayerStore :: IO (TVar (Map String Player))
- Sound.Conductive.ConductiveDefaults: defaultTempoClockStore :: IO (Map [Char] TempoClock)
+ Sound.Conductive.ConductiveDefaults: defaultTempoClockStore :: IO (TVar (Map [Char] TempoClock))
- Sound.Conductive.MusicalEnvironment: actions :: MVar MusicalEnvironment -> IO [String]
+ Sound.Conductive.MusicalEnvironment: actions :: MusicalEnvironment -> IO [String]
- Sound.Conductive.MusicalEnvironment: eChangeTempo :: MVar MusicalEnvironment -> String -> Double -> IO MusicalEnvironment
+ Sound.Conductive.MusicalEnvironment: eChangeTempo :: MusicalEnvironment -> String -> Double -> IO ()
- Sound.Conductive.MusicalEnvironment: eChangeTimeSignature :: MVar MusicalEnvironment -> String -> Int -> IO MusicalEnvironment
+ Sound.Conductive.MusicalEnvironment: eChangeTimeSignature :: MusicalEnvironment -> String -> Int -> IO ()
- Sound.Conductive.MusicalEnvironment: iOIs :: MVar MusicalEnvironment -> IO [String]
+ Sound.Conductive.MusicalEnvironment: iOIs :: MusicalEnvironment -> IO [String]
- Sound.Conductive.MusicalEnvironment: interrupts :: MVar MusicalEnvironment -> IO [String]
+ Sound.Conductive.MusicalEnvironment: interrupts :: MusicalEnvironment -> IO [String]
- Sound.Conductive.MusicalEnvironment: players :: MVar MusicalEnvironment -> IO [String]
+ Sound.Conductive.MusicalEnvironment: players :: MusicalEnvironment -> IO [String]
- Sound.Conductive.MusicalEnvironment: tempoClocks :: MVar MusicalEnvironment -> IO [String]
+ Sound.Conductive.MusicalEnvironment: tempoClocks :: MusicalEnvironment -> IO [String]
- Sound.Conductive.MusicalEnvironment: withAction :: ((MVar MusicalEnvironment -> Player -> IO ()) -> IO b) -> MVar MusicalEnvironment -> String -> IO b
+ Sound.Conductive.MusicalEnvironment: withAction :: MusicalEnvironment -> ((MusicalEnvironment -> Player -> Double -> Double -> IO ()) -> a) -> String -> IO (Maybe a)
- Sound.Conductive.MusicalEnvironment: withIOI :: ((MVar MusicalEnvironment -> Player -> IO Double) -> IO b) -> MVar MusicalEnvironment -> String -> IO b
+ Sound.Conductive.MusicalEnvironment: withIOI :: MusicalEnvironment -> ((MusicalEnvironment -> Player -> Double -> Double -> IO Double) -> a) -> String -> IO (Maybe a)
- Sound.Conductive.MusicalEnvironment: withInterrupt :: ([IO ()] -> IO b) -> MVar MusicalEnvironment -> String -> IO b
+ Sound.Conductive.MusicalEnvironment: withInterrupt :: MusicalEnvironment -> ([IO ()] -> a) -> String -> IO (Maybe a)
- Sound.Conductive.MusicalEnvironment: withPlayer :: (Player -> IO b) -> MVar MusicalEnvironment -> String -> IO b
+ Sound.Conductive.MusicalEnvironment: withPlayer :: MusicalEnvironment -> (Player -> a) -> String -> IO (Maybe a)
- Sound.Conductive.MusicalEnvironment: withTempoClock :: (TempoClock -> IO b) -> MVar MusicalEnvironment -> String -> IO b
+ Sound.Conductive.MusicalEnvironment: withTempoClock :: MusicalEnvironment -> (TempoClock -> a) -> String -> IO (Maybe a)
- Sound.Conductive.Player: addNewPlayer :: MVar MusicalEnvironment -> (String, (String, String, String, Double)) -> IO MusicalEnvironment
+ Sound.Conductive.Player: addNewPlayer :: MusicalEnvironment -> (String, (String, String, String, Double)) -> IO ()
- Sound.Conductive.Player: displayPlayer :: MVar MusicalEnvironment -> String -> IO ()
+ Sound.Conductive.Player: displayPlayer :: MusicalEnvironment -> String -> IO ()
- Sound.Conductive.Player: modifyPlayer :: MVar MusicalEnvironment -> String -> (Player -> Player) -> IO MusicalEnvironment
+ Sound.Conductive.Player: modifyPlayer :: MusicalEnvironment -> String -> (Player -> Player) -> IO ()
- Sound.Conductive.Player: newPlayerStore :: (String, (String, String, String, Double)) -> Map String Player
+ Sound.Conductive.Player: newPlayerStore :: (String, (String, String, String, Double)) -> IO (TVar (Map String Player))
- Sound.Conductive.Player: pause :: MVar MusicalEnvironment -> String -> IO ()
+ Sound.Conductive.Player: pause :: MusicalEnvironment -> String -> IO ()
- Sound.Conductive.Player: pauseAll :: MVar MusicalEnvironment -> IO ()
+ Sound.Conductive.Player: pauseAll :: MusicalEnvironment -> IO ()
- Sound.Conductive.Player: pauseN :: MVar MusicalEnvironment -> [String] -> IO ()
+ Sound.Conductive.Player: pauseN :: MusicalEnvironment -> [String] -> IO ()
- Sound.Conductive.Player: play :: MVar MusicalEnvironment -> String -> IO ()
+ Sound.Conductive.Player: play :: MusicalEnvironment -> String -> IO ()
- Sound.Conductive.Player: playAll :: MVar MusicalEnvironment -> IO ()
+ Sound.Conductive.Player: playAll :: MusicalEnvironment -> IO ()
- Sound.Conductive.Player: playAt :: Double -> MVar MusicalEnvironment -> String -> IO ()
+ Sound.Conductive.Player: playAt :: Double -> MusicalEnvironment -> String -> IO ()
- Sound.Conductive.Player: playAtTimeString :: [Char] -> MVar MusicalEnvironment -> String -> IO ()
+ Sound.Conductive.Player: playAtTimeString :: [Char] -> MusicalEnvironment -> String -> IO ()
- Sound.Conductive.Player: playN :: MVar MusicalEnvironment -> [String] -> IO ()
+ Sound.Conductive.Player: playN :: MusicalEnvironment -> [String] -> IO ()
- Sound.Conductive.Player: reset :: MVar MusicalEnvironment -> String -> IO ()
+ Sound.Conductive.Player: reset :: MusicalEnvironment -> String -> IO ()
- Sound.Conductive.Player: resetAll :: MVar MusicalEnvironment -> IO ()
+ Sound.Conductive.Player: resetAll :: MusicalEnvironment -> IO ()
- Sound.Conductive.Player: resetN :: MVar MusicalEnvironment -> [String] -> IO ()
+ Sound.Conductive.Player: resetN :: MusicalEnvironment -> [String] -> IO ()
- Sound.Conductive.Player: stop :: MVar MusicalEnvironment -> String -> IO ()
+ Sound.Conductive.Player: stop :: MusicalEnvironment -> String -> IO ()
- Sound.Conductive.Player: stopAll :: MVar MusicalEnvironment -> IO ()
+ Sound.Conductive.Player: stopAll :: MusicalEnvironment -> IO ()
- Sound.Conductive.Player: stopN :: MVar MusicalEnvironment -> [String] -> IO ()
+ Sound.Conductive.Player: stopN :: MusicalEnvironment -> [String] -> IO ()
- Sound.Conductive.Player: swapActions :: MVar MusicalEnvironment -> String -> String -> IO MusicalEnvironment
+ Sound.Conductive.Player: swapActions :: MusicalEnvironment -> String -> String -> IO ()
- Sound.Conductive.Player: swapBeat :: MVar MusicalEnvironment -> String -> Double -> IO MusicalEnvironment
+ Sound.Conductive.Player: swapBeat :: MusicalEnvironment -> String -> Double -> IO ()
- Sound.Conductive.Player: swapClock :: MVar MusicalEnvironment -> String -> String -> IO MusicalEnvironment
+ Sound.Conductive.Player: swapClock :: MusicalEnvironment -> String -> String -> IO ()
- Sound.Conductive.Player: swapCounter :: MVar MusicalEnvironment -> String -> Integer -> IO MusicalEnvironment
+ Sound.Conductive.Player: swapCounter :: MusicalEnvironment -> String -> Integer -> IO ()
- Sound.Conductive.Player: swapIOI :: MVar MusicalEnvironment -> String -> String -> IO MusicalEnvironment
+ Sound.Conductive.Player: swapIOI :: MusicalEnvironment -> String -> String -> IO ()
- Sound.Conductive.Player: swapInterrupt :: MVar MusicalEnvironment -> String -> String -> IO MusicalEnvironment
+ Sound.Conductive.Player: swapInterrupt :: MusicalEnvironment -> String -> String -> IO ()
- Sound.Conductive.Player: swapName :: MVar MusicalEnvironment -> String -> String -> IO MusicalEnvironment
+ Sound.Conductive.Player: swapName :: MusicalEnvironment -> String -> String -> IO ()
- Sound.Conductive.Player: swapPauseTime :: MVar MusicalEnvironment -> String -> Double -> IO MusicalEnvironment
+ Sound.Conductive.Player: swapPauseTime :: MusicalEnvironment -> String -> Double -> IO ()
- Sound.Conductive.Player: swapStatus :: MVar MusicalEnvironment -> String -> PlayerStatus -> IO MusicalEnvironment
+ Sound.Conductive.Player: swapStatus :: MusicalEnvironment -> String -> PlayerStatus -> IO ()
- Sound.Conductive.Table: displayPlayers :: MVar MusicalEnvironment -> IO ()
+ Sound.Conductive.Table: displayPlayers :: MusicalEnvironment -> IO ()
Files
- Sound/Conductive/ConductiveBase.hs +0/−22
- Sound/Conductive/ConductiveBaseData.hs +7/−17
- Sound/Conductive/ConductiveDefaults.hs +26/−31
- Sound/Conductive/Generator.hs +0/−97
- Sound/Conductive/IOI.hs +0/−62
- Sound/Conductive/MVarUtils.hs +0/−38
- Sound/Conductive/MiscListUtils.hs +207/−0
- Sound/Conductive/MusicalEnvironment.hs +117/−455
- Sound/Conductive/MusicalTime.hs +3/−5
- Sound/Conductive/MutableMap.hs +93/−0
- Sound/Conductive/Player.hs +124/−200
- Sound/Conductive/Table.hs +14/−9
- conductive-base.cabal +6/−6
− Sound/Conductive/ConductiveBase.hs
@@ -1,22 +0,0 @@----------------------------------------------------------------------------------- ConductiveBase.hs--- created: Wed Oct 27 00:32:30 JST 2010----------------------------------------------------------------------------------module Sound.Conductive.ConductiveBase where--import Control.Concurrent-import Control.Concurrent.MVar-import Data.Map -import Data.Maybe-import Sound.Conductive.ConductiveBaseData-import Sound.Conductive.ConductiveDefaults-import Sound.Conductive.Generator-import Sound.Conductive.IOI-import Sound.Conductive.MusicalEnvironment-import Sound.Conductive.MusicalTime-import Sound.Conductive.MVarUtils-import Sound.Conductive.Player-import Sound.Conductive.Table
Sound/Conductive/ConductiveBaseData.hs view
@@ -1,21 +1,13 @@ ------------------------------------------------------------------------------ -- ConductiveBaseData.hs--- created: Sun Oct 31 22:54:24 JST 2010+-- created: Fri Sep 14 16:30:33 JST 2012 ------------------------------------------------------------------------------ module Sound.Conductive.ConductiveBaseData where -import Control.Concurrent.MVar-import Data.IORef-import Data.Map--data Generator a = Generator- { generatorSource :: MVar [a]- , sourceLength :: IORef Int- , generatorCounter :: IORef Int- }+import Sound.Conductive.MutableMap -- | a data type for traditional musical time @@ -49,13 +41,11 @@ data MusicalEnvironment = MusicalEnvironment { environmentName :: String- , playerStore :: Map String Player- , tempoClockStore :: Map String TempoClock- , iOIStore :: Map String (MVar MusicalEnvironment -> Player -> IO Double)- , actionStore :: Map String (MVar MusicalEnvironment -> Player -> IO ())- , interruptStore :: Map String ([IO ()])- , doubleGeneratorStore :: Map String (Generator Double)- , iOIListStore :: Map String [Double]+ , playerStore :: MutableMap String Player+ , tempoClockStore :: MutableMap String TempoClock+ , iOIStore :: MutableMap String (MusicalEnvironment -> Player -> Double -> Double -> IO Double)+ , actionStore :: MutableMap String (MusicalEnvironment -> Player -> Double -> Double -> IO ())+ , interruptStore :: MutableMap String ([IO ()]) } instance Show MusicalEnvironment where
Sound/Conductive/ConductiveDefaults.hs view
@@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ -- ConductiveDefaults.hs--- created: Fri Oct 1 23:21:01 JST 2010+-- created: Sun Sep 16 22:15:39 JST 2012 ------------------------------------------------------------------------------ @@ -9,17 +9,16 @@ module Sound.Conductive.ConductiveDefaults where -import Control.Concurrent.MVar+import Control.Concurrent.STM import Data.Map import Sound.Conductive.ConductiveBaseData-import Sound.Conductive.Generator-import Sound.Conductive.IOI import Sound.Conductive.MusicalEnvironment import Sound.Conductive.MusicalTime+import Sound.Conductive.MutableMap import Sound.Conductive.Player -defaultPlayerStore :: Data.Map.Map String Player-defaultPlayerStore = newPlayerStore ("default",("default","defaultIOI","defaultAction",50))+defaultPlayerStore :: IO (TVar (Map String Player))+defaultPlayerStore = newPlayerStore ("default",("default","defaultIOI","defaultAction",0)) defaultTempoClock :: IO TempoClock defaultTempoClock = do@@ -37,42 +36,38 @@ , timeSignatureChanges = [defaultTS] } -defaultTempoClockStore :: IO (Map [Char] TempoClock)+defaultTempoClockStore :: IO (TVar (Map [Char] TempoClock)) defaultTempoClockStore = do t <- defaultTempoClock- return $ fromList [("default",t)]--defaultActionStore :: Data.Map.Map [Char] (t -> t1 -> IO ())-defaultActionStore = fromList [("defaultAction", (\x y -> putStrLn "yeah!"))]+ newMMap [("default",t)] -defaultIOI :: MVar MusicalEnvironment -> Player -> IO Double-defaultIOI e p = iOIFromList e p "default"+defaultActionStore :: IO (TVar (Map [Char] (t -> t1 -> t2 -> t3 -> IO ())))+defaultActionStore = newMMap [("defaultAction", (\x y z zz -> putStrLn message))]+ where message = "The default action is to print this message: yeah!" -defaultIOIStore- :: Data.Map.Map- [Char] (MVar MusicalEnvironment -> Player -> IO Double)-defaultIOIStore = fromList [("defaultIOI", defaultIOI)]+-- defaultIOI e p = iOIFromList e p "default" -defaultInterruptStore :: Data.Map.Map [Char] [IO ()]-defaultInterruptStore = fromList [("defaultInterrupt",[return()::IO()])]+defaultIOIStore :: IO (TVar (Map [Char] a))+defaultIOIStore = newMMap [("defaultIOI", undefined)] -defaultIOIListStore :: Data.Map.Map [Char] [Double]-defaultIOIListStore = fromList [("default",makeIOIList 0 [1.0])]+defaultInterruptStore :: IO (TVar (Map [Char] [IO ()]))+defaultInterruptStore = newMMap [("defaultInterrupt",[return()::IO()])] -defaultMusicalEnvironment :: IO (MVar MusicalEnvironment)+defaultMusicalEnvironment :: IO MusicalEnvironment defaultMusicalEnvironment = do tcs <- defaultTempoClockStore- gs <- defaultGeneratorStore+ ps <- defaultPlayerStore+ iois <- defaultIOIStore+ acs <- defaultActionStore+ ints <- defaultInterruptStore let me = MusicalEnvironment- { environmentName = "defaultEnvironment"- , playerStore = defaultPlayerStore+ { environmentName = "default MusicalEnvironment"+ , playerStore = ps , tempoClockStore = tcs- , iOIStore = defaultIOIStore- , actionStore = defaultActionStore- , interruptStore = defaultInterruptStore- , doubleGeneratorStore = gs- , iOIListStore = defaultIOIListStore+ , iOIStore = iois+ , actionStore = acs+ , interruptStore = ints }- newMVar me+ return me
− Sound/Conductive/Generator.hs
@@ -1,97 +0,0 @@----------------------------------------------------------------------------------- Generator.hs--- created: Fri Oct 1 23:20:44 JST 2010------------------------------------------------------------------------------------ | This is a module for creating and manipulating mutable generators. Generators contain a source finite list and a counter. Items are retrieved from the list one at a time, and the list loops when the last item has been given.--module Sound.Conductive.Generator where--import Control.Concurrent.MVar-import Data.IORef-import Data.Map-import Data.Maybe-import Sound.Conductive.ConductiveBaseData----- | creates a new Generator from the given source list.--newGenerator :: [a] -> IO (Generator a)-newGenerator source = do- c <- newCounter- g <- newMVar source- l <- newIORef $ length source- return $ Generator { generatorSource = g- , sourceLength = l- , generatorCounter = c- }---- | swaps the source of a Generator--swapGenerator :: Generator a -> [a] -> IO [a]-swapGenerator oldGenerator newSource = do- writeIORef ( sourceLength oldGenerator) $ length newSource- swapMVar ( generatorSource oldGenerator) newSource--newCounter :: IO (IORef Int)-newCounter = newIORef (-1)---- | returns the current value of a counter in a Generator--getCount :: Generator a -> IO Int-getCount generator = do- c <- readIORef $ generatorCounter generator- return $ c + 1---- | returns the source of a Generator--getGeneratorSource :: Generator a -> IO [a]-getGeneratorSource generator = readMVar $ generatorSource generator---- | resets the counter of a Generator--resetCounter :: Generator a -> IO ()-resetCounter generator = writeIORef (generatorCounter generator) (-1)---- | returns the next item from a Generator--next :: Generator a -> IO a-next generator = nextWithOffset 0 generator---- | adds the first argument to the counter value of a Generator and returns the corresponding item from the source--nextWithOffset :: Int -> Generator a -> IO a-nextWithOffset offset generator = do- lastCount <- readIORef $ generatorCounter generator- let newCount = lastCount + 1- writeIORef (generatorCounter generator) newCount- g <- getGeneratorSource generator- l <- readIORef $ sourceLength generator- let next' (l,xs) n = xs !! (mod n l)- return $ g !! (mod (newCount + offset) l)---- | given a list of Generators, returns a list containing the next item from all of them--nexts :: [Generator b] -> IO [b]-nexts generators = mapM next generators---- | runs a pure function on the next item from a Generator--withNext :: Generator a -> (a -> b) -> IO b-withNext generator function = fmap function $ next generator---- | creates a Map for storing Generators in--newGeneratorStore- :: (Ord t) => (t, [a]) -> IO (Data.Map.Map t (Generator a))-newGeneratorStore (k,s) = do- g <- newGenerator s- return $ fromList [(k,g)]---- | the defaultGeneratorStore used by the defaultMusicalEnvironment--defaultGeneratorStore- :: IO (Data.Map.Map [Char] (Generator Double))-defaultGeneratorStore = newGeneratorStore ("default",[1.0])
− Sound/Conductive/IOI.hs
@@ -1,62 +0,0 @@----------------------------------------------------------------------------------- IOI.hs--- created: Fri Oct 1 23:21:25 JST 2010------------------------------------------------------------------------------------ | This module contains functions related to IOI functions and IOI lists.--module Sound.Conductive.IOI where--import Control.Concurrent.MVar-import Data.List-import Data.List.Utils-import Data.Maybe-import Sound.Conductive.ConductiveBaseData-import Sound.Conductive.MusicalEnvironment-import Sound.Conductive.MusicalTime-import Sound.Conductive.Player---- | Creates an infinite length list from a start time and a finite list of relative time deltas--makeIOIList :: (Num a) => a -> [a] -> [a]-makeIOIList start source = deltasToAbsolutes start $ cycle source---- | An IOI function which gets an IOI from an IOI list---- The problem in this function is the error that accumulates from using doubles;--- the use of minDiff below solves this problem, but it's an ugly hack, I feel.--iOIFromList- :: MVar MusicalEnvironment -> Player -> String -> IO Double-iOIFromList e p m = let- minDiff = 0.1- start = playerStartingBeat p- b = playerBeat p- nextBeat currentBeat iOIList = let- nextTwoBeats = take 2 $ dropWhile (<= currentBeat) iOIList- in if ((head nextTwoBeats) - currentBeat) < minDiff- then (nextTwoBeats!!1)- else (head nextTwoBeats)- in do il <- getIOIList e m- return $ nextBeat b il- ---- | Creates an IOI list, adds it to the environment, and adds a lookup function for it to the MusicalEnvironment.--newIOIFunctionAndIOIList- :: MVar MusicalEnvironment- -> String- -> Double- -> [Double]- -> IO MusicalEnvironment-newIOIFunctionAndIOIList env name startingBeat deltas = let- newFunc e p = iOIFromList e p name- newIOIList = makeIOIList startingBeat deltas- in do addIOIList env (name,newIOIList)- addIOI env (name,newFunc)--addIOIs e iois = let - addIOI e (x,y,z) = newIOIFunctionAndIOIList e x y z- in mapM_ (addIOI e) iois
− Sound/Conductive/MVarUtils.hs
@@ -1,38 +0,0 @@----------------------------------------------------------------------------------- MVarUtils.hs--- created: Mon May 10 15:11:12 JST 2010------------------------------------------------------------------------------------ | These functions were found to be useful for dealing with MVars. For more on MVars, see <http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Control-Concurrent-MVar.html>.--module Sound.Conductive.MVarUtils where--import Control.Concurrent.MVar---- | Applies a pure function to the value stored in an MVar.--wm :: MVar a -> (a -> a1) -> IO a1-wm mvar func = do- val <- readMVar mvar- return $ func val---- | Applies an IO function to the value stored in an MVar.--wIOm :: MVar a -> (a -> IO b) -> IO b-wIOm mvar func = do- val <- readMVar mvar- func val---- | Changes the value stored in an MVar based on a pure function.--wcm :: MVar a -> (a -> a) -> IO a-wcm mvar func = do- val <- readMVar mvar- swapMVar mvar $ func val---- | An alias for the wcm function.--withChangeToMVar :: MVar a -> (a -> a) -> IO a-withChangeToMVar mvar func = wcm mvar func
+ Sound/Conductive/MiscListUtils.hs view
@@ -0,0 +1,207 @@+------------------------------------------------------------------------------++-- MiscListUtils.hs+-- created: Sun Mar 14 17:00:11 JST 2010++------------------------------------------------------------------------------++-- A set of functions for operating on lists of floats+-- The purpose is creating interesting lists for use in music.++module Sound.Conductive.MiscListUtils where++import System.Random+import Data.List+import Data.Array.ST+import Data.Time.Clock.POSIX+import Control.Monad+import Control.Monad.ST+import Data.STRef+import Sound.Conductive.MusicalTime++unconcat xs = map (\x -> [x]) xs++-- http://old.nabble.com/Request-for-code-review:-slice-1.0.0,-TestSupport-td20658828.html++getSeed = getPOSIXTime >>= \x -> return $ truncate $ x * 100000000++slice :: [a] -> [Int] -> [a]+xs `slice` indices = map (xs !!) indices++replaceAt :: Int -> [a] -> [a] -> [a]+replaceAt i ys xs = + let xz = splitAt i xs+ in (fst xz) ++ ys ++ (tail $ snd xz)++-- use this for double-time, creating triplets, fivelets even...++npletAt :: (Fractional a) => Int -> Int -> [a] -> [a]+npletAt n i xs =+ let x = xs!!i+ plet = replicate n $ x/(fromIntegral n)+ in replaceAt i plet xs++-- joins n number of values in list of xs beginning from sp++joinVals :: (Num a) => Int -> Int -> [a] -> [a]+joinVals sp n xs = let+ splitXs = splitAt sp xs+ newFront = fst splitXs+ oldRest = snd splitXs+ newRest = [sum $ take n $ oldRest] ++ (snd $ splitAt n oldRest)+ in newFront ++ newRest++stutter :: Int -> Int -> Int -> [a] -> [a]+stutter sp l n xs = let+ splitList = splitAt sp xs+ initial = fst splitList+ toBeStuttered = take l $ snd splitList+ remainder = snd $ splitAt l $ snd splitList+ stuttered = concat $ replicate n toBeStuttered+ in initial ++ stuttered ++ remainder++-- modified slightly from http://www.haskell.org/haskellwiki/99_questions/Solutions/24++diff_select :: Int -> Int -> IO [Int]+diff_select n to = diff_select' n [0..to]+ +diff_select' 0 _ = return []+diff_select' _ [] = error "too few elements to choose from"+diff_select' n xs = do r <- randomRIO (0,(length xs)-1)+ let remaining = take r xs ++ drop (r+1) xs+ rest <- diff_select' (n-1) remaining+ return ((xs!!r) : rest)++randomSubset xs subsetSize = let+ len = length xs+ in do is <- diff_select subsetSize $ (len - 1)+ return $ map (xs!!) is++-- | Randomly shuffle a list without the IO Monad+-- /O(N)/+-- ??? -- where did I get this function from? I didn't write it...++shuffle' :: [a] -> StdGen -> ([a],StdGen)+shuffle' xs gen = runST (do+ g <- newSTRef gen+ let randomRST lohi = do+ (a,s') <- liftM (randomR lohi) (readSTRef g)+ writeSTRef g s'+ return a+ ar <- newArray n xs+ xs' <- forM [1..n] $ \i -> do+ j <- randomRST (i,n)+ vi <- readArray ar i+ vj <- readArray ar j+ writeArray ar j vi+ return vj+ gen' <- readSTRef g+ return (xs',gen'))+ where+ n = length xs+ newArray :: Int -> [a] -> ST s (STArray s Int a)+ newArray n xs = newListArray (1,n) xs++shuffle :: [a] -> IO [a]+shuffle xs = getStdRandom (shuffle' xs) ++rotate :: [a] -> Int -> [a]+rotate xs n = drop nn xs ++ take nn xs+ where + nn = n `mod` length xs++lace :: [[a]] -> Int -> [a]+lace xss n = let+ listNLengths = zip (map length xss) (xss)+ selector t x = (snd x)!!(mod t $ fst x)+ aRun t = map (selector t) listNLengths+ o = ceiling $ (fromIntegral n)/(fromIntegral $ length xss)+ in take n $ concat $ map aRun [0..o]++randomList :: Int -> StdGen -> [Int]+randomList n = take n . unfoldr (Just . random)++-- normalizes to 1+normalize xs = map (\x -> x/m) xs where m = maximum xs++normalizeTo t xs = map (\x -> x * m) xs where m = t/(maximum xs)++-- linear interpolation of a point from+-- http://arcanesentiment.blogspot.jp/2009/08/function-of-day-lerp.html+-- retrieved June 2012++lerp (x1,y1) (x2,y2) x = y1 + (x - x1) * (y2 - y1) / (x2 - x1)++rList :: Int -> IO [Int]+rList x = do+ seed <- newStdGen+ let rs = randomList x seed+ return $ map abs rs++-- http://osfameron.vox.com/library/post/random-pain-in-haskell.html+-- pick a = do r <- randomRIO (1, length a)+-- return $ a !! (r - 1)++pick :: [a] -> IO a+pick [] = undefined+pick [x] = do return x+pick (x:xs) = pick' x xs (2 :: Int)++-- pick' :: (Num p, Random p) => t -> [t] -> p -> IO t+pick' curr [] _ = do return curr+pick' curr (next:rest) prob+ = do r <- getStdRandom (randomR (1,prob))+ let curr' = if r == 1 then next else curr+ pick' curr' rest (prob+1)++pickN :: (Num a, Enum a) => a -> [b] -> IO [b]+pickN n xs = mapM (\_ -> pick xs) [1..n]++coin :: IO Bool+coin = pick [True,False]++-- odds against ++odds :: Int -> Int -> IO Bool+odds n d = pick $ (replicate n False) ++ (replicate d True)++-- from tuples where fst says how many and snd says what, create the lists++replicator :: [(Int, b)] -> [b]+replicator xs = concat $ map (\x -> replicate (fst x) $ snd x ) xs++-- an alias for replicator++weightedList = replicator++------------------------------------------------------------------------------++-- takeToValue+-- give the maximum sum of a list+-- if the sum is greater than the given value, the list is cropped+-- the final sum is lowered so that the list sum equals the given value+-- if the list is short of the given value, another item is added so that the list sum equals the given value+--+-- This can be used to make a list of values sum to a specific number of beats.++takeToValue' :: (Ord a, Num a) => [a] -> a -> a -> [a] -> [a]+takeToValue' xs val curVal ys+ | xs == [] = if (val <= curVal)+ then ys+ else ys ++ [val-curVal]+ | otherwise =+ let c = head xs+ d = curVal + c+ adjustValue input comparison+ | input >= comparison = (False,input - comparison)+ | input < comparison = (True,0)+ test = adjustValue d val+ in if (fst test)+ then takeToValue' (tail xs) val d $ ys ++ [c]+ else takeToValue' ([]) val d $ ys ++ [c - (snd test)]++takeToValue :: (Num a, Ord a) => a -> [a] -> [a]+takeToValue val xs = takeToValue' xs val 0 []++------------------------------------------------------------------------------+
Sound/Conductive/MusicalEnvironment.hs view
@@ -1,493 +1,155 @@ ------------------------------------------------------------------------------ --- MusicalEnvironment.hs--- created: Fri Oct 1 23:21:13 JST 2010+-- /home/renick/haskell/conductive-0.3c/MusicalEnvironment.hs+-- created: Sun Sep 16 22:19:28 JST 2012 ------------------------------------------------------------------------------ -module Sound.Conductive.MusicalEnvironment ( actions- , addAction- , addDoubleGenerator- , addIOI- , addIOIList- , addInterrupt- , addNewGenerator- , addPlayer- , addTempoClock- , changeActions- , changeDoubleGenerators- , changeEnvironment- , changeIOILists- , changeIOIs- , changeInterrupts- , changePlayers- , changeTempoClocks- , deleteAction- , deleteDoubleGenerator- , deleteIOI- , deleteIOIList- , deleteInterrupt- , deletePlayer- , deleteTempoClock- , doubleGenerators- , eChangeTempo- , eChangeTimeSignature- , eCurrentTempo- , eCurrentTimeSignature- , eElapsedBeats- , eElapsedTime- , getAction- , getCurrentTime- , getDoubleGenerator- , getIOI- , getIOIList- , getInterrupt- , getPlayer- , getTempoClock- , iOIs- , iOILists- , interrupts- , players- , showCurrentTime- , tempoClocks- , withAction- , withDoubleGenerator- , withEnvironment- , withIOI- , withIOIList- , withInterrupt- , withPlayer- , withTempoClock- ) where+module Sound.Conductive.MusicalEnvironment where -import Control.Concurrent.MVar-import Data.Map +import Control.Concurrent.STM import Sound.Conductive.ConductiveBaseData-import Sound.Conductive.Generator import Sound.Conductive.MusicalTime-import Sound.Conductive.MVarUtils---environmentStoreKeys- :: MVar a -> (a -> Data.Map.Map k a1) -> IO [k]-environmentStoreKeys e sRecord = wm e $ (\x -> keys $ sRecord x)---- | allows a pure function to be run on a MusicalEnvironment stored in an MVar--withEnvironment :: MVar a -> (a -> a1) -> IO a1-withEnvironment e func = wm e func---- | used to update a MusicalEnvironment stored in an MVar--changeEnvironment :: MVar a -> (a -> a) -> IO a-changeEnvironment e func = wcm e func--withStore :: (t -> a) -> (a -> b) -> t -> b-withStore store func e = func $ store e ---- | allows a pure function to be run on a store (first argument) in a MusicalEnvironment in an MVar--withMEStore :: (a -> a1) -> (a1 -> b) -> MVar a -> IO b-withMEStore store func e = withEnvironment e $ withStore store func--getItem- :: (Ord k) => (a -> Data.Map.Map k a1) -> k -> MVar a -> IO a1-getItem store item e = withMEStore store (\x -> x ! item) e----------------------------------------------------------------------------------- boilerplate--- functions to retrieve an item from a MusicalEnvironment in an MVar---- | returns a Player from a MusicalEnvironment in an MVar--getPlayer :: MVar MusicalEnvironment -> String -> IO Player-getPlayer e n = getItem playerStore n e---- | returns a TempoClock from a MusicalEnvironment in an MVar--getTempoClock :: MVar MusicalEnvironment -> String -> IO TempoClock-getTempoClock e n = getItem tempoClockStore n e---- | returns an IOI function from a MusicalEnvironment in an MVar--getIOI- :: MVar MusicalEnvironment- -> String- -> IO (MVar MusicalEnvironment -> Player -> IO Double)-getIOI e n = getItem iOIStore n e---- | returns an action function from a MusicalEnvironment in an MVar--getAction- :: MVar MusicalEnvironment- -> String- -> IO (MVar MusicalEnvironment -> Player -> IO ())-getAction e n = getItem actionStore n e---- | returns an interrupt function from a MusicalEnvironment in an MVar--getInterrupt :: MVar MusicalEnvironment -> String -> IO [IO ()]-getInterrupt e n = getItem interruptStore n e---- | returns a double Generator from a MusicalEnvironment in an MVar--getDoubleGenerator- :: MVar MusicalEnvironment -> String -> IO (Generator Double)-getDoubleGenerator e n = getItem doubleGeneratorStore n e---- | returns an IOI list from a MusicalEnvironment in an MVar--getIOIList :: MVar MusicalEnvironment -> String -> IO [Double]-getIOIList e n = getItem iOIListStore n e----------------------------------------------------------------------------------withItem- :: (Ord k) =>- (a -> Data.Map.Map k a1) -> k -> (a1 -> IO b) -> MVar a -> IO b-withItem store item func e = getItem store item e >>= \i -> func i----------------------------------------------------------------------------------- irritating boilerplate--- functions to run a function on an item from a MusicalEnvironment in an MVar---- | runs a pure function on a stored Player--withPlayer- :: (Player -> IO b) -> MVar MusicalEnvironment -> String -> IO b-withPlayer func e n = withItem playerStore n func e---- | runs a pure function on a stored TempoClock--withTempoClock- :: (TempoClock -> IO b)- -> MVar MusicalEnvironment- -> String- -> IO b-withTempoClock func e n = withItem tempoClockStore n func e---- | runs a pure function on a stored IOI function--withIOI- :: ((MVar MusicalEnvironment -> Player -> IO Double) -> IO b)- -> MVar MusicalEnvironment- -> String- -> IO b-withIOI func e n = withItem iOIStore n func e---- | runs a pure function on a stored action function--withAction- :: ((MVar MusicalEnvironment -> Player -> IO ()) -> IO b)- -> MVar MusicalEnvironment- -> String- -> IO b-withAction func e n = withItem actionStore n func e---- | runs a pure function on a stored interrupt function--withInterrupt- :: ([IO ()] -> IO b) -> MVar MusicalEnvironment -> String -> IO b-withInterrupt func e n = withItem interruptStore n func e---- | runs a pure function on a stored double Generator--withDoubleGenerator- :: (Generator Double -> IO b)- -> MVar MusicalEnvironment- -> String- -> IO b-withDoubleGenerator func e n = withItem doubleGeneratorStore n func e---- | runs a pure function on a stored IOI List--withIOIList- :: ([Double] -> IO b) -> MVar MusicalEnvironment -> String -> IO b-withIOIList func e n = withItem iOIListStore n func e--------------------------------------------------------------------------------+import Sound.Conductive.MutableMap -storeKeys :: (a -> Data.Map.Map k a1) -> MVar a -> IO [k]-storeKeys store e = withMEStore store keys e+-- for getItem store item e = ... use+-- (store e) ?@ item ---------------------------------------------------------------------------------- annoying boilerplate--- functions to get all items of a type from a MusicalEnvironment in an MVar+-- for withItem store func e item = ... use+-- withKey (store e) item func -- | returns a list of the names of all Players stored in a MusicalEnvironment -players :: MVar MusicalEnvironment -> IO [String]-players e = storeKeys playerStore e+players :: MusicalEnvironment -> IO [String]+players e = keys $ playerStore e -- | returns a list of the names of all TempoClocks stored in a MusicalEnvironment -tempoClocks :: MVar MusicalEnvironment -> IO [String]-tempoClocks e = storeKeys tempoClockStore e+tempoClocks :: MusicalEnvironment -> IO [String]+tempoClocks e = keys $ tempoClockStore e -- | returns a list of the names of all IOI functions stored in a MusicalEnvironment -iOIs :: MVar MusicalEnvironment -> IO [String]-iOIs e = storeKeys iOIStore e+iOIs :: MusicalEnvironment -> IO [String]+iOIs e = keys $ iOIStore e -- | returns a list of the names of all action functions stored in a MusicalEnvironment -actions :: MVar MusicalEnvironment -> IO [String]-actions e = storeKeys actionStore e+actions :: MusicalEnvironment -> IO [String]+actions e = keys $ actionStore e -- | returns a list of the names of all interrupt functions stored in a MusicalEnvironment -interrupts :: MVar MusicalEnvironment -> IO [String]-interrupts e = storeKeys interruptStore e---- | returns a list of the names of all double Generators stored in a MusicalEnvironment--doubleGenerators :: MVar MusicalEnvironment -> IO [String]-doubleGenerators e = storeKeys doubleGeneratorStore e---- | returns a list of the names of all IOI lists stored in a MusicalEnvironment--iOILists :: MVar MusicalEnvironment -> IO [String]-iOILists e = storeKeys iOIListStore e----------------------------------------------------------------------------------- more annoying boilerplate--- functions operating on the various stores in a MusicalEnvironment stored in an MVar---- | runs a pure function on the Map in a MusicalEnvironment containing the Players--changePlayers- :: (Data.Map.Map String Player -> Data.Map.Map String Player)- -> MusicalEnvironment- -> MusicalEnvironment-changePlayers func e = e { playerStore = func $ playerStore e }---- | runs a pure function on the Map in a MusicalEnvironment containing the TempoClocks--changeTempoClocks- :: (Data.Map.Map String TempoClock- -> Data.Map.Map String TempoClock)- -> MusicalEnvironment- -> MusicalEnvironment-changeTempoClocks func e = e { tempoClockStore = func $ tempoClockStore e }---- | runs a pure function on the Map in a MusicalEnvironment containing the IOI functions--changeIOIs- :: (Data.Map.Map String (MVar MusicalEnvironment -> Player -> IO Double)- -> Data.Map.Map String (MVar MusicalEnvironment -> Player -> IO Double))- -> MusicalEnvironment- -> MusicalEnvironment-changeIOIs func e = e { iOIStore = func $ iOIStore e }---- | runs a pure function on the Map in a MusicalEnvironment containing the action functions--changeActions- :: (Data.Map.Map String (MVar MusicalEnvironment -> Player -> IO ())- -> Data.Map.Map String (MVar MusicalEnvironment -> Player -> IO ()))- -> MusicalEnvironment- -> MusicalEnvironment-changeActions func e = e { actionStore = func $ actionStore e }---- | runs a pure function on the Map in a MusicalEnvironment containing the interrupt functions--changeInterrupts- :: (Data.Map.Map String [IO ()] -> Data.Map.Map String [IO ()])- -> MusicalEnvironment- -> MusicalEnvironment-changeInterrupts func e = e { interruptStore = func $ interruptStore e }---- | runs a pure function on the Map in a MusicalEnvironment containing the double Generators--changeDoubleGenerators- :: (Data.Map.Map String (Generator Double)- -> Data.Map.Map String (Generator Double))- -> MusicalEnvironment- -> MusicalEnvironment-changeDoubleGenerators func e = e { doubleGeneratorStore = func $ doubleGeneratorStore e }---- | runs a pure function on the Map in a MusicalEnvironment containing the IOI lists--changeIOILists- :: (Data.Map.Map String [Double] -> Data.Map.Map String [Double])- -> MusicalEnvironment- -> MusicalEnvironment-changeIOILists func e = e { iOIListStore = func $ iOIListStore e }----------------------------------------------------------------------------------- will the boilerplate never end?--- functions to add an item to a store in a MusicalEnvironment in an MVar---- | Add a Player to a MusicalEnvironment in an MVar--addPlayer- :: MVar MusicalEnvironment- -> (String, Player)- -> IO MusicalEnvironment-addPlayer e (k,v) = changeEnvironment e $ changePlayers (insert k v)---- | Add a TempoClock to a MusicalEnvironment in an MVar--addTempoClock- :: MVar MusicalEnvironment- -> (String, TempoClock)- -> IO MusicalEnvironment-addTempoClock e (k,v) = changeEnvironment e $ changeTempoClocks (insert k v)---- | Add an IOI function to a MusicalEnvironment in an MVar--addIOI- :: MVar MusicalEnvironment- -> (String, MVar MusicalEnvironment -> Player -> IO Double)- -> IO MusicalEnvironment-addIOI e (k,v) = changeEnvironment e $ changeIOIs (insert k v)---- | Add an action function to a MusicalEnvironment in an MVar--addAction- :: MVar MusicalEnvironment- -> (String, MVar MusicalEnvironment -> Player -> IO ())- -> IO MusicalEnvironment-addAction e (k,v) = changeEnvironment e $ changeActions (insert k v)---- | Add an interrupt function to a MusicalEnvironment in an MVar--addInterrupt- :: MVar MusicalEnvironment- -> (String, [IO ()])- -> IO MusicalEnvironment-addInterrupt e (k,v) = changeEnvironment e $ changeInterrupts (insert k v)---- | Add a double Generator to a MusicalEnvironment in an MVar--addDoubleGenerator- :: MVar MusicalEnvironment- -> (String, Generator Double)- -> IO MusicalEnvironment-addDoubleGenerator e (k,v) = changeEnvironment e $ changeDoubleGenerators (insert k v)---- | Add an IOI list to a MusicalEnvironment in an MVar--addIOIList- :: MVar MusicalEnvironment- -> (String, [Double])- -> IO MusicalEnvironment-addIOIList e (k,v) = changeEnvironment e $ changeIOILists (insert k v)---- | Add a double Generator to a MusicalEnvironment in an MVar--addNewGenerator- :: MVar MusicalEnvironment- -> (String, [Double])- -> IO MusicalEnvironment-addNewGenerator e (n,x) = newGenerator x >>= \g -> addDoubleGenerator e (n,g)----------------------------------------------------------------------------------- functions to delete items from a MusicalEnvironment in an MVar--deleteItem- :: (Ord k) =>- ((Data.Map.Map k a -> Data.Map.Map k a) -> t -> t1) -> k -> t -> t1-deleteItem changeFunc k e = changeFunc (delete k) e- --- | Delete a Player to a MusicalEnvironment in an MVar--deletePlayer- :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment-deletePlayer e k = changeEnvironment e $ deleteItem (changePlayers) k---- | Delete a Tempo Clock from a MusicalEnvironment in an MVar--deleteTempoClock- :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment-deleteTempoClock e k = changeEnvironment e $ deleteItem (changeTempoClocks) k---- | Delete an IOI function from a MusicalEnvironment in an MVar--deleteIOI- :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment-deleteIOI e k = changeEnvironment e $ deleteItem (changeIOIs) k---- | Delete an action function from a MusicalEnvironment in an MVar--deleteAction- :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment-deleteAction e k = changeEnvironment e $ deleteItem (changeActions) k---- | Delete an interrupt function from a MusicalEnvironment in an MVar--deleteInterrupt- :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment-deleteInterrupt e k = changeEnvironment e $ deleteItem (changeInterrupts) k---- | Delete a double Generator from a MusicalEnvironment in an MVar--deleteDoubleGenerator- :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment-deleteDoubleGenerator e k = changeEnvironment e $ deleteItem (changeDoubleGenerators) k---- | Delete an IOI list from a MusicalEnvironment in an MVar--deleteIOIList- :: MVar MusicalEnvironment -> String -> IO MusicalEnvironment-deleteIOIList e k = changeEnvironment e $ deleteItem (changeIOILists) k----------------------------------------------------------------------------------- not crazy about the prefixed "e" in these function names...---- | convenience function for returning elapsed time from a stored TempoClock--eElapsedTime :: MVar MusicalEnvironment -> String -> IO Double-eElapsedTime e clock = withTempoClock elapsedTime e clock ---- | convenience function for returning elapsed beats from a stored TempoClock--eElapsedBeats :: MVar MusicalEnvironment -> String -> IO Double-eElapsedBeats e clock = withTempoClock elapsedBeats e clock ---- | convenience function for returning elapsed MusicalTime from a stored TempoClock+interrupts :: MusicalEnvironment -> IO [String]+interrupts e = keys $ interruptStore e -getCurrentTime- :: MVar MusicalEnvironment -> String -> IO MusicalTime-getCurrentTime e clock = withTempoClock currentMusicalTime e clock +-- don't like this, but it really is more convenient than using withKey directly. what's a better way? --- | convenience function for returning elapsed MusicalTime as a string from a stored TempoClock+withPlayer :: MusicalEnvironment -> (Player -> a) -> String -> IO (Maybe a)+withPlayer e func k = withKey (playerStore e) func k -showCurrentTime :: MVar MusicalEnvironment -> String -> IO [Char]-showCurrentTime e clock = withTempoClock currentMusicalTime2 e clock +withTempoClock :: MusicalEnvironment -> (TempoClock -> a) -> String -> IO (Maybe a)+withTempoClock e func k = withKey (tempoClockStore e) func k --- | convenience function for returning the current Tempo from a stored TempoClock+withIOI+ :: MusicalEnvironment+ -> ((MusicalEnvironment -> Player -> Double -> Double -> IO Double) -> a)+ -> String+ -> IO (Maybe a)+withIOI e func k = withKey (iOIStore e) func k -eCurrentTempo :: MVar MusicalEnvironment -> String -> IO Double-eCurrentTempo e clock = do- c <- getTempoClock e clock- return $ currentTempo c+withAction+ :: MusicalEnvironment+ -> ((MusicalEnvironment -> Player -> Double -> Double -> IO ()) -> a)+ -> String+ -> IO (Maybe a)+withAction e func k = withKey (actionStore e) func k --- | convenience function for returning the current TimeSignature from a stored TempoClock+withInterrupt :: MusicalEnvironment -> ([IO ()] -> a) -> String -> IO (Maybe a)+withInterrupt e func k = withKey (interruptStore e) func k -eCurrentTimeSignature- :: MVar MusicalEnvironment -> String -> IO Int-eCurrentTimeSignature e clock = withTempoClock currentTimeSignature e clock +--- ------------------------------------------------------------------------------+--- for these functions, now use modifyMMap+--- changePlayers+--- changeTempoClocks+--- changeIOIs+--- changeActions+--- changeInterrupts+--- +--- ------------------------------------------------------------------------------+--- for these functions from 0.2, now use addVal+--- addPlayer +-- (playerStore e) +@ (k,Player)+--- addTempoClock+--- addIOI+--- addAction+--- addInterrupt+--- +--- ------------------------------------------------------------------------------+--- for these functions from 0.2, now use deleteVal+--- deletePlayer+-- (playerStore e) -@ (k,Player)+--- addTempoClock+--- deleteTempoClock+--- deleteIOI+--- deleteAction+--- deleteInterrupt+--- +--- ------------------------------------------------------------------------------+--- -- not crazy about the prefixed "e" in these function names...+-- instead of them, use withTempoClock like this:+-- withTempoClock e elapsedTime clockKey+--- +--- -- | convenience function for returning elapsed time from a stored TempoClock+--- +--- eElapsedTime :: MVar MusicalEnvironment -> String -> IO Double+--- eElapsedTime e clock = withTempoClock elapsedTime e clock --- | convenience function for changing the current Tempo of a stored TempoClock+--- +--- -- | convenience function for returning elapsed beats from a stored TempoClock+--- +--- eElapsedBeats :: MVar MusicalEnvironment -> String -> IO Double+--- eElapsedBeats e clock = withTempoClock elapsedBeats e clock +--- +--- -- | convenience function for returning elapsed MusicalTime from a stored TempoClock+--- +--- getCurrentTime+--- :: MVar MusicalEnvironment -> String -> IO MusicalTime+--- getCurrentTime e clock = withTempoClock currentMusicalTime e clock +--- +--- -- | convenience function for returning elapsed MusicalTime as a string from a stored TempoClock+--- +--- showCurrentTime :: MVar MusicalEnvironment -> String -> IO [Char]+--- showCurrentTime e clock = withTempoClock currentMusicalTime2 e clock +--- +--- -- | convenience function for returning the current Tempo from a stored TempoClock+--- +--- eCurrentTempo :: MVar MusicalEnvironment -> String -> IO Double+--- eCurrentTempo e clock = do+--- c <- getItem tempoClockStore e clock+--- return $ currentTempo c+--- +--- -- | convenience function for returning the current TimeSignature from a stored TempoClock+--- +--- eCurrentTimeSignature+--- :: MVar MusicalEnvironment -> String -> IO Int+--- eCurrentTimeSignature e clock = withTempoClock currentTimeSignature e clock +--- +--+-- is there a better way for these two?+--- -- | convenience function for changing the current Tempo of a stored TempoClock -eChangeTempo- :: MVar MusicalEnvironment- -> String- -> Double- -> IO MusicalEnvironment+eChangeTempo :: MusicalEnvironment -> String -> Double -> IO () eChangeTempo e clock nt = do- tc <- getItem tempoClockStore clock e+ Just tc <- (tempoClockStore e) ?@ clock ntc <- changeTempo tc nt- addTempoClock e (clock,ntc)+ (tempoClockStore e) +@ (clock,ntc) --- | convenience function for changing the current TimeSignature of a stored TempoClock+--- +--- -- | convenience function for changing the current TimeSignature of a stored TempoClock -eChangeTimeSignature- :: MVar MusicalEnvironment- -> String- -> Int- -> IO MusicalEnvironment-eChangeTimeSignature e clock nts = do- tc <- getItem tempoClockStore clock e- ntc <- changeTimeSignature tc nts- addTempoClock e (clock,ntc)+eChangeTimeSignature :: MusicalEnvironment -> String -> Int -> IO ()+eChangeTimeSignature e clock nt = do+ Just tc <- (tempoClockStore e) ?@ clock + ntc <- changeTimeSignature tc nt+ (tempoClockStore e) +@ (clock,ntc)
Sound/Conductive/MusicalTime.hs view
@@ -1,7 +1,7 @@ ------------------------------------------------------------------------------ --- MusicalTime.hs--- created: Fri Oct 1 23:20:55 JST 2010+-- /home/renick/haskell/conductive-0.3c/MusicalTime.hs+-- created: Sun Sep 16 22:23:57 JST 2012 ------------------------------------------------------------------------------ @@ -9,11 +9,9 @@ module Sound.Conductive.MusicalTime where -import Sound.Conductive.ConductiveBaseData-import Data.List.Utils import Data.Map--- import System.Posix.Timer import Data.Time.Clock.POSIX+import Sound.Conductive.ConductiveBaseData -- | a function which displays a musical time with beats to three decimal places, as it's more readable that way...
+ Sound/Conductive/MutableMap.hs view
@@ -0,0 +1,93 @@+------------------------------------------------------------------------------++-- MutableMap.hs+-- created: Mon Mar 29 14:16:46 JST 2010++------------------------------------------------------------------------------++module Sound.Conductive.MutableMap where++import Control.Concurrent.STM+import Control.Monad+import Data.Maybe+import qualified Data.Map as M++type MutableMap t t1 = (TVar (M.Map t t1))++newMMapSingleton :: Ord k => (k, a) -> IO (TVar (M.Map k a))+newMMapSingleton (k,v) = do+ newStore <- newTVarIO $ M.fromList [(k,v)]+ return newStore++newMMap :: Ord k => [(k, a)] -> IO (TVar (M.Map k a))+newMMap kvs = do+ newStore <- newTVarIO $ M.fromList kvs+ return newStore++-- can this be done with fmap instead? if so, is there any advantage to doing so?++withMMap :: TVar t -> (t -> b) -> IO b+withMMap mm func = do+ mmap <- readTVarIO mm+ return $ func mmap++mapMMapIO_ :: TVar (M.Map k a) -> ((k, a) -> IO b) -> IO ()+mapMMapIO_ mm func = do+ mmap <- readTVarIO mm+ mapM_ func $ M.toList mmap++modifyMMap :: TVar a -> (a -> a) -> IO ()+modifyMMap mm func = atomically $ modifyTVar' mm func++addVal :: Ord k => TVar (M.Map k a) -> (k, a) -> IO ()+addVal mm (k,v) = modifyMMap mm $ M.insert k v++addVals :: Ord k => TVar (M.Map k a) -> [(k, a)] -> IO ()+addVals mm kvs = sequence_ $ map (addVal mm) kvs++(+@) :: Ord k => TVar (M.Map k a) -> (k, a) -> IO ()+(+@) mm (k,v) = addVal mm (k,v)++(?@) :: Ord k => TVar (M.Map k a) -> k -> IO (Maybe a)+(?@) mm k = withMMap mm $ M.lookup k++deleteVal :: Ord k => TVar (M.Map k a) -> k -> IO ()+deleteVal mm key = modifyMMap mm $ M.delete key++(-@) :: Ord k => TVar (M.Map k a) -> k -> IO ()+(-@) mm key = deleteVal mm key++copyVal :: Ord k => TVar (M.Map k a) -> k -> k -> IO ()+copyVal mm key newKey = do+ source <- mm ?@ key+ addVal mm (newKey,fromJust source)++changeVal :: Ord k => TVar (M.Map k a) -> (k, a) -> IO ()+changeVal mm (k,v) = addVal mm (k,v)++changeKey :: Ord k => TVar (M.Map k a) -> k -> k -> IO ()+changeKey mm oldKey newKey = do+ copyVal mm oldKey newKey+ deleteVal mm oldKey++keys :: TVar (M.Map k a) -> IO [k]+keys mm = withMMap mm M.keys++elems :: TVar (M.Map k a) -> IO [a]+elems mm = withMMap mm M.elems++withKey :: Ord k => TVar (M.Map k t) -> (t -> a) -> k -> IO (Maybe a)+withKey mm func key = let+ runFunc (Nothing) = Nothing+ runFunc (Just x) = Just (func x)+ in do v <- mm ?@ key+ return $ runFunc v++withKeys :: Ord a => TVar (M.Map a t) -> (t -> a1) -> [a] -> IO [Maybe a1]+withKeys mm func keys = mapM (withKey mm func) keys++withKeys_ :: Ord a => TVar (M.Map a t) -> (t -> a1) -> [a] -> IO ()+withKeys_ mm func keys = mapM_ (withKey mm func) keys++toMap :: TVar a -> IO a+toMap mm = readTVarIO mm
Sound/Conductive/Player.hs view
@@ -1,59 +1,28 @@ ------------------------------------------------------------------------------ --- Player.hs--- created: Fri Oct 1 23:21:08 JST 2010+-- /home/renick/haskell/conductive-0.3c/Player.hs+-- created: Sun Sep 16 22:20:21 JST 2012 ------------------------------------------------------------------------------ --- | This is a collection of functions which are useful for dealing with Players. The Player data type is in the MusicalEnvironment module. +-- | This is a collection of functions which are useful for dealing with Players. -module Sound.Conductive.Player ( addNewPlayer- , displayPlayer- , modifyPlayer- , newPlayer- , newPlayerStore- , pause- , pauseN- , pauseAll- , play- , playN- , playAll- , playAt- , playNAt- , playAllAt- , playAtTimeString- , reset- , resetN- , resetAll- , sleep- , stop- , stopN- , stopAll- , swapActions- , swapBeat- , swapClock- , swapCounter- , swapIOI- , swapInterrupt- , swapName- , swapPauseTime- , swapStatus- , timeDiff- )where+module Sound.Conductive.Player where import Control.Concurrent+import Control.Concurrent.STM import Data.Map import Data.Maybe import Sound.Conductive.ConductiveBaseData-import Sound.Conductive.Generator import Sound.Conductive.MusicalEnvironment import Sound.Conductive.MusicalTime+import Sound.Conductive.MutableMap -- | Displays information about a single player. -displayPlayer :: MVar MusicalEnvironment -> String -> IO ()+displayPlayer :: MusicalEnvironment -> String -> IO () displayPlayer env player = do- p <- getPlayer env player+ Just p <- (playerStore env) ?@ player let pString = concat [ playerName p , " " , show $ playerStatus p@@ -82,7 +51,6 @@ -> Player newPlayer name t deltaf actionf beat = Player { playerName = name- --, playerStatus = "not playing" , playerStatus = Stopped , playerIOI = deltaf , playerCounter = 0@@ -96,221 +64,167 @@ -- | Used to change a player stored in a MusicalEnvironment. -modifyPlayer- :: MVar MusicalEnvironment- -> String- -> (Player -> Player)- -> IO MusicalEnvironment+modifyPlayer :: MusicalEnvironment -> String -> (Player -> Player) -> IO () modifyPlayer e k func = do- p <- getPlayer e k- addPlayer e (k,func p)+ Just p <- (playerStore e) ?@ k+ addVal (playerStore e) (k,func p) +withPlayers :: MusicalEnvironment -> (Player -> a1) -> [String] -> IO [Maybe a1]+withPlayers e func = withKeys (playerStore e) func+ ------------------------------------------------------------------------------ -- the boilerplate for records is annoying. Is there no cleaner way?+---- can I eliminate all of these functions with a cleaner spelling using modifyPlayer directly?+-------------------------------------------------------------------------------- -- functions for updating one record of a player -- | Change the name of a player from old (second argument) to new (third argument). -swapName- :: MVar MusicalEnvironment- -> String- -> String- -> IO MusicalEnvironment+swapName :: MusicalEnvironment -> String -> String -> IO () swapName e k new = modifyPlayer e k $ (\x -> x { playerName = new }) -- | Change the status of a player. -swapStatus- :: MVar MusicalEnvironment- -> String- -> PlayerStatus- -> IO MusicalEnvironment+swapStatus :: MusicalEnvironment -> String -> PlayerStatus -> IO () swapStatus e k new = modifyPlayer e k $ (\x -> x { playerStatus = new }) --- | Change the IOI function of a player from old (second argument) to new (third argument).+-- | Change the IOI function of a player (second argument) from old IOI function to new one (third argument). -swapIOI- :: MVar MusicalEnvironment- -> String- -> String- -> IO MusicalEnvironment+swapIOI :: MusicalEnvironment -> String -> String -> IO () swapIOI e k new = modifyPlayer e k $ (\x -> x { playerIOI = new }) -- | Change the counter value of a player. -swapCounter- :: MVar MusicalEnvironment- -> String- -> Integer- -> IO MusicalEnvironment+swapCounter :: MusicalEnvironment -> String -> Integer -> IO () swapCounter e k new = modifyPlayer e k $ (\x -> x { playerCounter = new }) -- | Change the clock a player is following from old (second argument) to new (third argument). -swapClock- :: MVar MusicalEnvironment- -> String- -> String- -> IO MusicalEnvironment+swapClock :: MusicalEnvironment -> String -> String -> IO () swapClock e k new = modifyPlayer e k $ (\x -> x { playerClock = new }) -- | Change the action function of a player from old (second argument) to new (third argument). -swapActions- :: MVar MusicalEnvironment- -> String- -> String- -> IO MusicalEnvironment+swapActions :: MusicalEnvironment -> String -> String -> IO () swapActions e k new = modifyPlayer e k $ (\x -> x { playerAction = new }) -- | Change the interrupt function of a player from old (second argument) to new (third argument). -swapInterrupt- :: MVar MusicalEnvironment- -> String- -> String- -> IO MusicalEnvironment+swapInterrupt :: MusicalEnvironment -> String -> String -> IO () swapInterrupt e k new = modifyPlayer e k $ (\x -> x { playerInterrupt = new }) -- | Change the beat of the next event of a player. -swapBeat- :: MVar MusicalEnvironment- -> String- -> Double- -> IO MusicalEnvironment+swapBeat :: MusicalEnvironment -> String -> Double -> IO () swapBeat e k new = modifyPlayer e k $ (\x -> x { playerBeat = new }) -- | Change the time of the last pause of a player. -swapPauseTime- :: MVar MusicalEnvironment- -> String- -> Double- -> IO MusicalEnvironment+swapPauseTime :: MusicalEnvironment -> String -> Double -> IO () swapPauseTime e k new = modifyPlayer e k $ (\x -> x { playerPauseTime = new }) ------------------------------------------------------------------------------ -timeDiff :: TempoClock -> Double -> IO Double-timeDiff t b = let- st = timeOfTempoChange $ head $ tempoChanges t- beatDiff = b - (beatOfTempoChange $ head $ tempoChanges t)- in do actualTime <- currentTime- let d = actualTime - st- return $ d - (beatsToDelta t beatDiff)- -- | Plays a player, specified by the string, from a MusicalEnvironment. The start time is determined by the playerBeat field of the player. -play :: MVar MusicalEnvironment -> String -> IO ()-play e player = do- p <- getPlayer e player- if (playerStatus p == Playing)- then putStrLn $ "Player "++player++" is already playing!"- else (forkIO $ basicPlay e player $ playerStatus p) >> return ()+play :: MusicalEnvironment -> String -> IO ()+play e player = let+ statusCheck p Stopped = (forkIO $ basicPlay e player $ Stopped) >> return ()+ statusCheck p Playing = putStrLn $ "Player "++player++" is already Playing!"+ statusCheck p Pausing = sleep 0.01 >> play e player -- why is there a hardcoded sleep here and below?+ statusCheck p Paused = (forkIO $ basicPlay e player $ Paused) >> return ()+ statusCheck p Stopping = sleep 0.01 >> play e player+ statusCheck p Resetting = sleep 0.01 >> play e player+ in do Just p <- (playerStore e) ?@ player+ statusCheck p $ playerStatus p -- | Plays a player, specified by the string, from a MusicalEnvironment. The start time is given in beats as the first argument (the Double), from which the player automatically adjusts the playerBeat record. -playAt :: Double -> MVar MusicalEnvironment -> String -> IO ()+playAt :: Double -> MusicalEnvironment -> String -> IO () playAt beat e player = do- swapBeat e player beat- play e player+ swapBeat e player beat+ play e player -- | Plays a player, specified by the string, from a MusicalEnvironment. The start time is given as a time string as the first argument (the Double), from which the player automatically adjusts the playerBeat record. Time strings are specified in the MusicalTime module. -playAtTimeString- :: [Char] -> MVar MusicalEnvironment -> String -> IO ()+playAtTimeString :: [Char] -> MusicalEnvironment -> String -> IO () playAtTimeString ts e player = do- p <- getPlayer e player- clock <- getTempoClock e $ playerClock p+ Just p <- (playerStore e) ?@ player+ Just clock <- (tempoClockStore e) ?@ (playerClock p) let beat = musicalTimeToBeats clock $ timeStringToMusicalTime ts playAt beat e player +playNow :: MusicalEnvironment -> String -> IO ()+playNow e player = do+ Just p <- (playerStore e) ?@ player+ Just tc <- (tempoClockStore e) ?@ (playerClock p)+ cb <- currentBeat tc+ playAt cb e player++playAtStartOfNMeasure :: MusicalEnvironment -> Int -> String -> IO ()+playAtStartOfNMeasure e measure player = do+ Just p <- (playerStore e) ?@ player+ Just clock <- (tempoClockStore e) ?@ (playerClock p)+ cm <- currentMeasure clock+ let beat = musicalTimeToBeats clock $ MusicalTime {measure = cm + measure, beat = 0.0}+ playAt beat e player+ ------------------------------------------------------------------------------ -- the basicPlay function, number of cases -basicPlay- :: MVar MusicalEnvironment -> String -> PlayerStatus -> IO ()-+basicPlay :: MusicalEnvironment -> String -> PlayerStatus -> IO () basicPlay e player Stopped = do swapStatus e player Playing- p <- getPlayer e player- basicPlay e player $ playerStatus p+ basicPlay e player Playing basicPlay e player Playing = do- p <- getPlayer e player- tc <- getTempoClock e $ playerClock p- diff <- timeDiff tc (playerBeat p) - if (diff < 0)- then do putStrLn $ show player- putStrLn "The beat to play on is in the future!"- putStrLn $ "diff = " ++ show diff- sleep $ abs diff- p1 <- getPlayer e player+ Just p <- (playerStore e) ?@ player+ Just tc <- (tempoClockStore e) ?@ (playerClock p)+ cb <- currentBeat tc+ let pb = playerBeat p+ if (pb > cb)+ then do let diff = pb - cb + putStrLn "\n-------------------------------------------------"+ putStrLn $ "The beat for player " ++ player ++ " to play on is in the future."+ putStrLn $ show player+ putStrLn $ "currentBeat = " ++ show cb+ putStrLn $ "playerBeat = " ++ (show $ playerBeat p)+ putStrLn $ "diff = " ++ (show $ diff)+ putStrLn "Sleeping and trying again at that time."+ putStrLn "-------------------------------------------------\n"+ sleep diff + Just p1 <- (playerStore e) ?@ player basicPlay e player $ playerStatus p1- else do - iOIFunc <- getIOI e $ playerIOI p- beatOfNextEvent <- iOIFunc e p- st <- (timeDiff tc beatOfNextEvent)- let sleepTime = (-1) * st- -- putStrLn $ "sleep time = " ++ show sleepTime- if (sleepTime < 0.025)- then do -- putStrLn "\n"- -- putStrLn "-------------------------------------------------"- -- putStrLn "sleep time was too short!"- -- putStrLn $ playerName p- -- putStrLn $ show tc- -- putStrLn $ "playerBeat = " ++ (show $ playerBeat p)- -- putStrLn $ "nextBeat = " ++ (show $ beatOfNextEvent)- -- putStrLn $ "sleepTime = " ++ show sleepTime- -- putStrLn "-------------------------------------------------"- --swapStatus e player Stopping- --basicPlay e player Stopping- swapBeat e player beatOfNextEvent- p1 <- getPlayer e player- basicPlay e player $ playerStatus p- else do interrupt <- getInterrupt e $ playerInterrupt p- sequence_ interrupt- a <- getAction e $ playerAction p- forkIO $ a e p >> return ()- swapBeat e player beatOfNextEvent- swapCounter e player $ 1 + (playerCounter p)- sleep sleepTime- p1 <- getPlayer e player- basicPlay e player $ playerStatus p+ else do Just interrupt <- (interruptStore e) ?@ (playerInterrupt p)+ sequence_ interrupt+ Just a <- (actionStore e) ?@ (playerAction p)+ Just iOIFunc <- (iOIStore e) ?@ (playerIOI p)+ beatOfNextEvent <- iOIFunc e p pb cb+ forkIO $ a e p cb (beatOfNextEvent - cb) >> return ()+ swapBeat e player beatOfNextEvent+ -- swapCounter e player $ 1 + (playerCounter p)+ sleep $ beatsToDelta tc $ beatOfNextEvent - cb+ Just p1 <- (playerStore e) ?@ player+ basicPlay e player $ playerStatus p basicPlay e player Pausing = do- actualTime <- currentTime- swapPauseTime e player actualTime swapStatus e player Paused- putStrLn "The player has been paused."+ putStrLn $ "Player " ++ player ++ " has been paused." return () basicPlay e player Paused = do- p <- getPlayer e player- tc <- getTempoClock e $ playerClock p- let tmp = head $ tempoChanges tc- t <- currentTime- let beatsSinceChange = deltaToBeats (t - (timeOfTempoChange tmp)) $ newTempo tmp- let currentBeat = (beatOfTempoChange tmp) + beatsSinceChange- swapBeat e player currentBeat swapStatus e player Playing- p <- getPlayer e player- basicPlay e player $ playerStatus p+ basicPlay e player Playing basicPlay e player Stopping = do- swapCounter e player 0- swapBeat e player 0 swapStatus e player Stopped- putStrLn "The player has been stopped."+ putStrLn $ "Player " ++ player ++ " has been stopped." return () basicPlay e player Resetting = do- swapCounter e player 0- swapBeat e player 0 swapStatus e player Stopped- putStrLn "The player has been reset."+ putStrLn $ "Player " ++ player ++ " has been reset." return () -- end of the basicPlay function@@ -318,65 +232,75 @@ -- | Pauses the specified player. -pause :: MVar MusicalEnvironment -> String -> IO ()+pause :: MusicalEnvironment -> String -> IO () pause e player = do- p <- getPlayer e player+ Just p <- (playerStore e) ?@ player if (playerStatus p) == Playing- then do swapStatus e player Pausing >> return ()- else do putStrLn "The player is not playing. Nothing has been done."+ then do actualTime <- currentTime+ swapPauseTime e player actualTime+ swapStatus e player Pausing >> return ()+ else do putStrLn $ "Player " ++ player ++ " is not playing. It cannot be paused." -- | Stops the specified player. Doing so resets both the playerBeat and playerCounter to 0. -stop :: MVar MusicalEnvironment -> String -> IO ()+stop :: MusicalEnvironment -> String -> IO () stop e player = do- p <- getPlayer e player+ Just p <- (playerStore e) ?@ player if (playerStatus p) == Playing- then do swapStatus e player Stopping >> return ()- else do putStrLn "The player is not playing. Nothing has been done."+ then do swapCounter e player 0+ swapBeat e player 0+ swapStatus e player Stopping >> return ()+ else do putStrLn $ "Player " ++ player ++ " is not playing. It cannot be stopped." -- | Resets a paused player. Resetting means setting the playerBeat and playerCounter to 0. -reset :: MVar MusicalEnvironment -> String -> IO ()+reset :: MusicalEnvironment -> String -> IO () reset e player = do- p <- getPlayer e player+ Just p <- (playerStore e) ?@ player if (playerStatus p) == Paused- then do swapStatus e player Resetting- basicPlay e player Resetting- else do putStrLn "The player is not paused. Nothing has been done."+ then do swapCounter e player 0+ swapBeat e player 0+ swapStatus e player Resetting >> return ()+ else do putStrLn $ "Player " ++ player ++ " is not paused, therefore this player cannot be reset." +playN :: MusicalEnvironment -> [String] -> IO () playN e ps = mapM_ (play e) ps +playAll :: MusicalEnvironment -> IO () playAll e = players e >>= \x -> mapM_ (play e) $ x -playNAt e timestring ps = mapM_ (playAtTimeString timestring e) ps+-- the playAt functions appear not to work correctly. why? -playAllAt e timestring = players e >>= \x -> mapM_ (playAtTimeString timestring e) $ x+-- playNAt e timestring ps = mapM_ (playAtTimeString timestring e) ps +-- playAllAt e timestring = players e >>= \x -> mapM_ (playAtTimeString timestring e) $ x++pauseN :: MusicalEnvironment -> [String] -> IO () pauseN e ps = mapM_ (pause e) ps +pauseAll :: MusicalEnvironment -> IO () pauseAll e = players e >>= \x -> mapM_ (pause e) $ x +stopN :: MusicalEnvironment -> [String] -> IO () stopN e ps = mapM_ (stop e) ps +stopAll :: MusicalEnvironment -> IO () stopAll e = players e >>= \x -> mapM_ (stop e) $ x +resetN :: MusicalEnvironment -> [String] -> IO () resetN e ps = mapM_ (reset e) ps +resetAll :: MusicalEnvironment -> IO () resetAll e = players e >>= \x -> mapM_ (reset e) $ x -- | Used for setting up the playerStore of a MusicalEnvironment. It automatically creates one player according to the arguments it is given. -newPlayerStore- :: (String, (String, String, String, Double))- -> Data.Map.Map String Player+newPlayerStore :: (String, (String, String, String, Double)) -> IO (TVar (Map String Player)) newPlayerStore (k,(t, deltaf, actionf, beat)) = let p = newPlayer k t deltaf actionf beat- in fromList [(k,p)]+ in newMMap [(k,p)] -- | Creates a new player from the given arguments and adds it to the MusicalEnvironment. -addNewPlayer- :: MVar MusicalEnvironment- -> (String, (String, String, String, Double))- -> IO MusicalEnvironment-addNewPlayer e (n,(c,d,a,b)) = addPlayer e (n,newPlayer n c d a b)+addNewPlayer :: MusicalEnvironment -> (String, (String, String, String, Double)) -> IO ()+addNewPlayer e (n,(c,d,a,b)) = addVal (playerStore e) (n,newPlayer n c d a b)
Sound/Conductive/Table.hs view
@@ -9,11 +9,12 @@ ,displayPlayers ) where -import Control.Concurrent.MVar import Data.List-import Data.List.Utils+import Data.Maybe import Sound.Conductive.ConductiveBaseData import Sound.Conductive.MusicalEnvironment+import Sound.Conductive.MutableMap+import Sound.Conductive.Player -- | This function creates a text table suitable for printing in ghci or the terminal. --@@ -28,6 +29,9 @@ -- > hi a m k -- > hi a m k +join :: [a] -> [[a]] -> [a]+join delim l = concat (intersperse delim l)+ asciiTable :: [[Char]] -- ^ a list of column headers -> [Char] -- ^ a string containing the character used to separate the data in the columns from the header -> [[[Char]]] -- ^ a list of lists containing column data@@ -51,18 +55,19 @@ ] -playerChartData :: MVar MusicalEnvironment -> IO [[String]] playerChartData e = do ps <- players e- ss <- mapM (withPlayer (\x -> return $ playerStatus x) e) $ ps- cs <- mapM (withPlayer (\x -> return $ playerClock x) e) $ ps- as <- mapM (withPlayer (\x -> return $ playerAction x) e) $ ps- is <- mapM (withPlayer (\x -> return $ playerIOI x) e) $ ps- return [ps,map show ss,cs,as,is]+ ss <- withPlayers e playerStatus ps+ cs <- withPlayers e playerClock ps+ as <- withPlayers e playerAction ps+ is <- withPlayers e playerIOI ps+ let sss = map show ss+ let datum = sss:(map (map fromJust) [cs,as,is])+ return $ ps:datum -- | Uses the asciiTablefunction to create a five-column table of information about players in a MusicalEnvironment. That information is the player name, its status, the clock it follows, and the action and IOI function it uses when played. -displayPlayers :: MVar MusicalEnvironment -> IO ()+displayPlayers :: MusicalEnvironment -> IO () displayPlayers e = let pc = "player" sc = "status"
conductive-base.cabal view
@@ -7,13 +7,13 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented.-Version: 0.2+Version: 0.3 -- A short (one-line) description of the package.-Synopsis: a library for livecoding and real-time musical applications+Synopsis: a library for live coding and real-time musical applications -- A longer description of the package.-Description: Conductive is a set of Haskell libraries for livecoding and real-time music applications. The biggest immediate challenge in using Haskell for computer music was controlling the exact timing of events in a manner similar to that of the Task and Routine functions andPatterns library in SuperCollider. This library is intended to supply such facilities. This library wraps concurrent process manipulation in a way that makes controlling their timing more intuitive for musicians. At the same time, the library aims at being as concise as possible to lessen the burden on the user. Conductive-base is the core library for the Conductive set of libraries. This library includes the useful play, pause, stop, and reset functions, as well as corresponding data types, MusicalEnvironment, Player, and TempoClock.+Description: Conductive is a set of Haskell packages for live coding and real-time music applications. One of its central purposes is controlling the timing of events. Conductive-base is the core library for the Conductive set of libraries. This library includes the play, pause, stop, and reset functions, as well as corresponding data types, MusicalEnvironment, Player, and TempoClock. -- URL for the project homepage or repository. Homepage: http://www.renickbell.net/doku.php?id=conductive-base@@ -45,15 +45,15 @@ -- Extra-source-files: -- Constraint on the version of Cabal needed to build this package.-Cabal-version: >=1.4+Cabal-version: >=1.6 Library -- Modules exported by the library.- Exposed-modules: Sound.Conductive.MusicalEnvironment, Sound.Conductive.ConductiveBase, Sound.Conductive.ConductiveBaseData, Sound.Conductive.ConductiveDefaults, Sound.Conductive.MusicalTime, Sound.Conductive.Generator, Sound.Conductive.Player, Sound.Conductive.MVarUtils, Sound.Conductive.IOI, Sound.Conductive.Table+ Exposed-modules: Sound.Conductive.ConductiveBaseData, Sound.Conductive.ConductiveDefaults, Sound.Conductive.MiscListUtils, Sound.Conductive.MusicalEnvironment, Sound.Conductive.MusicalTime, Sound.Conductive.MutableMap, Sound.Conductive.Player, Sound.Conductive.Table -- Packages needed in order to build this package.- Build-depends: base < 5, containers >=0.3 && < 0.4, time >= 1.1 && < 1.3, MissingH >= 1.1 && < 1.2+ Build-depends: array, base == 4.*, containers, random, stm, time -- Modules not exported by this package. -- Other-modules: