|
本帖最后由 ZackLee 于 2016-12-11 02:40 编辑
我来说明下 ojm 格式。
参考链接:https://open2jam.wordpress.com/the-ojm-documentation/
ojm 的整体格式为:M30_header + (M30_sample_header + 音乐数据区)*sample_count。
ojm 首先是一个 header,28字节:
struct M30_header {
char signature[4]; // 固定字符串 "M30"
int file_format_version; // internal version of the OJM format.
int encryption_flag; // encrypted format: 1 scramble1; 2 scramble2; 4 decode; 8 decrypt; 16 nami
int sample_count; // the number of sound files inside the OJM(we don’t rely on this much)
int samples_offset; // where the data actually starts, usually after the header(28)
int payload_size; // the size of the rest of the file, usually total_file_size – 28(header), in bytes
int padding;
};
这部分结束后,每个 sample 还有一个 header 元信息,52字节:
struct M30_sample_header {
char sample_name[32]; //
int sample_size;
short codec_code;
short unk_fixed;
int unk_music_flag;
short ref;
short unk_zero;
int pcm_samples;
};
其中最重要的就是 sample_size,因为之后每个 sample_size 都是一个独立的音乐数据区,只要抓取出来就是一个 key 音。
需要注意的是,如果 M30_header 的 encryption_flag 为 16,则说明文件使用了 nami 加密,此时需要解密 sample_size 所代表的音乐数据区:
for(int i=0; i+3 < data.length; i=i+4) {
data[i+0] = 'n' XOR data[i+0];
data[i+1] = 'a' XOR data[i+1];
data[i+2] = 'm' XOR data[i+2];
data[i+3] = 'i' XOR data[i+3];
}
若剩余数据不满足4个字符,或说字节,则忽略异或操作。
|
|