summaryrefslogtreecommitdiffabout
path: root/include/midillo/message.h
Side-by-side diff
Diffstat (limited to 'include/midillo/message.h') (more/less context) (ignore whitespace changes)
-rw-r--r--include/midillo/message.h200
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 @@
+#ifndef __MIDILLO_MESSAGE_H
+#define __MIDILLO_MESSAGE_H
+
+#include <istream>
+#include <ostream>
+#include <vector>
+
+/**
+ * @file
+ * @brief MIDI message
+ */
+
+namespace midillo {
+ using std::istream;
+ using std::ostream;
+ using std::vector;
+
+ enum {
+ // bits
+ status_bit = 0x80,
+ status_event_bits = 0xF0,
+ status_channel_bits = 0x0F,
+ status_system_bits = 0xFF,
+ // channel voice messages
+ status_note_off = 0x80,
+ status_note_on = 0x90,
+ status_polyphonic_key_pressure = 0xA0,
+ status_aftertouch = status_polyphonic_key_pressure,
+ status_control_change = 0xB0,
+ status_program_change = 0xC0,
+ status_channel_pressure = 0xD0,
+ status_pitch_wheel_change = 0xE0,
+ status_system = 0xF0,
+ // system common messages
+ status_system_sysex = 0xF0,
+ status_system_MTC_quarter_frame = 0xF1,
+ status_system_song_position_pointer = 0xF2,
+ status_system_song_select = 0xF3,
+ status_system_tune_request = 0xF6,
+ status_system_end_of_sysex = 0xF7,
+ // system real-time messages
+ status_system_timing_clock = 0xF8,
+ status_system_midi_clock = status_system_timing_clock,
+ status_system_midi_tick = 0xF9,
+ status_system_start = 0xFA,
+ status_system_midi_start = status_system_start,
+ status_system_continue = 0xFB,
+ status_system_midi_continue = status_system_continue,
+ status_system_stop = 0xFC,
+ status_system_midi_stop = status_system_stop,
+ status_system_active_sense = 0xFE,
+ status_system_rest = 0xFF,
+ status_system_reset = status_system_rest,
+ // midi file specific
+ status_system_meta = 0xFF
+ };
+ enum {
+ // meta events
+ meta_sequence_number = 0x00,
+ meta_text = 0x01,
+ meta_copyright = 0x02,
+ meta_seq_track_name = 0x03,
+ meta_instrument = 0x04,
+ meta_lyric = 0x05,
+ meta_marker = 0x06,
+ meta_cue_point = 0x07,
+ meta_patch_name = 0x08,
+ meta_port_name = 0x09,
+ meta_EOT = 0x2F,
+ meta_tempo = 0x51,
+ meta_SMPTE_offset = 0x54,
+ meta_time_sig = 0x58,
+ meta_key_sig = 0x59,
+ meta_proprietary = 0x7F,
+ // obsolete meta events
+ meta_midi_channel = 0x20,
+ meta_midi_port = 0x21
+ };
+
+ /**
+ * MIDI message container
+ */
+ class message_t {
+ public:
+ /**
+ * MIDI status byte
+ */
+ int status;
+ /**
+ * MIDI meta event type
+ */
+ int meta_status;
+ typedef unsigned char byte_t;
+ typedef vector<byte_t> bytes_t;
+ /**
+ * MIDI message data -- content is message-specific
+ */
+ bytes_t data;
+
+ message_t()
+ : status(-1) { }
+ message_t(const message_t& m)
+ : status(m.status), meta_status(m.meta_status), data(m.data) { }
+
+ message_t& operator=(const message_t& m) {
+ status = m.status;
+ meta_status = m.meta_status;
+ data = m.data;
+ return *this;
+ }
+
+ /**
+ * Load MIDI message from the stream
+ * @param rs reference to the running status
+ * @param s input stream
+ */
+ void load(int& rs,istream& s);
+ /**
+ * Save MIDI message to the stream
+ * @param rs reference to the running status
+ * @param s output stream
+ */
+ void save(int& rs,ostream& s) const;
+ /**
+ * Calculate the amount of data that would be written to stream in
+ * case of save()
+ * @param rs reference to the running status
+ * @return the number of bytes
+ */
+ unsigned long calculate_save_size(int& rs) const;
+
+ /**
+ * Load data so that we have c bytes of data for the event
+ * @param s input stream
+ * @param c size of data needed for the event
+ */
+ void load_data(istream& s,int c);
+ /**
+ * Load sysex data from the stream
+ * @param s input stream
+ */
+ void load_sysex(istream& s);
+
+ /**
+ * Save data to the stream
+ * @param s output stream
+ */
+ void save_data(ostream& s) const;
+ /**
+ * Save data to the stream and verify if the amount of data is
+ * correct
+ * @param s output stream
+ * @param c data bytes count
+ */
+ void save_data(ostream& s,int c) const;
+ /**
+ * Save sysex data to the stream
+ * @param s output stream
+ */
+ void save_sysex(ostream& s) const;
+
+ /**
+ * See if the event is meta event
+ * @return true if yes
+ */
+ bool is_meta() const {
+ return status==status_system_meta;
+ }
+ /**
+ * Check whether the event is a specific meta event
+ * @param meta meta event type
+ * @return true if yes
+ */
+ bool is_meta(int meta) const {
+ return is_meta() && (meta_status==meta);
+ }
+
+ /**
+ * See if the event is system event
+ * @return true if yes
+ */
+ bool is_system() const {
+ return (status&status_event_bits)==status_system && !is_meta();
+ }
+
+ /**
+ * Dump textual representation of midi message to stream
+ * @param s output stream
+ */
+ void dump(ostream& s) const;
+
+ };
+
+ inline ostream& operator<<(ostream& s,const message_t& m) {
+ m.dump(s); return s;
+ }
+
+}
+
+#endif /* __MIDILLO_MESSAGE_H */