summaryrefslogtreecommitdiff
path: root/AlsaSeq.hs
diff options
context:
space:
mode:
Diffstat (limited to 'AlsaSeq.hs')
-rw-r--r--AlsaSeq.hs30
1 files changed, 26 insertions, 4 deletions
diff --git a/AlsaSeq.hs b/AlsaSeq.hs
index 5b65967..0512c80 100644
--- a/AlsaSeq.hs
+++ b/AlsaSeq.hs
@@ -1,7 +1,7 @@
1{-# LANGUAGE NondecreasingIndentation #-} 1{-# LANGUAGE NondecreasingIndentation #-}
2module AlsaSeq (withAlsaInit, parseAlsaEvents, parseAlsaEvents', forwardNoteEvent, 2module AlsaSeq (withAlsaInit, parseAlsaEvents, parseAlsaEvents', parseAlsaEvents'', forwardNoteEvent,
3cmdlineAlsaConnect, printChordLn, showChord, pitchList, showPitch, 3cmdlineAlsaConnect, printChordLn, printChordLn', showChord, pitchList, showPitch,
4unPitch, unChannel, MidiHook, MidiPitchSet) where 4unPitch, unChannel, MidiHook, MidiPitchSet, MidiPitchMap) where
5import qualified Sound.ALSA.Exception as AlsaExc 5import qualified Sound.ALSA.Exception as AlsaExc
6import qualified Sound.ALSA.Sequencer.Address as Addr 6import qualified Sound.ALSA.Sequencer.Address as Addr
7import qualified Sound.ALSA.Sequencer as SndSeq 7import qualified Sound.ALSA.Sequencer as SndSeq
@@ -23,6 +23,7 @@ import Text.Printf
23import Control.Monad (when, forM_, forM) 23import Control.Monad (when, forM_, forM)
24 24
25import qualified Data.Set as Set 25import qualified Data.Set as Set
26import qualified Data.Map.Strict as Map
26import Data.List (group, sort) 27import Data.List (group, sort)
27import Haskore.Basic.Pitch 28import Haskore.Basic.Pitch
28import Foreign.C.Error (Errno(Errno)) 29import Foreign.C.Error (Errno(Errno))
@@ -32,6 +33,7 @@ unPitch = Event.unPitch
32unChannel = Event.unChannel 33unChannel = Event.unChannel
33 34
34printChordLn set = printWords $ pitchWords set 35printChordLn set = printWords $ pitchWords set
36printChordLn' = printWords . map (showPitch . Event.unPitch . snd) . Map.keys
35 37
36joinWords [] = "" 38joinWords [] = ""
37joinWords ls = foldr1 (\a b -> a ++ " " ++ b) ls 39joinWords ls = foldr1 (\a b -> a ++ " " ++ b) ls
@@ -41,7 +43,7 @@ printWords ls = putStrLn $ joinWords ls
41 43
42showChord ls = joinWords $ pitchWords ls 44showChord ls = joinWords $ pitchWords ls
43 45
44showPitch x = 46showPitch x =
45 let (octave, pitch) = Haskore.Basic.Pitch.fromInt $ fromIntegral x 47 let (octave, pitch) = Haskore.Basic.Pitch.fromInt $ fromIntegral x
46 in Haskore.Basic.Pitch.classFormat pitch (show octave) 48 in Haskore.Basic.Pitch.classFormat pitch (show octave)
47 49
@@ -145,6 +147,7 @@ inputPendingLoop h b = do
145 (Right result) -> return result 147 (Right result) -> return result
146 148
147type MidiPitchSet = Set.Set (Event.Channel, Event.Pitch) 149type MidiPitchSet = Set.Set (Event.Channel, Event.Pitch)
150type MidiPitchMap = Map.Map (Event.Channel, Event.Pitch) Event.Velocity
148parseAlsaEvents :: SndSeq.AllowInput mode => 151parseAlsaEvents :: SndSeq.AllowInput mode =>
149 SndSeq.T mode -> Set.Set (Event.Channel, Event.Pitch) -> (Event.T -> IO a) -> IO MidiPitchSet 152 SndSeq.T mode -> Set.Set (Event.Channel, Event.Pitch) -> (Event.T -> IO a) -> IO MidiPitchSet
150parseAlsaEvents h keysDown immediate = loop keysDown 153parseAlsaEvents h keysDown immediate = loop keysDown
@@ -185,6 +188,25 @@ parseAlsaEvents' h keysDown immediate = loop [] keysDown
185 loop (ev:events) (Set.delete (Event.noteChannel n, Event.noteNote n) keysDown) 188 loop (ev:events) (Set.delete (Event.noteChannel n, Event.noteNote n) keysDown)
186 _ -> loop (ev:events) keysDown 189 _ -> loop (ev:events) keysDown
187 190
191parseAlsaEvents'' h keysDown immediate = loop [] keysDown
192 where
193 loop events keysDown = do
194 pending <- inputPendingLoop h True
195 if (pending == 0) then
196 return (events, keysDown)
197 else do
198 ev <- Event.input h
199 immediate ev
200 case Event.body ev of
201 Event.NoteEv Event.NoteOn n ->
202 if (Event.unVelocity (Event.noteVelocity n) == 0) then
203 loop (ev:events) (Map.delete (Event.noteChannel n, Event.noteNote n) keysDown)
204 else
205 loop (ev:events) (Map.insert (Event.noteChannel n, Event.noteNote n) (Event.noteVelocity n) keysDown)
206 Event.NoteEv Event.NoteOff n ->
207 loop (ev:events) (Map.delete (Event.noteChannel n, Event.noteNote n) keysDown)
208 _ -> loop (ev:events) keysDown
209
188type MidiHook = Event.T -> IO () 210type MidiHook = Event.T -> IO ()
189 211
190forwardNoteEvent :: SndSeq.AllowOutput mode => SndSeq.T mode -> Queue.T -> Addr.T -> MidiHook 212forwardNoteEvent :: SndSeq.AllowOutput mode => SndSeq.T mode -> Queue.T -> Addr.T -> MidiHook