@@ -39,6 +39,28 @@ pub enum Message {
3939 PitchWheelChange ( Channel , U7 , U7 ) ,
4040 /// Control Change (CC) message.
4141 ControlChange ( Channel , ControlFunction , U7 ) ,
42+ /// MTC Quarter Frame message.
43+ MtcQuarterFrame ( U7 ) ,
44+ /// Song Position Pointer message.
45+ SongPositionPointer ( U7 , U7 ) ,
46+ /// Song Select message.
47+ SongSelect ( U7 ) ,
48+ /// Tune Request message.
49+ TuneRequest ,
50+ /// Timing Clock message.
51+ TimingClock ,
52+ /// Tick message.
53+ Tick ,
54+ /// Start message.
55+ Start ,
56+ /// Continue message.
57+ Continue ,
58+ /// Stop message.
59+ Stop ,
60+ /// Active Sensing message.
61+ ActiveSensing ,
62+ /// Reset message.
63+ Reset ,
4264}
4365
4466const NOTE_OFF_MASK : u8 = 0b1000_0000 ;
@@ -49,6 +71,18 @@ const CHANNEL_AFTERTOUCH_MASK: u8 = 0b1101_0000;
4971const PITCH_BEND_MASK : u8 = 0b1110_0000 ;
5072const CONTROL_CHANGE_MASK : u8 = 0b1011_0000 ;
5173
74+ const MTC_QUARTER_FRAME : u8 = 0xF1 ;
75+ const SONG_POSITION_POINTER : u8 = 0xF2 ;
76+ const SONG_SELECT : u8 = 0xF3 ;
77+ const TUNE_REQUEST : u8 = 0xF6 ;
78+ const TIMING_CLOCK : u8 = 0xF8 ;
79+ const TICK : u8 = 0xF9 ;
80+ const START : u8 = 0xFA ;
81+ const CONTINUE : u8 = 0xFB ;
82+ const STOP : u8 = 0xFC ;
83+ const ACTIVE_SENSING : u8 = 0xFE ;
84+ const RESET : u8 = 0xFF ;
85+
5286impl From < Message > for Raw {
5387 fn from ( value : Message ) -> Raw {
5488 match value {
@@ -87,6 +121,61 @@ impl From<Message> for Raw {
87121 let status = CONTROL_CHANGE_MASK | u8:: from ( chan) ;
88122 Raw { status, payload }
89123 }
124+ Message :: MtcQuarterFrame ( frame) => {
125+ let payload = Payload :: SingleByte ( frame) ;
126+ let status = MTC_QUARTER_FRAME ;
127+ Raw { status, payload }
128+ }
129+ Message :: SongPositionPointer ( lsb, msb) => {
130+ let payload = Payload :: DoubleByte ( lsb, msb) ;
131+ let status = SONG_POSITION_POINTER ;
132+ Raw { status, payload }
133+ }
134+ Message :: SongSelect ( song) => {
135+ let payload = Payload :: SingleByte ( song) ;
136+ let status = SONG_SELECT ;
137+ Raw { status, payload }
138+ }
139+ Message :: TuneRequest => {
140+ let payload = Payload :: Empty ;
141+ let status = TUNE_REQUEST ;
142+ Raw { status, payload }
143+ }
144+ Message :: TimingClock => {
145+ let payload = Payload :: Empty ;
146+ let status = TIMING_CLOCK ;
147+ Raw { status, payload }
148+ }
149+ Message :: Tick => {
150+ let payload = Payload :: Empty ;
151+ let status = TICK ;
152+ Raw { status, payload }
153+ }
154+ Message :: Start => {
155+ let payload = Payload :: Empty ;
156+ let status = START ;
157+ Raw { status, payload }
158+ }
159+ Message :: Continue => {
160+ let payload = Payload :: Empty ;
161+ let status = CONTINUE ;
162+ Raw { status, payload }
163+ }
164+ Message :: Stop => {
165+ let payload = Payload :: Empty ;
166+ let status = STOP ;
167+ Raw { status, payload }
168+ }
169+ Message :: ActiveSensing => {
170+ let payload = Payload :: Empty ;
171+ let status = ACTIVE_SENSING ;
172+ Raw { status, payload }
173+ }
174+ Message :: Reset => {
175+ let payload = Payload :: Empty ;
176+ let status = RESET ;
177+ Raw { status, payload }
178+ }
90179 }
91180 }
92181}
@@ -100,6 +189,46 @@ impl TryFrom<&[u8]> for Message {
100189 None => return Err ( UsbMidiEventPacketError :: MissingDataPacket ) ,
101190 } ;
102191
192+ match * status_byte {
193+ MTC_QUARTER_FRAME => {
194+ return Ok ( Message :: MtcQuarterFrame ( get_u7_at ( data, 1 ) ?) ) ;
195+ }
196+ SONG_POSITION_POINTER => {
197+ return Ok ( Message :: SongPositionPointer (
198+ get_u7_at ( data, 1 ) ?,
199+ get_u7_at ( data, 2 ) ?,
200+ ) ) ;
201+ }
202+ SONG_SELECT => {
203+ return Ok ( Message :: SongSelect ( get_u7_at ( data, 1 ) ?) ) ;
204+ }
205+ TUNE_REQUEST => {
206+ return Ok ( Message :: TuneRequest ) ;
207+ }
208+ TIMING_CLOCK => {
209+ return Ok ( Message :: TimingClock ) ;
210+ }
211+ TICK => {
212+ return Ok ( Message :: Tick ) ;
213+ }
214+ START => {
215+ return Ok ( Message :: Start ) ;
216+ }
217+ CONTINUE => {
218+ return Ok ( Message :: Continue ) ;
219+ }
220+ STOP => {
221+ return Ok ( Message :: Stop ) ;
222+ }
223+ ACTIVE_SENSING => {
224+ return Ok ( Message :: ActiveSensing ) ;
225+ }
226+ RESET => {
227+ return Ok ( Message :: Reset ) ;
228+ }
229+ _ => { }
230+ }
231+
103232 let event_type = status_byte & 0b1111_0000 ;
104233 let channel_bytes = ( status_byte) & 0b0000_1111 ;
105234
@@ -184,6 +313,17 @@ impl Message {
184313 Self :: PolyphonicAftertouch ( _, _, _) => CodeIndexNumber :: PolyKeyPress ,
185314 Self :: ProgramChange ( _, _) => CodeIndexNumber :: ProgramChange ,
186315 Self :: ControlChange ( _, _, _) => CodeIndexNumber :: ControlChange ,
316+ Self :: MtcQuarterFrame ( _) => CodeIndexNumber :: SystemCommon2Bytes ,
317+ Self :: SongPositionPointer ( _, _) => CodeIndexNumber :: SystemCommon3Bytes ,
318+ Self :: SongSelect ( _) => CodeIndexNumber :: SystemCommon2Bytes ,
319+ Self :: TuneRequest => CodeIndexNumber :: SystemCommon1Byte ,
320+ Self :: TimingClock => CodeIndexNumber :: SingleByte ,
321+ Self :: Tick => CodeIndexNumber :: SingleByte ,
322+ Self :: Start => CodeIndexNumber :: SingleByte ,
323+ Self :: Continue => CodeIndexNumber :: SingleByte ,
324+ Self :: Stop => CodeIndexNumber :: SingleByte ,
325+ Self :: ActiveSensing => CodeIndexNumber :: SingleByte ,
326+ Self :: Reset => CodeIndexNumber :: SingleByte ,
187327 }
188328 }
189329}
@@ -239,5 +379,16 @@ mod tests {
239379 channel_aftertouch: ( [ 13 , 208 , 127 , 0 ] , Message :: ChannelAftertouch ( Channel1 , U7 ( 127 ) ) . into_packet( Cable0 ) ) ,
240380 pitch_wheel: ( [ 14 , 224 , 64 , 32 ] , Message :: PitchWheelChange ( Channel1 , U7 ( 64 ) , U7 ( 32 ) ) . into_packet( Cable0 ) ) ,
241381 control_change: ( [ 11 , 177 , 1 , 32 ] , Message :: ControlChange ( Channel2 , ControlFunction :: MOD_WHEEL_1 , U7 ( 32 ) ) . into_packet( Cable0 ) ) ,
382+ mtc_quarter_frame: ( [ 0x02 , 0xF1 , 12 , 0 ] , Message :: MtcQuarterFrame ( U7 ( 12 ) ) . into_packet( Cable0 ) ) ,
383+ song_position_pointer: ( [ 0x03 , 0xF2 , 38 , 75 ] , Message :: SongPositionPointer ( U7 ( 38 ) , U7 ( 75 ) ) . into_packet( Cable0 ) ) ,
384+ song_select: ( [ 0x02 , 0xF3 , 4 , 0 ] , Message :: SongSelect ( U7 ( 4 ) ) . into_packet( Cable0 ) ) ,
385+ tune_request: ( [ 0x05 , 0xF6 , 0 , 0 ] , Message :: TuneRequest . into_packet( Cable0 ) ) ,
386+ timing_clock: ( [ 0x0F , 0xF8 , 0 , 0 ] , Message :: TimingClock . into_packet( Cable0 ) ) ,
387+ tick: ( [ 0x0F , 0xF9 , 0 , 0 ] , Message :: Tick . into_packet( Cable0 ) ) ,
388+ start: ( [ 0x0F , 0xFA , 0 , 0 ] , Message :: Start . into_packet( Cable0 ) ) ,
389+ continue_: ( [ 0x0F , 0xFB , 0 , 0 ] , Message :: Continue . into_packet( Cable0 ) ) ,
390+ stop: ( [ 0x0F , 0xFC , 0 , 0 ] , Message :: Stop . into_packet( Cable0 ) ) ,
391+ active_sensing: ( [ 0x0F , 0xFE , 0 , 0 ] , Message :: ActiveSensing . into_packet( Cable0 ) ) ,
392+ reset: ( [ 0x0F , 0xFF , 0 , 0 ] , Message :: Reset . into_packet( Cable0 ) ) ,
242393 }
243394}
0 commit comments