先从 Microsoft C++ Build Tools - Visual Studio
下载 1.73GB 安装 "Microsoft C++ Build Tools“
下载:midifile 项目 , 将 midifile-master.zip 解压到 D:\Music-soft
参阅: cmake超详细入门教程
CMake是一个跨平台的自动化建构系统,它使用一个名为 CMakeLists.txt 的文件来描述构建过程。CMake可以运行在Windows和Linux环境下,根据配置的编译器不同,生成符合所在操作系统的 Makefile 文件,在Windows下可以生成VS的工程文件系统。
将 CMake/bin 目录加入到 系统环境变量Path 中
这是一个将开放式基金数据转换为 MIDI音乐的 C++ 程序示例。该程序将基金净值映射为 MIDI音符的音高
/funds/data/660008.csv 文件开头:
date,jz,ljjz
2016-01-04,1.1141,1.1141
2016-01-05,1.1161,1.1161
2016-01-06,1.1350,1.1350
1. midifile 项目--目录结构
2025/03/31 21:18 <DIR> .
2025/03/31 21:18 <DIR> ..
2025/03/18 00:31 185 .gitignore
2025/03/18 00:31 1,566 .travis.yml
2025/03/18 00:31 1,268 appveyor.yml
2025/03/31 21:42 <DIR> bin
2025/03/31 22:15 <DIR> build
2025/03/31 22:15 7,446 CMakeLists.txt
2025/03/18 00:31 <DIR> include
2025/03/31 21:40 <DIR> lib
2025/03/18 00:31 1,287 LICENSE.txt
2025/03/31 21:51 2,727 Makefile
2025/03/18 00:31 5,731 Makefile.library
2025/03/18 00:31 5,270 Makefile.programs
2025/03/31 21:22 <DIR> obj
2025/03/18 00:31 80,092 README.md
2025/03/31 21:40 <DIR> src
2025/03/31 21:57 <DIR> tools
2025/03/18 00:31 <DIR> visual-studio
2.编写 tools/fund2mid.cpp 程序,如下
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include "MidiFile.h"
using namespace std;
using namespace smf;
// CSV 数据结构/
struct FundData {
string date;
double jz;
};
// 解析 CSV 文件(适配三列格式)
vector<FundData> readCSV(const string& filename) {
vector<FundData> data;
ifstream file(filename);
string line;
// 跳过标题行
getline(file, line);
while (getline(file, line)) {
// 使用字符串流分割三列
stringstream ss(line);
string date, jzStr, ljjzStr;
// 按逗号分割字段
getline(ss, date, ',');
getline(ss, jzStr, ',');
getline(ss, ljjzStr); // 第三列不需要使用
if (date > "2024-01-01") {
try {
double jz = stod(jzStr);
data.push_back({date, jz});
} catch (const exception& e) {
cerr << "解析错误: " << line << endl;
}
}
}
return data;
}
// 生成 MIDI 文件
void generateMIDI(const vector<double>& prices, const string& fcode) {
MidiFile midiFile;
midiFile.addTrack();
midiFile.setTicksPerQuarterNote(480);// PPQ 需与 addNoteOff 参数一致
// 计算价格范围
auto [minIt, maxIt] = minmax_element(prices.begin(), prices.end());
double minPrice = *minIt;
double maxPrice = *maxIt;
double priceRange = maxPrice - minPrice;
// 音符范围配置
int minNote = 48; // C3
int maxNote = 84; // C5
if (maxPrice / minPrice < 84.0/48.0) {
maxNote = static_cast<int>(50 * (maxPrice / minPrice));
}
if (maxNote % 2 != 0) maxNote++;
// 添加音符事件
int track = 0;
int channel = 0;
int velocity = 80;
int timeCounter = 0;
int PPQ = 480; // 音符持续时间为 1个四分音符(480 ticks)
for (double price : prices) {
int pitch = (priceRange < 0.001)
? (maxNote + minNote) / 2
: minNote + static_cast<int>((price - minPrice) / priceRange * (maxNote - minNote));
midiFile.addNoteOn(track, timeCounter, channel, pitch, velocity);
midiFile.addNoteOff(track, timeCounter + PPQ, channel, pitch);
timeCounter += PPQ; // ms 间隔1拍, 单位:毫秒
}
// 保存文件
string outputFile = "melo_" + fcode + ".mid";
midiFile.write(outputFile);
cout << "生成成功: " << outputFile << endl;
}
int main(int argc, char** argv) {
if (argc != 2 || strlen(argv[1]) != 6) {
cerr << "用法: " << argv[0] << " <6位基金代码>" << endl;
return 1;
}
string fcode = argv[1];
string csvFile = "/funds/data/" + fcode + ".csv";
try {
auto data = readCSV(csvFile);
if (data.size() < 20) {
cerr << "数据不足: " << data.size() << " < 20" << endl;
return 2;
}
vector<double> prices;
for (auto& entry : data) {
prices.push_back(entry.jz);
}
generateMIDI(prices, fcode);
} catch (const exception& e) {
cerr << "错误: " << e.what() << endl;
return 3;
}
return 0;
}
3.修改后的 CMakeLists.txt 关键部分
# 在 "Programs:" 部分添加你的可执行文件(大约第 66 行附近)
if(NOT BUILD_MIDILIBRARY_ONLY)
# 已有的工具列表...
add_executable(textmidi tools/textmidi.cpp)
add_executable(toascii tools/toascii.cpp)
add_executable(tobin tools/tobin.cpp)
# 添加你的自定义程序
add_executable(fund2mid tools/fund2mid.cpp) # 新增行
# 继续原有工具列表...
add_executable(tobinary tools/tobinary.cpp)
add_executable(todec tools/todec.cpp)
# ...
# 在链接库部分添加(大约第 136 行附近)
target_link_libraries(textmidi midifile)
target_link_libraries(toascii midifile)
target_link_libraries(tobin midifile)
target_link_libraries(fund2mid midifile) # 新增行
target_link_libraries(tobinary midifile)
target_link_libraries(todec midifile)
4.完整修改说明
-
文件结构要求:
midifile/ ├── CMakeLists.txt ├── include/ ├── src/ └── tools/ ├── fund2mid.cpp # 你的程序源码 ├── createmidifile.cpp └── ...其他工具源码
必要修改点:
-
在
add_executable
列表中添加:
add_executable(fund2mid tools/fund2mid.cpp)
在target_link_libraries
部分添加:
target_link_libraries(fund2mid midifile) -
编译验证:
# 生成构建系统 mkdir build cd build cmake .. # 编译项目(Windows) cmake --build . --config Release
适配注意事项
-
C++ 标准要求:
# 建议升级到 C++17(修改第 4 行)
set(CMAKE_CXX_STANDARD 17) -
附件:完整的 CMakeLists.txt
-
运行 cmake --build . --config Release
D:\Music-soft\midifile-master\build> cmake --build . --config Release 适用于 .NET Framework MSBuild 版本 17.9.8+b34f75857 midifile.vcxproj -> D:\Music-soft\midifile-master\build\Release\midifile.lib 80off.vcxproj -> D:\Music-soft\midifile-master\build\Release\80off.exe asciimidi.vcxproj -> D:\Music-soft\midifile-master\build\Release\asciimidi.exe base642midi.vcxproj -> D:\Music-soft\midifile-master\build\Release\base642midi.exe binasc.vcxproj -> D:\Music-soft\midifile-master\build\Release\binasc.exe chaninfo.vcxproj -> D:\Music-soft\midifile-master\build\Release\chaninfo.exe createmidifile.vcxproj -> D:\Music-soft\midifile-master\build\Release\createmidifile.exe createmidifile2.vcxproj -> D:\Music-soft\midifile-master\build\Release\createmidifile2.exe deltatimes.vcxproj -> D:\Music-soft\midifile-master\build\Release\deltatimes.exe drumtab.vcxproj -> D:\Music-soft\midifile-master\build\Release\drumtab.exe durations.vcxproj -> D:\Music-soft\midifile-master\build\Release\durations.exe extractlyrics.vcxproj -> D:\Music-soft\midifile-master\build\Release\extractlyrics.exe fund2mid.cpp D:\Music-soft\midifile-master\tools\fund2mid.cpp(42,39): warning C4101: “e”: 未引用的局部变量 [D:\Music-soft\midifile-master\bu ild\fund2mid.vcxproj] fund2mid.vcxproj -> D:\Music-soft\midifile-master\build\Release\fund2mid.exe maxtick.vcxproj -> D:\Music-soft\midifile-master\build\Release\maxtick.exe mid2hex.vcxproj -> D:\Music-soft\midifile-master\build\Release\mid2hex.exe mid2mat.vcxproj -> D:\Music-soft\midifile-master\build\Release\mid2mat.exe mid2mtb.vcxproj -> D:\Music-soft\midifile-master\build\Release\mid2mtb.exe mid2svg.vcxproj -> D:\Music-soft\midifile-master\build\Release\mid2svg.exe midi2base64.vcxproj -> D:\Music-soft\midifile-master\build\Release\midi2base64.exe midi2binasc.vcxproj -> D:\Music-soft\midifile-master\build\Release\midi2binasc.exe midi2chords.vcxproj -> D:\Music-soft\midifile-master\build\Release\midi2chords.exe midi2melody.vcxproj -> D:\Music-soft\midifile-master\build\Release\midi2melody.exe midi2notes.vcxproj -> D:\Music-soft\midifile-master\build\Release\midi2notes.exe midi2skini.vcxproj -> D:\Music-soft\midifile-master\build\Release\midi2skini.exe midi2text.vcxproj -> D:\Music-soft\midifile-master\build\Release\midi2text.exe midicat.vcxproj -> D:\Music-soft\midifile-master\build\Release\midicat.exe mididiss.vcxproj -> D:\Music-soft\midifile-master\build\Release\mididiss.exe midimean.vcxproj -> D:\Music-soft\midifile-master\build\Release\midimean.exe midimixup.vcxproj -> D:\Music-soft\midifile-master\build\Release\midimixup.exe midirange.vcxproj -> D:\Music-soft\midifile-master\build\Release\midirange.exe midireg.vcxproj -> D:\Music-soft\midifile-master\build\Release\midireg.exe miditime.vcxproj -> D:\Music-soft\midifile-master\build\Release\miditime.exe midiuniq.vcxproj -> D:\Music-soft\midifile-master\build\Release\midiuniq.exe mts-type2.vcxproj -> D:\Music-soft\midifile-master\build\Release\mts-type2.exe mts-type9.vcxproj -> D:\Music-soft\midifile-master\build\Release\mts-type9.exe perfid.vcxproj -> D:\Music-soft\midifile-master\build\Release\perfid.exe readstatus.vcxproj -> D:\Music-soft\midifile-master\build\Release\readstatus.exe redexpress.vcxproj -> D:\Music-soft\midifile-master\build\Release\redexpress.exe removenote.vcxproj -> D:\Music-soft\midifile-master\build\Release\removenote.exe retick.vcxproj -> D:\Music-soft\midifile-master\build\Release\retick.exe shutak.vcxproj -> D:\Music-soft\midifile-master\build\Release\shutak.exe smfdur.vcxproj -> D:\Music-soft\midifile-master\build\Release\smfdur.exe stretch.vcxproj -> D:\Music-soft\midifile-master\build\Release\stretch.exe sysextest.vcxproj -> D:\Music-soft\midifile-master\build\Release\sysextest.exe temper.vcxproj -> D:\Music-soft\midifile-master\build\Release\temper.exe text2midi.vcxproj -> D:\Music-soft\midifile-master\build\Release\text2midi.exe textmidi.vcxproj -> D:\Music-soft\midifile-master\build\Release\textmidi.exe toascii.vcxproj -> D:\Music-soft\midifile-master\build\Release\toascii.exe tobin.vcxproj -> D:\Music-soft\midifile-master\build\Release\tobin.exe tobinary.vcxproj -> D:\Music-soft\midifile-master\build\Release\tobinary.exe todec.vcxproj -> D:\Music-soft\midifile-master\build\Release\todec.exe tohex.vcxproj -> D:\Music-soft\midifile-master\build\Release\tohex.exe type0.vcxproj -> D:\Music-soft\midifile-master\build\Release\type0.exe vlv.vcxproj -> D:\Music-soft\midifile-master\build\Release\vlv.exe
cd D:\Music-soft\midifile-master\build\Release
fund2mid.exe 660008
生成成功: melo_660008.mid
\python\mido_msg.py melo_660008.mid
\python\play_mid.py melo_660008.mid