midi-0.2.0.1: Handling of MIDI messages and files

Safe Haskell | None

Sound.MIDI.Message.Channel

Description

Channel messages

Synopsis

- data T = Cons {
  - messageChannel :: Channel
  - messageBody :: Body
  }
- data Body
  - = Voice T
  - | Mode T
- get :: C parser => Int -> Channel -> Int -> Fallible parser T
- getWithStatus :: C parser => Int -> Fallible (T parser) T
- put :: C writer => T -> writer
- putWithStatus :: C writer => T -> T writer
- data Channel
- fromChannel :: Channel -> Int
- toChannel :: Int -> Channel
- data Pitch
- fromPitch :: Pitch -> Int
- toPitch :: Int -> Pitch
- data Velocity
- fromVelocity :: Velocity -> Int
- toVelocity :: Int -> Velocity
- data Program
- fromProgram :: Program -> Int
- toProgram :: Int -> Program
- data Controller
- fromController :: Controller -> Int
- toController :: Int -> Controller
- decodeStatus :: Int -> (Int, Channel)

# Documentation

data T Source

Constructors

Cons |

Fields

messageChannel :: Channel
messageBody :: Body

Instances

Eq T |
Ord T |
Show T |
Arbitrary T |
C T |
C T |

data Body Source

Constructors

Voice T |
Mode T |

Instances

Eq Body |
Ord Body |
Show Body |

get :: C parser => Int -> Channel -> Int -> Fallible parser T Source

Parse a MIDI Channel message. Note that since getting the first byte is a little complex (there are issues with running status), the code, channel and first data byte must be determined by the caller.

getWithStatus :: C parser => Int -> Fallible (T parser) T Source

Parse an event. Note that in the case of a regular MIDI Event, the tag is the status, and we read the first byte of data before we call `get`. In the case of a MIDIEvent with running status, we find out the status from the parser (it's been nice enough to keep track of it for us), and the tag that we've already gotten is the first byte of data.

put :: C writer => T -> writerSource

putWithStatus :: C writer => T -> T writerSource

data Channel Source

This definition should be in Message.Channel, but this results in a cyclic import.

Instances

Bounded Channel |
Enum Channel |
Eq Channel |
Ord Channel |
Show Channel |
Ix Channel |

fromChannel :: Channel -> Int Source

toChannel :: Int -> Channel Source

data Pitch Source

Instances

Bounded Pitch |
Enum Pitch |
Eq Pitch |
Ord Pitch |
Show Pitch |
Ix Pitch |
Random Pitch |
Arbitrary Pitch |

fromPitch :: Pitch -> Int Source

toPitch :: Int -> Pitch Source

data Velocity Source

Instances

Bounded Velocity | ToDo: We have defined minBound = Velocity 0, but strictly spoken the minimum Velocity is 1, since Velocity zero means NoteOff. One can at least think of NoteOff with (Velocity 0), but I have never seen that.
Eq Velocity |
Ord Velocity |
Show Velocity |
Random Velocity |
Arbitrary Velocity |

fromVelocity :: Velocity -> Int Source

toVelocity :: Int -> Velocity Source

data Program Source

Instances

Bounded Program |
Enum Program |
Eq Program |
Ord Program |
Show Program |
Ix Program |
Random Program |
Arbitrary Program |

fromProgram :: Program -> Int Source

toProgram :: Int -> Program Source

data Controller Source

We do not define `Controller` as enumeration with many constructors, because some controllers have multiple names and some are undefined. It is also more efficient this way. Thus you cannot use `case` for processing controller types, but you can use `lookup` instead.

     maybe (putStrLn "unsupported controller") putStrLn $
     lookup ctrl $
        (portamento, "portamento") :
        (modulation, "modulation") :
        []

Instances

Bounded Controller |
Enum Controller |
Eq Controller |
Ord Controller |
Show Controller |
Ix Controller |
Random Controller |
Arbitrary Controller |

fromController :: Controller -> Int Source

toController :: Int -> Controller Source

decodeStatus :: Int -> (Int, Channel)Source

for internal use