summaryrefslogtreecommitdiffabout
path: root/include/midillo
Unidiff
Diffstat (limited to 'include/midillo') (more/less context) (ignore whitespace changes)
-rw-r--r--include/midillo/MThd.h74
-rw-r--r--include/midillo/MTrk.h54
-rw-r--r--include/midillo/SMF.h87
-rw-r--r--include/midillo/chunk.h88
-rw-r--r--include/midillo/event.h99
-rw-r--r--include/midillo/exception.h55
-rw-r--r--include/midillo/message.h200
-rw-r--r--include/midillo/util.h63
8 files changed, 720 insertions, 0 deletions
diff --git a/include/midillo/MThd.h b/include/midillo/MThd.h
new file mode 100644
index 0000000..20263cd
--- a/dev/null
+++ b/include/midillo/MThd.h
@@ -0,0 +1,74 @@
1#ifndef __MIDILLO_MTHD_H
2#define __MIDILLO_MTHD_H
3
4#include <istream>
5#include <ostream>
6#include <midillo/chunk.h>
7
8/**
9 * @file
10 * @brief the MThd_t -- MThd header chunk class
11 */
12
13namespace midillo {
14 using std::istream;
15 using std::ostream;
16
17 /**
18 * MThd header chunk container
19 */
20 class MThd_t : public chunk_t {
21 public:
22 enum {
23 fmt_0 = 0, fmt_1 = 1, fmt_2 = 2,
24 fmt_singletrack = fmt_0,
25 fmt_multitrack = fmt_1,
26 fmt_tracksequence = fmt_2
27 };
28 /**
29 * SMF format. 0 for single track, 1 for multitrack, 2 for track
30 * sequence.
31 */
32 int fmt;
33 /**
34 * Number of tracks in the file
35 */
36 int ntracks;
37 /**
38 * The number of pulses per quarter note
39 */
40 int division;
41
42 /**
43 * Load MThd chunk from the stream
44 * @param s input stream
45 */
46 void load(istream& s);
47
48 /**
49 * Read MThd chunk data from the stream. This function assumes that
50 * header is already read.
51 * @param s input stream
52 */
53 void load_data(istream& s);
54
55 /**
56 * Save MThd chunk to the stream
57 * @param s output stream
58 */
59 void save(ostream& s) const;
60
61 /**
62 * Dump textual representation of MThd chunk to stream
63 * @param s output stream
64 */
65 void dump(ostream& s) const;
66 };
67
68 inline ostream& operator<<(ostream& s,const MThd_t& mthd) {
69 mthd.dump(s); return s;
70 }
71
72}
73
74#endif /* MIDILLO_MTHD_H */
diff --git a/include/midillo/MTrk.h b/include/midillo/MTrk.h
new file mode 100644
index 0000000..0884388
--- a/dev/null
+++ b/include/midillo/MTrk.h
@@ -0,0 +1,54 @@
1#ifndef __MIDILLO_MTRK_H
2#define __MIDILLO_MTRK_H
3
4#include <istream>
5#include <ostream>
6#include <list>
7#include <midillo/chunk.h>
8#include <midillo/event.h>
9
10/**
11 * @file
12 * @brief MTrk -- track chunk container
13 */
14
15namespace midillo {
16 using std::istream;
17 using std::ostream;
18
19 /**
20 * MTrk track chunk container class
21 */
22 class MTrk_t : public chunk_t {
23 public:
24 /**
25 * MIDI events contained in the track
26 */
27 events_t events;
28
29 /**
30 * Load MTrk chunk from the stream
31 * @param s input stream
32 */
33 void load(istream& s);
34
35 /**
36 * Save MTrk chunk to the stream
37 * @param s output stream
38 */
39 void save(ostream& s) const;
40
41 /**
42 * Dump textual representation of MTrk chunk to stream
43 * @param s output stream
44 */
45 void dump(ostream& s) const;
46 };
47
48 inline ostream& operator<<(ostream& s,const MTrk_t& mtrk) {
49 mtrk.dump(s); return s;
50 }
51
52}
53
54#endif /* __MIDILLO_MTRK_H */
diff --git a/include/midillo/SMF.h b/include/midillo/SMF.h
new file mode 100644
index 0000000..bec9f7a
--- a/dev/null
+++ b/include/midillo/SMF.h
@@ -0,0 +1,87 @@
1#ifndef __MIDILLO_SMF_H
2#define __MIDILLO_SMF_H
3
4#include <istream>
5#include <ostream>
6#include <list>
7#include <midillo/MThd.h>
8#include <midillo/MTrk.h>
9
10/**
11 * @file
12 * @brief the SMF_t -- standard midi file
13 */
14
15namespace midillo {
16 using std::istream;
17 using std::vector;
18 using std::ostream;
19
20 /**
21 * Standard midi file object
22 */
23 class SMF_t {
24 public:
25 /**
26 * MThd header chunk
27 */
28 MThd_t mthd;
29 /**
30 * The type for collection of MTrk track chunks
31 */
32 typedef list<MTrk_t> tracks_t;
33 /**
34 * MTrk track chunks collection for the file
35 */
36 tracks_t tracks;
37
38 SMF_t() { }
39 /**
40 * Construct object from the file
41 * @see load(const char *f,bool stdinable)
42 */
43 SMF_t(const char *f,bool stdinable=true) { load(f,stdinable); }
44 /**
45 * Construct object from the stream
46 * @see load(istream& s)
47 */
48 SMF_t(istream& s) { load(s); }
49
50 /**
51 * Load MIDI data from the file
52 * @param f filename
53 * @param stdinable true if '-' is treatead as cin input stream
54 */
55 void load(const char *f,bool stdinable=true);
56 /**
57 * Load midi data from the stream
58 * @param s input stream
59 */
60 void load(istream& s);
61
62 /**
63 * Save MIDI data to the file
64 * @param f filename
65 * @param stdoutable true if '-' is treated as cout output stream
66 */
67 void save(const char *f,bool stdoutable=true) const;
68 /**
69 * Save MIDI data to the stream
70 * @param s output stream
71 */
72 void save(ostream& s) const;
73
74 /**
75 * Dump textual representation of SMF to stream
76 * @param s output stream
77 */
78 void dump(ostream& s) const;
79 };
80
81 inline ostream& operator<<(ostream& s,const SMF_t& smf) {
82 smf.dump(s); return s;
83 }
84
85}
86
87#endif /* __MIDILLO_SMF_H */
diff --git a/include/midillo/chunk.h b/include/midillo/chunk.h
new file mode 100644
index 0000000..8b6c034
--- a/dev/null
+++ b/include/midillo/chunk.h
@@ -0,0 +1,88 @@
1#ifndef __MIDILLO_CHUNK_H
2#define __MIDILLO_CHUNK_H
3
4#include <istream>
5#include <ostream>
6
7/**
8 * @file
9 * @brief Generic SMF chunk manipulation
10 */
11
12namespace midillo {
13 using std::istream;
14 using std::ostream;
15
16 enum {
17 chunk_id_MThd = 0x6468544d,
18 chunk_id_MTrk = 0x6b72544d
19 };
20 /**
21 * Chunk header data structure
22 */
23 struct chunk_header_t {
24 /**
25 * Track signature data
26 */
27 union {
28 /**
29 * ASCII representation
30 */
31 char id_chars[4];
32 /**
33 * long integer representation
34 */
35 unsigned long id_number;
36 };
37 /**
38 * Chunk length
39 */
40 unsigned long length;
41
42 chunk_header_t()
43 : id_number(0), length(0) { }
44 chunk_header_t(const chunk_header_t& s)
45 : id_number(s.id_number), length(s.length) { };
46
47 chunk_header_t& operator=(const chunk_header_t& s) {
48 id_number=s.id_number; length=s.length;
49 return *this;
50 }
51
52 /**
53 * Load chunk header from the stream
54 * @param s input stream
55 */
56 void load(istream& s);
57 /**
58 * Save chunk header to the stream
59 * @param s output stream
60 */
61 void save(ostream& s) const;
62
63 /**
64 * Dump textual representation of chunk header to stream
65 * @param s output stream
66 */
67 void dump(ostream& s) const;
68
69 };
70
71 inline ostream& operator<<(ostream& s,const chunk_header_t& ch) {
72 ch.dump(s); return s;
73 }
74
75 /**
76 * Base class for specific chunk containers
77 */
78 class chunk_t {
79 public:
80 /**
81 * Chunk header data
82 */
83 chunk_header_t header;
84 };
85
86}
87
88#endif /* __MIDILLO_CHUNK_H */
diff --git a/include/midillo/event.h b/include/midillo/event.h
new file mode 100644
index 0000000..85f6175
--- a/dev/null
+++ b/include/midillo/event.h
@@ -0,0 +1,99 @@
1#ifndef __MIDILLO_EVENT_H
2#define __MIDILLO_EVENT_H
3
4#include <istream>
5#include <ostream>
6#include <list>
7#include <midillo/message.h>
8
9/**
10 * @file
11 * @brief midi event container
12 */
13
14namespace midillo {
15 using std::istream;
16 using std::ostream;
17 using std::list;
18
19 /**
20 * MIDI event container class
21 */
22 class event_t {
23 public:
24 /**
25 * delta time since the last event
26 */
27 long deltat;
28 /**
29 * MIDI message itself
30 */
31 message_t message;
32
33 /**
34 * Load MIDI event from the stream
35 * @param rs reference to the running status
36 * @param s input stream
37 */
38 void load(int& rs,istream& s);
39
40 /**
41 * Save MIDI event to the stream
42 * @param rs reference to the running status
43 * @param s output stream
44 */
45 void save(int& rs,ostream& s) const;
46
47 /**
48 * Calculate the amount of data that would be written to stream in
49 * case of save
50 * @param rs reference to the running status
51 * @return the number of bytes
52 */
53 unsigned long calculate_save_size(int& rs) const;
54
55 /**
56 * Dump textual representation of event to stream
57 * @param s output stream
58 */
59 void dump(ostream& s) const;
60 };
61
62 inline ostream& operator<<(ostream& s,const event_t& e) {
63 e.dump(s); return s;
64 }
65
66 /**
67 * MIDI events list container
68 */
69 class events_t : public list<event_t> {
70 public:
71
72 /**
73 * Append empty event to the end of the list
74 * @return iterator, pointing to the appended event
75 */
76 iterator append_event();
77
78 /**
79 * Load MIDI events (track data) from the stream
80 * @param s input stream
81 */
82 void load(istream& s);
83 /**
84 * Save MIDI events (track data) to the stream
85 * @param s output stream
86 */
87 void save(ostream& s) const;
88
89 /**
90 * Calculate the size of the track data that would be written to
91 * the stream by save()
92 * @return the number of bytes
93 */
94 unsigned long calculate_save_size() const;
95 };
96
97}
98
99#endif /* __MIDILLO_EVENT_H */
diff --git a/include/midillo/exception.h b/include/midillo/exception.h
new file mode 100644
index 0000000..fb6da27
--- a/dev/null
+++ b/include/midillo/exception.h
@@ -0,0 +1,55 @@
1#ifndef __MIDILLO_EXCEPTION_H
2#define __MIDILLO_EXCEPTION_H
3
4#include <konforka/exception.h>
5
6/**
7 * @file
8 * @brief midillo specific exceptions
9 */
10
11namespace midillo {
12 using std::string;
13
14 /**
15 * Base midillo exception class
16 */
17 class exception : public konforka::exception {
18 public:
19 explicit exception(const string& fi,const string& fu,int l,const string& w)
20 : konforka::exception(fi,fu,l,w) { }
21 };
22
23 class exception_io_error : public exception {
24 public:
25 explicit exception_io_error(const string& fi,const string& fu,int l,const string& w)
26 : exception(fi,fu,l,w) { }
27 };
28
29 class exception_input_error : public exception_io_error {
30 public:
31 explicit exception_input_error(const string& fi,const string& fu,int l,const string& w)
32 : exception_io_error(fi,fu,l,w) { }
33 };
34
35 class exception_invalid_input : public exception_input_error {
36 public:
37 explicit exception_invalid_input(const string& fi,const string& fu,int l,const string& w)
38 : exception_input_error(fi,fu,l,w) { }
39 };
40
41 class exception_unexpected_input : public exception_invalid_input {
42 public:
43 explicit exception_unexpected_input(const string& fi,const string& fu,int l,const string& w)
44 : exception_invalid_input(fi,fu,l,w) { }
45 };
46
47 class exception_output_error : public exception_io_error {
48 public:
49 explicit exception_output_error(const string& fi,const string& fu,int l,const string& w)
50 : exception_io_error(fi,fu,l,w) { }
51 };
52
53};
54
55#endif /* __MIDILLO_EXCEPTION_H */
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
13namespace 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 */
diff --git a/include/midillo/util.h b/include/midillo/util.h
new file mode 100644
index 0000000..f9c8430
--- a/dev/null
+++ b/include/midillo/util.h
@@ -0,0 +1,63 @@
1#ifndef __MIDILLO_UTIL_H
2#define __MIDILLO_UTIL_H
3
4#include <istream>
5#include <ostream>
6
7/**
8 * @file
9 * @brief utilities
10 */
11
12namespace midillo {
13 using std::istream;
14 using std::ostream;
15
16 /**
17 * read 32 bits word from the stream
18 * @param s input stream
19 * @return the data acquired
20 */
21 unsigned long read32(istream& s);
22 /**
23 * read 16 bits word from the stream
24 * @param s input stream
25 * @return the data acquired
26 */
27 unsigned int read16(istream& s);
28 /**
29 * read the variable length quantity from the stream
30 * @param s input stream
31 * @return the data acquired
32 */
33 unsigned long readVL(istream& s);
34
35 /**
36 * write 32 bits word to the stream
37 * @param s output stream
38 * @param d data to write
39 */
40 void write32(ostream& s,unsigned long d);
41 /**
42 * write 16 bits word to the stream
43 * @param s output stream
44 * @param d data to write
45 */
46 void write16(ostream& s,unsigned int d);
47 /**
48 * write the variable length quantity to the stream
49 * @param s output stream
50 * @param d data to write
51 */
52 void writeVL(ostream& s,unsigned long d);
53
54 /**
55 * calculate the amount of data that would be written by writeVL
56 * @param d data that would be written
57 * @return the number of bytes
58 */
59 unsigned long calcVLsize(unsigned long d);
60
61}
62
63#endif /* __MIDILLO_UTIL_H */