↑ページトップへ
表示調整
閉じる
挿絵表示切替ボタン
▼配色
▼行間
▼文字サイズ
▼メニューバー
×閉じる

ブックマークに追加しました

設定
0/400
設定を保存しました
エラーが発生しました
※文字以内
ブックマークを解除しました。

エラーが発生しました。

エラーの原因がわからない場合はヘルプセンターをご確認ください。

ブックマーク機能を使うにはログインしてください。
PR
46/50

エピ34 mp3のデコーダのオプションを調べよう


 ***


 エピ34 mp3のデコーダのオプションを調べよう


 ***


 mp3デコーダの libmad です。


 幾つか調べたmp3デコーダの中で飛び抜けてRMSエラーレベルが大きいのです。


 開発元はISO準拠の方法で評価していて、WEBにて(参考文献の [M10]、LayerIII の RMS-Level の欄)、


   9.000e-8 --- MAD 0.11.4b, x86

   5.555e-8 --- MAD 0.11.4b, x86 (optimized for accuracy)

   7.227e-6 --- MAD 0.11.4b, x86 (optimized for speed)


 という、とても良い評価結果を掲載しています。これは mpg123g 相当です。それにビルド時の指定オプションでRMSレベルが違うようです。


 これは調べてみないと、ですね。


 ***


 ./configure --help の Optional Features から精度に影響がありそうなオプションを選びます。


  --enable-speed optimize for speed over accuracy

  --enable-accuracy optimize for accuracy over speed

  --enable-fpm=ARCH use ARCH-specific fixed-point math routines (one of: intel, arm, mips, sparc, ppc, 64bit, default)

  --enable-sso use the subband synthesis optimization

  --disable-aso disable architecture-specific optimizations

  --disable-debugging do not enable debugging and use more optimization


 速度か精度かを選べるようです。SSO と ASO も気になりますね。optimization とは精度に影響するのでしょうか。


 オプションは6個ありますから組合せは64?、...ARCH が intel と 64bit があって96かな。あ、でも --enable-speed と --enable-accuracy は同時には指定できないようです(エラーになった)。SSO や ASO は調べる意味あるのかを先に調べるべきか。

 うむむ。


 ***


 とりあえず ./configure の次の行を削除


   optimize="$optimize -fforce-mem"


 毎回、Makefile を編集するのは面倒だからここで削ります。


 ***


 オプションの指定で何が変化するかを整理します。


 *


 ./configure では2つのファイルを変更します。Makefile と config.h です。それから make で mad.h を生成します。mad.h はアプリが include するファイルなので、とりあえず関係ないですね。


 Makefile の差分を調べると、--enable-fpm=ARCH の指定によりコンパイル時のオプションが -DFPM_DEFAULT, -DFPM_INTEL, -DFPM_64BIT と変わる。他のオプションでは差分はなさげ。


 config.h は、オプションに応じて、


  #define OPT_SPEED 1 : --enable-speed の場合

  #define OPT_ACCURACY 1 : --enable-accuracy の場合

  #define OPT_SSO 1 : --enable-sso の場合

  #define NDEBUG 1 : --disable-debugging の場合


 と定義する。

 なお、--disable-aso の有無で差異は無かった。ソースコードには ASO_IMDCT などの ASO_で始まる識別子が幾つかあるのだけど。どうしてかな? ...、もしかしてデフォルトは disable で、enable したら機能がオンするとか?


 *


 NDEBUG の有無は、あちこちで参照しているがデバッグ出力の制御だけみたい。精度に影響しないはず。


 FPM_* は、fixed.h, synth.c, version.c で参照

 OPT_* は、fixed.h, synth.c, global.h, version.c で参照


 fixed.h ではオプションで選択する機能、...FPM_INTEL や FPM_64BIT に対応する乗算用関数などを定義している。ここが本体。OPT_ACCURACY も参照。

 FPM_DEFAULT の 32bit x 32bit の処理は、下位ビットを切捨てて、上位ビットだけの乗算をする。これだと精度落ちるよね。

 FPM_INTEL だとインラインアセンブル asm() で、imull 命令により 32bit 乗算。FPM_64BIT はコンパイラ任せ!(つまり、return (((x)*(y))>>28); って感じだ)


 synth.c にて

 ・FPM_DEFAULT が定義済のとき、OPT_SSO を定義する。

 ・OPT_SSO, OPT_SPEED を参照して、処理を切り替えている。


 global.h にて

 ・DEBUG と NDEBUG の同時定義はエラー

 ・OPT_SPEED と OPT_ACCURACY の同時定義はエラー

 ・OPT_SPEED が定義済のとき、OPT_SSO を定義する


 version.c はバージョン表示のための参照。


 *


 整理すると、


  ・FPM の ARCH は、FPM_DEFAULT, FPM_INTEL, FPM_64BIT の3つ


  ・速度/精度は、default, OPT_SPEED, OPT_ACCURACY の3つ


  ・OPT_SSO は、有無の2つ


 この組合せで3x3x2=18パターンを調べる。


 ***

 **

 *


 調べました。


 コンパイルを18回して、内部データを18セット出力して、RMSレベルを求めました。数が多いので dist10 との比較だけです。


       INTEL   64BIT   DEFAULT

   DEF | 9.297e-08 | 9.297e-08 | 1.904e-04 |

   ACC | 5.100e-08 | 5.170e-08 | 1.904e-04 |

   SPD | 1.494e-05 | 1.494e-05 | 4.091e-04 |


   --enable-sso

   DEF | 1.494e-05 | 1.494e-05 | 1.904e-04 |

   ACC | 1.494e-05 | 1.494e-05 | 1.904e-04 |

   SPD | 1.494e-05 | 1.494e-05 | 4.091e-04 |


 デフォルトに比べて FPM_INTEL で精度アップ。FPM_INTEL+OPT_ACCURACY で更にアップ


 SSOオンだと精度ダウン。FPM_DEFAULT も SSOオンですし、OPT_SPEED も SSOオンです。精度が落ちるよー


 *


 FPM_INTEL + OPT_ACCURACY な波形を見ましょう。dist10 の波形との差分です。

 挿絵(By みてみん)

 libmat_i_a は mpg123g と同レベルか、mpg123g は差分が跳ねているところがあるのに比べれば、±1.0e-07 の範囲に収まっている感じです。...、もちろん全体を見ないとダメですけど。印象で語るとね。


 *


 まとめです。


 ビルド時のオプションを変えて libmad の評価をした結果です。


   最良: 5.100e-08 --- libmad INTEL for ACCURACY

   最悪: 4.091e-04 --- libmad Default for SPEED (+SSO)


   参考: 8.003e-08 --- mpg123g


 調べた範囲での結果です。よろしくお願いします。


 見落としたオプションの組合せがある可能性があって、特に ASO 関係で細かい選択肢が隠れていそうです。ソースには謎?なコメントがボツボツとあって、色々と改良を試みている最中の気配がしました。


 ***

 **

 *


 CPUを INTEL と指定するとエラーが劇的に減りました。mpg123g 相当です。...、OPT_ACCURACY を指定すれば mpg123g より良い結果になります(...、ほぼ同レベルですが)。これが libmad の実力なのか。


 ./configure を調べると、--enable-fpm=ARCH の指定がないときはCPUの型をチェックして「i?86-*」だったら INTEL を選択するようです。


 i386(1985年10月)や i486(1989年4月)あるいは i586(Pentium,1993年3月)、i686(Pentium II, 1997年5月、Pentium III,1999年2月、etc)、... x86 の時代ならそれで良かったのです。


 でも現在のCPUは x86_64 です。「i?86-*」とは一致しないのです。


 x86_64 って調べたら、2003年4月(AMD64)とか 2006年7月(Intel64)に発売されたのが最初らしい。x64 という呼び方もある。


 2000年に開発開始して、2004年2月に終了した libmad にとっては、x86_64 は知らないCPUなのでしょう。合掌、...。


 *


 今日のトリビアです。

 

   libmad をビルドするときは --enable-fpm=ARCH を指定すると良いです。


 RMSエラーレベルが1000倍ほど改善します。


 ***


 間違いの指摘とか疑問とか、ご意見・ご感想とかありましたら、どうぞ感想欄に!


 ***

2026.8.31 微推敲


評価をするにはログインしてください。
ブックマークに追加
ブックマーク機能を使うにはログインしてください。
― 新着の感想 ―
このエピソードに感想はまだ書かれていません。
感想一覧
+注意+

特に記載なき場合、掲載されている作品はすべてフィクションであり実在の人物・団体等とは一切関係ありません。
特に記載なき場合、掲載されている作品の著作権は作者にあります(一部作品除く)。
作者以外の方による作品の引用を超える無断転載は禁止しており、行った場合、著作権法の違反となります。