用C语言生成MIDI文件

用C语言生成MIDI文件,c,midi,C,Midi,我试图用C语言生成MIDI文件,但文件的头块有点问题 因此,MIDI标头的形式为: 块类型长度格式ntrks分区 区块类型是四个ASCII字符“MThd”;长度是数字6的32位表示形式(高字节优先)。其余的是16位 因此,我为标题创建了一个结构,如下所示: struct headerStruct { char chunktype[4]; //MThd long length; //32bit length int format;//16bit format int

我试图用C语言生成MIDI文件,但文件的头块有点问题

因此,MIDI标头的形式为:

块类型长度格式ntrks分区

区块类型是四个ASCII字符“MThd”;长度是数字6的32位表示形式(高字节优先)。其余的是16位

因此,我为标题创建了一个结构,如下所示:

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 0600 0000 0100 6000 0000

这是什么原因?这是一个endianness问题还是我使用了错误的数据类型。我使用的是64位os X 10.10.5。因为如果我理解正确,报头中的16位部分应该是int,长度(32位)应该是long,以此类推。如果这是一个长期的事情,我如何才能纠正这一点。我在这里读了一些endianness主题,但并不真正理解它们

有关MIDI的更多信息,请参见pdf的链接:

MIDI文件要求以大端字节顺序写入值,即“网络顺序”;您可能会发现和
htons
(3)非常有用:

#包括
...
mthd->长度=htonl(6);
mthd->ntraks=htons(1);
...

MIDI文件要求以大端字节顺序(也称为“网络顺序”)写入值;您可能会发现和
htons
(3)非常有用:

#包括
...
mthd->长度=htonl(6);
mthd->ntraks=htons(1);
...


我猜你的
int
s是32位的。尝试
short
获取16位值。我认为您是对的,但它们的顺序仍然错误,长度为int,其余为short。十六进制看起来是:4d54 6864 0600 0000 0100 6000 0000,应该是:4d54 6864 0000 0006 0000 0001 0060,因此仍然有16位太多。我想知道这是否是因为strncpy和额外的\0?我建议您包括
stdint.h
,并使用
uint32\u t
uint16\u t
等。这将更便于移植(因为
int
也可以是32位)。请检查其他生成MIDI文件的程序,例如。谢谢。我将介绍一下!Myst我在stackoverflow的其他一些主题中看到了这些,但我在C方面没有那么丰富的经验,那么这些uint32\u t uint16\u t是如何工作的呢?像是文件开头的某种定义吗?我猜你的
int
s是32位的。尝试
short
获取16位值。我认为您是对的,但它们的顺序仍然错误,长度为int,其余为short。十六进制看起来是:4d54 6864 0600 0000 0100 6000 0000,应该是:4d54 6864 0000 0006 0000 0001 0060,因此仍然有16位太多。我想知道这是否是因为strncpy和额外的\0?我建议您包括
stdint.h
,并使用
uint32\u t
uint16\u t
等。这将更便于移植(因为
int
也可以是32位)。请检查其他生成MIDI文件的程序,例如。谢谢。我将介绍一下!Myst我在stackoverflow的其他一些主题中看到了这些,但我在C方面没有那么丰富的经验,那么这些uint32\u t uint16\u t是如何工作的呢?像是文件开头的定义吗?是的,就是这样!谢谢!现在,ableton接受了这个文件,嗯……崩溃:我想我现在需要处理MTrk部分。尽管我将结构的int改为short,long改为int,但仍然有16位太多。现在十六进制是这样的:4d54 6864 0000 0006 0000 0001 0060 0000,所以最后两个字节太多。它们来自何处?如何将结构写入文件?不要使用
sizeof(*mthd)
,因为这是4字节的倍数(长
的对齐方式)。一个接一个地写这些字段。是的,这就成功了!太好了,非常感谢!为什么它是4字节的倍数?它是4的倍数,因为它包含一个
long
成员,编译器需要将结构的大小设置为
long
所需对齐方式的倍数,以防您将其设置为数组。是的,就是这样!谢谢!现在,ableton接受了这个文件,嗯……崩溃:我想我现在需要处理MTrk部分。尽管我将结构的int改为short,long改为int,但仍然有16位太多。现在十六进制是这样的:4d54 6864 0000 0006 0000 0001 0060 0000,所以最后两个字节太多。它们来自何处?如何将结构写入文件?不要使用
sizeof(*mthd)
,因为这是4字节的倍数(长
的对齐方式)。一个接一个地写这些字段。是的,这就成功了!太好了,非常感谢!为什么它是4字节的倍数?它是4的倍数,因为它包含一个
long
成员,编译器需要将结构的大小设置为
long
所需对齐方式的倍数,以防生成它们的数组。