module Sound.Conductive.Generator where
import Control.Concurrent.MVar
import Data.IORef
import Data.Map
import Data.Maybe
import Sound.Conductive.ConductiveBaseData
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
}
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)
getCount :: Generator a -> IO Int
getCount generator = do
c <- readIORef $ generatorCounter generator
return $ c + 1
getGeneratorSource :: Generator a -> IO [a]
getGeneratorSource generator = readMVar $ generatorSource generator
resetCounter :: Generator a -> IO ()
resetCounter generator = writeIORef (generatorCounter generator) (1)
next :: Generator a -> IO a
next generator = nextWithOffset 0 generator
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)
nexts :: [Generator b] -> IO [b]
nexts generators = mapM next generators
withNext :: Generator a -> (a -> b) -> IO b
withNext generator function = fmap function $ next generator
newGeneratorStore
:: (Ord t) => (t, [a]) -> IO (Data.Map.Map t (Generator a))
newGeneratorStore (k,s) = do
g <- newGenerator s
return $ fromList [(k,g)]
defaultGeneratorStore
:: IO (Data.Map.Map [Char] (Generator Double))
defaultGeneratorStore = newGeneratorStore ("default",[1.0])