diff options
author | Andrew Cady <d@jerkface.net> | 2014-01-15 11:27:14 -0500 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2014-01-15 11:27:14 -0500 |
commit | 53ee5dfebc44c84c4a67581655686426eef51986 (patch) | |
tree | 9acaac9b7c6d146f95eb2573663869d6d722dcfd /midi-dump.hs | |
parent | 134a30530c8bccf3df9943796742351c0bed00bf (diff) |
factor out new function: parseAlsaEvents
Diffstat (limited to 'midi-dump.hs')
-rw-r--r-- | midi-dump.hs | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/midi-dump.hs b/midi-dump.hs index 50f0020..b94b178 100644 --- a/midi-dump.hs +++ b/midi-dump.hs | |||
@@ -21,6 +21,7 @@ import Control.Monad (when, forM_, forM) | |||
21 | import qualified Data.Set as Set | 21 | import qualified Data.Set as Set |
22 | import Data.List (group, sort) | 22 | import Data.List (group, sort) |
23 | import Haskore.Basic.Pitch | 23 | import Haskore.Basic.Pitch |
24 | import Control.Concurrent (threadDelay) | ||
24 | 25 | ||
25 | joinWords [] = "" | 26 | joinWords [] = "" |
26 | joinWords ls = foldr1 (\a b -> a ++ " " ++ b) ls | 27 | joinWords ls = foldr1 (\a b -> a ++ " " ++ b) ls |
@@ -106,37 +107,44 @@ cmdlineAlsaConnect h public = do | |||
106 | IO.hPutStrLn IO.stderr "need arguments: input-port output-port" | 107 | IO.hPutStrLn IO.stderr "need arguments: input-port output-port" |
107 | Exit.exitFailure | 108 | Exit.exitFailure |
108 | 109 | ||
110 | parseAlsaEvents h keysDown immediate = loop keysDown | ||
111 | where | ||
112 | loop keysDown = do | ||
113 | pending <- Event.inputPending h True | ||
114 | if (pending == 0) then | ||
115 | return keysDown | ||
116 | else do | ||
117 | ev <- Event.input h | ||
118 | case Event.body ev of | ||
119 | Event.NoteEv Event.NoteOn n -> do | ||
120 | immediate Event.NoteEv Event.NoteOn n | ||
121 | loop (Set.insert (Event.noteNote n) keysDown) | ||
122 | Event.NoteEv Event.NoteOff n -> do | ||
123 | immediate Event.NoteEv Event.NoteOff n | ||
124 | loop (Set.delete (Event.noteNote n) keysDown) | ||
125 | _ -> loop keysDown | ||
126 | |||
109 | main :: IO () | 127 | main :: IO () |
110 | main = (do | 128 | main = (do |
111 | 129 | ||
112 | alsaInit $ \h public private q publicAddr privateAddr -> do | 130 | alsaInit $ \h public private q publicAddr privateAddr -> do |
113 | cmdlineAlsaConnect h public | 131 | cmdlineAlsaConnect h public |
114 | 132 | ||
115 | let wait keysDown = do | ||
116 | pending <- Event.inputPending h True | ||
117 | if (pending > 0) | ||
118 | then do | ||
119 | ev <- Event.input h | ||
120 | case Event.body ev of | ||
121 | Event.NoteEv Event.NoteOn n -> return (Event.NoteOn, n, Set.insert (Event.noteNote n) keysDown) | ||
122 | Event.NoteEv Event.NoteOff n -> return (Event.NoteOff, n, Set.delete (Event.noteNote n) keysDown) | ||
123 | _ -> wait keysDown | ||
124 | else | ||
125 | wait keysDown | ||
126 | |||
127 | let mkEv e = | 133 | let mkEv e = |
128 | (Event.simple publicAddr e) { | 134 | (Event.simple publicAddr e) { |
129 | Event.queue = q, | 135 | Event.queue = q, |
130 | Event.time = Time.consAbs $ Time.Real $ RealTime.fromDouble 0 | 136 | Event.time = Time.consAbs $ Time.Real $ RealTime.fromDouble 0 |
131 | } | 137 | } |
132 | 138 | ||
133 | let go keysDown = do | 139 | let |
134 | (onoff, note, down) <- wait keysDown | 140 | go keysDown = do |
135 | --putStrLn $ prettyNote note | 141 | let immediate = \a b c -> do { Event.output h $ mkEv $ a b c; _ <- Event.drainOutput h; return (); } |
136 | printWords $ pitchWords down | 142 | keysDown' <- parseAlsaEvents h keysDown immediate |
137 | Event.output h $ mkEv $ Event.NoteEv onoff note | 143 | if (keysDown == keysDown') then |
138 | _ <- Event.drainOutput h | 144 | threadDelay 15000 -- 15ms. Seems like a lot, but it sounds OK. Cuts CPU down to 2%. |
139 | go down | 145 | else do |
146 | printWords $ pitchWords keysDown' | ||
147 | go keysDown' | ||
140 | 148 | ||
141 | putStrLn "Rock on!" | 149 | putStrLn "Rock on!" |
142 | go Set.empty) | 150 | go Set.empty) |