「パケット」という用語は、ヘッダー付きの圧縮されたオーディオ サンプルのグループを指します。直後のデータをデコードするには、ヘッダーが必要です。ima4 ファイルを本と見なす場合、各パケットはページです。上部には、そのページをデコードするために必要な値があり、その後に圧縮されたオーディオが続きます。
そのため、アンパックされたデータのサイズを計算する (そしてそのためのスペースを確保する) 必要があります。データは圧縮されているため、データを出力する前に、圧縮されたオーディオから非圧縮のオーディオにデータを変換する必要があります。出力バッファを割り当てるには、必要な大きさを知る必要があります (注: 一度に 1 つのパケットよりも大きなチャンクで出力する必要がある場合があります)。
前の「概要」セクションによると、典型的な構造のように見えますが、64 サンプルのセットで、各 16 ビット (つまり 128 バイト) が 2 バイトのヘッダーと 32 バイトの圧縮サンプル セット (34 バイト) に変換されます。全部で)。したがって、一般的なケースでは、入力データ サイズを取得し、34 で割ってパケット数を取得し、128 バイトを乗算してパケットあたりの圧縮されていないオーディオを取得することにより、予想される出力データ サイズを生成できます。
しかし、あなたはそれをすべきではありません。代わりに、kAudioFilePropertyDataFormat をクエリして mBytesPerPacket を取得する必要があるようです -- これは上記の「34」の値であり、mFramesPerPacket -- これは上記の 64 であり、2 を掛けて (16 バイトのサンプルの場合) 128 バイトを作成します。出力の。
次に、パケットごとに、投稿で説明されているデコードを実行する必要があります。ヘッダーを処理するために、バイトの配列を取得していると仮定して、やや長い疑似 C コードで:
packet = GetPacket();
Header = (packet[0] << 8) | packet[1]; //Big-endian 16-bit value
step_index = Header & 0x007f; //Lower seven bits
predictor = Header & 0xff80; //Upper nine bits
for (i = 2; i < mBytesPerPacket; i++)
{
nibble = packet[i] & 0x0f; //Low Nibble
process that nibble, per the blogpost -- be careful on sign-extension!
nibble = (packet[i] & 0xf0) >> 4; //High Nibble
process that nibble, per the blogpost -- be careful on sign-extension!
}
上記の符号拡張は、ポストが各ニブルを符号なしと符号付きの両方で処理することを含むという事実を指します。ニブルの上位ビット (ビット 3) が 1 の場合、それは負です。さらに、ビットシフトは符号拡張を行う場合があります。これは、上記の擬似コードでは処理されません。