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
相关产品推荐
相关产品推荐

