8

我有一组 PCM 数据;它可以是 16 位、24 位压缩、32 位等。它可以是有符号的,也可以是无符号的,它可以是 32 位或 64 位浮点数。它当前存储为void**矩阵,首先按通道索引,然后按帧索引。目标是允许我的库采用任何 PCM 格式并对其进行缓冲,而无需处理数据以适应指定的结构。如果 A/D 转换器输出交错 PCM 的 24 位打包数组,我需要优雅地接受它。我还需要支持 16 位非交错,以及上述格式的任何排列。

我知道运行时的位深度和其他信息,并且我正在尝试有效地编码而不复制代码。我需要的是一种有效的方式来投射矩阵,将PCM数据放入矩阵中,然后再将其拉出。

我可以将矩阵分别转换int32_tint16_t32 位和 16 位带符号的 PCM;我可能还必须将 24 位 PCM 存储在int32_t32 位、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 回答