summaryrefslogtreecommitdiff
path: root/midi-dump.hs
blob: 7d6d2384cb90285b372e4b06e8d9f98c8702749b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import AlsaSeq
import Control.Concurrent (threadDelay)
import qualified Sound.ALSA.Exception as AlsaExc
import qualified Data.Set as Set
import qualified Haskore.Basic.Pitch as Pitch
import qualified Sound.ALSA.Sequencer.Event as Event
import Control.Monad.RWS.Strict
import Data.Maybe
import Data.List

main = main' `AlsaExc.catch` handler
  where
  handler e = putStrLn $ "alsa_exception: " ++ AlsaExc.show e

data LoopState = LoopState {
  keysDown :: MidiPitchSet,
  inputHistory :: [Maybe Event.T]
}

emptyLoopState = LoopState Set.empty []

main' = withAlsaInit $ \h public private q publicAddr privateAddr -> do
  cmdlineAlsaConnect h public

  putStrLn "Rock on!"

  (_, ()) <- execRWST loop (h, public, private, q, publicAddr, privateAddr) emptyLoopState
  return ()

loop = do
  (h, _, _, q, publicAddr, _) <- ask
  oldKeys <- gets keysDown
  let forwardNOW = forwardNoteEvent h q publicAddr
  (events, newKeys) <- liftIO $ parseAlsaEvents' h oldKeys forwardNOW

  if (oldKeys == newKeys) then
    liftIO $ threadDelay 15000 -- 15ms.  Seems like a lot, but it sounds OK.  Cuts CPU down to 2%.
  else do
    let newEvents = map Just events

    liftIO $ printChordLn newKeys
    modify $ \s -> s { keysDown = newKeys, inputHistory = newEvents ++ inputHistory s }

    when (Set.null newKeys) $ do
      hist <- gets (takeWhile isJust . inputHistory)
      liftIO $ print hist
      modify $ \s -> s { inputHistory = Nothing:inputHistory s }

  loop