summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2015-12-05 01:07:46 -0500
committerAndrew Cady <d@jerkface.net>2015-12-05 01:10:53 -0500
commit7dd4353d51eec254965ac23de085d829df94c05d (patch)
treeba6e31e5ed1e19a968a32526a51406aa25d10490
parent05f25fe9b784e49099bde8b718147fcec1a0a9d7 (diff)
Fix all hlint and GHC warnings.
-rw-r--r--midi-dump.hs41
1 files changed, 31 insertions, 10 deletions
diff --git a/midi-dump.hs b/midi-dump.hs
index dd59a96..146ac5d 100644
--- a/midi-dump.hs
+++ b/midi-dump.hs
@@ -1,6 +1,8 @@
1{-# LANGUAGE FlexibleContexts #-} 1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleInstances #-} 2{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE OverloadedStrings #-} 3{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE ScopedTypeVariables #-}
5{-# LANGUAGE KindSignatures #-}
4 6
5import AlsaSeq 7import AlsaSeq
6import Control.Monad.RWS.Strict 8import Control.Monad.RWS.Strict
@@ -27,8 +29,10 @@ import qualified Sound.ALSA.Sequencer.Address
27import qualified Sound.ALSA.Sequencer.Port 29import qualified Sound.ALSA.Sequencer.Port
28import qualified Sound.ALSA.Sequencer.Queue 30import qualified Sound.ALSA.Sequencer.Queue
29 31
32verbose :: Bool
30verbose = False 33verbose = False
31 34
35main :: IO ()
32main = main' `AlsaExc.catch` handler 36main = main' `AlsaExc.catch` handler
33 where 37 where
34 handler e = when verbose $ putStrLn $ "alsa_exception: " ++ AlsaExc.show e 38 handler e = when verbose $ putStrLn $ "alsa_exception: " ++ AlsaExc.show e
@@ -53,6 +57,7 @@ data LoopState = LoopState {
53 lastTick :: TimeSpec 57 lastTick :: TimeSpec
54} 58}
55 59
60initializeState :: TimeSpec -> LoopState
56initializeState now = LoopState False Set.empty [] (emptyRecording now) now 61initializeState now = LoopState False Set.empty [] (emptyRecording now) now
57 62
58data LoopEnv = LoopEnv { 63data LoopEnv = LoopEnv {
@@ -70,12 +75,14 @@ data LoopEnv = LoopEnv {
70 _lineReader :: MVar String 75 _lineReader :: MVar String
71} 76}
72 77
78getAbsTime :: RWST LoopEnv () LoopState IO TimeSpec
73getAbsTime = do 79getAbsTime = do
74 startTime <- asks _startTime 80 startTime <- asks _startTime
75 startTimeReal <- asks _startTimeReal 81 startTimeReal <- asks _startTimeReal
76 now <- liftIO $ getTime Monotonic 82 now <- liftIO $ getTime Monotonic
77 return $ now - startTime + startTimeReal 83 return $ now - startTime + startTimeReal
78 84
85createTable :: Query
79createTable = fromString $ concat 86createTable = fromString $ concat
80 ["CREATE TABLE IF NOT EXISTS axis_input", 87 ["CREATE TABLE IF NOT EXISTS axis_input",
81 " (id INTEGER PRIMARY KEY,", 88 " (id INTEGER PRIMARY KEY,",
@@ -86,6 +93,7 @@ createTable = fromString $ concat
86 " leading_silence INTEGER,", 93 " leading_silence INTEGER,",
87 " midi BLOB)"] 94 " midi BLOB)"]
88 95
96main' :: IO ()
89main' = withAlsaInit $ \h public private q publicAddr privateAddr -> do 97main' = withAlsaInit $ \h public private q publicAddr privateAddr -> do
90 cmdlineAlsaConnect h public 98 cmdlineAlsaConnect h public
91 99
@@ -105,6 +113,7 @@ main' = withAlsaInit $ \h public private q publicAddr privateAddr -> do
105 (_, ()) <- execRWST mainLoop env $ initializeState startTimeReal 113 (_, ()) <- execRWST mainLoop env $ initializeState startTimeReal
106 return () 114 return ()
107 115
116mainLoop :: RWST LoopEnv () LoopState IO ()
108mainLoop = do 117mainLoop = do
109 maybeReadLine >>= maybe processMidi processCommand 118 maybeReadLine >>= maybe processMidi processCommand
110 wantExit <- gets _wantExit 119 wantExit <- gets _wantExit
@@ -117,17 +126,21 @@ mainLoop = do
117 126
118 unless wantExit mainLoop 127 unless wantExit mainLoop
119 128
120playNote noteOn note = 129_playNote :: Bool -> Event.Note -> RWST LoopEnv () LoopState IO ()
130_playNote noteOn note =
121 playNoteEv $ Event.NoteEv onoff note 131 playNoteEv $ Event.NoteEv onoff note
122 where onoff = if noteOn then Event.NoteOn else Event.NoteOff 132 where onoff = if noteOn then Event.NoteOn else Event.NoteOff
123 133
134playNoteEv :: Event.Data -> RWST LoopEnv () LoopState IO ()
124playNoteEv nevdata = do 135playNoteEv nevdata = do
125 ms <- getMidiSender 136 ms <- getMidiSender
126 publicAddr <- asks _publicAddr 137 publicAddr <- asks _publicAddr
127 liftIO $ ms $ Event.simple publicAddr nevdata 138 liftIO $ ms $ Event.simple publicAddr nevdata
128 139
129whenFlag flag f = gets flag >>= flip when f 140_whenFlag :: forall (m :: * -> *) s. MonadState s m => (s -> Bool) -> m () -> m ()
141_whenFlag flag f = gets flag >>= flip when f
130 142
143processCommand :: forall (m :: * -> *). (MonadIO m, MonadState LoopState m) => String -> m ()
131processCommand "exit" = modify $ \s -> s { _wantExit = True } 144processCommand "exit" = modify $ \s -> s { _wantExit = True }
132processCommand "" = return () 145processCommand "" = return ()
133processCommand "C" = do 146processCommand "C" = do
@@ -136,12 +149,14 @@ processCommand "C" = do
136 modify $ \s -> s { _playNOW = notes } 149 modify $ \s -> s { _playNOW = notes }
137processCommand str = liftIO $ putStrLn $ "Unknown command: " ++ str 150processCommand str = liftIO $ putStrLn $ "Unknown command: " ++ str
138 151
152getMidiSender :: RWST LoopEnv () LoopState IO MidiHook
139getMidiSender = do 153getMidiSender = do
140 h <- asks _h 154 h <- asks _h
141 q <- asks _q 155 q <- asks _q
142 publicAddr <- asks _publicAddr 156 publicAddr <- asks _publicAddr
143 return $ forwardNoteEvent h q publicAddr 157 return $ forwardNoteEvent h q publicAddr
144 158
159processMidi :: RWST LoopEnv () LoopState IO ()
145processMidi = do 160processMidi = do
146 h <- asks _h 161 h <- asks _h
147 oldKeys <- gets keysDown 162 oldKeys <- gets keysDown
@@ -164,12 +179,16 @@ processMidi = do
164 when doSave $ gets _recording >>= saveMidi >> return () 179 when doSave $ gets _recording >>= saveMidi >> return ()
165 modify $ \s -> s { _recording = emptyRecording now } 180 modify $ \s -> s { _recording = emptyRecording now }
166 181
182emptyRecording :: TimeSpec -> Recording
167emptyRecording now = Recording now [] 183emptyRecording now = Recording now []
168 184
185maybeReadLine :: RWST LoopEnv () LoopState IO (Maybe String)
169maybeReadLine = asks _lineReader >>= liftIO . tryTakeMVar 186maybeReadLine = asks _lineReader >>= liftIO . tryTakeMVar
187
188startLineReader :: IO (MVar String)
170startLineReader = do 189startLineReader = do
171 mv <- liftIO newEmptyMVar 190 mv <- liftIO newEmptyMVar
172 thread <- liftIO $ forkIO (forever $ tryIOError getLine >>= either (const $ putMVar mv "exit") (putMVar mv)) 191 _thread <- liftIO $ forkIO (forever $ tryIOError getLine >>= either (const $ putMVar mv "exit") (putMVar mv))
173 return mv 192 return mv
174 193
175data Chunk = Chunk Int64 Int64 Int64 Int64 Int64 BS.ByteString 194data Chunk = Chunk Int64 Int64 Int64 Int64 Int64 BS.ByteString
@@ -185,11 +204,13 @@ instance ToRow Chunkable where
185 (FinishedRecording (Recording start@(TimeSpec s ns) midi) (TimeSpec s' ns')) = reco 204 (FinishedRecording (Recording start@(TimeSpec s ns) midi) (TimeSpec s' ns')) = reco
186 leadingSilence = fromIntegral $ timeSpecAsNanoSecs $ ts - start 205 leadingSilence = fromIntegral $ timeSpecAsNanoSecs $ ts - start
187 206
207saveMidi :: forall (m :: * -> *). (MonadIO m, MonadState LoopState m, MonadReader LoopEnv m) => Recording -> m ()
188saveMidi recording = do 208saveMidi recording = do
189 saver <- asks _saver 209 saver <- asks _saver
190 end <- gets lastTick 210 end <- gets lastTick
191 liftIO $ writeChan saver $ FinishedRecording recording end 211 liftIO $ writeChan saver $ FinishedRecording recording end
192 212
213startSaver :: forall (m :: * -> *). MonadIO m => Connection -> m (Chan FinishedRecording)
193startSaver sqlite = do 214startSaver sqlite = do
194 chan <- liftIO newChan 215 chan <- liftIO newChan
195 _thread <- liftIO $ forkIO (saver chan) 216 _thread <- liftIO $ forkIO (saver chan)
@@ -203,14 +224,14 @@ startSaver sqlite = do
203 return () 224 return ()
204 225
205 226
206getMidiDesc :: Event.T -> Maybe String 227_getMidiDesc :: Event.T -> Maybe String
207getMidiDesc (Event.Cons _ _ _ _ _ _ (Event.NoteEv Event.NoteOn ev)) = return $ ("on:" ++) $ showPitch $ unPitch $ Event.noteNote ev 228_getMidiDesc (Event.Cons _ _ _ _ _ _ (Event.NoteEv Event.NoteOn ev)) = return $ ("on:" ++) $ showPitch $ unPitch $ Event.noteNote ev
208getMidiDesc (Event.Cons _ _ _ _ _ _ (Event.NoteEv Event.NoteOff ev)) = return $ ("off:" ++) $ showPitch $ unPitch $ Event.noteNote ev 229_getMidiDesc (Event.Cons _ _ _ _ _ _ (Event.NoteEv Event.NoteOff ev)) = return $ ("off:" ++) $ showPitch $ unPitch $ Event.noteNote ev
209getMidiDesc _ = Nothing 230_getMidiDesc _ = Nothing
210 231
211tsDeltas :: [TimeSpec] -> [Integer] 232_tsDeltas :: [TimeSpec] -> [Integer]
212tsDeltas [] = [] 233_tsDeltas [] = []
213tsDeltas ls@(x:_) = zipWith (-) nsecs (0:nsecs) 234_tsDeltas ls@(x:_) = zipWith (-) nsecs (0:nsecs)
214 where 235 where
215 nsecs = map timeSpecAsNanoSecs rel 236 nsecs = map timeSpecAsNanoSecs rel
216 rel = map (\y -> y - x) ls 237 rel = map (\y -> y - x) ls