カクタスソフトウェア
カクタスソフトウェア
サウンド MIDI マルチメディア アプリケーション

フレームヘッダー

mpegのデータ本体は、フレームと呼ばれるバイナリーブロックがじゅずつなぎになった構造をしています。各フレームの先頭にはフレームヘッダーと呼ばれる4バイト長のパラメータが設けられています。

以下にフレームヘッダーの詳細を示します。アルファベットABCなどの文字はビットを表し、各パラメータの位置と長さを示します。データは左から若いアドレス順に並んでいます。

A A A A A A A A A A A B B C C D E E E E F F G H I I J J K L M M
  名称 長さ(Bit) 数値 意味
A frame sync 11 すべて1 正しくフレームの先頭を示していることの確認
B version 2 00 MPEG バージョン 2.5
01 未使用
10 MPEG バージョン 2 (ISO/IEC 13818-3)
11 MPEG バージョン 1 (ISO/IEC 11172-3)
C layer 2 00 未使用
01 レイヤー III
10 レイヤー II
11 レイヤー I
D protection 1 0 16ビットのCRC誤り検出を支援
1 CRCなし
E bit rate 4   別掲(ビットレート)
F sampling rate 2   別掲(サンプリング周波数)
G padding 1 0 拡張バイトなし
1 フレームに拡張バイトを追加
H extension 1   未使用
I channel mode 2 00 ステレオ
01 ジョイントステレオ(ステレオ)
10 デュアルチャンネル(ステレオ)
11 シングルチャンネル(モノ)
J mode extension 2   別掲(モード拡張)
K copyright 1 0 著作権なし
1 著作権あり
L original 1 0 オリジナルからコピーされたメディア
1 オリジナル
M emphasis 2 00 なし
01 50/15 ms
10 未使用
11 CCIT J.17

フレームシンク

セットされたビットが11ビット続くことで、そこからフレームが開始されることを示します。mpegファイルの構造を理解したソフトウェアであれば、現在のフレームの長さから次のフレームの先頭を求めることがでます。しかしフレームシンクを使えば、頭から順に読み込むタイプのソフトウェア・ハードウェアでもフレームの開始位置を知ることができます。

バージョン

実はバージョン2.5は公式なものではありません。本来フレームシンクは12ビット割り当てられているのですが、バージョン2.5の識別のために、バージョンがフレームシンクの1ビットを借用した形となっています。

バージョン2.5を支援しないのであれば、本来のフレームシンクを12ビット、バージョンを1ビットと実装することも可能です。ここでバージョン2.5が入力された場合、バージョン2でフレームが見つからないというエラーになります。

プロテクション

CRC誤り検出が有効であると、フレームヘッダーに続く16ビットがCRCチェックサムであることを示します。オーディオデータはチェックサムの後に続きます。

ビットレート

ビットレートは直接数値が記録されているわけではありません。ビットレートはインデックスとして記録され、数値は以下のテーブルから求めます。単位は「kbit/sec」です。

「自由」はこのテーブルによらずビットレートを独自に決めていることを示します。これはプライベートな用途でmpegファイルを利用したケースなどに見られるかも知れません。この場合、サウンドファイルの製作者に問い合わせるなどしない限り、正しいビットレートを知る手段はありません。

「禁止」はこの数値を指定してはならないこを示します。

  MPEG バージョン 1 MPEG バージョン 2、2.5
数値 レイヤー I レイヤー II レイヤー III レイヤー I レイヤー II レイヤー III
0000 自由 自由 自由 自由 自由 自由
0001 32 32 32 32 8 8
0010 64 48 40 48 16 16
0011 96 56 48 56 24 24
0100 128 64 56 64 32 32
0101 160 80 64 80 40 40
0110 192 96 80 96 48 48
0111 224 112 96 112 56 56
1000 256 128 112 128 64 64
1001 288 160 128 144 80 80
1010 320 192 160 160 96 96
1011 352 224 192 176 112 112
1100 384 256 224 192 128 128
1101 416 320 256 224 144 144
1110 448 384 320 256 160 160
1111 禁止 禁止 禁止 禁止 禁止 禁止

サンプリング周波数

サンプリング周波数も直接数値を指定する代りにインデックスとして記録されています。バージョンに応じて以下のように定義されています。数値の単位は「Hz」です。

数値 バージョン 1 バージョン 2 バージョン 2.5
00 44100 22050 11025
01 48000 24000 12000
10 32000 16000 8000
11 未使用 未使用 未使用

パッディング

もしフレーム最後のデータが0xFFだったとすると、次のフレームの頭とつながって偽のシンクフレームを作ってしまいます。この現象を防止するため、フレームの最後にNULLバイトを挿入することがあります。

チャンネルモード

チャンネルモードはチャンネル数とサウンドデータの記録方式を示します。

