解析フォーマット:Unreal Engineのサウンドパッケージ





前回、UE3エンジンのサウンドとテキストの関係の研究について話しました。 今日は、より単純なケースをより詳細に検討します-Bioshock Infiniteサウンドパッケージの分析。ロシア語でのこのゲームの完全なローカライズが始まりました。



リソースの解析は、パズルやクロスワードパズルを解くようなものです。一方から始め、徐々にすべての新しい分野の意味を学び、それ以外のすべてを解きます。 最初は、ゲームのリソースの構造は私たちにとって暗い森のようでした。 しかし、次第にそれらについてより多くのことを学び、あるものが別のものを引き付け、その結果、ゲームのリソースのほとんどすべてが研究され、修正されました:サウンド、テクスチャ、3Dモデル。 テクスチャ、照明と反射マップ、発光電球、ハイライトと影とともにモデルの形で変更された碑文の例は、写真で見ることができます。



しかし、それはすべて一見単純なタスクから始まりました。サウンドがゲーム内のどこにあるのか、どのように置き換えることができるのかを見つけることです。



ゲームフォルダーの内容をざっと見てみると、大きなファイルが「オーディオ」フォルダーにあることがわかります。Pckは、ゲームのすべてのサウンド(フレーズ)を含むパッケージである可能性が高いため、その形式を解析し、サウンドを抽出し、すべて(または一部のそれらの)、およびファイルを組み立てます。



16進エディターで開き、前後にスクロールすると、先頭に見出しがあり、次に各ファイルのデータが含まれたテーブルがあり、実際にはこれらすべてのファイルが次々に接着されていると想定できます。 混乱しないように、大きなファイル(パッケージ全体)を「ファイル」と呼び、小さなファイルを「サウンド」で構成します。 ここでさらに詳しく見てみましょう。





...





見出しから始めましょう。 その中で、最初にAKKRコード(ファイルの種類のサイン、または一部の人々がそれを魔法の言葉と呼ぶ)、次にいくつかの数字、および碑文「english(us)」、「sfx」を確認します。 これらの数字の意味はわかりませんが、後でわかるように、それらは必要ありません。 これらは、パッケージのさまざまなプロパティ、ヘッダーのサイズ、個々のパーツのサイズなどです。 したがって、パッケージ(サウンドファイル)の内容を変更せずに変更するため、ヘッダーをそのままにしておくことができます。 多くの場合、ファイルの全長がまだ含まれているため、変更する必要がありますが、この場合は変更しません。 そうしないと、ヘッダーにこの番号(0xF49668E)が存在することがすぐにわかります。



それでは、テーブルに移りましょう。 繰り返し構造によって常に認識でき、ファイルを「スクロール」しながら、特徴的に「揺らめき」ます。 その内容がわからなくても、通常は行の要素数を決定できますが、どこから始まるのか、要素の数(パケットに含まれる音の数)は正確にはわかりません。 ただし、内容を分析した後、これを判断できます。



表には、原則として、要素の数と、各要素のアドレス(オフセット)および長さが記録されます。 ご覧のとおり、サウンドファイル自体には標準のRIFFヘッダーがあるため、最初のサウンドは0x2ED58(緑)から始まり、長さは0x981C(黄色)、2番目のサウンドは0x38574から始まり、長さは0x20B3などであることがすぐにわかります。 。 また、これらのRIFFヘッダーの数9587(0x2573)をカウントするだけで、その数を調べることもできます。 この数値は、ファイル内の0x54(赤で強調表示)で確認できます。



サウンドの形式が非標準である場合、Dead Spaceで行われたように、目的の形式、または特別なコーデックに変換するためのプログラムを作成する必要があるという事実は言うまでもなく、決定するのはより困難です。 。



これで、テーブルと一緒にパケットヘッダーの全長を取得し、サウンドの数で割ることができます。 最初の音はアドレス0x2ED58(191832)で始まります。 191832/9587 = 20.01ヘッダーの長さがわからないため、数値は整数ではありませんでした。 したがって、テーブル内の各サウンドには20バイトがあります。 5つの32ビットワード、およびテーブルの全長= 9587 * 20 =191740。それにもかかわらず、テーブルがどこから始まるかはまだわかりません。パラメータ。 テーブルの長さしかわからず、残りの191832-191740 = 92バイトがヘッダーに残ります。 191740 = 0x2ECFC-0x14のヘッダーに表示される同様の番号(Ox2ED00)。何らかの理由で4未満です。



