Listing a Void * array for float, int32, int16, etc.

I have a PCM dataset, it can be 16 bits, 24 bits packed, 32 bits, etc. It can be signed or unsigned, and it can be 32 or 64 bit floating point. Currently, it is stored as a "void **" matrix, indexed by channel, then by frame. The goal is to allow my library to accept in any PCM format and buffer it without requiring data manipulation in accordance with the assigned structure. If the A / D converter produces 24-bit PCM interleaved arrays, I have to accept it gracefully. I also need to support 16-bit non-movable, as well as any permutation of the above formats.

I know the bit depth and other information at runtime, and I'm trying to efficiently encode without duplicating the code. I need an efficient way to drop the matrix, put the PCM data into the matrix, and then pull it out later.

I can pass the matrix to int32_t or int16_t for 32 and 16-bit signed PCM, respectively, I will probably have to store 24-bit PCM in int32_t for 32-bit 8-bit byte systems.

Can anyone recommend a good way to put data into this array and pull it out later? I would like to avoid large sections of code that look like this:

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 ... 

Limitations: I work in C / C ++, without templates, without RTTI, STL. Think embedded. Things get more complicated when I have to port this to a DSP with 16-bit bytes.

Does anyone have useful macros that they can provide?

Thanks,

-Griff

+7
source share
1 answer

This one will match typecodes for casting functions. The basic idea is that it creates a set of tiny conversion functions for each type and an array of function pointers, and then indexes into that array based on the data format to find the right conversion function for the call.

through:

 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; } 

header file:

 // 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 

hopes help

+5
source

All Articles