Cleanest way to store lists of filter coefficients in a C header

旧城冷巷雨未停 提交于 2019-12-23 05:41:41

问题


I have many (~100 or so) filter coefficients calculated with the aid of some Matlab and Excel that I want to dump into a C header file for general use, but I'm not sure what the best way to do this would be. I was starting out as so:

#define BUTTER 1
#define BESSEL 2
#define CHEBY 3
#if FILT_TYPE == BUTTER
    #if FILT_ROLLOFF == 0.010
        #define B0 256
        #define B1 512
        #define B2 256
        #define A1 467
        #define A2 -214
    #elif FILT_ROLLOFF == 0.015
        #define B0 256
        #define B1 512
// and so on...

However, if I do that and shove them all into a header, I need to set the conditionals (FILT_TYPE, FILT_ROLLOFF) in my source before including it, which seems kinda nasty. What's more, if I have 2+ different filters that want different roll-offs/filter types it won't work. I could #undef my 5 coefficients (A1-2, B0-2) in that coefficients file, but it still seems wrong to have to insert an #include buried in code.

Edit: This is for an embedded 8-bit processor with very small (2-4K) code space. I cannot seem to accomplish this by storing them into an array of structs because the space it consumes is unacceptable. Even declaring them all constant, my compiler will not 'optimize them away' so I'm left with a shade over 1.2K of extra binary data.

The below does not work.

typedef struct { 
    int16_t b0, b1, b2, a1, a2;
} filtCoeff;

const filtCoeff butter[41] = {
    {256,512,256,467,-214},
    {256,512,256,444,-196},
    {255,512,255,422,-179},
    // ...
};
const filtCoeff bessel[41]  // ...

回答1:


You could use token concatenation to get these to be parameters to a macro.

#define BUTTER 1
#define BESSEL 2
#define CHEBY 3

#define ROLLOFF_0_010 1
#define ROLLOFF_0_015 2

// BUTTER, ROLLOFF_0_010
#define B0_11 256
#define B1_11 512
#define B2_11 256
#define A1_11 467
#define A2_11 -214

// BUTTER, ROLLOFF_0_015
#define B0_12 256
#define B1_12 512
// ...

#define B0_(type, rolloff) (BO_##type##rolloff)
#define B1_(type, rolloff) (B1_##type##rolloff)
#define B2_(type, rolloff) (B2_##type##rolloff)
#define A1_(type, rolloff) (A1_##type##rolloff)
#define A2_(type, rolloff) (A2_##type##rolloff)

/*
 * This two level define is so that the parameters to these macros
 * get run through the macro process.   That is, B1_(BUTTER, ROLLOFF_0_010) 
 * evaluates as B1_BUTTERROLLOFF_0_010, while B1(BUTTER, ROLLOFF_0_010)
 * evaluates as B1_11 and thus as 256.
 */

#define B0(type, rolloff) B0_(type, rolloff)
#define B1(type, rolloff) B1_(type, rolloff)
#define B2(type, rolloff) B2_(type, rolloff)
#define A1(type, rolloff) A1_(type, rolloff)
#define A2(type, rolloff) A2_(type, rolloff)

B1(BUTTER, ROLLOFF_0_015) is now equivalent to 512. Then you can build any more complicated things as macros. E.g.:

#define CROSSPRODUCT(type, rolloff, values) \
    B0(type, rolloff) * ((values)[0]) + \
    B1(type, rolloff) * ((values)[1]) + \
    ...

You could also put your code in another file and use TYPE and ROLLOFF. Then just #define TYPE and ROLLOFF and include the other file. I think I prefer using a macro though.




回答2:


Put the filter coefficients in an array of structs. Instead of worrying about header files, I would just put the declaration of the array pointer in the .h files and define them in a specific .c file that you link in.



来源:https://stackoverflow.com/questions/2685888/cleanest-way-to-store-lists-of-filter-coefficients-in-a-c-header

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!