diff options
-rw-r--r-- | midi-dump.hs | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/midi-dump.hs b/midi-dump.hs index 0adef56..369ee9c 100644 --- a/midi-dump.hs +++ b/midi-dump.hs | |||
@@ -218,15 +218,14 @@ metronome = gets _metronome >>= mapM_ f | |||
218 | where | 218 | where |
219 | f (Metronome start interval ticked) = do | 219 | f (Metronome start interval ticked) = do |
220 | now <- getAbsTime | 220 | now <- getAbsTime |
221 | let next = now + interval - (now `tsMod` interval) | 221 | let next = ticked + interval |
222 | when (next > ticked) $ do | 222 | prequeue = 0::Int |
223 | when (now > next - (interval * TimeSpec (fromIntegral prequeue) 0)) $ do | ||
223 | let delay = next - now | 224 | let delay = next - now |
224 | delayNoteEv delay $ metronote 127 | 225 | forM_ [0..prequeue] $ fromIntegral >>> \n -> alsaDelayNoteEv (delay + interval * TimeSpec n 0) $ metronote 127 |
225 | -- delayNoteEv (metroDuration + delay) $ metronote 0 | 226 | modify $ \s -> s { _metronome = Just $ Metronome start interval (next + interval * TimeSpec (fromIntegral prequeue) 0) } |
226 | modify $ \s -> s { _metronome = Just $ Metronome start interval next } | ||
227 | 227 | ||
228 | metronote vel = Event.NoteEv Event.NoteOn $ Event.simpleNote (Event.Channel 9) (Event.Pitch 37) (Event.Velocity vel) | 228 | metronote vel = Event.NoteEv Event.NoteOn $ Event.simpleNote (Event.Channel 9) (Event.Pitch 37) (Event.Velocity vel) |
229 | -- metroDuration = TimeSpec 0 (1*10^(6::Integer)) | ||
230 | 229 | ||
231 | tsMod :: forall a. Num a => TimeSpec -> TimeSpec -> a | 230 | tsMod :: forall a. Num a => TimeSpec -> TimeSpec -> a |
232 | tsMod x y = fromInteger (timeSpecAsNanoSecs x `mod` timeSpecAsNanoSecs y) | 231 | tsMod x y = fromInteger (timeSpecAsNanoSecs x `mod` timeSpecAsNanoSecs y) |
@@ -297,16 +296,16 @@ processCommand "M-m" = do | |||
297 | now <- getAbsTime | 296 | now <- getAbsTime |
298 | m <- gets _metronome | 297 | m <- gets _metronome |
299 | times <- takeNoteTimes 8 <$> gets _replay | 298 | times <- takeNoteTimes 8 <$> gets _replay |
300 | let deltas = drop 1 $ toDeltas times | 299 | let deltas = drop 1 . map negate . toDeltas $ times |
301 | deltas' = dropOutliers deltas | 300 | deltas' = dropOutliers deltas |
302 | len = length deltas' | 301 | len = length deltas' |
303 | dropOutliers xs@(x:_) = takeWhile ((2 * x) >) xs | 302 | dropOutliers xs@(x:_) = takeWhile (< TimeSpec 2 0 * x) xs |
304 | dropOutliers [] = [] | 303 | dropOutliers [] = [] |
305 | if isNothing m && (len >= 3) then do | 304 | if isNothing m && (len >= 3) then do |
306 | let interval = sum deltas' `tsDiv` fromIntegral len | 305 | let interval = sum deltas' `tsDiv` fromIntegral len |
307 | nextTick = now + interval - (now `tsMod` interval) | 306 | nextBeat = now - now `tsMod` interval + interval |
308 | lastTick = nextTick - interval | 307 | lastBeat = nextBeat - interval |
309 | modify $ \s -> s { _metronome = Just $ Metronome lastTick interval nextTick } | 308 | modify $ \s -> s { _metronome = Just $ Metronome lastBeat interval nextBeat } |
310 | else | 309 | else |
311 | modify $ \s -> s { _metronome = Nothing } | 310 | modify $ \s -> s { _metronome = Nothing } |
312 | processCommand "C'" = do | 311 | processCommand "C'" = do |