MIDI 文件中的未知日文编码
Unknown Japanese encoding in MIDI file
我有一个我认为包含日语字符的 MIDI 文件(从 https://www.mediafire.com/file/y8wp3bd7at1agnd/Africa.rar/file 下载)。不幸的是,none 我试过的 MIDI 程序似乎能够正确解码日语。
例如,一些乐器名称显示为
ƒp[ƒJƒbƒVƒ‡ƒ“‚Piƒ}ƒbƒv‚Pj•ƒeƒ“ƒ|�
# hex bytes (from od -t x1)
0000000 c2 83 70 c2 81 5b c2 83 4a c2 83 62 c2 83 56 c2
0000020 83 c2 87 c2 83 c2 93 c2 82 50 c2 81 69 c2 83 7d
0000040 c2 83 62 c2 83 76 c2 82 50 c2 81 6a c2 81 c2 95
0000060 c2 83 65 c2 83 c2 93 c2 83 7c ef bf bd
ƒMƒ^[•‰ŠúÝ’è•‚eD‚n�
# hex bytes (from od -t x1)
0000000 c2 83 4d c2 83 5e c2 81 5b c2 81 c2 95 c2 8f c2
0000020 89 c2 8a c3 ba c2 90 c3 9d c2 92 c3 a8 c2 81 c2
0000040 95 c2 82 65 c2 81 44 c2 82 6e ef bf bd
我使用脚本对 iconv
知道的每个转换进行暴力尝试(感谢 https://unix.stackexchange.com/a/184565),我得到了一些 几乎 使用 SHIFT_JISX0213 编码可读。
ツパツーツカツッツシツδ傔δ督1ツ(ツマツッツプツ1ツ)ツ⊊閉テツδ督ポ魹ス
ツギツタツーツ⊊閉渉可甘コツ静敖津ィツ⊊閉Fツ.ツO魹ス
可见有几个片假名单词穿插ツ字:“Percussion”(パーカッシ)、“Map 1”(マップ1)、“Guitar”(ギター)。我不知道如何理解该行的其余部分(我看不懂日文所以我依赖 Google 翻译)。
有人知道正确的编码应该是什么吗?
事实证明,上面的字节串并不存在于原始 MIDI 文件中。它们被我使用的 MIDI reader 破坏了。
借助于
http://www.music.mcgill.ca/~ich/classes/mumt306/StandardMIDIfileformat.html
我能够编写一个简单的 C 程序来提取原始字节,这些字节采用基本的 SHIFT-JIS 编码。
% cc extract_instruments.c -o extract_instruments
% cat AFRICA_55.MID| ./extract_instruments| iconv -f SHIFT-JIS -t UTF8
【 AFRICA / TOTO 】 for SC-55 by 染之介
...
extract_instruments.c:
#include <stdio.h>
/*
Acknowledgement:
ReadVarLen is derived from http://www.music.mcgill.ca/~ich/classes/mumt306/StandardMIDIfileformat.html#BMA2_
(c) Copyright 1999 David Back.
EMail: david@csw2.co.uk
Web: http://www.csw2.co.uk
This document may be freely copied in whole or in part provided the copy contains
this Acknowledgement.
*/
int ReadVarLen() {
register int value;
register char c;
if((value = getchar()) & 0x80) {
value &= 0x7f;
do {
value = (value << 7) + ((c = getchar()) & 0x7f);
} while (c & 0x80);
}
return(value);
}
void ReadAndPrintName(int length) {
char name[length+1];
fgets(name, length+1, stdin);
printf("%s\n", name);
}
int main() {
int c1 = 0;
int c2 = getchar();
while (c2 != EOF) {
// 0xFF03 == Sequence/Track Name
if (c1 == 0xff && c2 == 0x03) {
int length = ReadVarLen();
ReadAndPrintName(length);
}
c1 = c2;
c2 = getchar();
}
return 0;
}
我有一个我认为包含日语字符的 MIDI 文件(从 https://www.mediafire.com/file/y8wp3bd7at1agnd/Africa.rar/file 下载)。不幸的是,none 我试过的 MIDI 程序似乎能够正确解码日语。
例如,一些乐器名称显示为
ƒp[ƒJƒbƒVƒ‡ƒ“‚Piƒ}ƒbƒv‚Pj•ƒeƒ“ƒ|�
# hex bytes (from od -t x1)
0000000 c2 83 70 c2 81 5b c2 83 4a c2 83 62 c2 83 56 c2
0000020 83 c2 87 c2 83 c2 93 c2 82 50 c2 81 69 c2 83 7d
0000040 c2 83 62 c2 83 76 c2 82 50 c2 81 6a c2 81 c2 95
0000060 c2 83 65 c2 83 c2 93 c2 83 7c ef bf bd
ƒMƒ^[•‰ŠúÝ’è•‚eD‚n�
# hex bytes (from od -t x1)
0000000 c2 83 4d c2 83 5e c2 81 5b c2 81 c2 95 c2 8f c2
0000020 89 c2 8a c3 ba c2 90 c3 9d c2 92 c3 a8 c2 81 c2
0000040 95 c2 82 65 c2 81 44 c2 82 6e ef bf bd
我使用脚本对 iconv
知道的每个转换进行暴力尝试(感谢 https://unix.stackexchange.com/a/184565),我得到了一些 几乎 使用 SHIFT_JISX0213 编码可读。
ツパツーツカツッツシツδ傔δ督1ツ(ツマツッツプツ1ツ)ツ⊊閉テツδ督ポ魹ス
ツギツタツーツ⊊閉渉可甘コツ静敖津ィツ⊊閉Fツ.ツO魹ス
可见有几个片假名单词穿插ツ字:“Percussion”(パーカッシ)、“Map 1”(マップ1)、“Guitar”(ギター)。我不知道如何理解该行的其余部分(我看不懂日文所以我依赖 Google 翻译)。
有人知道正确的编码应该是什么吗?
事实证明,上面的字节串并不存在于原始 MIDI 文件中。它们被我使用的 MIDI reader 破坏了。
借助于 http://www.music.mcgill.ca/~ich/classes/mumt306/StandardMIDIfileformat.html 我能够编写一个简单的 C 程序来提取原始字节,这些字节采用基本的 SHIFT-JIS 编码。
% cc extract_instruments.c -o extract_instruments
% cat AFRICA_55.MID| ./extract_instruments| iconv -f SHIFT-JIS -t UTF8
【 AFRICA / TOTO 】 for SC-55 by 染之介
...
extract_instruments.c:
#include <stdio.h>
/*
Acknowledgement:
ReadVarLen is derived from http://www.music.mcgill.ca/~ich/classes/mumt306/StandardMIDIfileformat.html#BMA2_
(c) Copyright 1999 David Back.
EMail: david@csw2.co.uk
Web: http://www.csw2.co.uk
This document may be freely copied in whole or in part provided the copy contains
this Acknowledgement.
*/
int ReadVarLen() {
register int value;
register char c;
if((value = getchar()) & 0x80) {
value &= 0x7f;
do {
value = (value << 7) + ((c = getchar()) & 0x7f);
} while (c & 0x80);
}
return(value);
}
void ReadAndPrintName(int length) {
char name[length+1];
fgets(name, length+1, stdin);
printf("%s\n", name);
}
int main() {
int c1 = 0;
int c2 = getchar();
while (c2 != EOF) {
// 0xFF03 == Sequence/Track Name
if (c1 == 0xff && c2 == 0x03) {
int length = ReadVarLen();
ReadAndPrintName(length);
}
c1 = c2;
c2 = getchar();
}
return 0;
}