93 lines
2.9 KiB
C++
93 lines
2.9 KiB
C++
#pragma once
|
|
#include "rapidjson/document.h"
|
|
#include "rapidjson/filereadstream.h"
|
|
#include <cstdio>
|
|
#include <string> // Added: needed for std::string
|
|
#include <vector> // Added: needed for std::vector
|
|
#include <cassert> // Added: needed for assert
|
|
|
|
struct Note {
|
|
std::string name;
|
|
int midi;
|
|
int duration_ticks;
|
|
int duration_ms; // Duration of the note in milliseconds
|
|
int ticks;
|
|
int position_ms; // How many milliseconds into the song the note occurs
|
|
};
|
|
|
|
struct Instrument {
|
|
std::string family;
|
|
int number;
|
|
};
|
|
|
|
struct Track {
|
|
std::string name;
|
|
Instrument instrument;
|
|
std::vector<Note> notes;
|
|
};
|
|
|
|
struct Header {
|
|
std::string name;
|
|
std::string artist;
|
|
int ppq;
|
|
float bpm;
|
|
};
|
|
|
|
struct Song {
|
|
Header header;
|
|
std::vector<Track> tracks;
|
|
};
|
|
|
|
Song parseSong(const rapidjson::Document& doc) {
|
|
assert(doc.IsObject());
|
|
|
|
Song song;
|
|
|
|
if (doc.HasMember("header") && doc["header"].IsObject()) {
|
|
const auto& h = doc["header"].GetObject();
|
|
Header header;
|
|
header.name = h.HasMember("name") && h["name"].IsString() ? h["name"].GetString() : "";
|
|
header.artist = h.HasMember("artist") && h["artist"].IsString() ? h["artist"].GetString() : "";
|
|
header.ppq = h["ppq"].GetInt();
|
|
printf("header has tempos: %d\n", h.HasMember("tempos"));
|
|
if (h.HasMember("tempos") && h["tempos"].IsArray()) {
|
|
const auto& tempos = h["tempos"].GetArray();
|
|
header.bpm = tempos[0]["bpm"].GetFloat();
|
|
}
|
|
song.header = header;
|
|
}
|
|
|
|
if (doc.HasMember("tracks") && doc["tracks"].IsArray()) {
|
|
const auto& a = doc["tracks"].GetArray();
|
|
for (auto& t : a) {
|
|
Track track;
|
|
track.name = t["name"].GetString();
|
|
|
|
if (t.HasMember("instrument") && t["instrument"].IsObject()) { // Fixed: added closing parenthesis
|
|
const auto& i = t["instrument"].GetObject();
|
|
Instrument instrument;
|
|
instrument.family = i["family"].GetString();
|
|
instrument.number = i["number"].GetInt();
|
|
track.instrument = instrument;
|
|
} // Fixed: removed extra closing parenthesis
|
|
|
|
if (t.HasMember("notes") && t["notes"].IsArray()) {
|
|
const auto& notes = t["notes"].GetArray();
|
|
for (auto& n : notes) {
|
|
Note note;
|
|
note.name = n["name"].GetString();
|
|
note.midi = n["midi"].GetInt();
|
|
note.duration_ticks = n["durationTicks"].GetInt();
|
|
note.duration_ms = n["duration"].GetFloat() * 1000;
|
|
note.ticks = n["ticks"].GetInt();
|
|
note.position_ms = n["time"].GetFloat() * 1000;
|
|
track.notes.push_back(note);
|
|
}
|
|
}
|
|
|
|
song.tracks.push_back(track);
|
|
}
|
|
}
|
|
|
|
return song;
|
|
} |