在 C 中生成 MIDI 文件
Posted
技术标签:
【中文标题】在 C 中生成 MIDI 文件【英文标题】:Generating MIDI-files in C 【发布时间】:2017-12-22 00:18:02 【问题描述】:我正在尝试,但文件的标题块有点问题。
所以 MIDI 头的形式是:
块类型-长度-格式-ntrks-划分
块类型是四个ASCII字符'MThd';长度是数字 6 的 32 位表示(高字节在前)。其余为 16 位。
所以我为 Header 创建了一个结构体,如下所示:
struct headerStruct
char chunktype[4]; //MThd
long length; //32bit length
int format;//16bit format
int ntraks;//16bit number of tracks
int division;//16bit division
;
然后我在代码中创建结构:
struct headerStruct *mthd = malloc(sizeof(struct headerStruct));
strncpy(mthd->chunktype, "MThd",4);
mthd->length = 6;
mthd->format = 0;
mthd->ntraks = 1;
mthd->division = 96;
然后我用 fwrite 编写文件(还有这里没有介绍的其他内容),我将保留这部分代码。但是,如果我用 xxd 查看二进制/十六进制并将其与使用 ableton 创建的正确 midi 文件进行比较,我会发现它们是不同的,而我的不正确。
正确的十六进制 midi 标头:
4d54 6864 0000 0006 0000 0001 0060
我不正确的十六进制 midi 标头:
4d54 6864 0000 0000 0600 0000 0000 0000 0000 0100 6000 0000
这是什么原因造成的?是字节顺序问题还是我使用了错误的数据类型。我在 64 位操作系统 X 10.10.5 上。因为如果我理解正确,标题中的 16 位部分应该是整数和长度(32 位)长等等。如果这是一个字节顺序的事情,我该如何纠正这个问题。我在这里阅读了一些字节顺序主题,但并没有真正理解它们。
以下是 pdf 的链接,以获取有关 MIDI 的更多信息: https://www.cs.cmu.edu/~music/cmsip/readings/Standard-MIDI-file-format-updated.pdf
【问题讨论】:
我猜你的int
s 是 32 位的。尝试 short
获取 16 位值。
我认为你是对的,但它们的顺序仍然错误,长度为 int 并且剩余短裤的十六进制看起来像这样:4d54 6864 0600 0000 0000 0100 6000 0000 应该是这样的:4d54 6864 0000 0006 0000 0001 0060 所以还有16位太多了。我想知道是不是因为 strncpy 和额外的 \0?
我建议您包含stdint.h
并使用uint32_t
、uint16_t
等。这将更便携(因为int
也可以是 32 位)。
检查其他生成 MIDI 文件的程序,例如,git.alsa-project.org/?p=alsa-utils.git;a=blob;f=seq/aplaymidi/…。
谢谢 CL 我会经历的! Myst 我在 *** 中查看了其他一些主题中的内容,但我在 C 方面没有那么丰富的经验,那么这些 uint32_t uint16_t 是如何工作的?就像文件开头的某种定义一样吗?
【参考方案1】:
MIDI 文件要求值以大端字节顺序写入,也称为“网络顺序”;您可能会发现 htnol
(3) 和 htons
(3) 很有用:
#include <arpa/inet.h>
...
mthd->length = htonl(6);
mthd->ntraks = htons(1);
...
【讨论】:
是的,就是这样!非常感谢!现在,ableton 接受了文件并且很好......崩溃了:D 猜猜我现在需要处理 MTrk 部分。 嗯。即使我将结构的 int 更改为 shorts 并将 long 更改为 int,仍然有 16 位太多。现在十六进制是这样的: 4d54 6864 0000 0006 0000 0001 0060 0000 所以最后两个字节太多了。他们来自哪里? 如何将结构写入文件?不要使用sizeof(* mthd)
,因为那是4字节的倍数(long
的对齐方式)。一个一个地写字段。
是的,成功了!太好了,非常感谢!为什么是4字节的倍数?
它是 4 的倍数,因为它包含一个 long
成员,并且编译器需要使结构的大小成为 long
所需对齐的倍数,以防你创建一个数组其中。以上是关于在 C 中生成 MIDI 文件的主要内容,如果未能解决你的问题,请参考以下文章
[转]如何禁止 IIS 在 C:WindowsSystem32LogFilesHTTPERR 中生成日志文件