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

C语言 读取 MIDI文件头部

在C语言中直接读取MIDI文件并不简单,因为MIDI文件是一种包含音乐事件(如音符的开始和结束、控制信号等)的二进制格式,而不是像文本文件那样容易解析。不过,你可以通过以下步骤来实现:

  1. 了解MIDI文件格式
    • MIDI文件有多种格式,最常见的是SMF (Standard MIDI File) 格式,也被称为Type 0、Type 1或Type 2。
    • 你需要了解MIDI文件的各个部分,包括文件头、轨道头和轨道事件等。
  2. 编写解析器
    • 编写一个C程序来读取MIDI文件的二进制内容。
    • 首先,你需要读取文件头以获取文件的整体信息(如文件类型、轨道数等)。
    • 然后,逐个读取轨道头,了解每个轨道的详细信息。
    • 接下来,解析轨道中的MIDI事件,这通常涉及解析时间戳和事件数据。
  3. 处理MIDI事件
    • 对于每个MIDI事件,你需要解析事件数据以了解它是什么类型的事件(如音符开始、音符结束、控制更改等)。
    • 根据事件类型,你可以执行相应的操作,如播放音符、更改音量或发送其他MIDI消息。
  4. 使用库
    • 考虑到MIDI文件的复杂性,你可能希望使用现有的库来帮助解析和处理MIDI文件。
    • 例如,你可以查找支持C语言的MIDI库,如libsmflibmidi(请注意,这些库可能不存在或已过时,因为MIDI文件处理在C语言中并不常见)。
  5. 集成到项目中
    • 一旦你能够解析和处理MIDI文件,你可以将其集成到你的C项目中。
    • 这可能涉及将MIDI事件转换为音频输出(如使用MIDI输出设备或软件合成器)或将MIDI数据转换为其他格式(如MIDI转乐谱)。
  6. 测试和调试
    • 编写测试用例来验证你的MIDI解析器是否能够正确处理各种MIDI文件。
    • 使用调试工具来查找和修复任何错误或问题。

请注意,直接处理MIDI文件需要深入了解MIDI规范和相关文件格式。如果你不熟悉这些概念,可能需要花费一些时间来学习它们。此外,由于MIDI文件的复杂性,编写一个健壮且可靠的MIDI解析器可能是一个相当复杂的任务。

如果你只是想在C语言项目中播放MIDI文件,而不是解析和处理MIDI文件的内部细节,那么一个更简单的方法是使用外部MIDI播放器或库来播放MIDI文件,并通过命令行或API接口与你的C程序进行交互。

 请先看百度百科:MIDI文件格式

编写 mid_head.c 读取 midi 文件头部:

#include <stdio.h>
#include <stdint.h>typedef struct {char ctag[4]; // chunk_tag: MThdint32_t chunk_size;// 指定Midi的格式: 00 00单音轨; 00 01多音轨,且同步; 00 02多音轨,但不同步uint16_t geshi; uint16_t tracks; // 轨道数:=实际音轨数字 +1个全局音轨// 指定基本时间格式类型: 类型1:定义一个四分音符的tick数; //     类型2:定义每秒中SMTPE帧的数量及每个SMTPE帧的ticksuint16_t ticks; char ttag[4]; // track_tag: MTrkuint8_t t_id;uint16_t track_size;
} MidiHeader;uint16_t swapUint16(uint16_t shortValue){return ((shortValue & 0x00FF ) <<8) | ((shortValue & 0xFF00)>>8);
}int32_t swapInt32(int32_t intValue){int32_t temp = 0;temp = ((intValue & 0x000000FF) <<24) +((intValue & 0x0000FF00) <<8) +((intValue & 0x00FF0000) >>8) +((intValue & 0xFF000000) >>24);return temp;
}int main(int argc, char *argv[])
{if (argc < 2) {printf("Usage: %s <filename>\n", argv[0]);return 1;}const char *f1 = argv[1]; // filenameFILE *file = fopen(f1, "rb");if (!file) {perror("Error opening file");return -1;}MidiHeader hd;if (fread(&hd, sizeof(MidiHeader), 1, file) != 1) {fclose(file);perror("Error reading file head");return -1;}// 打印读取到的数据,验证读取成功printf("Chunk tag: %s\n", hd.ctag);printf("Chunk Size: %04d\n", swapInt32(hd.chunk_size));printf("geshi:%d, tracks:%d, ticks:%d\n",swapUint16(hd.geshi),swapUint16(hd.tracks),swapUint16(hd.ticks));printf("Track tag: %s\n", hd.ttag);printf("track id: %x, track Size: %d\n", hd.t_id, swapUint16(hd.track_size));if (fseek(file, swapUint16(hd.track_size)-2, 1) !=0) {fclose(file);perror("Error fseek file ");return -1;}char t1tag[5];if (fread(&t1tag, sizeof(char), 4, file) != 4) {fclose(file);perror("Error reading file head");return -1;}printf("track1 tag: %s\n", t1tag);uint32_t track1_size;if (fread(&track1_size, sizeof(uint32_t), 1, file) != 1) {fclose(file);perror("Error reading file head");return -1;}printf("track1 size: %d\n", swapInt32(track1_size));    fclose(file);return 0;
}

