module Sound.MIDI.Message.Class.Utility where import Sound.MIDI.Message.Channel.Voice (Pitch, Velocity, Program, Controller, ) import qualified Sound.MIDI.Message.Channel.Voice as VoiceMsg import qualified Sound.MIDI.Message.Channel.Mode as Mode import qualified Sound.MIDI.Message.Channel as ChannelMsg note :: Maybe ChannelMsg.Body -> Maybe (Velocity, Pitch, Bool) program :: Maybe ChannelMsg.Body -> Maybe Program anyController :: Maybe ChannelMsg.Body -> Maybe (Controller, Int) pitchBend :: Maybe ChannelMsg.Body -> Maybe Int channelPressure :: Maybe ChannelMsg.Body -> Maybe Int mode :: Maybe ChannelMsg.Body -> Maybe Mode.T note msg = do ChannelMsg.Voice voice <- msg case voice of VoiceMsg.NoteOn pitch velocity -> Just (velocity, pitch, True) VoiceMsg.NoteOff pitch velocity -> Just (velocity, pitch, False) _ -> Nothing program msg = do ChannelMsg.Voice (VoiceMsg.ProgramChange pgm) <- msg return pgm anyController msg = do ChannelMsg.Voice (VoiceMsg.Control ctrl val) <- msg return (ctrl, val) pitchBend msg = do ChannelMsg.Voice (VoiceMsg.PitchBend bend) <- msg return bend channelPressure msg = do ChannelMsg.Voice (VoiceMsg.MonoAftertouch pressure) <- msg return pressure mode msg = do ChannelMsg.Mode m <- msg return m explicitNoteOff :: (Velocity, Pitch, Bool) -> (Velocity, Pitch, Bool) explicitNoteOff x@(v,p,b) = if b && v == VoiceMsg.toVelocity 0 then (VoiceMsg.toVelocity 64, p, False) else x implicitNoteOff :: (Velocity, Pitch, Bool) -> (Velocity, Pitch, Bool) implicitNoteOff x@(v,p,b) = if not b && v == VoiceMsg.toVelocity 64 then (VoiceMsg.toVelocity 0, p, True) else x