summaryrefslogtreecommitdiff
path: root/midi-dump.hs
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2014-01-14 08:06:00 -0500
committerAndrew Cady <d@jerkface.net>2014-01-14 08:06:05 -0500
commite7547448ce9d4af01cd2a78036606f123a25cfaf (patch)
tree48d3f9780e3ec6895d147ecc94b0d23bd64e4a09 /midi-dump.hs
parentfcf7062c5ecbda5d2815caea624e1e04cc8be557 (diff)
axis --> fluidsynth alsa proxy works!
Diffstat (limited to 'midi-dump.hs')
-rw-r--r--midi-dump.hs136
1 files changed, 68 insertions, 68 deletions
diff --git a/midi-dump.hs b/midi-dump.hs
index 4d1946c..74b9596 100644
--- a/midi-dump.hs
+++ b/midi-dump.hs
@@ -1,82 +1,82 @@
1import Control.Monad (forever, )
2import Control.Monad (mplus, )
3import Data.Maybe.HT (toMaybe, )
4import qualified Sound.ALSA.Exception as AlsaExc
5import qualified Sound.ALSA.Sequencer.Address as Addr
6import qualified Sound.ALSA.Sequencer as SndSeq
1import qualified Sound.ALSA.Sequencer.Client as Client 7import qualified Sound.ALSA.Sequencer.Client as Client
2import qualified Sound.ALSA.Sequencer.Port as Port 8import qualified Sound.ALSA.Sequencer.Connect as Connect
3import qualified Sound.ALSA.Sequencer.Event as Event 9import qualified Sound.ALSA.Sequencer.Event as Event
4import qualified Sound.ALSA.Sequencer as SndSeq 10import qualified Sound.ALSA.Sequencer.Event.RemoveMonad as Remove
5import qualified Sound.ALSA.Exception as AlsaExc
6import Control.Monad (forever, )
7
8
9import qualified Sound.ALSA.Sequencer.Client.Info as ClientInfo
10import qualified Sound.ALSA.Sequencer.Port.Info as PortInfo
11import qualified Sound.ALSA.Sequencer.Port as Port 11import qualified Sound.ALSA.Sequencer.Port as Port
12import qualified Data.EnumSet as EnumSet 12import qualified Sound.ALSA.Sequencer.Port.InfoMonad as PortInfo
13import Text.Printf (printf, ) 13import qualified Sound.ALSA.Sequencer.Queue as Queue
14import Control.Monad (liftM5, liftM2, join, when, filterM, forM_) 14import qualified Sound.ALSA.Sequencer.RealTime as RealTime
15import qualified Sound.ALSA.Sequencer.Time as Time
16import qualified System.Exit as Exit
17import qualified System.IO as IO
18import System.Environment (getArgs, )
15 19
16import Sound.ALSA.Sequencer.Connect as AlsaConn 20main :: IO ()
17import qualified Sound.ALSA.Sequencer.Address as Addr 21main = (do
22 SndSeq.withDefault SndSeq.Block $ \h -> do
23 Client.setName (h :: SndSeq.T SndSeq.DuplexMode) "Haskell-Beat"
24 Port.withSimple h "inout"
25 (Port.caps [Port.capRead, Port.capSubsRead,
26 Port.capWrite, Port.capSubsWrite])
27 (Port.types [Port.typeMidiGeneric, Port.typeApplication]) $ \public -> do
28 Port.withSimple h "private"
29 (Port.caps [Port.capRead, Port.capWrite])
30 (Port.types [Port.typeMidiGeneric]) $ \private -> do
31 Queue.with h $ \q -> do
18 32
33 PortInfo.modify h public $ do
34 PortInfo.setTimestamping True
35 PortInfo.setTimestampReal True
36 PortInfo.setTimestampQueue q
19 37
20listPorts :: IO () 38 c <- Client.getId h
21listPorts = do 39 let publicAddr = Addr.Cons c public
22 putStrLn " Port Client name Port name Caps" 40 privateAddr = Addr.Cons c private
23 SndSeq.withDefault SndSeq.Block $ \h ->
24 ClientInfo.queryLoop_ (h :: SndSeq.T SndSeq.OutputMode) $ \cinfo -> do
25 client <- ClientInfo.getClient cinfo
26 PortInfo.queryLoop_ h client $ \pinfo -> do
27 join $ liftM5 (\a b c d e -> when (c == "AXIS-49 2A") $ printf "%3d:%-3d %-32.32s %-24.24s %s\n" a b c d e)
28 (fmap (\(Client.Cons p) -> p) $ PortInfo.getClient pinfo)
29 (fmap (\(Port.Cons p) -> p) $ PortInfo.getPort pinfo)
30 (ClientInfo.getName cinfo)
31 (PortInfo.getName pinfo)
32 (do
33 caps <- PortInfo.getCapability pinfo
34 let disp (cap, char) =
35 if EnumSet.disjoint caps cap then ' ' else char
36 return $ map disp $
37 (Port.capRead, 'r') :
38 (Port.capSubsRead, 'R') :
39 (Port.capWrite, 'w') :
40 (Port.capSubsWrite, 'W') :
41 [])
42 41
43findPort wantName f = do 42--args <- getArgs
44 SndSeq.withDefault SndSeq.Block $ \h -> 43 let args = ["20", "128"]
45 ClientInfo.queryLoop_ (h :: SndSeq.T SndSeq.OutputMode) $ \cinfo -> do 44 case args of
46 name <- (ClientInfo.getName cinfo) 45 [input, output] ->
47 when (name == wantName) $ do 46 (Connect.createFrom h public =<< Addr.parse h input)
48 client <- ClientInfo.getClient cinfo 47 >>
49 PortInfo.queryLoop_ h client $ \pinfo -> do 48 (Connect.createTo h public =<< Addr.parse h output)
50 port <- (fmap (\(Client.Cons p) -> p) $ PortInfo.getClient pinfo) 49 >>
51 f $ show port 50 return ()
51 _ ->
52 IO.hPutStrLn IO.stderr "need arguments: input-client output-client"
53 >>
54 Exit.exitFailure
52 55
53main :: IO ()
54main = (do
55--outport <- findPort "AXIS-49 2A" return -- nope
56--outport <- findPort "AXIS-49 2A" (\p -> return p) -- nope
57 putStrLn "Starting."
58 SndSeq.withDefault SndSeq.Nonblock $ \h -> do
59 Client.setName (h :: SndSeq.T SndSeq.InputMode) "Axis-of-Eval"
60 putStrLn "Created sequencer."
61 Port.withSimple h "primary"
62 (Port.caps [Port.capWrite, Port.capSubsWrite]) Port.typeMidiGeneric $ \ _p1 -> do
63 Port.withSimple h "secondary"
64 (Port.caps [Port.capWrite, Port.capSubsWrite]) Port.typeMidiGeneric $ \ _p2 -> do
65 putStrLn "Created ports." 56 putStrLn "Created ports."
66 57
67 clientID <- Client.getId h 58 let wait = do
59 ev <- Event.input h
60 case Event.body ev of
61 Event.NoteEv Event.NoteOn n -> return (Event.NoteOn, n)
62 Event.NoteEv Event.NoteOff n -> return (Event.NoteOff, n)
63 _ -> wait
68 64
69 findPort "AXIS-49 2A" (connectAxis h clientID _p1) 65 Queue.control h q Event.QueueStart Nothing
70 66
71 forever $ do 67 let mkEv e =
72 putStrLn "waiting for an event:" 68 (Event.simple publicAddr e) {
73 print =<< Event.input h) 69 Event.queue = q,
74 `AlsaExc.catch` \e -> 70 Event.time = Time.consAbs $ Time.Real $ RealTime.fromDouble 0
75 putStrLn $ "alsa_exception: " ++ AlsaExc.show e 71 }
76 72
77connectAxis h myID myPort axisID = do 73 let go = do
78 myID_int <- (\(Client.Cons p) -> return p) myID 74 (onoff, note) <- wait
79 printf "Found my ID: %d.\nFound Axis ID: %s.\n" myID_int axisID 75 print note
80 AlsaConn.createFrom h myPort =<< Addr.parse h (axisID ++ ":0") 76 Event.output h $ mkEv $ Event.NoteEv onoff note
81 return () 77 _ <- Event.drainOutput h
78 go
82 79
80 go)
81 `AlsaExc.catch` \e ->
82 putStrLn $ "alsa_exception: " ++ AlsaExc.show e