summaryrefslogtreecommitdiff
path: root/midi-dump.hs
diff options
context:
space:
mode:
Diffstat (limited to 'midi-dump.hs')
-rw-r--r--midi-dump.hs51
1 files changed, 9 insertions, 42 deletions
diff --git a/midi-dump.hs b/midi-dump.hs
index f053e28..07281f5 100644
--- a/midi-dump.hs
+++ b/midi-dump.hs
@@ -14,8 +14,6 @@ import qualified Sound.ALSA.Sequencer.Event as Event
14import System.Clock 14import System.Clock
15 15
16import Control.Applicative 16import Control.Applicative
17import qualified Data.ByteString as BS
18import Data.ByteString.Char8 (pack)
19import Data.Int 17import Data.Int
20import Database.SQLite.Simple 18import Database.SQLite.Simple
21import Database.SQLite.Simple.FromRow () 19import Database.SQLite.Simple.FromRow ()
@@ -31,6 +29,8 @@ import qualified Sound.ALSA.Sequencer.Queue
31import qualified Sound.ALSA.Sequencer.Time as Time 29import qualified Sound.ALSA.Sequencer.Time as Time
32import qualified Sound.ALSA.Sequencer.RealTime as RealTime 30import qualified Sound.ALSA.Sequencer.RealTime as RealTime
33 31
32import Midi
33
34verbose :: Bool 34verbose :: Bool
35verbose = False 35verbose = False
36 36
@@ -39,30 +39,6 @@ main = main' `AlsaExc.catch` handler
39 where 39 where
40 handler e = when verbose $ putStrLn $ "alsa_exception: " ++ AlsaExc.show e 40 handler e = when verbose $ putStrLn $ "alsa_exception: " ++ AlsaExc.show e
41 41
42type RecordedEvent = (TimeSpec, Event.T)
43
44data Recording = StartRecording TimeSpec |
45 RecordingInProgress TimeSpec TimeSpec [RecordedEvent]
46
47data CompleteRecording = CompleteRecording {
48 _recStart :: TimeSpec,
49 _recEnd :: TimeSpec,
50 _recFirst :: TimeSpec,
51 _recLast :: TimeSpec,
52 _recEvents :: [RecordedEvent]
53}
54
55recordEvents :: Recording -> [RecordedEvent]-> Recording
56recordEvents (RecordingInProgress x y orig) new = RecordingInProgress x y $ new ++ orig
57recordEvents i@(StartRecording _) [] = i
58recordEvents (StartRecording x) new@(_:_) = RecordingInProgress x y new
59 where y = fst $ last new
60
61stopRecording :: Recording -> TimeSpec -> Maybe CompleteRecording
62stopRecording (RecordingInProgress x y ls@((z,_):_)) end = Just $ CompleteRecording x end y z ls
63stopRecording _ _ = Nothing
64
65
66data LoopState = LoopState { 42data LoopState = LoopState {
67 _wantExit :: Bool, 43 _wantExit :: Bool,
68 keysDown :: MidiPitchSet, 44 keysDown :: MidiPitchSet,
@@ -176,7 +152,7 @@ playNoteEv :: Event.Data -> RWST LoopEnv () LoopState IO ()
176playNoteEv nevdata = do 152playNoteEv nevdata = do
177 ms <- getMidiSender 153 ms <- getMidiSender
178 publicAddr <- asks _publicAddr 154 publicAddr <- asks _publicAddr
179 liftIO $ ms $ Event.simple publicAddr nevdata `delayEvent` (10 * 10^(9::Int)) 155 liftIO $ ms $ Event.simple publicAddr nevdata `delayEvent` (2 * 10^(9::Int))
180 156
181_whenFlag :: forall (m :: * -> *) s. MonadState s m => (s -> Bool) -> m () -> m () 157_whenFlag :: forall (m :: * -> *) s. MonadState s m => (s -> Bool) -> m () -> m ()
182_whenFlag flag f = gets flag >>= flip when f 158_whenFlag flag f = gets flag >>= flip when f
@@ -188,6 +164,12 @@ processCommand "C" = do
188 let mkNote pitch = Event.simpleNote (Event.Channel 0) (Event.Pitch pitch) (Event.Velocity 128) 164 let mkNote pitch = Event.simpleNote (Event.Channel 0) (Event.Pitch pitch) (Event.Velocity 128)
189 let notes = (Event.NoteEv Event.NoteOn . mkNote) <$> [60, 64, 67] 165 let notes = (Event.NoteEv Event.NoteOn . mkNote) <$> [60, 64, 67]
190 modify $ \s -> s { _playNOW = notes } 166 modify $ \s -> s { _playNOW = notes }
167processCommand "C'" = do
168 -- changing the duration seems to do nothing
169 let mkNote pitch = Event.simpleNote (Event.Channel 0) (Event.Pitch pitch) (Event.Velocity 128)
170 setDuration d note = note { Event.noteDuration = Event.Duration d }
171 let notes = (Event.NoteEv Event.NoteOn . setDuration 4290000000 . mkNote) <$> [60, 64, 67]
172 modify $ \s -> s { _playNOW = notes }
191processCommand str = liftIO $ putStrLn $ "Unknown command: " ++ str 173processCommand str = liftIO $ putStrLn $ "Unknown command: " ++ str
192 174
193getMidiSender :: RWST LoopEnv () LoopState IO MidiHook 175getMidiSender :: RWST LoopEnv () LoopState IO MidiHook
@@ -239,21 +221,6 @@ startLineReader = do
239 _thread <- liftIO $ forkIO (forever $ tryIOError getLine >>= either (const $ putMVar mv "exit") (putMVar mv)) 221 _thread <- liftIO $ forkIO (forever $ tryIOError getLine >>= either (const $ putMVar mv "exit") (putMVar mv))
240 return mv 222 return mv
241 223
242midiToBytes :: [RecordedEvent] -> BS.ByteString
243midiToBytes = pack . show
244bytesToMidi :: BS.ByteString -> [RecordedEvent]
245bytesToMidi = undefined
246
247instance FromRow CompleteRecording where
248 fromRow = cons <$> field <*> field <*> field <*> field <*> field <*> field <*> field <*> field <*> field
249 where
250 cons a a' b b' c c' d d' z = CompleteRecording (TimeSpec a a') (TimeSpec b b') (TimeSpec c c') (TimeSpec d d') (bytesToMidi z)
251
252instance ToRow CompleteRecording where
253 toRow reco = toRow (s, ns, s', ns', s'', ns'', s''', ns''', midiToBytes midi)
254 where
255 (CompleteRecording (TimeSpec s ns) (TimeSpec s' ns') (TimeSpec s'' ns'') (TimeSpec s''' ns''') midi) = reco
256
257saveMidi :: forall (m :: * -> *). (MonadIO m, MonadState LoopState m, MonadReader LoopEnv m) => Recording -> m () 224saveMidi :: forall (m :: * -> *). (MonadIO m, MonadState LoopState m, MonadReader LoopEnv m) => Recording -> m ()
258saveMidi recording = do 225saveMidi recording = do
259 saver <- asks _saver 226 saver <- asks _saver