チャンネルモード チャンネル数 説明
ステレオ 2 左右を独立したチャンネルとして記録する方法。通常のステレオ。
ジョイントステレオ 2 MSステレオ(Mid/Side Stereo)あるいはIステレオ(Intensity Stereo)による記録法。※モード拡張を参照。
デュアルチャンネル 2 日本語・英語などの独立したチャンネルによる記録法。
シングルチャンネル 1 通常のモノラル。

モード拡張

モード拡張はジョイントステレオの時のみ使用します。レイヤー Iとレイヤー IIはIステレオのみで、利用する帯域を指定します。レイヤー IIIは、IステレオとMSステレオのどれを使うかを指定します。

  レイヤー I・レイヤー II レイヤー III
数値 Iステレオ Iステレオ MSステレオ
00 帯域 4 〜 31 off off
01 帯域 8 〜 31 on off
10 帯域 12 〜 31 off on
11 帯域 16 〜 31 on on

Iステレオ(Intensity Stereo)は、高域の定位が主に左右の音量差に依存し、位相には鈍感という人間の聴覚の性質に注目した保存方式。モノラルデータと左右の定位位置の組で表現する。

MSステレオ(Mid/Side Stereo)は、左右を加算した中央のシグナル(M)と、左右の差分を表すシグナル(S)の組で記録する方法。

ジョイントステレオは、一般に通常のステレオに比べ高い圧縮率を得ることができると言われています。

フレームサイズ

フレームサイズは1フレームあたりのサンプル数とビットレートから計算することができます。バージョンとレイヤーによって計算式が異なります。

1フレームあたりのサンプル数
レイヤー バージョン 1 バージョン 2 バージョン 2.5
レイヤー I 384 384 384
レイヤー II 1152 1152 1152
レイヤー III 1152 576 576

レイヤーI

1フレームあたり384サンプルです。フレームサイズは4の倍数でなければならないので、「(・・・)*4」の形の式となっています。

フレームサイズ = (((96 * ビットレート / 8) / サンプリング周波数) + パッディング) * 4

定数をまとめると以下のようになります。

フレームサイズ = ((12 * ビットレート / サンプリング周波数) + パッディング) * 4

レイヤーII・レイヤーIII(バージョン1)

1フレームあたり1152サンプルです。

フレームサイズ = ((1152 * ビットレート / 8) / サンプリング周波数) + パッディング

定数をまとめると以下のようになります。

フレームサイズ = (144 * ビットレート / サンプリング周波数) + パッディング

レイヤーIII(バージョン2・2.5)

1フレームあたり576サンプルです。

フレームサイズ = ((576 * ビットレート / 8) / サンプリング周波数) + パッディング

定数をまとめると以下のようになります。

フレームサイズ = (72 * ビットレート / サンプリング周波数) + パッディング
ビットレートの単位は、「bit/sec」です。ビットレートテーブルから求めた数値「kbit/sec」を使う時は、数値を1000倍しなければなりません。ビットレートを8で割っているのは、単位をバイトに直しているためです。

パッディングはフレームごとに有無を決められるため、フレームサイズがフレームによって変化する可能性があります。そのためフレームを次々とたぐる場合は、一つ一つフレームサイズを計算しなければなりません。

フレームヘッダーの実装

フレームヘッダーのようなビット単位の定義は、ビットフィールドを用いると実装が楽です。しかし利用するCPUによってエンディアン方式が異なったり、コンパイラーによってビットの割り当て順が異なるなど、環境に依存する面もあるので注意が必要です。

ビックエンディアン方式

typedef struct tagMPEGINFO
    unsigned    emphasis : 2;
    unsigned    original : 1;
    unsigned    copyright : 1;
    unsigned    extensionmode : 2;
    unsigned    channelmode : 2;
    unsigned    extension : 1;
    unsigned    padding : 1;
    unsigned    samplerate : 2;
    unsigned    bitrate : 4;
    unsigned    errorprotect : 1;
    unsigned    layer : 2;
    unsigned    version : 2;
    unsigned    synchead : 11;
} MPEGINFO;

リトルエンディアン方式(Windows対応)

フレームシンクが分割されていることに注意して下さい。

typedef struct tagMPEGINFO
{
    unsigned    synchead1 : 8;
    unsigned    errorprotect : 1;
    unsigned    layer : 2;
    unsigned    version : 2;
    unsigned    synchead2 : 3;
    unsigned    extension : 1;
    unsigned    padding : 1;
    unsigned    samplerate : 2;
    unsigned    bitrate : 4;
    unsigned    emphasis : 2;
    unsigned    original : 1;
    unsigned    copyright : 1;
    unsigned    extensionmode : 2;
    unsigned    channelmode : 2;
} MPEGINFO;
環境に依存しないコードを書くには、フレームヘッダーをバイト配列としてアクセスし、シフトとアンド演算を用いると良いでしょう。

ドキュメントの先頭へ

カクタスソフトウェア 技術協力 資料室 資料室の広場 SourceForge.jp お問い合わせ