【发布时间】:2015-07-21 04:23:23
【问题描述】:
我正在为一个类编写一个 MIDI 文件解析器。我正在逐字节读取值,然后将它们分配给结构中的变量。
这是有问题的代码:
unsigned long deltatime = 0;
unsigned long totaltime = 0;
unsigned char *sbyte = (unsigned char *)malloc(sizeof(unsigned char));
unsigned char meta_e;
printf("\nTrack %d\n", i+1);
n = 0;
while (n<track[i].length)
{
sbyte[0] = 0;
t += ReadVarLen(track[i].data, n, &deltatime);
n += t;
totaltime += deltatime;
if (t == 0) n++;
memcpy(sbyte, &(track[i].data[n]), sizeof(unsigned char));
printf("%lu\t %lu %.2X ",totaltime, deltatime, *sbyte);
if (*sbyte >= 0xFF)
{
unsigned long length = 0;
unsigned char *dta;
meta_e = track[i].data[++n];
printf("%.2X ", meta_e);
n += ReadVarLen(track[i].data, ++n, &length);
printf("%.2lX ", length);
dta = (char *)malloc(sizeof(char) * length);
memcpy(dta, &(track[i].data[++n]), length);
for (j=0;j<length;j++) {printf("%.2X ",dta[j]);}
n += length;
printf("\n");
}
if ((*sbyte >= 0x80) && (*sbyte < 0xF0))
{
if ((*sbyte >= 0x80) && (*sbyte < 0x90)) {
unsigned char *midi_e;
midi_e = (char *)malloc(sizeof(char) * 2);
memcpy(midi_e, &(track[i].data[++n]), 2);
for (i=0;i<2;i++) printf("%.2X ",midi_e[i]);
n += 2;
printf("\n");
}
if ((*sbyte >= 0x90) && (*sbyte < 0xA0)) {
char *midi_e;
midi_e = (char *)malloc(sizeof(char) * 2);
memcpy(midi_e, &(track[i].data[++n]), 2);
for (i=0;i<2;i++) printf("%.2X ",midi_e[i]);
n += 2;
printf("\n");
}
if ((*sbyte >= 0xA0) && (*sbyte < 0xB0)) {
char *midi_e;
midi_e = (char *)malloc(sizeof(char) * 2);
memcpy(midi_e, &(track[i].data[++n]), 2);
for (i=0;i<2;i++) printf("%.2X ",midi_e[i]);
n += 2;
printf("\n");
}
if ((*sbyte >= 0xB0) && (*sbyte < 0xC0)) {
char *midi_e;
midi_e = (char *)malloc(sizeof(char) * 2);
memcpy(midi_e, &(track[i].data[++n]), 2);
for (i=0;i<2;i++) printf("%.2X ",midi_e[i]);
n += 2;
printf("\n");
}
if ((*sbyte >= 0xC0) && (*sbyte < 0xD0)) {
char *midi_e;
midi_e = (char *)malloc(sizeof(char));
memcpy(midi_e, &(track[i].data[++n]),1);
printf("%.2X ",midi_e[0]);
n++;
printf("\n");
}
if ((*sbyte >= 0xD0) && (*sbyte < 0xE0)) {
char *midi_e;
midi_e = (char *)malloc(sizeof(char));
memcpy(midi_e, &(track[i].data[++n]), 1);
printf("%.2X ",midi_e[0]);
n++;
printf("\n");
}
if ((*sbyte >= 0xE0) && (*sbyte < 0xF0)) {
char *midi_e;
midi_e = (char *)malloc(sizeof(char) * 2);
memcpy(midi_e, &(track[i].data[++n]), 2);
for (i=0;i<2;i++) printf("%.2X ",midi_e[i]);
n += 2;
printf("\n");
}
}
}
}
我的输出如下所示:
Track 1
0 0 FF 01 27 43 6F 6D 70 6F 73 65 64 20 41 6E 64 20 53 65 71 75 65 6E 63 65 64 20 42 79 20 4D 69 63 68 61 65 6C 20 53 68 69 72 6B
0 0 FF 54 05 00 00 00 00 00
0 0 FF 51 03 07 A1 20
0 0 FF 58 04 04 02 18 08
0 0 FF 59 02 00 00
0 0 FF 2F 00
Track 2
0 0 FF 21 01 00
0 0 FF 20 01 03
0 0 B3 07 7F
0 0 C7 05
1800 1800 08 1808 8 97 4D 50
输出的倒数第二行是问题所在。应该是:
0 0 C3 44 81
根据我用来检查示例 MIDI 文件的十六进制转换器工具。
我已经逐字节打印出缓冲区,它还说值应该是 C3 而不是 C7。似乎只有当我将缓冲区的值分配给变量 sbyte 时,它才会(在我看来莫名其妙地)更改为 0xC7。
【问题讨论】:
-
要查看的代码相当多,如果没有输入文件,这对我们来说意义不大。请创建MCVE 以获得最佳答案。
-
我在这里遗漏了什么吗?当数据大小为1字节时,用
malloc分配内存,用memcpy复制数据有什么意义?为什么不直接声明unsigned char sbyte?我也注意到你没有free()edsbyte所以你有内存泄漏。midi_e同上,你可以声明一个数组unsigned char midi_e[2]并简化代码。 -
一个程序改变事件不能有多个数据字节;
81将是以下时间戳的一部分。您显示的代码看起来不错(如果不完整);显示输入文件的 hexdump。