【问题标题】:Data Generation Issue数据生成问题
【发布时间】:2017-08-03 23:55:35
【问题描述】:

由于我开发的函数存在问题,我在将数据写入 C++ 文件时遇到了问题。我将一个.dat 文件从外部源加载到我的C++ 项目中。开发的while循环正确地逐行读取每个数据元素并将其传递给FIR滤波器函数,该函数接受三个参数,即滤波器长度、滤波器系数std::vector<float>float data

float f0 = 8000;
float fs = 32000;
int filt_length = 21;
float filtered,data;
fir_lowpass windowed_filter(f0,fs);

std::ifstream input;
std::ofstream output;
input.open("chirp.dat");
output.open("filter_test_sig.dat");

std::vector<float> blackman_choice,basic_lpf;

basic_lpf = windowed_filter.fir_sinc_filter_weights(filt_length);

blackman_choice = windowed_filter.blackman_window(filt_length, basic_lpf);

if (input.fail() && output.fail()) {
    std::cout << "Files not opened." << std::endl;
}
else{
    while (input >> data) {
        filtered = windowed_filter.generic_fir_filter(filt_length, blackman_choice, data);
        output << filtered << std::endl;
        std::cout << filtered << std::endl;
    }
}

我已确认此循环确实按预期工作,因为我有一个不太复杂的 FIR 滤波器头文件。这是与上述代码一起使用的原始函数:

float lpf_filter(float input){

    forward_buffer[0] = input;
    float output;

    for (int i = 0; i<filter_length; i++) {
        output += B[i]*forward_buffer[i];
    }
    for (int i = filter_length-1; i>0; i--) {
        forward_buffer[i] = forward_buffer[i-1];
    }
    return output;
}

注意array B 是预定义的,在Matlab 内部计算并导出。在下一个函数中,我尝试重写此函数以从另一个函数中获取已计算的系数。这是代码和它下面的示例系数函数(更新float output = 0):

float generic_fir_filter(const std::vector<float> &coefficients, float input){
    std::vector<float> buffer(coefficients.size(),0.0f);
    buffer[0] = input;
    float output = 0;

    for (int i = 0; i<(int)coefficients.size(); i++) {
        output += coefficients[i]*buffer[i];
    }
    for (int i = (int)coefficients.size()-1; i>0; i--) {
        buffer[i] = buffer[i-1];
    }
    return output;
}
std::vector<float> fir_sinc_filter_weights(int filt_length){
    std::vector<float> w(filt_length);
    M = filt_length-1;

    for (int i = 0; i<filt_length; i++) {
        if (i == M/2) {
            w[i] = 2*fn;
        }
        else{
            w[i] = sin(2*M_PI*fn*(i-M/2))/(M_PI*(i-M/2));
        }
    }
    return w;
}

当我在 .cpp 文件的内部 while 循环中运行此函数时,它只会为每个循环迭代生成相同的过滤值,而我的原始函数没有。我还将加载的.dat 文件转换为std::vector&lt;float&gt; 并尝试一次加载一个样本,但这也不起作用。对此问题的任何帮助将不胜感激!

编辑:

我现在已将我的std::vector&lt;float&gt; buffer 移动到private: 以尝试将先前的剩余状态保留在缓冲区内。我还在构造函数中添加了一个小补充,告诉std::vector&lt;float&gt; buffer 它应该有多少个数组元素,并将它们全部初始化为零。现在的问题是,当我在generic_fir_filter() 中调用缓冲区时,当我在上述函数中调用buffer[0] = input; 时出现EXC_BAD_ACCESS 错误:

private:
   int M;
   float fn;
   std::vector<float> buffer;
public:
fir_lowpass(float f0,float fs,int weight_size){
    fn = f0/fs;
    std::vector<float> buffer(weight_size, 0.0f);
}
float generic_fir_filter(const std::vector<float> &coefficients, float input){
    //std::vector<float> buffer(coefficients.size(),0.0f);
    buffer[0] = input;
    float output = 0;

    for (int i = 0; i<(int)coefficients.size(); i++) {
        output += coefficients[i]*buffer[i];
    }
    for (int i = (int)coefficients.size()-1; i>0; i--) {
        buffer[i] = buffer[i-1];
    }
    return output;
}

【问题讨论】:

  • generic_fir_filter() 中,输出应该为零,因为您将所有buffer 元素初始化为零。但是在lpf_filter() 中,您只将forward_buffer 的第一个元素设置为零。您没有显示其余部分的初始化位置。
  • .dat 文件的格式是什么?是二进制的吗?当您执行input &gt;&gt; data 时,您是否正在检查input 流中的错误?
  • 感谢快速响应的人们。我相信 Shibli 的建议是问题,但现在我有另一个问题!我已经通过过滤器运行了我的数据,但是与它们应该的值相比,输出的过滤值绝对很小。我通过与我的 Matlab 版本和 Matlab 滤波器(具有几乎相同的系数进行舍入或舍入)进行比较来仔细检查它,并且不会产生类似的响应。
  • buffer 应该是 fir_lowpass 类的成员(初始化为零,除非您想以给定状态开始过滤),这样过滤器的状态将在所有 @ 987654348@ 呼叫每个人input 样本。
  • 是的,这就是我现在遇到的问题。我不确定如何保持std::vector&lt;float&gt; buffer 的状态。我添加了一些断点,你指出的事情正在发生。对于我的过滤响应,我基本上得到了几乎一致的 0 值,这不是我希望发生的。任何与此相关的建议都会有很大帮助!

标签: c++ filtering signal-processing


【解决方案1】:

我找到了调用std:vector&lt;float&gt; buffer 并将其数组大小设置为我需要的任何问题的解决方案。诀窍是在private: 中声明缓冲区,然后在构造函数设置中通过构造函数名称旁边的以下: 操作初始化缓冲区:

private:
int M;
float fn;
std::vector<float> buffer;
public:
fir_lowpass(float f0,float fs,int weight_size) : buffer(weight_size, 0.0f)
{
    fn = f0/fs;
    //std::vector<float> buffer2(weight_size, 0.0f);
}

感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 2011-01-09
    • 2023-04-02
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-09-19
    相关资源
    最近更新 更多