-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMidi.purs
165 lines (136 loc) · 4.36 KB
/
Midi.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
-- | Data structures used by the MIDI parser and by Web MIDI.
module Data.Midi
( Track(..)
, Header(..)
, Event(..)
, TimedEvent(..)
, Message(..)
, Recording(..)
, Ticks
, Byte
, Channel
, Note
, Velocity
, SysExFlavour(..)
) where
import Prelude (class Show, class Eq, class Ord)
import Data.List (List)
import Data.List.NonEmpty (NonEmptyList) as Nel
import Data.Maybe (Maybe)
import Data.Generic.Rep
import Data.Eq.Generic (genericEq)
import Data.Ord.Generic (genericCompare)
import Data.Show.Generic (genericShow)
-- | A Tick represents a MIDI time increment. See the MIDI Specification,
-- | page 135 - delta-time.
type Ticks = Int
-- | A MIDI byte (for use in a Byte array) and represented as an Int.
type Byte = Int
-- | A MIDI Channel in the range ( 0 <= channel <= 15).
-- | See the MIDI specification - page 7.
type Channel = Int
-- | A MIDI note number representing a pitch in the range (0 <= note <= 127).
-- | See the MIDI specification page 42 - Note Number.
-- | 0 in a NoteOn message is equivalent to NoteOff.
type Note = Int
-- | An indication of the pressure applied to a key on a MIDI isntrument and
-- | hence of note volume. See the MIDI specification page 42 - Volume.
type Velocity = Int
-- | System exclusive messages exist in two different flavours as introduced by
-- | a lead-in byte of 0xF0 or 0xF7. See the MIDI specification page 135.
data SysExFlavour
= F0 -- normal
| F7 -- escaped
derive instance genericSysExFlavour :: Generic SysExFlavour _
instance showSysExFlavour :: Show SysExFlavour where
show = genericShow
instance eqSysExFlavour :: Eq SysExFlavour where
eq = genericEq
instance ordSysExFlavour :: Ord SysExFlavour where
compare = genericCompare
-- | A Midi Event.
-- |
-- | Note that RunningStatus messages are not included within Event
-- | because the parser translates them to the underlying channel messages
data Event
= -- meta messages
SequenceNumber Int
| Text String
| Copyright String
| TrackName String
| InstrumentName String
| Lyrics String
| Marker String
| CuePoint String
| ChannelPrefix Int
| Tempo Int
| SMPTEOffset Int Int Int Int Int
| TimeSignature Int Int Int Int
| KeySignature Int Int
| SequencerSpecific (List Byte)
-- system exclusive message
| SysEx SysExFlavour (Nel.NonEmptyList Byte)
| Unspecified Int (List Byte)
-- channel messages
| NoteOn Channel Note Velocity
| NoteOff Channel Note Velocity
| NoteAfterTouch Channel Note Velocity
| ControlChange Channel Int Int
| ProgramChange Channel Int
| ChannelAfterTouch Channel Velocity
| PitchBend Channel Int
derive instance genericEvent :: Generic Event _
instance showEvent :: Show Event where
show = genericShow
instance eqEvent :: Eq Event where
eq = genericEq
instance ordEvent :: Ord Event where
compare = genericCompare
-- | a timestamped parsed MIDI Event message for use with Web MIDI
newtype TimedEvent = TimedEvent {
timeStamp :: Number
, event :: Maybe Event
}
derive instance genericTimedEvent:: Generic TimedEvent _
instance showTimedEvent :: Show TimedEvent where
show = genericShow
-- | A MIDI Message.
data Message = Message Ticks Event
derive instance genericMessage :: Generic Message _
instance showMessage :: Show Message where
show = genericShow
instance eqMessage :: Eq Message where
eq = genericEq
instance ordMessage :: Ord Message where
compare = genericCompare
-- | A Midi Track.
newtype Track = Track
(List Message)
derive instance genericTrack :: Generic Track _
instance showTrack :: Show Track where
show = genericShow
instance eqTrack :: Eq Track where
eq = genericEq
instance ordTrack :: Ord Track where
compare = genericCompare
-- | The Midi Header.
newtype Header = Header
{ formatType :: Int
, trackCount :: Int
, ticksPerBeat :: Int
}
derive instance genericHeader :: Generic Header _
instance showHeader :: Show Header where
show = genericShow
instance eqHeader :: Eq Header where
eq = genericEq
-- | A Midi Recording.
newtype Recording = Recording
{ header :: Header
, tracks :: List Track
}
derive instance genericRecording :: Generic Recording _
instance showRecording :: Show Recording where
show = genericShow
instance eqRecording :: Eq Recording where
eq = genericEq