/* * Filename: SMF.h * * Description: * * * Version: * Created: Wed Mar 11 01:18:30 2020 * Revision: None * Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws * */ #include "message.h" namespace amalgam { typedef std::basic_string ByteString; namespace midi { static unsigned int vlv_length(unsigned char* bytes) { int vlvLength = 1; int i = 0; while ((bytes[i] & 0x80) == 0x80) { vlvLength++; i++; } return vlvLength; } static unsigned int vlv_to_int(unsigned char* bytes) { unsigned char* vlvBytes; unsigned int real = 0; int vlvLength = vlv_length(bytes); vlvBytes = (unsigned char*) calloc(vlvLength, sizeof(unsigned char)); memcpy(vlvBytes,bytes, vlvLength); int i = 0; do { vlvLength--; real |= (vlvBytes[i] & 0x7f) << (7*vlvLength); i++; } while (vlvLength >= 0); free(vlvBytes); return real; } static unsigned int int_vlv_length(unsigned int i) { int bytes = 0; int temp = i; while (temp > 127) { bytes++; temp >>= 7; } return bytes; } static void int_to_vlv(unsigned int i, ByteString ba) { unsigned int bytes = int_vlv_length(i); unsigned int temp = i; for (int i = bytes; i >= 0; i--) { int cv = temp & 0x7f; temp >>= 7; if (i < bytes) cv |= 0x80; ba.insert(ba.begin(),cv); } } class Event { protected: unsigned int delta; ByteString bytes; }; class MidiEvent : Event { Message midi; ByteString toBytes() { if (bytes.length() == 0) { bytes += int_to_vlv(delta, bytes, length); bytes += midi.raw; } return bytes } }; class SysexEvent : MidiEvent { }; class MetaEvent : Event { enum class MetaType : int { SequenceNumber = 0x00, Text, Copyright, TrackName, InstrumentName, Lyric, Marker, Cue, ChannelPrefix = 0x20, End = 0x2F, Tempo = 0x51, SMPTEOffset = 0x54, SequencerSpecificEvent = 0x7f, TimeSigniture = 0x58, KeySigniture = 0x59 }; MetaType mt; unsigned int length; ByteString bytes; } class Track { uint32_t bytelength; unsigned char* bytes; std::list events; ByteString toBytes() { if (bytes.length() == 0) { uint32_t length = 0; for (auto e = events.begin(); e != events.end(); ++e) { ByteString ebytes = e->toBytes(); length += ebytes.length(); bytes += ebytes; } ByteString len; unsigned char* l = (unsigned char* &length); len += l[3]; len += l[2]; len += l[1]; len += l[0]; bytes = "MTrk" + len + bytes; } return bytes; } Track(){} Track(unsigned char* b) { bytes = b; fromBytes(); } Track(std::list e) { events = e; toBytes(); } } class SMF { } } } // Local Variables: // mode: c++ // flycheck-clang-language-standard: "c++11" // End: