7-Zipアーカイバーのmp3ファイルフィルターの実装

長い間、私の唯一のアーカイバは7-Zipプログラムです。 私はその圧縮率と作業速度が好きなので、ソフトウェア配布の圧縮、写真のコレクションのアーカイブ、音楽リリースの保存など、ほぼすべての場所で使用しています。 オンラインの非営利ラベルから音楽をダウンロードします。音楽は、ほとんどの場合、楽曲やカバーアートを含むアーカイブ(zipまたはrar)の形式で配信されます。 ダウンロード後、アーカイブは7-Zipで圧縮され、そのままハードディスクに保存されます。 音楽を聴くために、現代のプレーヤーは音楽を直接再生できるため(特にFoobar2000を使用しています)、アーカイブを解凍する必要はありません。 そして、すべてのアーカイブが占有するメモリの総量はまだハードドライブの容量からは程遠いですが、mp3ファイルの圧縮率を改善するというアイデアを取り始めました。 私の先生の一人が言ったように、課題は不満な不安感です。 それはまさに私が感じていた。 トランスコーダーを発明したくなかったので、冗長な情報を削除するフィルターを作成することにしました。





タスク条件の分析



mp3とは、MPEG-1 / 2 / 2.5レイヤー3を意味します。mp3ファイルとは何かを見てみましょう。

したがって、mp3ファイルは多くのフレームで構成され、フレームは相互に接続できます。つまり、1つのフレームをデコードするには、別のフレームを調べる必要がある場合があります。 ファイルには、オーディオデータの前後にタグが含まれる場合があります。 各フレームには1152サンプル(ステレオモードの場合)が保存され、26 msの持続時間があります。 フレームサイズは、使用されるビットレートとサンプリングレートによって異なり、次の式で計算されます。





パディングは、フレームヘッダー内の特別なフラグで、フレームが1バイトでパディングされることを意味します。



フレームは、ヘッダー、検証コード(オプション)、サンプルのデコードに必要な情報(このフレーズのロシア語の翻訳を受け入れられないため、この情報を「サイド情報」と呼びます)、実際にパックされたサンプル、およびエンコードされたサンプルとの直接的な関係:







32ビットヘッダーの構造は次のとおりです。

役職 フィールド長 予定
同期ワード 11 タイトルの検索に使用されます。 11ビットすべてが「1」に設定されます
MPEGバージョン 2
レイヤーインデックス 2
少しの保護 1 設定されていない場合、フレームにはCRCが含まれます
ビットレートインデックス 4
サンプルレートインデックス 2
パディングビット 1 フレームに1バイトが追加されたことを示す同じフラグ
プライベートビット 1 特定の情報を保持します。
チャネルコーディングモード 2 モノラル、ステレオ、ジョイントステレオ、デュアルチャネル
モード拡張 2 ジョイントステレオチャネルエンコーディングモードで使用
著作権ビット 1 このビットが設定されている場合、ファイルのコピーは違法であることを意味します
元のビット 1 このビットが設定されている場合、ファイルが元のメディアにあることを意味します
アクセント(強調) 2 追加のオーディオ処理が必要であることをデコーダに伝えます




実際には、一部のヘッダーフィールドは使用されず、かつ/またはmp3ファイル全体で同じままです。 たとえば、MPEGバージョン、レイヤーインデックス、プライベートビット、著作権ビット、元のビットなど。 ファイルが固定ビットレート(CBR)を使用して作成された場合、ビットレートインデックスフィールドは変更されません。

最初に考えたのは、フレームのすべてのヘッダーフィールドを保存する必要はなく、ファイル全体で変化するヘッダーフィールドのみを保存する必要があるということです。 残りのフィールドは、フィールドの変更ではなく、1回のみ保存できます。 すべてのフレームのヘッダーを調べて、統計を収集し、実際に使用されているフィールドを特定できます。



CRC検証コードは、ヘッダーのすぐ後ろにあります。 フレームヘッダーの最後の16ビットとすべてのサイド情報バイトに対してCRC16アルゴリズムを使用して計算される16ビット整数です。

2番目の考えは、検証コードの計算方法がわかっているため、保存できないことです。 もちろん、フレームからCRCを取り出して捨てる権利はありません。 最初に、エラーが検証コード自体または計算されるバイトに侵入する可能性があるため、それが正しい値を表していることを確認する必要があります。



サイド情報の詳細については詳しく説明しません。 サイド情報は、各フレームで変化する多くのフィールドを持つかなり複雑な構造です。 フレームヘッダーフィールドと同じように、サイドインフォメーションフィールドでも同じトリックを実行することはできません。



サイド情報の後には、ハフマン圧縮オーディオデータが続きます。 実際、ハフマンコードはスケールファクターと交互に変化するため、これは完全に真実ではありませんが、簡単にするために、サイド情報の後、フレームの最後までオーディオデータが配置されると仮定します。



このデータ間にフレームヘッダーシグネチャ(同期ワード)がない場合のみ、他のデータがフレーム間にある可能性があります。



アルゴリズム



7-Zipのソースコードを調べた後、実行可能ファイル(* .exe、* .dll)の圧縮を改善するために設計されたBCJ2フィルターの実装に出会いました。 このフィルターの特徴は、1つの入力と4つの出力があることです。 各出力には独自のエンコーダがあります。 したがって、入力ファイルは4つのストリームに分割され、各ストリームは独自のエンコーダーで圧縮されていることがわかります。



いくつかのexitのアイデアが気に入ったので、フィルターに適用することにしました。

-最初の考えに従って、フレームヘッダーフィールドを1つのストリームにパックする

-2番目のストリームのサイド情報をパックする

-最後に、3番目のストリームで、残りの情報(ハフマンのタグとコード)をパックします



最初の2つのストリームは、アーカイブヘッダーを圧縮するために7-Zip内で使用される設定でLZMAアルゴリズムを使用して圧縮され、3番目のストリームは[アーカイブに追加]ウィンドウでユーザーが選択したアルゴリズムによって圧縮されます。



エンコーダは次のように機能します。ファイルのすべてのフレームが順番に検索されます。 フレームは3つの部分に分かれています。サイド情報はサイド情報ストリームに送信され、ハフマンコードはメイン出力ストリームに送信され、ヘッダーフィールドはバッファに保存されます。 フレームにCRCが存在し、それが真であることが判明した場合、スキップされます。それ以外の場合、その値はアンパック時に復元できるようにヘッダーストリームに転送されます。

各ヘッダーの同期ワード(11ビット)は、単に破棄されます。 ファイル中に変更されなかったフィールドの値は、ヘッダーストリームに1回だけ書き込まれますが、変更フィールドは次々に順番に書き込まれます。



デコーダーはエンコーダーにミラーリングされて機能します。まず、すべてのヘッダーが復元され、次に各フレームの復元が開始されます。 最初のCRCストリームから計算または復元され、その後にサイド情報とフレームの残りが続きます。



実装と実際の結果



実装は特に複雑ではないため、ここに実装する意味はわかりません。 githubに投稿されたソース。 7-Zipでのそのようなフィルター(1つの入力と複数の出力)のサポートが十分に透過的に実装されていないことに注意してください。 はい、ところで、フィルターを開発するとき、7-Zip 9.20のソースが使用されました。

コンパイルされたdllは同じgithubにあります。 彼女は、7-Zipをインストールしたフォルダー内の7z.dllを置き換える必要があります。



作業のテストは、Windows XPオペレーティングシステム、Intel Core 2 6700プロセッサ(2.66 GHz)、および3ギガバイトのRAMを搭載したコンピューターで、総容量16755839778バイト(15.605 GB)の1351ファイルのサンプルで実行されました。 各ファイルは個別にアーカイブに圧縮され、解凍されました。 まず、フィルターを使用せずに、次にフィルターを使用します。 すべての場所でUltra圧縮レベルが使用されました。



フィルターなし フィルター付き
圧縮データの総量 16300442691バイト(15.181 GB) 16064243440バイト(14.961 GB)
パッケージングに費やした合計時間 12181.09秒 11273.47秒
開梱にかかった合計時間 3215.44秒 2744.76秒




保存できるフィルター:

-ハードドライブ上の236199251バイト(〜225 MB)のメモリ

-パッケージで908秒(〜15分)

-開梱で407秒(〜8分)



ご覧のように、パッケージング速度は8%増加し、解凍速度は最大15%増加しました。



おわりに



このフィルターにより、mp3ファイルの圧縮率が1.5%向上しました。 フィルターは圧縮データで機能するため、この結果は未解決とは言えませんが、悪いとも言えません。

以上です。 ご清聴ありがとうございました。



All Articles