北斗効果音
北斗のディスクをPCに入れて見られるHK_B.BINを某ツールにつっこんでもなんか取りきれてない音声があるんですよね。サウザーの必殺技とかレイの「ついに死兆星が見えるようになったか」とか。バイナリエディタで開いてみるとファイル名がそのまま見えるのですが、".wav"や".aif"で検索すると明らかに某ツールが見逃しているファイルがあります。どうやら「32バイトの謎データ・32バイトのファイル名(残りは0x00詰め)・ファイルデータ(とその他あるかも)・パディング」が連続しているようで、1ファイル分(ヘッダから次のデータのヘッダの直前まで)を切りだして某ツールのScanに食わせたら認識したのでこの作業をプログラムにやらせることにしました。
パディング(詰め物)のおかげで64バイトずつ読めばヘッダにぴったり合います(もう少し大きなアラインメントかもね)。パディングにヒットすれば.wavや.aifといったキーワードにひっかかるのでそれで各セクションのオフセットを得た後、バラバラのファイルに抽出します。他の拡張子のデータとか変なものが変なままになりますが、まあツールに食わせるのでいいでしょう。files以下にできたファイル群をScan Directoryに食わせて成功。サウザーの必殺技ボイスがないと話にならんですわ。
#include <stdio.h> #include <string.h> typedef struct { unsigned int unknown[8]; char filename[32]; } HEADER; int is_valid_header(const HEADER *ph) { if (ph->filename[31] == '\0') { if (strstr(ph->filename, ".wav") != NULL || strstr(ph->filename, ".aif") != NULL) { return 1; } } return 0; } void copy_part(FILE *fin, const char *outname, size_t offset, size_t len) { FILE *fout = fopen(outname, "wb"); fseek(fin, offset, SEEK_SET); unsigned char buf[1024]; while (len > 0) { size_t readlen = len > sizeof(buf) ? sizeof(buf) : len; fread(buf, readlen, 1, fin); fwrite(buf, readlen, 1, fout); len -= readlen; } fclose(fout); } int main() { int i; size_t offset[2000]; int count = 0; FILE *fin = fopen("HK_B.BIN", "rb"); HEADER head; while (fread(&head, sizeof(head), 1, fin) == 1) { if (is_valid_header(&head)) { offset[count] = ftell(fin) - sizeof(head); count++; } } printf("%d files.\n", count); for (i = 0; i < count; i++) { char name[16]; sprintf(name, "files/file%04d.bin", i); size_t begin = offset[i]; size_t len; if (i == count - 1) { fseek(fin, 0, SEEK_END); len = ftell(fin); } else { len = offset[i + 1] - offset[i]; } printf("Output: %s\n", name); copy_part(fin, name, begin, len); } fclose(fin); return 0; }
もなど さんの発言 (21:35): *J2A>J2A>JA>J2A *ばすk yappy さんの発言 (21:35): *あるあr *レミリア:3A > 3A > 3A スイカ:2B > 2B > 2B *オレが知ってるのはこれだけだg もなど さんの発言 (21:36): *・・・・・・・・・・・・・・ yappy さんの発言 (21:36): *受け身不能・魔方陣 もなど さんの発言 (21:36): *北斗には魔方陣がないのですk yappy さんの発言 (21:37): *ありませんね!!!