当前位置: 首页 > news >正文

Cmake:Win10 如何编译 midifile C++应用程序

先从 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.完整修改说明

  1. 文件结构要求

    midifile/
    ├── CMakeLists.txt
    ├── include/
    ├── src/
    └── tools/
        ├── fund2mid.cpp      # 你的程序源码
        ├── createmidifile.cpp
        └── ...其他工具源码

    必要修改点

  2. 在 add_executable 列表中添加:
    add_executable(fund2mid tools/fund2mid.cpp)
    在 target_link_libraries 部分添加:
    target_link_libraries(fund2mid midifile)

  3. 编译验证

    # 生成构建系统
    mkdir build
    cd build
    cmake ..
    
    # 编译项目(Windows)
    cmake --build . --config Release
    

 适配注意事项

  1. C++ 标准要求
    # 建议升级到 C++17(修改第 4 行)
    set(CMAKE_CXX_STANDARD 17)

  2. 附件:完整的 CMakeLists.txt

  3. 运行 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 


 

http://www.dtcms.com/a/111477.html

相关文章:

  • leetcode 数组总结篇
  • 湖北师范大学计信学院研究生课程《工程伦理》12.6章节练习
  • 离线部署kubesphere(已有k8s和私有harbor的基础上)
  • 鸿蒙 harmonyOS 网络请求
  • AWS云安全基线:构建企业级安全防护体系的完整指南
  • Ubuntu 安装 JMeter:为你的服务器配置做好准备
  • C++ - 宏基础(简单常量替换宏、函数样式的宏、多行宏、预定义宏、字符串化宏、连接宏、可变参数日志宏)
  • 深入理解C++引用:从基础到现代编程实践
  • 【设计模式】代理模式
  • 如何计算财富自由所需要的价格?
  • mapbox进阶,使用本地dem数据,加载hillshade山体阴影图层
  • 什么是缓存穿透、缓存雪崩、缓存击穿?
  • 使用VS2022远程调试Linux项目问题
  • Linux / Windows 下 Mamba / Vim / Vmamba 安装教程及安装包索引
  • 程序化广告行业(54/89):人群标签、用户标签与Look Alike原理详解
  • 鸿蒙NEXT开发随机工具类(ArkTs)
  • 【大模型基础_毛玉仁】6.5 实践与应用--RAG、Agent、LangChain
  • FPGA--HDLBits网站练习
  • 思维链、思维树、思维图与思维森林在医疗AI编程中的应用蓝图
  • ARXML文件解析-1
  • 14.流程自动化工具:n8n和家庭自动化工具:node-red
  • 解决LeetCode“使括号有效的最少添加”问题
  • Android Hilt 教程
  • 马斯克 AI 超算
  • 蓝桥云客---九宫幻方
  • ngx_ssl_init
  • 【2-7】脉码调制
  • Apache httpclient okhttp(2)
  • 【winodws】夜神模拟器虚拟机启动失败,请进行修复。关闭hyper-v
  • CSS Id 和 Class 选择器学习笔记