mp3 header 抽出
以下のページを参考に mp3 header の抽出を試みました。
- http://www.m2osw.com/en/swf_alexref.html#tag_definesound
- http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm
試験対象の MP3 が DefineSound に入っていた時の情報は以下の通り。
[4] tag=DefineSound(14) length=2505 sound_id=1 format=2(MP3) rate=1 is_16bits=1 is_stereo=0 samples_count=11019 sound_data(length=2498)
実験コード
実験結果
mp3_filename=../game-1.mp3 mp3_data_len=2498 sync_word=0x7ff version=0 layer=1 no_protection=1 bit_rate=2 sample_rate=0 padding=0 reserved=0 channel_mode=3 mode_extension=0 copyright=0 original=0 emphasis=0
-
-
- -
-
試しに sync word を scan してみたところ、
一個目の header は正しく抽出されてそう(= Winamp のファイル情報の表示内容と一致した)
ですが、2つ目以降はボロボロ。
header の後ろはある程度 skip する必要があるらしいので、
一応想定通りではあります。さて…
skip 処理を入れてみた
試しに header の後ろを何 byte か skip した所、
いい感じに header が取れました。
while (mp3_dump_frame(bs)) { // bitstream_incrpos(bs, 97, 0); // NG bitstream_incrpos(bs, 98, 0); // OK // bitstream_incrpos(bs, 100, 0); // OK }
実行結果
% ./a.out ../game-1.mp3 | grep version=0 | wc bitstream_getbit: bs->data_len(2498) <= bs->byte_offset(2498) 24 24 240
bitstream_getbit の警告は bitstream.c 側の問題なのでご容赦を。(⊃д⊂)
この 98 というのは仮の数字で、
実際は header の内容から frame size を算出して
(frame size - header size 分だけ) skip する必要があるのですが、
mpglib のコード(lame/mpglib/common.c)を見ると、
witch(fr->lay) case 1: fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000; fr->framesize /= freqs[fr->sampling_frequency]; fr->framesize = ((fr->framesize+fr->padding)<<2)-4; fr->down_sample=0; fr->down_sample_sblimit = SBLIMIT>>(fr->down_sample); break; case 2: fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000; fr->framesize /= freqs[fr->sampling_frequency]; fr->framesize += fr->padding - 4; fr->down_sample=0; fr->down_sample_sblimit = SBLIMIT>>(fr->down_sample); break; case 3: <略>
なんだか、面倒そうなのでやっぱり自前はやめて mpglib を利用する事にします。(´Д`;)