You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中uint8_t*转int16_t*:PDM麦克风滤波绕过实现方案问询

问题

我正在修改Arm开发者生态的pico麦克风库示例,该示例通过USB串口读取PDM麦克风数据并打印到电脑。我希望绕过示例中的滤波阶段,自行编写滤波逻辑,同时保留其他功能。当前计划是将输入的PDM原始数据直接作为滤波阶段的输出,但输入为uint8_t*类型,输出为int16_t*类型,请问最简单的类型转换方式是什么?以下是完整的pdm_microphone_read函数代码:

int pdm_microphone_read(int16_t* buffer, size_t samples) {
    int filter_stride = (pdm_mic.filter.Fs / 1000);
    samples = (samples / filter_stride) * filter_stride;

    if (samples > pdm_mic.config.sample_buffer_size) {
        samples = pdm_mic.config.sample_buffer_size;
    }

    if (pdm_mic.raw_buffer_write_index == pdm_mic.raw_buffer_read_index) {
        return 0;
    }

    uint8_t* in = pdm_mic.raw_buffer[pdm_mic.raw_buffer_read_index];
    int16_t* out = buffer; //need to change this line
    
    pdm_mic.raw_buffer_read_index++;

    for (int i = 0; i < samples; i += filter_stride) {
#if PDM_DECIMATION == 64
        Open_PDM_Filter_64(in, out, pdm_mic.filter_volume, &pdm_mic.filter);
#elif PDM_DECIMATION == 128
        Open_PDM_Filter_128(in, out, pdm_mic.filter_volume, &pdm_mic.filter);
#else
        #error "Unsupported PDM_DECIMATION value!"
#endif

        in += filter_stride * (PDM_DECIMATION / 8);
        out += filter_stride;
    }

    return samples;
}
解决方案

最简单的类型转换方式

直接将uint8_t类型的值赋值给int16_t变量即可完成隐式类型提升,这是C语言原生支持的操作。如果需要适配音频处理常用的有符号范围(-128到127),可以在转换后减去128,把原始0-255的无符号范围偏移为有符号区间。

修改后的代码实现

替换原函数中调用滤波函数的循环逻辑,直接完成类型转换并填充输出缓冲区:

int pdm_microphone_read(int16_t* buffer, size_t samples) {
    int filter_stride = (pdm_mic.filter.Fs / 1000);
    samples = (samples / filter_stride) * filter_stride;

    if (samples > pdm_mic.config.sample_buffer_size) {
        samples = pdm_mic.config.sample_buffer_size;
    }

    if (pdm_mic.raw_buffer_write_index == pdm_mic.raw_buffer_read_index) {
        return 0;
    }

    uint8_t* in = pdm_mic.raw_buffer[pdm_mic.raw_buffer_read_index];
    int16_t* out = buffer;
    
    pdm_mic.raw_buffer_read_index++;

    // 替换原有滤波逻辑,直接转换类型填充输出
    for (int i = 0; i < samples; i += filter_stride) {
        // 方式1:直接隐式转换,保留0-255的无符号范围到int16_t
        for (int j = 0; j < filter_stride; j++) {
            out[j] = in[j];
        }

        // 方式2:转换为音频常用的有符号范围(-128到127)
        // for (int j = 0; j < filter_stride; j++) {
        //     out[j] = (int16_t)in[j] - 128;
        // }

        // 步长调整:原滤波函数会对PDM数据抽取解码,跳过滤波后需根据原始数据逻辑调整步长
        // 此处直接按filter_stride推进,确保读取对应数量的原始字节
        in += filter_stride;
        out += filter_stride;
    }

    return samples;
}

关键说明

  • 隐式转换:uint8_t是8位无符号整数,赋值给int16_t时会自动填充高位为0,得到0-255范围内的16位整数,无需额外显式转换操作。
  • 范围偏移:若后续滤波需要有符号音频数据,减去128可将原始无符号范围转换为对称有符号区间,适配多数音频处理流程。
  • 步长适配:原代码中in的步长包含PDM抽取系数,跳过滤波后需根据原始数据的采样逻辑调整步长,确保读取正确的原始PDM字节。

内容的提问来源于stack exchange,提问作者jjjjbbb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 19:16:30