在嵌入式系统上检测两个频率的线性插值

问题描述

我正在尝试识别嵌入式系统上的一系列音频帧 - 音频帧是一个频率或两个频率的插值,时间可变。我知道我试图识别的声音(即线性插值的开始和结束频率以及每个音频帧的持续时间),但它们是由另一个嵌入式系统产生的,因此麦克风和扬声器很便宜而且有些不准确。输出是方波。有什么建议如何去做吗?

我现在要做的是使用 FFT 来获取所有频率的幅度,检测峰值,查看检测持续时间/2 ms 前并检查它是否与音频帧有些匹配,最后只是检查是否我正在寻找的任何声音都与序列相匹配。

到目前为止,我使用 FFT 来处理麦克风输入 - 在应用 Hann 窗口之后 - 然后根据偏离平均值的标准偏差数为每个频率仓分配一个系数,该系数是峰值。这并没有奏效,因为它认为在房间里安静时会出现高峰。关于如何更准确地检测峰值的任何想法?另外我认为由于方波/插值有很多谐波?如果峰值不在两倍频率处真正排列,我可以做谐波乘积频谱吗?

在这里,我用 2226 和 1624 Hz 的插值绘制了噪声(几乎是寂静的房间)。 https://i.stack.imgur.com/R5Gs2.png

我以 91 微秒采样 -> 10989 Hz。我应该更频繁地采样吗?

我在此处添加了在笔记本电脑和嵌入式系统上录制时插值听起来如何的示例。 https://easyupload.io/m/5l72b0


#define MIC_SAMPLE_RATE         10989 // Hz
#define AUdio_SAMPLES_NUMBER    1024


MicroBitAudioProcessor::MicroBitAudioProcessor(DataSource& source) : audiostream(source)
{   
    arm_rfft_fast_init_f32(&fft_instance,AUdio_SAMPLES_NUMBER);

    buf = (float *)malloc(sizeof(float) * (AUdio_SAMPLES_NUMBER * 2));
    output = (float *)malloc(sizeof(float) * AUdio_SAMPLES_NUMBER);
    mag = (float *)malloc(sizeof(float) * AUdio_SAMPLES_NUMBER / 2);
}

float henn(int i){
    return 0.5 * (1 - arm_cos_f32(2 * 3.14159265 * i / AUdio_SAMPLES_NUMBER));
}

int MicroBitAudioProcessor::pullRequest()
{
    int s;
    int result;

    auto mic_samples = audiostream.pull();

    if (!recording)
        return DEVICE_OK;

    int8_t *data = (int8_t *) &mic_samples[0];

    int samples = mic_samples.length() / 2;

    for (int i=0; i < samples; i++)
    {

        s = (int) *data;
        result = s;

        data++;
        buf[(position++)] = (float)result;


        if (position % AUdio_SAMPLES_NUMBER == 0)
        {
            position = 0;

            float maxValue = 0;
            uint32_t index = 0;

            // Apply a Henn window 
            for(int i=0; i< AUdio_SAMPLES_NUMBER; i++)
                buf[i] *= henn(i);

            arm_rfft_fast_f32(&fft_instance,buf,output,0);
            arm_cmplx_mag_f32(output,mag,AUdio_SAMPLES_NUMBER / 2);
       }
    }

    return DEVICE_OK;
}

uint32_t frequencyToIndex(int freq) {
    return (freq / ((uint32_t)MIC_SAMPLE_RATE / AUdio_SAMPLES_NUMBER));
} 

float MicroBitAudioProcessor::getFrequencyIntensity(int freq){
    uint32_t index = frequencyToIndex(freq);
    if (index <= 0 || index >= (AUdio_SAMPLES_NUMBER / 2) - 1) return 0;
    return mag[index];
}


解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...