From 0c21a7a0d5b84dc6726462f0fbe51b8c32433262 Mon Sep 17 00:00:00 2001 From: Michael Krelin Date: Fri, 11 Aug 2006 16:01:56 +0000 Subject: initial commit into repository --- (limited to 'include') diff --git a/include/.gitignore b/include/.gitignore new file mode 100644 index 0000000..282522d --- a/dev/null +++ b/include/.gitignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..edfb186 --- a/dev/null +++ b/include/Makefile.am @@ -0,0 +1,5 @@ +nobase_include_HEADERS = \ + midillo/util.h midillo/exception.h \ + midillo/SMF.h \ + midillo/chunk.h midillo/MTrk.h midillo/MThd.h \ + midillo/event.h midillo/message.h 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 @@ +#ifndef __MIDILLO_MTHD_H +#define __MIDILLO_MTHD_H + +#include +#include +#include + +/** + * @file + * @brief the MThd_t -- MThd header chunk class + */ + +namespace midillo { + using std::istream; + using std::ostream; + + /** + * MThd header chunk container + */ + class MThd_t : public chunk_t { + public: + enum { + fmt_0 = 0, fmt_1 = 1, fmt_2 = 2, + fmt_singletrack = fmt_0, + fmt_multitrack = fmt_1, + fmt_tracksequence = fmt_2 + }; + /** + * SMF format. 0 for single track, 1 for multitrack, 2 for track + * sequence. + */ + int fmt; + /** + * Number of tracks in the file + */ + int ntracks; + /** + * The number of pulses per quarter note + */ + int division; + + /** + * Load MThd chunk from the stream + * @param s input stream + */ + void load(istream& s); + + /** + * Read MThd chunk data from the stream. This function assumes that + * header is already read. + * @param s input stream + */ + void load_data(istream& s); + + /** + * Save MThd chunk to the stream + * @param s output stream + */ + void save(ostream& s) const; + + /** + * Dump textual representation of MThd chunk to stream + * @param s output stream + */ + void dump(ostream& s) const; + }; + + inline ostream& operator<<(ostream& s,const MThd_t& mthd) { + mthd.dump(s); return s; + } + +} + +#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 @@ +#ifndef __MIDILLO_MTRK_H +#define __MIDILLO_MTRK_H + +#include +#include +#include +#include +#include + +/** + * @file + * @brief MTrk -- track chunk container + */ + +namespace midillo { + using std::istream; + using std::ostream; + + /** + * MTrk track chunk container class + */ + class MTrk_t : public chunk_t { + public: + /** + * MIDI events contained in the track + */ + events_t events; + + /** + * Load MTrk chunk from the stream + * @param s input stream + */ + void load(istream& s); + + /** + * Save MTrk chunk to the stream + * @param s output stream + */ + void save(ostream& s) const; + + /** + * Dump textual representation of MTrk chunk to stream + * @param s output stream + */ + void dump(ostream& s) const; + }; + + inline ostream& operator<<(ostream& s,const MTrk_t& mtrk) { + mtrk.dump(s); return s; + } + +} + +#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 @@ +#ifndef __MIDILLO_SMF_H +#define __MIDILLO_SMF_H + +#include +#include +#include +#include +#include + +/** + * @file + * @brief the SMF_t -- standard midi file + */ + +namespace midillo { + using std::istream; + using std::vector; + using std::ostream; + + /** + * Standard midi file object + */ + class SMF_t { + public: + /** + * MThd header chunk + */ + MThd_t mthd; + /** + * The type for collection of MTrk track chunks + */ + typedef list tracks_t; + /** + * MTrk track chunks collection for the file + */ + tracks_t tracks; + + SMF_t() { } + /** + * Construct object from the file + * @see load(const char *f,bool stdinable) + */ + SMF_t(const char *f,bool stdinable=true) { load(f,stdinable); } + /** + * Construct object from the stream + * @see load(istream& s) + */ + SMF_t(istream& s) { load(s); } + + /** + * Load MIDI data from the file + * @param f filename + * @param stdinable true if '-' is treatead as cin input stream + */ + void load(const char *f,bool stdinable=true); + /** + * Load midi data from the stream + * @param s input stream + */ + void load(istream& s); + + /** + * Save MIDI data to the file + * @param f filename + * @param stdoutable true if '-' is treated as cout output stream + */ + void save(const char *f,bool stdoutable=true) const; + /** + * Save MIDI data to the stream + * @param s output stream + */ + void save(ostream& s) const; + + /** + * Dump textual representation of SMF to stream + * @param s output stream + */ + void dump(ostream& s) const; + }; + + inline ostream& operator<<(ostream& s,const SMF_t& smf) { + smf.dump(s); return s; + } + +} + +#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 @@ +#ifndef __MIDILLO_CHUNK_H +#define __MIDILLO_CHUNK_H + +#include +#include + +/** + * @file + * @brief Generic SMF chunk manipulation + */ + +namespace midillo { + using std::istream; + using std::ostream; + + enum { + chunk_id_MThd = 0x6468544d, + chunk_id_MTrk = 0x6b72544d + }; + /** + * Chunk header data structure + */ + struct chunk_header_t { + /** + * Track signature data + */ + union { + /** + * ASCII representation + */ + char id_chars[4]; + /** + * long integer representation + */ + unsigned long id_number; + }; + /** + * Chunk length + */ + unsigned long length; + + chunk_header_t() + : id_number(0), length(0) { } + chunk_header_t(const chunk_header_t& s) + : id_number(s.id_number), length(s.length) { }; + + chunk_header_t& operator=(const chunk_header_t& s) { + id_number=s.id_number; length=s.length; + return *this; + } + + /** + * Load chunk header from the stream + * @param s input stream + */ + void load(istream& s); + /** + * Save chunk header to the stream + * @param s output stream + */ + void save(ostream& s) const; + + /** + * Dump textual representation of chunk header to stream + * @param s output stream + */ + void dump(ostream& s) const; + + }; + + inline ostream& operator<<(ostream& s,const chunk_header_t& ch) { + ch.dump(s); return s; + } + + /** + * Base class for specific chunk containers + */ + class chunk_t { + public: + /** + * Chunk header data + */ + chunk_header_t header; + }; + +} + +#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 @@ +#ifndef __MIDILLO_EVENT_H +#define __MIDILLO_EVENT_H + +#include +#include +#include +#include + +/** + * @file + * @brief midi event container + */ + +namespace midillo { + using std::istream; + using std::ostream; + using std::list; + + /** + * MIDI event container class + */ + class event_t { + public: + /** + * delta time since the last event + */ + long deltat; + /** + * MIDI message itself + */ + message_t message; + + /** + * Load MIDI event from the stream + * @param rs reference to the running status + * @param s input stream + */ + void load(int& rs,istream& s); + + /** + * Save MIDI event 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; + + /** + * Dump textual representation of event to stream + * @param s output stream + */ + void dump(ostream& s) const; + }; + + inline ostream& operator<<(ostream& s,const event_t& e) { + e.dump(s); return s; + } + + /** + * MIDI events list container + */ + class events_t : public list { + public: + + /** + * Append empty event to the end of the list + * @return iterator, pointing to the appended event + */ + iterator append_event(); + + /** + * Load MIDI events (track data) from the stream + * @param s input stream + */ + void load(istream& s); + /** + * Save MIDI events (track data) to the stream + * @param s output stream + */ + void save(ostream& s) const; + + /** + * Calculate the size of the track data that would be written to + * the stream by save() + * @return the number of bytes + */ + unsigned long calculate_save_size() const; + }; + +} + +#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 @@ +#ifndef __MIDILLO_EXCEPTION_H +#define __MIDILLO_EXCEPTION_H + +#include + +/** + * @file + * @brief midillo specific exceptions + */ + +namespace midillo { + using std::string; + + /** + * Base midillo exception class + */ + class exception : public konforka::exception { + public: + explicit exception(const string& fi,const string& fu,int l,const string& w) + : konforka::exception(fi,fu,l,w) { } + }; + + class exception_io_error : public exception { + public: + explicit exception_io_error(const string& fi,const string& fu,int l,const string& w) + : exception(fi,fu,l,w) { } + }; + + class exception_input_error : public exception_io_error { + public: + explicit exception_input_error(const string& fi,const string& fu,int l,const string& w) + : exception_io_error(fi,fu,l,w) { } + }; + + class exception_invalid_input : public exception_input_error { + public: + explicit exception_invalid_input(const string& fi,const string& fu,int l,const string& w) + : exception_input_error(fi,fu,l,w) { } + }; + + class exception_unexpected_input : public exception_invalid_input { + public: + explicit exception_unexpected_input(const string& fi,const string& fu,int l,const string& w) + : exception_invalid_input(fi,fu,l,w) { } + }; + + class exception_output_error : public exception_io_error { + public: + explicit exception_output_error(const string& fi,const string& fu,int l,const string& w) + : exception_io_error(fi,fu,l,w) { } + }; + +}; + +#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 @@ +#ifndef __MIDILLO_MESSAGE_H +#define __MIDILLO_MESSAGE_H + +#include +#include +#include + +/** + * @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 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 */ 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 @@ +#ifndef __MIDILLO_UTIL_H +#define __MIDILLO_UTIL_H + +#include +#include + +/** + * @file + * @brief utilities + */ + +namespace midillo { + using std::istream; + using std::ostream; + + /** + * read 32 bits word from the stream + * @param s input stream + * @return the data acquired + */ + unsigned long read32(istream& s); + /** + * read 16 bits word from the stream + * @param s input stream + * @return the data acquired + */ + unsigned int read16(istream& s); + /** + * read the variable length quantity from the stream + * @param s input stream + * @return the data acquired + */ + unsigned long readVL(istream& s); + + /** + * write 32 bits word to the stream + * @param s output stream + * @param d data to write + */ + void write32(ostream& s,unsigned long d); + /** + * write 16 bits word to the stream + * @param s output stream + * @param d data to write + */ + void write16(ostream& s,unsigned int d); + /** + * write the variable length quantity to the stream + * @param s output stream + * @param d data to write + */ + void writeVL(ostream& s,unsigned long d); + + /** + * calculate the amount of data that would be written by writeVL + * @param d data that would be written + * @return the number of bytes + */ + unsigned long calcVLsize(unsigned long d); + +} + +#endif /* __MIDILLO_UTIL_H */ -- cgit v0.9.0.2