diff options
author | Andrew Cady <d@jerkface.net> | 2014-01-15 02:19:47 -0500 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2014-01-15 02:19:47 -0500 |
commit | fb1f73e37b37d4ee2966554efc0e47aed0fcb5c9 (patch) | |
tree | bf96ab9856202774e1ad5a48ec2e76d2614229a9 /midi-dump.hs | |
parent | 01148ed6fbd490e295e0aba31a7b87a393d779d0 (diff) |
output the set of midi pitches being played
Diffstat (limited to 'midi-dump.hs')
-rw-r--r-- | midi-dump.hs | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/midi-dump.hs b/midi-dump.hs index 2534fd4..d0bde4e 100644 --- a/midi-dump.hs +++ b/midi-dump.hs | |||
@@ -1,6 +1,3 @@ | |||
1 | import Control.Monad (forever, ) | ||
2 | import Control.Monad (mplus, ) | ||
3 | import Data.Maybe.HT (toMaybe, ) | ||
4 | import qualified Sound.ALSA.Exception as AlsaExc | 1 | import qualified Sound.ALSA.Exception as AlsaExc |
5 | import qualified Sound.ALSA.Sequencer.Address as Addr | 2 | import qualified Sound.ALSA.Sequencer.Address as Addr |
6 | import qualified Sound.ALSA.Sequencer as SndSeq | 3 | import qualified Sound.ALSA.Sequencer as SndSeq |
@@ -16,14 +13,27 @@ import qualified Sound.ALSA.Sequencer.Time as Time | |||
16 | import qualified System.Exit as Exit | 13 | import qualified System.Exit as Exit |
17 | import qualified System.IO as IO | 14 | import qualified System.IO as IO |
18 | import System.Environment (getArgs, ) | 15 | import System.Environment (getArgs, ) |
16 | import Text.Printf | ||
19 | 17 | ||
20 | main :: IO () | 18 | import qualified Data.Set as Set |
21 | main = (do | 19 | |
20 | printWords [] = return () | ||
21 | printWords ls = putStrLn $ foldr1 (\a b -> a ++ " " ++ b) ls | ||
22 | |||
23 | pitchWords set = map (show . Event.unPitch) $ Set.toList set | ||
24 | |||
25 | prettyNote :: Event.Note -> String | ||
26 | prettyNote (Event.Note noteChannel noteNote noteVelocity noteOffVelocity noteDuration) = | ||
27 | let pitch = Event.unPitch noteNote | ||
28 | vlcty = Event.unVelocity noteVelocity | ||
29 | in | ||
30 | printf "%d (%d)" pitch vlcty | ||
31 | |||
32 | alsaInit k = do | ||
22 | SndSeq.withDefault SndSeq.Block $ \h -> do | 33 | SndSeq.withDefault SndSeq.Block $ \h -> do |
23 | Client.setName (h :: SndSeq.T SndSeq.DuplexMode) "Haskell-Beat" | 34 | Client.setName (h :: SndSeq.T SndSeq.DuplexMode) "Haskell-Beat" |
24 | Port.withSimple h "inout" | 35 | Port.withSimple h "inout" |
25 | (Port.caps [Port.capRead, Port.capSubsRead, | 36 | (Port.caps [Port.capRead, Port.capSubsRead, Port.capWrite, Port.capSubsWrite]) |
26 | Port.capWrite, Port.capSubsWrite]) | ||
27 | (Port.types [Port.typeMidiGeneric, Port.typeApplication]) $ \public -> do | 37 | (Port.types [Port.typeMidiGeneric, Port.typeApplication]) $ \public -> do |
28 | Port.withSimple h "private" | 38 | Port.withSimple h "private" |
29 | (Port.caps [Port.capRead, Port.capWrite]) | 39 | (Port.caps [Port.capRead, Port.capWrite]) |
@@ -39,25 +49,31 @@ main = (do | |||
39 | let publicAddr = Addr.Cons c public | 49 | let publicAddr = Addr.Cons c public |
40 | privateAddr = Addr.Cons c private | 50 | privateAddr = Addr.Cons c private |
41 | 51 | ||
52 | k h public private q publicAddr privateAddr | ||
53 | |||
54 | main :: IO () | ||
55 | main = (do | ||
56 | |||
57 | alsaInit $ \h public private q publicAddr privateAddr -> do | ||
58 | |||
42 | args <- getArgs | 59 | args <- getArgs |
43 | case args of | 60 | case args of |
44 | [input, output] -> | 61 | |
62 | [input, output] -> do | ||
45 | (Connect.createFrom h public =<< Addr.parse h input) | 63 | (Connect.createFrom h public =<< Addr.parse h input) |
46 | >> | ||
47 | (Connect.createTo h public =<< Addr.parse h output) | 64 | (Connect.createTo h public =<< Addr.parse h output) |
48 | >> | ||
49 | return () | 65 | return () |
50 | _ -> | 66 | |
67 | _ -> do | ||
51 | IO.hPutStrLn IO.stderr "need arguments: input-client output-client" | 68 | IO.hPutStrLn IO.stderr "need arguments: input-client output-client" |
52 | >> | ||
53 | Exit.exitFailure | 69 | Exit.exitFailure |
54 | 70 | ||
55 | let wait = do | 71 | let wait keysDown = do |
56 | ev <- Event.input h | 72 | ev <- Event.input h |
57 | case Event.body ev of | 73 | case Event.body ev of |
58 | Event.NoteEv Event.NoteOn n -> return (Event.NoteOn, n) | 74 | Event.NoteEv Event.NoteOn n -> return (Event.NoteOn, n, Set.insert (Event.noteNote n) keysDown) |
59 | Event.NoteEv Event.NoteOff n -> return (Event.NoteOff, n) | 75 | Event.NoteEv Event.NoteOff n -> return (Event.NoteOff, n, Set.delete (Event.noteNote n) keysDown) |
60 | _ -> wait | 76 | _ -> wait keysDown |
61 | 77 | ||
62 | Queue.control h q Event.QueueStart Nothing | 78 | Queue.control h q Event.QueueStart Nothing |
63 | 79 | ||
@@ -67,13 +83,14 @@ main = (do | |||
67 | Event.time = Time.consAbs $ Time.Real $ RealTime.fromDouble 0 | 83 | Event.time = Time.consAbs $ Time.Real $ RealTime.fromDouble 0 |
68 | } | 84 | } |
69 | 85 | ||
70 | let go = do | 86 | let go keysDown = do |
71 | (onoff, note) <- wait | 87 | (onoff, note, down) <- wait keysDown |
72 | print note | 88 | --putStrLn $ prettyNote note |
89 | printWords $ pitchWords down | ||
73 | Event.output h $ mkEv $ Event.NoteEv onoff note | 90 | Event.output h $ mkEv $ Event.NoteEv onoff note |
74 | _ <- Event.drainOutput h | 91 | _ <- Event.drainOutput h |
75 | go | 92 | go down |
76 | 93 | ||
77 | go) | 94 | go Set.empty) |
78 | `AlsaExc.catch` \e -> | 95 | `AlsaExc.catch` \e -> |
79 | putStrLn $ "alsa_exception: " ++ AlsaExc.show e | 96 | putStrLn $ "alsa_exception: " ++ AlsaExc.show e |