1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #import <Foundation/Foundation.h>
18 
19 /**
20  * A MIDI channel number.
21  *
22  * Note that the first channel is '1'.
23  */
24 typedef uint8_t MIDIChannel;
25 typedef uint8_t MIDIByte;
26 
27 typedef NS_ENUM(MIDIByte, MIDIMessageType) {
28   // Channel messages
29   MIDIMessageNoteOff          = 0x08,
30   MIDIMessageNoteOn           = 0x09,
31   MIDIMessageKeyPressure      = 0x0A,
32   MIDIMessageControlChange    = 0x0B,
33   MIDIMessageProgramChange    = 0x0C,
34   MIDIMessageChannelPressure  = 0x0D,
35   MIDIMessagePitchBend        = 0x0E,
36 
37   // System messages
38   MIDIMessageSysEx            = 0xF0,
39   MIDIMessageQuarterFrame     = 0xF1,
40   MIDIMessageSongPosition     = 0xF2,
41   MIDIMessageSongSelect       = 0xF3,
42   MIDIMessageTuneRequest      = 0xF6,
43   MIDIMessageSysExEnd         = 0xF7,
44   MIDIMessageTimingClock      = 0xF8,
45   MIDIMessageStart            = 0xFA,
46   MIDIMessageContinue         = 0xFB,
47   MIDIMessageStop             = 0xFC,
48   MIDIMessageActiveSensing    = 0xFE,
49   MIDIMessageReset            = 0xFF,
50 };
51 
52 extern const MIDIChannel kMIDINoChannel;
53 
54 #pragma mark Message Parsing
55 
56 /** Returns the MIDIMessageType for a given status byte. */
57 MIDIMessageType MIDIMessageTypeFromStatus(MIDIByte status);
58 
59 /**
60  * Returns the MIDIChannel for a given status byte, or kMIDINoChannel if the status byte does not
61  * describe a channel message.
62  */
63 MIDIChannel MIDIChannelFromStatus(MIDIByte status);
64 
65 /**
66  * Returns the body portion from a complete MIDI message (i.e., without leading or trailing data).
67  */
68 NSData *MIDIMessageBody(NSData *message);
69 
70 #pragma mark Message Building
71 
72 /** Returns the MIDI status byte for a message type sent to a particular channel. */
73 MIDIByte MIDIStatusByte(MIDIMessageType type, MIDIChannel channel);
74 
75 /** Creates a complete MIDI message packet for a given message type, channel, and its body. */
76 NSData *MIDIMessageCreate(MIDIMessageType type, MIDIChannel channel, NSData *body);
77 
78 /** Creates a complete MIDI message packet for a simple message containing one data byte. */
79 NSData *MIDIMessageCreateSimple1(MIDIMessageType type, MIDIChannel channel, MIDIByte first);
80 
81 /** Creates a complete MIDI message packet for a simple message containing two data bytes. */
82 NSData *MIDIMessageCreateSimple2(MIDIMessageType type,
83                                  MIDIChannel channel,
84                                  MIDIByte first,
85                                  MIDIByte second);
86