where gcc
D:\Strawberry\c\bin\gcc.exe

编译 gcc mid_head.c -o mid_head.exe

运行 mid_head  happy_birthday.mid

mid_head happy_birthday.mid
Chunk tag: MThd
Chunk Size: 0006
geshi:1, tracks:2, ticks:1024
Track tag: MTrk
Track id: 0, Track Size: 20
Track1 tag: MTrk
track1 size: 247

为了对单个几十MB的.mid 文件采样数据,读取.mid 文件头部 4080 bytes 

Unix 命令 head -c 4080 sample1.mid > temp1.mid

运行 strings temp1.mid

相关文章:

C语言 读取 MIDI文件头部

在C语言中直接读取MIDI文件并不简单&#xff0c;因为MIDI文件是一种包含音乐事件&#xff08;如音符的开始和结束、控制信号等&#xff09;的二进制格式&#xff0c;而不是像文本文件那样容易解析。不过&#xff0c;你可以通过以下步骤来实现&#xff1a; 了解MIDI文件格式&am…...

C# Winform实现五子棋游戏(代完善)

实现了基本的玩法。 BoardController.cs using System;namespace GomokuGame {public class BoardController{private static BoardController instance;private readonly int[,] board;private const int boardSize 15;private BoardController(){board new int[boardSize…...

文档档案管理系统整体建设方案书(实际项目原件word2024)

1.系统概述 1.1.需求描述 1.2.需求分析 1.3.重难点分析 1.4.重难点解决措施 2.系统架构设计 2.1.系统架构图 2.2.关键技术 数据备份技术 3.系统功能设计 3.1.功能清单列表 3.2.基础数据管理 3.3.位置管理 3.4.文档使用 3.5.文档管理 软件全套资料包获取方式①&#xff1a;软件项…...

React与Vue的区别?

一、区别: 1. 语法 Vue采用自己特有的模板语法&#xff1b; React是单向的&#xff0c;采用jsx语法创建react元素。 2.监听数据变化的实现原理不同 Vue2.0 通过Object.defineproperty()方法的getter/setter属性, 实现数据劫持, 每次修改完数据会触发diff算法(双端对比) …...

leetcode 2115.从给定原材料中找到所有可以做出的菜

思路&#xff1a;拓补排序&#xff0c;哈希表 在思路上其实很好发现&#xff0c;我们需要有一个明确的做菜顺序&#xff0c;也就是说需要定下来我们根据原材料先做哪些菜&#xff0c;然后做完该做的菜之后&#xff0c;后来又能做哪些菜。 你也发现了&#xff0c;这个顺序其实…...

Opencompass模型评测教程

模型评测 模型评测非常关键&#xff0c;目前主流的方法主要可以概括为主观评测和客观评测&#xff0c;主观评测又可以分为两种形式&#xff1a;人工判断或者和模型竞技场。客观评测一般采用评测数据集的形式进行模型评测。本教程使用Opencompass工具进行对Internlm2-7b模型进行…...

什么是安全测试,如何进行安全测试?

什么是安全测试&#xff1f; 概述 安全测试是一种旨在识别系统、网络或应用程序中的安全漏洞的测试方法。其目标是确保系统能够抵御恶意攻击&#xff0c;保护数据的机密性、完整性和可用性。安全测试通常包括漏洞扫描、渗透测试、代码审计和安全评估等多个方面。 安全测试的…...

ros的pcl库中对于自己定义的消息,调用pcl库时总是报错 c++

首先定义自己的消息类型 struct CustomPoint { // 定义点类型结构PCL_ADD_POINT4D; // 该点类型有4个元素float intensity 0.0;uint32_t zone;uint32_t ring;uint32_t sector;EIGEN_MAKE_ALIGNED_OPERATOR_NEW // 确保new操作符对齐操作 } EIGEN_ALIGN16; // 强制SSE对齐POIN…...

DataFrame—数据汇总6

文章最前&#xff1a; 我是Octopus&#xff0c;这个名字来源于我的中文名--章鱼&#xff1b;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github &#xff1b;这博客是记录我学习的点点滴滴&#xff0c;如果您对 Python、Java、AI、算法有兴趣&#xff0c;可以关注我的…...

Java入门基础学习笔记41——实体类

实体JavaBean/实体类&#xff1a; 就是一种特殊形式的类。 1&#xff09;这个类中的成员变量都要私有&#xff0c;并且要对外提供相应的getXXX&#xff0c;setXXX的方法。 2&#xff09;类中必须要有一个公共的无参的构造器。其他的构造器可写可不写。 右键菜单中&#xff0…...

【Linux】信号之信号的保存和处理详解

&#x1f916;个人主页&#xff1a;晚风相伴-CSDN博客 &#x1f496;如果觉得内容对你有帮助的话&#xff0c;还请给博主一键三连&#xff08;点赞&#x1f49c;、收藏&#x1f9e1;、关注&#x1f49a;&#xff09;吧 &#x1f64f;如果内容有误或者有写的不好的地方的话&…...

基于Django的图书管理系统

文章目录 前言一、页面展示1.登录2.前端页面3.后端页面 二、项目上传&#xff08;1&#xff09;导入数据库&#xff08;2&#xff09;导入项目&#xff08;3&#xff09;数据库密码修改&#xff08;4&#xff09;进入网站 总结 前言 本网站调用Django编写了图书管理网站&#…...

js实现元素根据鼠标滚轮滚动向左右上下滑动着从模糊到清楚显示出来

html代码 <div ref{test} id"animatedElement" className"not-animated"> <div style{{width:"100px",height:"50px",backgroundColor:"red"}}> </div> </div> JS代码 const te…...

yocto学习

bitbake命令单独编译u-boot&#xff1a; $ bitbake -c compile -f u-boot-imx $ bitbake -c deploy -f u-boot-imx //部署编译生成的u-boot镜像到deploy bitbake命令单独编译kernel&#xff1a; bitbake -c compile -f linux-imx //编译内核 bitbake -c deploy -f linux-imx /…...

【IC设计】牛客网-序列检测习题总结

文章目录 状态机基础知识VL25 输入序列连续的序列检测VL26 含有无关项的序列检测VL27 不重叠序列检测VL28 输入序列不连续的序列检测参考资料 状态机基础知识 VL25 输入序列连续的序列检测 timescale 1ns/1ns module sequence_detect(input clk,input rst_n,input a,output re…...

python爬虫登录到海康相机管理页面

简述 1.最近接到个任务是在管理页面更改相机的某个参数&#xff0c;下载官方的sdk貌似没有提供这个接口&#xff0c;所以只能自己写爬虫登录发请求了。 1.主要步骤 1.1 发送get请求获取到salt&#xff0c;sessionID&#xff0c;challenge等信息 http://admin:123456192.168.…...

9.Docker网络

文章目录 1、Docker网络简介2、常用基本命令3、网络模式对比举例3.1、bridge模式3.2、host模式3.3、none模式3.4、container模式3.5、自定义网络 1、Docker网络简介 作用&#xff1a; 容器间的互联和通信以及端口映射容器IP变动时候可以通过服务名直接进行网络通信而不受到影…...

Windows VS2022 C语言使用 sqlite3.dll 访问 SQLite数据库

今天接到一个学生C语言访问SQLite数据库的的需求: 第一步,SQLite Download Page下载 sqlite3.dll 库 下载解压,发现只有两个文件: 于是使用x64 Native Tools Command Prompt 终端 生成 sqlite3.lib 和 sqlite3.exp文件 LIB -def:sqlite3.def -out:sqlite3.lib -machin…...

java库和包的概念

在Java中&#xff0c;"库"和"包"是两个不同的概念&#xff0c;但它们之间存在着密切的关联。 库&#xff08;Library&#xff09; 定义&#xff1a;库是一组已经编写好的代码和资源&#xff0c;用于解决特定的问题或提供特定的功能。它可以包含一个或多个…...

mysql内存结构

一&#xff1a;逻辑存储结构&#xff1a;表空间->段->区->页->行、 表空间&#xff1a;一个mysql实例对应多个表空间&#xff0c;用于存储记录&#xff0c;索引等数据。 段&#xff1a;分为数据段&#xff0c;索引段&#xff0c;回滚段。innoDB是索引组织表&…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题&#xff0c;进而引发后续程序异常。使用工具进行标准化操作&#xff0c;能有效降低出错概率。 需要快速整理大量文件的技术用户而言&#xff0c;这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB&#xff0c;…...