-rw-r--r-- | include/midillo/message.h | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/include/midillo/message.h b/include/midillo/message.h new file mode 100644 index 0000000..d6f0f36 --- a/dev/null +++ b/include/midillo/message.h | |||
@@ -0,0 +1,200 @@ | |||
1 | #ifndef __MIDILLO_MESSAGE_H | ||
2 | #define __MIDILLO_MESSAGE_H | ||
3 | |||
4 | #include <istream> | ||
5 | #include <ostream> | ||
6 | #include <vector> | ||
7 | |||
8 | /** | ||
9 | * @file | ||
10 | * @brief MIDI message | ||
11 | */ | ||
12 | |||
13 | namespace midillo { | ||
14 | using std::istream; | ||
15 | using std::ostream; | ||
16 | using std::vector; | ||
17 | |||
18 | enum { | ||
19 | // bits | ||
20 | status_bit = 0x80, | ||
21 | status_event_bits = 0xF0, | ||
22 | status_channel_bits = 0x0F, | ||
23 | status_system_bits = 0xFF, | ||
24 | // channel voice messages | ||
25 | status_note_off = 0x80, | ||
26 | status_note_on = 0x90, | ||
27 | status_polyphonic_key_pressure = 0xA0, | ||
28 | status_aftertouch = status_polyphonic_key_pressure, | ||
29 | status_control_change = 0xB0, | ||
30 | status_program_change = 0xC0, | ||
31 | status_channel_pressure = 0xD0, | ||
32 | status_pitch_wheel_change = 0xE0, | ||
33 | status_system = 0xF0, | ||
34 | // system common messages | ||
35 | status_system_sysex = 0xF0, | ||
36 | status_system_MTC_quarter_frame = 0xF1, | ||
37 | status_system_song_position_pointer = 0xF2, | ||
38 | status_system_song_select = 0xF3, | ||
39 | status_system_tune_request = 0xF6, | ||
40 | status_system_end_of_sysex = 0xF7, | ||
41 | // system real-time messages | ||
42 | status_system_timing_clock = 0xF8, | ||
43 | status_system_midi_clock = status_system_timing_clock, | ||
44 | status_system_midi_tick = 0xF9, | ||
45 | status_system_start = 0xFA, | ||
46 | status_system_midi_start = status_system_start, | ||
47 | status_system_continue = 0xFB, | ||
48 | status_system_midi_continue = status_system_continue, | ||
49 | status_system_stop = 0xFC, | ||
50 | status_system_midi_stop = status_system_stop, | ||
51 | status_system_active_sense = 0xFE, | ||
52 | status_system_rest = 0xFF, | ||
53 | status_system_reset = status_system_rest, | ||
54 | // midi file specific | ||
55 | status_system_meta = 0xFF | ||
56 | }; | ||
57 | enum { | ||
58 | // meta events | ||
59 | meta_sequence_number = 0x00, | ||
60 | meta_text = 0x01, | ||
61 | meta_copyright = 0x02, | ||
62 | meta_seq_track_name = 0x03, | ||
63 | meta_instrument = 0x04, | ||
64 | meta_lyric = 0x05, | ||
65 | meta_marker = 0x06, | ||
66 | meta_cue_point = 0x07, | ||
67 | meta_patch_name = 0x08, | ||
68 | meta_port_name = 0x09, | ||
69 | meta_EOT = 0x2F, | ||
70 | meta_tempo = 0x51, | ||
71 | meta_SMPTE_offset = 0x54, | ||
72 | meta_time_sig = 0x58, | ||
73 | meta_key_sig = 0x59, | ||
74 | meta_proprietary = 0x7F, | ||
75 | // obsolete meta events | ||
76 | meta_midi_channel = 0x20, | ||
77 | meta_midi_port = 0x21 | ||
78 | }; | ||
79 | |||
80 | /** | ||
81 | * MIDI message container | ||
82 | */ | ||
83 | class message_t { | ||
84 | public: | ||
85 | /** | ||
86 | * MIDI status byte | ||
87 | */ | ||
88 | int status; | ||
89 | /** | ||
90 | * MIDI meta event type | ||
91 | */ | ||
92 | int meta_status; | ||
93 | typedef unsigned char byte_t; | ||
94 | typedef vector<byte_t> bytes_t; | ||
95 | /** | ||
96 | * MIDI message data -- content is message-specific | ||
97 | */ | ||
98 | bytes_t data; | ||
99 | |||
100 | message_t() | ||
101 | : status(-1) { } | ||
102 | message_t(const message_t& m) | ||
103 | : status(m.status), meta_status(m.meta_status), data(m.data) { } | ||
104 | |||
105 | message_t& operator=(const message_t& m) { | ||
106 | status = m.status; | ||
107 | meta_status = m.meta_status; | ||
108 | data = m.data; | ||
109 | return *this; | ||
110 | } | ||
111 | |||
112 | /** | ||
113 | * Load MIDI message from the stream | ||
114 | * @param rs reference to the running status | ||
115 | * @param s input stream | ||
116 | */ | ||
117 | void load(int& rs,istream& s); | ||
118 | /** | ||
119 | * Save MIDI message to the stream | ||
120 | * @param rs reference to the running status | ||
121 | * @param s output stream | ||
122 | */ | ||
123 | void save(int& rs,ostream& s) const; | ||
124 | /** | ||
125 | * Calculate the amount of data that would be written to stream in | ||
126 | * case of save() | ||
127 | * @param rs reference to the running status | ||
128 | * @return the number of bytes | ||
129 | */ | ||
130 | unsigned long calculate_save_size(int& rs) const; | ||
131 | |||
132 | /** | ||
133 | * Load data so that we have c bytes of data for the event | ||
134 | * @param s input stream | ||
135 | * @param c size of data needed for the event | ||
136 | */ | ||
137 | void load_data(istream& s,int c); | ||
138 | /** | ||
139 | * Load sysex data from the stream | ||
140 | * @param s input stream | ||
141 | */ | ||
142 | void load_sysex(istream& s); | ||
143 | |||
144 | /** | ||
145 | * Save data to the stream | ||
146 | * @param s output stream | ||
147 | */ | ||
148 | void save_data(ostream& s) const; | ||
149 | /** | ||
150 | * Save data to the stream and verify if the amount of data is | ||
151 | * correct | ||
152 | * @param s output stream | ||
153 | * @param c data bytes count | ||
154 | */ | ||
155 | void save_data(ostream& s,int c) const; | ||
156 | /** | ||
157 | * Save sysex data to the stream | ||
158 | * @param s output stream | ||
159 | */ | ||
160 | void save_sysex(ostream& s) const; | ||
161 | |||
162 | /** | ||
163 | * See if the event is meta event | ||
164 | * @return true if yes | ||
165 | */ | ||
166 | bool is_meta() const { | ||
167 | return status==status_system_meta; | ||
168 | } | ||
169 | /** | ||
170 | * Check whether the event is a specific meta event | ||
171 | * @param meta meta event type | ||
172 | * @return true if yes | ||
173 | */ | ||
174 | bool is_meta(int meta) const { | ||
175 | return is_meta() && (meta_status==meta); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * See if the event is system event | ||
180 | * @return true if yes | ||
181 | */ | ||
182 | bool is_system() const { | ||
183 | return (status&status_event_bits)==status_system && !is_meta(); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Dump textual representation of midi message to stream | ||
188 | * @param s output stream | ||
189 | */ | ||
190 | void dump(ostream& s) const; | ||
191 | |||
192 | }; | ||
193 | |||
194 | inline ostream& operator<<(ostream& s,const message_t& m) { | ||
195 | m.dump(s); return s; | ||
196 | } | ||
197 | |||
198 | } | ||
199 | |||
200 | #endif /* __MIDILLO_MESSAGE_H */ | ||