次に、テーブルの内容を処理します。 最初の音-0x981Cと0x2ED58の長さとアドレスがわかっており、0x60で見つかります。 この時点でテーブルが開始するとします。 次に、団結、特定の数、そして再び団結があります。 次に、2番目のサウンドの長さとアドレスなどが続きます。 表の最後まで:



  0000981C 0002ED58 00000001 00068064 00000001
 000020B3 00038574 00000001 0007C532 00000001
 00003587 0003A627 00000001 0008A458 00000001
 .....
 00013D1B 0F482973 00000001 00000000 


最後のサウンドはファイルの最後に行くだけであることがわかります(長さ0x13D1Bに開始アドレス0xF482973を加えただけでパッケージファイルの合計長0xF49668Eになります)が、テーブルが途切れ、最初のサウンドにRIFFヘッダーが付きます(ピンク色で強調表示されます)。 そのため、私たちの仮定は間違っていて、テーブルは音の数の直後に開始されます。 アドレス0x58に戻って、次のものを取得します。



  00023E36 00000001 0000981C 0002ED58 00000001
 00068064 00000001 000020B3 00038574 00000001
 0007C532 00000001 00003587 0003A627 00000001
 .....
 3FFE9BEF 00000001 00013D1B 0F482973 00000001
 00000000 


つまり、テーブルには、サウンドごとに9587行があります。いくつかの番号、1つ、サウンドのアドレスと長さ、最後の行です。 テーブルの後、ゼロ、明らかにテーブルが終了した兆候、または何らかの理由で、私たちは知らないので、そのままにしておきます。 このゼロは4バイトで、これを0x2ECFCに追加すると、テーブルの合計長が取得されます。これは、ファイルの先頭の0x14に書き込まれます。



別の方法、たとえば、最初(0x64)と2番目(0x78)のサウンドのアドレスがテーブルのどこに記録されているかを見つけ、すぐに1つのサウンド(20バイト)の記録サイズを計算できます。 次に、テーブルのおおよそのサイズを20で割って、おおよそのレコード数を取得し、実際にファイルに0x54で書き込まれていることを確認します。 または、別の方法で:ファイルの先頭にあるサウンドの数を見つけようとします。ゲームには明らかに数千のサウンドがあるため、適切な数は9587だけです。他のすべての数は小さすぎるか大きすぎます。 次に、このサイズなどでヘッダーサイズを除算します。 一般に、どこから掘り始めたとしても、最終的にはヘッダーとサウンドのテーブルを解析し、レコードの要素数、サイズ、構造を決定する必要があります。



これで、パッケージを個々のサウンドに「カット」しようとする簡単なプログラムを作成できます。 これを実行し、それらをwwise形式から通常のoggに変換することにより、すべてを聞くことができます。 しかし、今では、それらをプッシュバックできることを確認しておくといいでしょう。 ゲームを開始します。 最初は、スクリーンセーバーの直後に画面が暗くなり、女性の声が何かを言います。 このフレーズがどのファイルにあるかを見つけ、自分のフレーズに置き換えて、公式サイトからダウンロードしたwwiseを使用してエンコードします(このパッケージは非営利目的での使用は無料です)。 パッケージを再構築し、フレーズをそれがあった同じ場所に直接挿入するまで。 ゲームを開始します-そしてそれは実際に動作します。 素晴らしい、それから研究を続けます。



テーブル構造に戻りましょう。 3と4の数字は、すでに決定したとおり、長さと住所です。 残りはどういう意味ですか? 実際、これも必要ありません。 2と5の数字は常に1であり、最初の数字はサウンドごとに異なることを確認できます。つまり、これらの数字を覚えておくだけで十分であり、新しいファイルを組み立てるときは、そのままテーブルに入れます。 ゲームが機能しない場合は、それが何であり、なぜそれらが必要なのかを理解できます。



後に、声優と仕事をする過程で、これらの数字が何であるかを知りました。 ゲームには2つのパケットがあり、1つは音声、もう1つは効果音です。 行の最後の数字は、サウンドのタイプ(0エフェクト、1ボイス)です。 XBOXの同じパッケージの内容を見ると、他のユニットの意味が明確になりました。







