8

PCM データの配列があります。16 ビット、24 ビット パック、32 ビットなどです。符号付きまたは符号なし、32 ビットまたは 64 ビット浮動小数点のいずれかです。現在、void**マトリックスとして格納されており、最初にチャネルごと、次にフレームごとにインデックスが付けられています。目標は、指定された構造に合わせてデータを操作する必要なく、ライブラリが任意の PCM 形式を取り込んでバッファリングできるようにすることです。A/D コンバーターがインターリーブされた PCM の 24 ビットにパックされた配列を出力した場合、それを適切に受け入れる必要があります。また、16 ビットの非インターリーブ、および上記の形式の順列もサポートする必要があります。

実行時のビット深度やその他の情報を把握しており、コードを複製せずに効率的にコーディングしようとしています。私が必要としているのは、行列をキャストし、PCM データを行列に入れ、後でそれを引き出す効果的な方法です。

行列をint32_t、またはint16_t32 ビットと 16 ビットの符号付き PCM にそれぞれキャストできます。おそらく、24 ビットの PCMint32_tを 32 ビット、8 ビットのバイト システムにも格納する必要があります。

データをこの配列に入れ、後で引き出す良い方法を誰かが推奨できますか? 次のような大きなコード セクションは避けたいと思います。

switch (mFormat) {
case 1:  // unsigned 8 bit
  for (int i = 0; i < mChannels; i++)
    framesArray = (uint8_t*)pcm[i];
  break;
case 2:  // signed 8 bit
  for (int i = 0; i < mChannels; i++)
    framesArray = (int8_t*)pcm[i];
  break;
case 3:  // unsigned 16 bit
...

制限: 私は C/C++ で作業しており、テンプレートも RTTI も STL もありません。埋め込まれていると考えてください。これを 16 ビット バイトの DSP に移植しなければならない場合、事態はさらに複雑になります。

誰かが喜んで共有できる便利なマクロを持っていますか?

4

1 に答える 1

7

これはタイプコードをキャスト関数に一致させます。基本的な考え方は、タイプごとに小さな変換関数のセットと関数ポインターの配列を作成し、呼び出す正しい変換関数を見つけるために、データ形式に基づいてその配列にインデックスを付けることです。

使用例:

int main ()
{   
    void** pcm;
    int currentChannel;
    int currentFrame;
    int mFormat;

    // gets data casted to our type
    STORETYPE translatedFrameData = GET_FRAMEDATA(pcm, currentChannel, currentFrame, mFormat);  

    return 0;
}

ヘッダーファイル:

// this is a big type, we cast to this one
#define STORETYPE int32_t

// these functions get a single frame
typedef STORETYPE (*getterFunction)(void**, int, int);

// this macros make an array that maps format codes to cast functions
#define BEGIN_RESERVE_FORMAT_CODES getterFunction __getter_array[] = {
#define RESERVE_FORMAT_CODE(code) __get__##code##__,
#define END_RESERVE_FORMAT_CODES };

//
#define FORMAT_DEFINITION(code, format) STORETYPE __get__##code##__(void**pcm, int channel, int frame) \
{ return (STORETYPE) ((format**)pcm)[channel][frame]; }

// get corresponding function 
#define GET_FRAMEDATA( pcm, channel, frame, format ) __getter_array[format](pcm,channel,frame)

//serious part, define needed types
FORMAT_DEFINITION(0, uint8_t)
FORMAT_DEFINITION(1, int8_t)
FORMAT_DEFINITION(2, uint16_t)
FORMAT_DEFINITION(3, int16_t)

//actually this makes the array which binds types
BEGIN_RESERVE_FORMAT_CODES
    RESERVE_FORMAT_CODE(0)
    RESERVE_FORMAT_CODE(1)
    RESERVE_FORMAT_CODE(2)
    RESERVE_FORMAT_CODE(3)
END_RESERVE_FORMAT_CODES

//WATCH OUT FOR SEQUENCE

希望が役立ちます

于 2011-01-10T02:32:42.887 に答える