diff options
Diffstat (limited to 'trivmix/Trivmix.hs')
-rw-r--r-- | trivmix/Trivmix.hs | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/trivmix/Trivmix.hs b/trivmix/Trivmix.hs index 7c18965..b9474f2 100644 --- a/trivmix/Trivmix.hs +++ b/trivmix/Trivmix.hs | |||
@@ -172,11 +172,12 @@ trivmix Options{..} = do | |||
172 | level <- newMVar initialLevel | 172 | level <- newMVar initialLevel |
173 | balance <- newMVar initialBalance | 173 | balance <- newMVar initialBalance |
174 | level' <- newMVar 0 | 174 | level' <- newMVar 0 |
175 | stderrLock <- newEmptyMVar | ||
175 | let withFiles = foldl (.) id $ map (\f -> onStateFile f (show initialLevel ++ "\n")) levelFiles | 176 | let withFiles = foldl (.) id $ map (\f -> onStateFile f (show initialLevel ++ "\n")) levelFiles |
176 | ++ map (\f -> onStateFile f (show initialBalance ++ "\n")) balanceFiles | 177 | ++ map (\f -> onStateFile f (show initialBalance ++ "\n")) balanceFiles |
177 | withFiles $ withINotify $ \inotify -> do | 178 | withFiles $ withINotify $ \inotify -> do |
178 | handleFiles inotify level levelFiles | 179 | handleFiles inotify level levelFiles |
179 | handleFiles inotify balance levelFiles | 180 | handleFiles inotify balance balanceFiles |
180 | Jack.handleExceptions $ | 181 | Jack.handleExceptions $ |
181 | Jack.withClientDefault client $ \client' -> | 182 | Jack.withClientDefault client $ \client' -> |
182 | Jack.withPort client' input $ \input' -> | 183 | Jack.withPort client' input $ \input' -> |
@@ -196,18 +197,19 @@ trivmix Options{..} = do | |||
196 | currentLevel <- (\(CFloat f) -> Lin . either error id . refine $ realToFrac f) <$> readMVar level' | 197 | currentLevel <- (\(CFloat f) -> Lin . either error id . refine $ realToFrac f) <$> readMVar level' |
197 | case compare currentLevel newLevel of | 198 | case compare currentLevel newLevel of |
198 | EQ -> threadDelay . round $ interval * 1e6 | 199 | EQ -> threadDelay . round $ interval * 1e6 |
199 | _ -> mapM_ (\x -> (swapMVar level' $! toRealFloat . unrefine . toLin $ linInt' x currentLevel newLevel) >> threadDelay delay) (takeWhile (<= 1) $ iterate (+ recip frames) 0) | 200 | _ -> do |
201 | mapM_ (\x -> (swapMVar level' $! toRealFloat . unrefine . toLin $ linInt' x currentLevel newLevel) >> threadDelay delay) (takeWhile (<= 1) $ iterate (+ recip frames) 0) | ||
202 | withMVarLock stderrLock . hPutStrLn stderr $ "Finished smooth transition from ‘" ++ show currentLevel ++ "’ to ‘" ++ show newLevel ++ "’." | ||
200 | notifyReady | 203 | notifyReady |
201 | forever $ threadDelay (round $ watchdogInterval * 1e6) >> notifyWatchdog | 204 | forever $ threadDelay (round $ watchdogInterval * 1e6) >> notifyWatchdog |
202 | 205 | ||
203 | mix :: MVar CFloat -> CFloat -> IO CFloat | 206 | mix :: MVar CFloat -> CFloat -> IO CFloat |
204 | mix level input = (input *) <$> readMVar level | 207 | mix level input = (input *) <$> readMVar level |
205 | 208 | ||
206 | handleFiles :: (Read l, Show l, Eq l) => INotify -> MVar l -> [FilePath] -> IO () | 209 | handleFiles :: (Read l, Show l, Eq l) => INotify -> MVar l -> MVar () -> [FilePath] -> IO () |
207 | handleFiles inotify level files = do | 210 | handleFiles inotify level stderrLock files = do |
208 | initLevel <- readMVar level | 211 | initLevel <- readMVar level |
209 | levelChanges <- newChan | 212 | levelChanges <- newChan |
210 | stderrLock <- newEmptyMVar | ||
211 | let | 213 | let |
212 | handleFile file = addWatch inotify watchedAttrs file (const $ readLevel levelChanges level file stderrLock) | 214 | handleFile file = addWatch inotify watchedAttrs file (const $ readLevel levelChanges level file stderrLock) |
213 | mapM_ handleFile files | 215 | mapM_ handleFile files |
@@ -227,19 +229,19 @@ onStateFile file initial action = do | |||
227 | setFileCreationMask nullFileMode | 229 | setFileCreationMask nullFileMode |
228 | let acquireFile = case exists of | 230 | let acquireFile = case exists of |
229 | True -> return () | 231 | True -> return () |
230 | False -> do | 232 | False -> withMVarLock stderrLock $ do |
231 | hPutStrLn stderr $ "Creating ‘" ++ file ++ "’ (file)" | 233 | hPutStrLn stderr $ "Creating ‘" ++ file ++ "’ (file)" |
232 | createFile file defFileMode >>= closeFd >> writeFile file initial | 234 | createFile file defFileMode >>= closeFd >> writeFile file initial |
233 | releaseFile = case exists of | 235 | releaseFile = case exists of |
234 | True -> return () | 236 | True -> return () |
235 | False -> do | 237 | False -> withMVarLock stderrLock $ do |
236 | hPutStrLn stderr $ "Removing ‘" ++ file ++ "’ (file)" | 238 | hPutStrLn stderr $ "Removing ‘" ++ file ++ "’ (file)" |
237 | removeFile file | 239 | removeFile file |
238 | acquireDir = (flip mapM) (reverse createDirs) $ \directory -> do | 240 | acquireDir = (flip mapM) (reverse createDirs) $ \directory -> withMVarLock stderrLock $ do |
239 | hPutStrLn stderr $ "Creating ‘" ++ directory ++ "’ (dir)" | 241 | hPutStrLn stderr $ "Creating ‘" ++ directory ++ "’ (dir)" |
240 | createDirectory directory | 242 | createDirectory directory |
241 | setFileMode directory defDirectoryMode | 243 | setFileMode directory defDirectoryMode |
242 | releaseDir = (flip mapM) createDirs $ \directory -> do | 244 | releaseDir = (flip mapM) createDirs $ \directory -> withMVarLock stderrLock $ do |
243 | hPutStrLn stderr $ "Removing ‘" ++ directory ++ "’ (dir)" | 245 | hPutStrLn stderr $ "Removing ‘" ++ directory ++ "’ (dir)" |
244 | removeDirectory directory | 246 | removeDirectory directory |
245 | acquire = acquireDir >> acquireFile | 247 | acquire = acquireDir >> acquireFile |