在 C 标头中存储滤波器系数列表的最简洁方法

发布于 2024-08-29 22:28:23 字数 1135 浏览 2 评论 0原文

我有许多(约 100 个左右)滤波器系数,借助一些 Matlab 和 Excel 计算出来,我想将其转储到 C 头文件中以供一般使用,但我不确定最好的是什么这样做的方法是。我是这样开始的:

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

但是,如果我这样做并将它们全部放入标头中,我需要先在源代码中设置条件(FILT_TYPEFILT_ROLLOFF)包括它,这看起来有点令人讨厌。更重要的是,如果我有 2 个以上不同的滤波器需要不同的滚降/滤波器类型,它将无法工作。我可以在该系数文件中#undef我的5个系数(A1-2,B0-2),但必须插入埋在代码中的#include似乎仍然是错误的。

编辑: 这是针对具有非常小的 (2-4K) 代码空间的嵌入式 8 位处理器。我似乎无法通过将它们存储到结构数组中来实现这一点,因为它消耗的空间是不可接受的。即使将它们全部声明为常量,我的编译器也不会“优化它们”,因此我留下了超过 1.2K 的额外二进制数据。

以下内容不起作用。

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深居我梦 2024-09-05 22:28:24

将滤波器系数放入结构体数组中。我不必担心头文件,只需将数组指针的声明放在 .h 文件中,并在链接的特定 .c 文件中定义它们。

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.

攒眉千度 2024-09-05 22:28:24

您可以使用标记串联将它们作为宏的参数。

#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) 现在相当于 512。然后你可以构建任何更复杂的东西作为宏。例如:

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

您还可以将代码放在另一个文件中并使用 TYPEROLLOFF。然后只需 #define TYPEROLLOFF 并包含其他文件。我想我更喜欢使用宏。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文