amalgam/src/midi/SMF.h

140 lines
4.0 KiB
C++

/*
* 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<unsigned char> 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<Event> 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<event> e) {
events = e;
toBytes();
}
}
class SMF {
}
}
}
// Local Variables:
// mode: c++
// flycheck-clang-language-standard: "c++11"
// End: