-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.cpp
More file actions
147 lines (143 loc) · 5.68 KB
/
Copy pathparser.cpp
File metadata and controls
147 lines (143 loc) · 5.68 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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// parser.cpp
#include "parser.h"
#include <iostream>
#include <fstream>
//构造函数,初始化文件名
ChartParser::ChartParser(const std::string& filename)
: filename(filename),
drag_endbeat0(0.0),
drag_endbeat1(0.0),
drag_endbeat2(0.0),
drag_endbeat3(0.0),
current_drag_endbeat0(0.0),
current_drag_endbeat1(0.0),
current_drag_endbeat2(0.0),
current_drag_endbeat3(0.0)
{
// 其他成员如 offset, bpm 等虽未初始化,但会在 parseMeta 中赋值,
// 而 drag 相关变量必须在此初始化,否则会导致 UB。
}
//解析谱面文件函数
bool ChartParser::parse() {
//打开文件
std::ifstream file(filename);
if (!file.is_open()) {
std::cerr << "Failed to open file: " << filename << std::endl;
return false;
}
//读取文件内容到Json::Value对象
file >> root;
//调用函数解析元数据和音符信息
parseMeta();
parseNotes();
return true;
}
//打印谱面信息函数(调试用)
void ChartParser::printInfo() const {
for (const auto& note : notes) {
std::cout << "Note - Time: " << note.beat.time
<< ", Column: " << note.column
<< ", Long Note: " << note.iflong;
if (note.iflong) {
std::cout << ", End Time: " << note.endbeat.time;
}
std::cout << std::endl;
}
std::cout << "Playing: " << std::endl;
std::cout << "Song Title: " << songTitle << std::endl;
std::cout << "Song Artist: " << songArtist << std::endl;
std::cout << "Sound File: " << sound << std::endl;
std::cout << "Offset: " << offset << std::endl;
std::cout << "BPM: " << bpm << std::endl;
std::cout << "Seconds per Beat: " << secondsPerBeat << std::endl;
}
//解析元数据函数
void ChartParser::parseMeta() {
//曲名与曲师
songTitle = root["meta"]["song"]["title"].asString();
songArtist = root["meta"]["song"]["artist"].asString();
//在最后一个音符中提取音频文件名和偏移量
const Json::Value& lastNote = root["note"][root["note"].size() - 1];
sound = lastNote.get("sound", "").asString();
offset = lastNote.get("offset", 0).asInt();
//获取bpm,计算每拍秒数和每小节秒数
const Json::Value& firstTime = root["time"][0];
bpm = firstTime.get("bpm", 0.0).asDouble();
secondsPerBeat = 60.0 / bpm;
}
//解析音符信息函数
void ChartParser::parseNotes() {
//遍历每个音符
for (const auto& item : root["note"]) {
if (!item.isMember("column")) continue;//跳过最后一项note,因为存储了特殊信息
Note note;
//计算音符时间戳(以秒为单位)
const Json::Value& beatArray = item["beat"];
note.beat.time = (beatArray[0].asInt() * secondsPerBeat) +
beatArray[1].asInt() * (secondsPerBeat / beatArray[2].asInt());
//设置音符所在列
note.column = item["column"].asInt();
if (current_drag_endbeat0 || current_drag_endbeat1 || current_drag_endbeat2 || current_drag_endbeat3) {
//长音符处理(添加drag)
while (current_drag_endbeat0 <= drag_endbeat0 && current_drag_endbeat0 <= note.beat.time) {
Note note1;
note1.beat.time = current_drag_endbeat0;
note1.column = 0;
note1.ifdrag = 1; //标记为drag
notes.push_back(note1);
current_drag_endbeat0 += secondsPerBeat / 4;
}
while (current_drag_endbeat1 <= drag_endbeat1 && current_drag_endbeat1 <= note.beat.time) {
Note note1;
note1.beat.time = current_drag_endbeat1;
note1.column = 1;
note1.ifdrag = 1;
notes.push_back(note1);
current_drag_endbeat1 += secondsPerBeat / 4;
}
while (current_drag_endbeat2 <= drag_endbeat2 && current_drag_endbeat2 <= note.beat.time) {
Note note1;
note1.beat.time = current_drag_endbeat2;
note1.column = 2;
note1.ifdrag = 1;
notes.push_back(note1);
current_drag_endbeat2 += secondsPerBeat / 4;
}
while (current_drag_endbeat3 <= drag_endbeat3 && current_drag_endbeat3 <= note.beat.time) {
Note note1;
note1.beat.time = current_drag_endbeat3;
note1.column = 3;
note1.ifdrag = 1;
notes.push_back(note1);
current_drag_endbeat3 += secondsPerBeat / 4;
}
}
//长音符处理
if (item.isMember("endbeat")) {
note.iflong = 1;
//计算长音符结束时间戳(以秒为单位)
const Json::Value& endbeatArray = item["endbeat"];
note.endbeat.time = (endbeatArray[0].asInt() * secondsPerBeat) +
endbeatArray[1].asInt() * (secondsPerBeat / endbeatArray[2].asInt());
//长音符处理(记录drag)
if (note.column == 0) {
drag_endbeat0 = note.endbeat.time; //记录长音符结束时间
current_drag_endbeat0 = note.beat.time + secondsPerBeat / 4;
}
else if (note.column == 1) {
drag_endbeat1 = note.endbeat.time;
current_drag_endbeat1 = note.beat.time + secondsPerBeat / 4;
}
else if (note.column == 2) {
drag_endbeat2 = note.endbeat.time;
current_drag_endbeat2 = note.beat.time + secondsPerBeat / 4;
}
else if (note.column == 3) {
drag_endbeat3 = note.endbeat.time;
current_drag_endbeat3 = note.beat.time + secondsPerBeat / 4;
}
}
//将解析后音符添加到notes向量中
notes.push_back(note);
}
}