統一の代わりに、どこにでも0x800があることがわかります。 サウンドがどのように配置されているかを確認すると、これがバイト単位のアライメントの量であると推測できます。 XBOXのパッケージでは、ファイル内のサウンドは2048バイトの境界に揃えられています。 つまり、サウンドの長さが2048の倍数でない場合、ゼロになります。 この「絶滅」の原理がすでにいくつかのパラグラフでどのように説明されているかを見たことがありますが、これは明確に示すのが最も簡単なようです。 音の内容は緑色で強調表示され、それらの間にはゼロがあります。これは同じ種類で、2048バイトの最も近い境界まで続きます。







これで、テーブルの行の最初の数のみが不明のままになります。 0から2 30の範囲で単調に増加する一意の値のように見えます。 これらはサウンドの一意の識別子であり、ゲームがパッケージ内でそれらを見つけるためのハッシュです。 計算式も既知です。



したがって、ゲームのサウンドを変更するには、ファイルパッケージを個別のサウンドファイルに解析し、識別子を記憶し、それを収集して、まったく同じヘッダー、新しいアドレス、および新しいアドレスを作成するプログラムを作成する必要があります音の長さ、そしてすべての音が一緒に畳まれています。 識別子を覚える場所-誰でも好きなようにそれを行います。 テキスト形式、XML、またはファイル名の最後の番号に署名することもできます。 これは、このリストがどのように見えるかです:



  146998 vo_fndr_female_02_taunt_creepy_20943
 426084 vo_vox_male_02_gammaReact_close_20235
 509234 vo_vox_male_06_emotion_scream_21209
 566360 vo_vox_female_04_taunt_22534
 612724 vo_vox_male_10_reload_21286
 971110 vo_vox_male_06_death_21181 


組み立てるときは、常にまったく同じファイル順序を保存する必要があります。 原則として、通常の原則から単純に行動するのに、なぜそうするのか疑問に思う必要はありません。 しかし、実際には、パッケージ内のサウンドの検索は、古いがまだかけがえのない半除算の方法を使用して実行されます-このため、それらは昇順にソートされます。 この例では、最大14回の操作で、一度に1つずつ並べ替える代わりに、すべての9587から目的のサウンドを見つけることができます。 順序を混ぜると、アルゴリズムが機能しなくなり、一部のサウンドが単に見つからず、必要なときに再生されません。



必要なすべての操作を実行するプログラムを作成したとします。 ファイル構造がわかっていれば、これは難しくありません。 そして、再構築されたサウンドでゲームの最初の起動のエキサイティングな瞬間が来ます。 スクリーンセーバーが通過し、画面が暗くなり、音楽が沈静化し、少し間を置くと、ロシアの声が完全に無音で聞こえます。 いいでしょう、それから私たちはすべてを正しくしました。 さらに、幸運なことに、この.pckファイルは自給自足であることが判明したようです-サウンドに関する必要な情報はその中にのみ保存されているため、サウンドの長さと内容を変更したため、何も壊れませんでした。 あなたは声の演技を始めることができます-材料を準備し、俳優に与えるために。



もっとひどかったかもしれません。 一部のゲーム(UE3エンジンを含む)では、パッケージ内のサウンドの変位への参照が他のファイルにあり、最悪の場合、多くの場所にあります。 つまり、ゲーム内の10か所で何らかの種類のサウンドを使用する場合、10個のリンクがあり、2つのオプションがあります。これらすべての場所を検索してリンクを置き換えるか、サウンドを作成して長さを正確にオリジナル。 そして、これは難しく、時には不可能です。 しかし、前述のように、幸運なことに、サウンドは任意の長さに置き換えられ、ゲームは機能しました。



数ヵ月後、作品がすでに本格的であり、かなりの数の役割が表明されていたとき、テスト中にキャラクターの1人が英語で1つのフレーズを話していることがわかったのに驚いたただ口を開きます つまり、いくつかの音を除いてすべてが機能します。 そのようなシーンの例を次に示します。







ここで、ロバートとロザリンドは、プレイヤーにコインを投げ、何が起こるかを推測します。ワシまたは尾。 その瞬間まで、すべてがうまくいき、ダイアログ全体がすでに音声化され、処理され、ゲームに挿入されていました。 そして、ロバートは必要に応じて冷静に、そして静かに始まります:「頭...」、そしてロザリンドは、まったく驚かないで、「...または尾?」



どうして? なぜこれらのフレーズが機能しなかったのか、なぜ異なる方法で? UE3の場合、これは一般的な状況であり、このような驚きに満ちていると言わなければなりません。 この問題を解決するには、他の形式のファイルをさらに解析する必要がありましたが、それは別の話です。



All Articles