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

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

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

エラーが発生しました。

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

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

エピ32 mp3のデコードプログラムはどれでも同じかな


 ***


 エピ32 mp3のデコードプログラムはどれでも同じかな


 ***


 mp3はエンコーダによって音質の違い(こだわり)があるのです。


 なので、CDからコピーしたWAVファイルをmp3に変換するとき、エンコーダによってファイルサイズが(多少?)違います。プレーヤーで再生すると音質が違うと分かるそうです(分かる人にはね)。


 でもデコーダは、...。仕様・形式が定まっているのですから。

 デジタルなデータをデジタルなデータにデコードするのですから同じになるはず。それがデジタルですよね。


 これは圧縮ソフトによって圧縮率が違うのと似ていますね。ZIPファイルのサイズは圧縮ソフトにより違う(...コンマ数%の違いかもですが)。でも解凍すると同じファイルになる。1ビットの違いもなくね。当り前のことです。


 デコーダのことを確認しましょう。


 ***


 音楽プレーヤは、再生時の音響的な処理(エコライザやボリューム調整)、再生モード(連続、リピート、シャッフル、...)、再生時の画面表示が楽しいとか色々ありますね。


 でもデコード用プログラムは、...。mp3をPCMに変換するだけだから。

 あ、...でも処理速度は気になるかな。音楽プレーヤから利用するなら実時間で動かないとダメよね。再生中の負荷は軽い方が良いし。

 違いがあるとしたらその辺ではないかと予想。


 *


 まずは ffmpeg です。


 ググれば沢山の「使い方」の解説があってね、...。Wiki にもページがありますね。動画も音声も多数のファイル形式をサポート。ffpmeg を利用しているアプリは沢山。VLC も ffpmeg を利用しているんだ。

 初版か不明だけど v0.3 が 2000/12/20 リリースで、最新版は 2026/8/4 リリースの v9.0。つい最近ですね。


 mp3の実装は、エンコードは lame(libmp3lame)を利用。デコードは独自な実装。v9.0 では libavcodec/mpegaudiodec_template.c の mp_decode_layer3() で実装している。


 *


 次は lame。


 mp3のエンコードが本体だけど(LAME Ain't an MP3 Encoder, LAME)、デコードもできる。

 開発は 1998/9 頃から。「the 8hz source code」というコードがあって、これへのパッチとして始まり、1998/10/1 に v1.0 をリリースするも「ISO reference code (dist10)」を改造したものを 1998/10/4 に v2.0 としてリリース。2000/5/8 の 3.81beta にて「all ISO code removed!」。Wiki に書いてある通りですね。

 ときどきでてくる Takehiro Tominaga さんって日本人?

 最新版は 2026/7/11 リリースの v4.0。その前は 2017/10/13 の v3.100 だったので9年ぶりでした(2026/7/9 に v3.101 と v3.102 があるけど)。...、その9年間にもソースコードの更新は続いていて凄いよ。


 mp3のデコードは、3.x までは mpglib/layer3.c の decode_layer3_frame() で実装。元は mpg123 のコードだけど、mpglib として改良を続けていた。アセンブラを使っていないので mpg123 ほど速くはない。

 v4.0 では RIP mpglib(...、R.I.P は安らかに眠れ、ね)で、デコードは mpg123(libmpg123)を採用。mp3x って気になるな。


 *


 mpg123。


 mp3プレーヤー。デコード専用。再生中にコンソール操作できる。軽量で高速。CPU 毎にアセンブラで最適化。

 開発開始は 1997 年頃みたい。最新版は 2026/8/2 リリースの v1.33.7。古参ね。


 デコードの実装は、src/libmpg123/layer3.c の INT123_do_layer3() です。


 *


 dist10 です。


 ISO MPEG Audio サブグループが作成配布した参照リファレンス実装。WEB で公開されている。初期の lame は lame とは別に dist10 を入手してパッチを当てる形でビルドしていたって。2000 年頃までの話。

 Readme ファイルには 1997/01/28 の日付がある。


 デコードの実装は lsf/decoder/musicout.c の main() の case 3: にあって、ここから decode.c 内の関数をコールしている。

 ここで使している変数や構造体、関数の名前は、他のプログラムに影響を与えてますね。どのプログラムもほぼ同じ名前を使っている。


 *


 libmad (MAD)


 デコーダ。ライブラリだけど、シンプルな使用例(minimad.c)がついている。

 浮動小数点演算を使わず、固定小数点(整数)演算のみ。なので組込み系のCPUでも実装し易い(らしい)。多数の音楽プレーヤが利用。...、

 README では「MAD is NOT a derivation of the ISO reference source or any other code」と書いている。

 開発開始は 2000 年。2004/02/17 リリースの v0.15.1b が最新(と言うか、これが最後)。

 20年もメンテナンスがないとね。./configure して make したらエラーメッセージが出る(gcc: error: unrecognized command line option '-fforce-mem'; did you mean '-fforce-addr'?)。Makefile から '-fforce-mem' を削除したらビルドできたけど。...、コンパイラ側の変更があったのが原因。


 デコードの実装は layer3.c の III_decode()。


 ***


 ffmpeg は使うとして。エンコードは lame で、デコードは mpg123。この3つが中心かな。


 libmad は幾つかの脆弱性(セキュリティ上の問題)が指摘されているけどメンテナンスがないのが不安なんだな。ローカルのみで使うなら関係ないけど。

 lame は脆弱性の指摘があったけど v3.100 で修正したし、mpg123 は脆弱性の報告と同時にパッチ提供があるようです。...、だから本当に安全かどうかは分らないけど大丈夫そう。


 ***

 **

 *


 mp3ファイルを WAV または PCM に変換します。変換方法は各々、次のコマンドで行います。


 ■ffmpeg-3.4.2-2

 ffmpeg -i test.mp3 a.wav


 オプション -i で入力ファイル名(mp3ファイル)と、出力ファイル名を与える。出力は WAV 形式なので PCM データを取り出すには 'data' を検索。0x90 番地にある。


 ■lame3.100.1

 ./lame --decode test.mp3 a.wav


 ...まあ、mpg123 と同じかな。'data' は 0x24 番地。先頭をカットしている?


 ■mpg123-1.34.0

 ./mpg123 -s test.mp3 >a.bin


 オプションの -s で標準出力を選択してリダイレクトしてファイルに保存する。単純な PCM データ。オプションの -w f で WAV ファイルに出力できるみたい。

 mpg123 はmp3プレーヤなので通常はスピーカー(デバイス)に出力するのです。


 ■dist10

 ./decode test.mp3


 これで test.mp3.dec ファイルができる。出力ファイル名を指定することもできるけど。オプションで AIFF ファイルにもできるようです。

 出力は PCM だけど、ビックエンディアンなので注意。最初に 384 サンプルの0(384*4 = 1536 バイトの 00h)が入っている。


 ■libmad-0.15.1b

 ./minimad <test.mp3 >a.bin


 minimad は make でターゲット指定するとビルドする。標準入力と標準出力を使うし、オプション無し。とてもシンプル。普通に PCM。


 *


 では、PCM(あるいは WAV ファイル)を比較します。


 完全一致するよね、...おや? ...、一致しないよ。エラーの最大・最少は、


      |libmad|ffmpeg|lame3x|mpg123|dist10|

   libmad|--,---|37,-38|37,-38|37,-38|37,-38|

   ffmpeg|38,-37|--,---|_2,_-2|_1,_-1|_1,_-1|

   lame3x|38,-37|_2,_-2|--,---|_1,_-1|_1,_-1|

   mpg123|38,-37|_1,_-1|_1,_-1|--,---|_1,_-1|

   dist10|38,-37|_1,_-1|_1,_-1|_1,_-1|--,---|

  ※ 2026.8.17:libmadの値が間違ってました。訂正します。

  ※2026.8.18:dist10の値が間違ってました。訂正します。度々申し訳ない。


 libmad vs 他は (37,-38) のエラー。

 ffmpeg vs lame3x は ±2のエラー。

 他の組合せは ±1のエラー。


 *


 dist10 のエラー (3825, -3823) は何なんだろう? ...、と調べていたら消えてしましまいました。バグなのか? 夏の夜の夢?


 *


 ISO/IEC 11172 の Part 4 で「compliance tests」を定義しているので、これの真似をします。


 評価式は差分の二乗の平均のルート rms (root-mean-square) で、評価結果は三段階あって、


   ・Fully Compliant  : 0.000e-00 〜 8.810e-06

   ・Limited Accuracy : 8.810e-06 〜 1.410e-04

   ・Not Compliant  : 1.410e-04 〜 ∞


 16ビットの整数化する前の実数での差分を求めるようだけど、...PCM 出力を 32768.0 で割って、他との差分を求める。

 エラーレートは次の値になりました。


  PCM16b |libmad___ |ffmpeg___ |lame3x___ |mpg123___ |dist10___ |

  -------+----------+----------+----------+----------+----------+

  libmad |--------- |1.910e-04 |1.884e-04 |1.908e-04 |1.908e-04 |

  ffmpeg |1.910e-04 |--------- |1.721e-05 |1.530e-05 |1.530e-05 |

  lame3x |1.884e-04 |1.721e-05 |--------- |1.411e-05 |1.411e-05 |

  mpg123 |1.908e-04 |1.530e-05 |1.411e-05 |--------- |1.251e-06 |

  dist10 |1.908e-04 |1.530e-05 |1.411e-05 |1.251e-06 |--------- |

  ※2026.8.18 バグ?修正

  ※2026.8.24 32768.0 に変更(libmad vs lame3x が 0.001e-04 減)


 dist10 vs mpg123 は Fully Compliant な値です。


 libmad は、開発元の評価で ISO/IEC 11172-4 を満たしている(RMS Level: 5.555e-08)ことから、この値は正しい評価になっていないのでしょう。差分の求め方が違うし。

 でも波形を比較すると20〜30の差分は多々でている。ビルド環境やコンパイルオプションの指定が悪いかな?


 *

 *

 *


 dist10 は特定区間で大きなエラーが出ていました。最初はね。

 0.1秒単位で調べると

 挿絵(By みてみん)

 という感じでした。エラー発生時間の波形を見ると、

 挿絵(By みてみん)

 のように振幅に差異が。差分を表示すると、

 挿絵(By みてみん)

 ノイズ的な信号が混入? どこから入った?


 デバック文を入れて変数を出力して見たら、エラーはない。それで不思議に思って PCM ファイルを生成し直したら、エラーが消えた。最初の PCM ファイルにはエラーがあるけど、2つ目の PCM ファイルではエラーはない。

 デバック文の影響か? うーん、無いとは言えないが。...。


 今、分っているのはここまでです。※2026.8.18修正


 ***


 最下位ビットがズレる原因は、...恐らくは実数を16ビットのPCMデータに変換する際の誤差でしょう。プログラムの中を見ないと分かりませんけど。


 あ、だとしたらそれをエラーにカウントしてはいけない? ...、汗;


 ***

 **

 *


 mp3ファイルの中身が気になってきましたね。


 実数と整数か。...、あ、実数はアナログではないよ。数学での実数とパソコンの実数も違うし。


 ***


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


 ***

2026.8.17 バグと誤記の訂正と推敲

2026.8.18 バグ?の修正と推敲

2026.8.21 微推敲

2026.8.24 表の更新と微推敲





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

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