-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxmidix_file.cc
More file actions
94 lines (73 loc) · 2.2 KB
/
xmidix_file.cc
File metadata and controls
94 lines (73 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "xmidix_file.h"
#include <spdlog/spdlog.h>
#include <algorithm>
#include <QTextCodec>
#define PARSER_BUF_SIZE 16
std::string decode_string(MidiEvent *event) {
auto txt = dynamic_cast<MidiMessage *>(event)->getMetaContent();
auto codec = QTextCodec::codecForName("Shift-JIS");
auto decoded = codec->toUnicode(txt.c_str());
return decoded.toStdString();
}
void xmidix_file::handle_meta_event(MidiEvent *event, snd_seq_event_t *seq_event) {
if (event->isTempo()) {
snd_seq_ev_set_queue_tempo(seq_event, 0, event->getTempoMicro());
return;
}
if (event->isText()) {
texts.emplace_back(decode_string(event));
return;
}
if (event->isMarkerText()) {
markers.emplace_back(xmidix_marker_t{
event->tick,
decode_string(event)
});
return;
}
if (event->isTrackName()) {
track_names[event->track] = decode_string(event);
return;
}
}
xmidix_file::xmidix_file(const std::string &filename) {
MidiFile midifile;
if (!midifile.read(filename)) {
spdlog::warn("could not open MIDI file...");
return;
}
midifile.joinTracks();
ppqn = midifile.getTicksPerQuarterNote();
snd_midi_event_t *parser;
snd_midi_event_new(PARSER_BUF_SIZE, &parser);
auto midi_events = midifile[0]; // only support single track atm
for (int i = 0; i < midi_events.getEventCount(); i++) {
auto event = midi_events[i];
snd_seq_event_t seq_event;
snd_seq_ev_clear(&seq_event);
snd_midi_event_reset_encode(parser);
auto result = snd_midi_event_encode(parser, event.data(), static_cast<long>(event.size()), &seq_event);
if (result <= 0) {
spdlog::warn("error encoding midi event at tick = {}", event.tick);
continue;
}
if (event.isMeta()) {
handle_meta_event(&event, &seq_event);
}
seq_event.time.tick = event.tick;
events.emplace_back(seq_event);
}
for (const auto& t : texts) {
spdlog::info("text = [{}]", t);
}
for (const auto& m : markers) {
spdlog::info("marker = {}: [{}]", m.tick, m.name);
}
for (const auto& [k, v] : track_names) {
spdlog::info("track = {}: [{}]", k, v);
}
snd_midi_event_free(parser);
}
xmidix_file::~xmidix_file() {
spdlog::debug("destructing xmidix_file");
}