- 2012.08.07 MP3再生機能追加に対応。
- 2012.08.25現在 次の MP3 形式に対応している。
- サンプル周波数
- HSFタイプの場合 32kHz 44.1kHz 48kHzに対応
- LSFタイプの場合 16kHz 22.05kHz 24kHz
- ビットレート
- ほぼ、全てのビットレートに対応(したつもり)
- VBR(可変ビットレート)にも対応。
- 注意:一部のMP3に再生はできるものの、『ジッ』と言う雑音が入るものがある。
MP3再生追加の技術的解説 †
- こっから先は、ある意味、単なる苦労話なんだけど、もし、他のCPUとかにMP3再生機能を移植する事があったら、参考になるかもしれないので、記録しておく。
まず、参考になりそうな情報を探した。 †
- 参考になりそうなのは、次の雑誌。これらは、ネットでググって見つけた。
- インターフェース 2005年6月号
- インターフェース 2010年8月号
- インターフェース 2010年11月号
- インターフェース 2010年12月号
- インターフェース 2011年6月号
- 既に古い雑誌なので、図書館とかを探した。見つからなかった雑誌もあったが、役に立ったのは、インターフェース 2010年8月号と2010年12月号。
インターフェース 2010年8月号 P102〜を参考に †
- メモリ上に展開されたMP3ファイルをSH-2Aで再生する事を説明した記事。
- MAD:MPEG Audio Decoder が役に立ちそうな事が判る。
- FTPからたどって、「libmad-0.15.1b.tar.gz」をダウンロード。
- ライブラリを展開。
$ cd STM32F4/
$ tar zxvf libmad-0.15.1b.tar.gz
インターフェース 2010年12月号 P183〜を参考に †
- SDカード上のMP3ファイルをSH-2Aで再生する事を説明した記事
- 最も関連性が高い・・と期待。
- ところが、そうでも無かったんだよねえ。結果論だけど。
- この記事に関連するプログラムは、CQ出版からダウンロードできる。
- インターフェース誌のダウンロードページ
- ここの『2010年12月号のSH-2Aマイコンによる本格的MP3プレーヤの製作(後編)』のプログラム「mp3p20100924.zip」をダウンロード。
- 上記のプログラムを展開して調べてみる。
- mp3p/libmad-0.15.1b/ の中のソースはオリジナルのlibmad-0.15.1b.tar.gzと同じようだ。
- ただし、frame.c が異なる。下記のように関数「mad_header_decode」の中に「copy_next_header()」や「get_next_frame()」、「read_frame(N)」と言ったトリッキーな関数が入り込んでいる。
- 関数「mad_header_decode」は、「mad_frame_decode()」や「decoder.c」の「run_sync()」から呼ばれている。「mad_frame_decode()」も「run_sync()」から呼ばれている。「run_sync()」は「mad_decoder_run()」から呼ばれている。
- mp3p/src/ の中のソースは、新規のものの同じようだ。
libmadだけで、デコードできないか、挑戦。 †
- オリジナルのlibmad-0.15.1b.tar.gzのminimad.cの関数「decode()」を見ると
- mad_decoder_init() で input、output、error の関数を設定し。
- mad_decoder_run() が本体
- mad_decoder_finish() で終了・・なだけ。
- じゃあ、input、output、error を何とかすれば良いだけじゃないの?
- 方針をlibmad 自体に手を入れること無く、ユーザー定義関数の input、output、error だけで対応する方向にしよう。
2012.07.21〜23。STM32F4 上ではなく、PC上で確認。 †
- インターフェース 2010年12月号では、libmad 自体に手を入れていた。しかし、libmad 自体に手を入れること無く、ユーザー定義関数 input だけで、何とかなる事を確認。
- 最初は、input関数のところで、MP3ファイル全体をメモリ上に全て読み込んで、デコードするテストを行った。
- 次に、input関数で、ファイルを分割して読みだすテストを行った。
- この時、インターフェース 2010年12月号の記事だと、1152バイト毎じゃないとデコードしてくれない様に書いてあるが、1フレーム毎でもデコードする事が判った。
- MP3のファイルのフレーム長は1152バイトじゃなくて、MP3の速度に依存する。テストの結果が次の通り。
速度 | ヘッダ | フレーム長 | 備考 |
1 | 2 | 3 |
128kbps | 0xff | 0xfb | 0x90 | 417バイト | デコードには+8バイト必要 |
128kbps | 0xff | 0xfb | 0x92 | 418バイト | デコードには+8バイト必要 |
256kbps | 0xff | 0xfb | 0xd0 | 835バイト | デコードには+8バイト必要 |
256kbps | 0xff | 0xfb | 0xd2 | 836バイト | デコードには+8バイト必要 |
速度 | サンプリング周波数 | フレーム長 | パディングビットが ONの時 |
128kbps | 44.1kHz | 417 | 418 |
192kbps | 44.1kHz | 626 | 627 |
256kbps | 44.1kHz | 835 | 836 |
320kbps | 44.1kHz | 1044 | 1045 |
128kbps | 48kHz | 384 | 385 |
192kbps | 48kHz | 576 | 577 |
256kbps | 48kHz | 768 | 769 |
320kbps | 48kHz | 960 | 961 |
- つまり、関数 input は、読み出される度に、フレームヘッダを読み取り、フレームヘッダからフレーム長+8バイトをメモリ上に取り込めば良いってわけ。フレームの後の8バイトは重なっているから注意ね。
- フレームヘッダの中に、速度とかサンプリング周波数とかの情報が入っている。この情報の詳細はMP3ファイルの内部構成を見てね。
- デコードされたデータは、関数 output に渡される。この時こそ、1152個ごとに渡される。ただし、1152個と言っても1152バイトじゃない。16bitのデータがステレオ2ch分ずつ1152個なので、4608バイトずつね。
- 1152個なのは、HSFの場合のみ。LSFの場合は、半分の576個ずつ渡される。
- 関数 error は、曲の最後に呼び出されるだけなので、無視しよう。
2012.07.24〜08.03 STM32F4 に移植 †
- ここまで行けば、STM32F4 に移植するのも難しくない。
- 関数 input の方は、FatFs?で読みだすだけだから、大したことない。
- 関数 output は、I2S 用のリングバッファにデータを渡すだけだ。
- 簡単な移植の割に時間がかかったのは、途中でロケット飛ばしに行っていたから。
CPUクロック †
- 当たり前だが、WAVEファイルを演奏するよりもCPU速度を要求する。
- CPUクロックを 24MHz から 48MHz に上げる必要がある。
- SDIOのクロックは12.8MHzのままでOK。まあ、読み出し量は、むしろ少ないのだから、当たり前か。
ファイルロード用のバッファ長がラスボスだった。 †
- なんでか知らないけど、256kbpsのように SDカードからファイルを読み出すバッファ長が512よりも長いと音楽が乱れる。たぶん、ロードが遅れるんだろうなあ。
- とにかく訳も分からず、512バイトで分割すると問題は消えた。
で、現状。 †
- 一応、手持ちの128kbpsと256kbpsのMP3は、ちゃんと再生できる。
- それ以外の速度のMP3の再生もできるはず・・・なんだけど、まだ確認していない。ただし、サンプル周波数は、44.1kHzだけで、48kHzは対応していない。いずれ対応するつもりだけど。
- 2012.08.12 48kHzのMP3ファイルにも対応した。
- 2012.08.25 16kHz 22.05kHz 24kHz 32kHzのMP3ファイルにも対応した。
- もし、再生できないMP3ファイルがあったら、教えてください。
- 音質なんだけど
- 128kbpsのMP3は、はっきり言って余り良くない。
- 今まで、アキバで980円くらいで買ったMP3プレーヤーで聞いていた時には余り気にならなかったが、今回作ったデジタルオーディオプレーヤーは、元々音が良いから、とても粗が目立つ。
- そもそも、libmad の音質が悪いという可能性もゼロではない・・・
- 256kbpsのMP3だと一応鑑賞に耐える。
- でも、44.1kHzのWAVEファイルの方が音が良いよ。当たり前だけど・・
- まあ、一応、役に立つって言うレベルかな?
MP3ファイルの内部構成 †
内容 |
ヘッダー部分 | ID3やRIFF等の種類がある。ヘッダーの無い場合もある。 | スキップする。 |
MP3部分 | | libmadへ送る。 |
テール部分 | 無い場合が多い。 | 無視する。 |
MP3部分:
位置 | 内容 | 意味 |
0 | 0xff | ヘッダー |
1 | 7-4bit | 1111 | ヘッダー |
3bit | MPEG-2 LSF 使用の有無 | 0:LSF extention |
1:HSF |
2-1bit | Layer | 00:予約済み |
01:Layer III |
10:Layer II |
11:Layer I |
0bit | Protection_bit | 0:冗長性・保護付き |
1:冗長性・保護無し |
2 | 7-4bit | ビットレート | HSFの時 | LSFの時 |
0000:FreeFormat? | 0000:FreeFormat? |
0001:32kbps | 0001:8kbps |
0010:40kbps | 0010:16kbps |
0011:48kbps | 0011:24kbps |
0100:56kbps | 0100:32kbps |
0101:64kbps | 0101:40kbps |
0110:80kbps | 0110:48kbps |
0111:96kbps | 0111:56kbps |
1000:112kbps | 1000:64kbps |
1001:128kbps | 1001:80kbps |
1010:160kbps | 1010:96kbps |
1011:192kbps | 1011:112kbps ?? |
1100:224kbps | 1100:128kbps |
1101:256kbps | 1101:144kbps |
1110:320kbps | 1110:160kbps |
1111:禁止 | 1111:禁止 |
3-2bit | サンプル周波数 | HSFの時 | LSFの時 |
00:44.1kHz | 22.05kHz |
01:48kHz | 24kHz |
10:32kHz | 16kHz |
01:予約済み | 01:予約済み |
1bit | Padding_bit | 0:フレームには追加 slot が含まれない |
1:追加の 1 slot を含む |
0bit | 私用 | 未使用 |
3 | 7-6bit | Mode | 00:stereo |
01:joint stereo |
10:dual channel |
11:single channel |
5-4bit | Mode_extension | |
3bit | Copyright | 0:著作権保護なし |
1:著作権保護あり |
2bit | Original / copy | 0:コピー |
1:オリジナル |
1-0bit | Emphasis | 00:エンファシスなし |
01:50/15μs |
10:予約 |
11:ITU-T J.17 |
フレーム長の計算方法 †
- Layer1の場合
- HSFの時
- フレーム長= 12 × ビットレート ÷ サンプリング周波数 (パディングビットが ON なら更に+1)
- LSFの時
- フレーム長= 12 × ビットレート ÷ (サンプリング周波数 × 2) (パディングビットが ON なら更に+1)
- Layer2 または Layer3の場合
- HSFの時
- フレーム長= 144 × ビットレート ÷ サンプリング周波数 (パディングビットが ON なら更に+1)
- LSFの時
- フレーム長= 144 × ビットレート ÷ (サンプリング周波数 × 2) (パディングビットが ON なら更に+1)
プロジェクト
共通
最新の20件
2020-11-14
2014-11-10
2014-08-17
2013-12-23
2013-09-29
2013-08-09
2013-08-07
2013-08-03
2012-11-28
2012-08-25
2012-07-05
2012-07-03
2012-07-01
今日の20件
- counter: 3660
- today: 1
- yesterday: 0
- online: 1