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

如何在C语言中通过popen获取arecord的输出并处理?

通过C语言管道捕获arecord音频数据并绘图的实现

你这段代码的思路很清晰:通过popen调用arecord录制音频,读取采样数据写入文件,再调用gnuplot绘图展示。不过有几个细节可以优化或者需要注意,我帮你梳理一下:

原始代码(补全必要定义)

#include <stdio.h>
// 必须定义GNUPLOT宏,否则编译会报错;-persist参数让绘图窗口保持打开
#define GNUPLOT "gnuplot -persist"

int main(int argc,char *argv[]) { 
    FILE* file = popen("arecord -r 8000 --format S32_LE -D plughw:0,0 -d 4", "r"); 
    long buffer[100]; 
    FILE *fp; 
    fp=fopen("./record.dat", "w+"); 
    int i; 
    for (i=0; i<40000; i++){ 
        fscanf(file, "%ld", &buffer[i%100]); 
        fprintf(fp,"%d\t%ld\n", i , buffer[i%100] ) ; 
    } 
    pclose(file); 
    fclose(fp) ; 
    FILE *p = popen(GNUPLOT,"w"); 
    fprintf(p,"plot 'record.dat' lt rgb 'red' title 'yeag' \n"); 
    fclose(p); 
    return 0; 
}

关键问题与优化建议

  • 音频数据读取方式错误:你指定arecord输出的是S32_LE格式,这是二进制32位小端整数,但用fscanf("%ld")按文本格式读取会完全解析错误——二进制数据会被当成字符处理,拿到的数值和实际采样值毫无关系。正确的做法是用fread读取二进制数据:
    // 替换原有的fscanf行
    fread(&buffer[i%100], sizeof(long), 1, file);
    
  • 循环次数不合理:录制4秒、8000Hz采样率,总采样数应为8000*4=32000,但你循环了40000次,最后8000次会读取失败。建议把循环条件改成i < 32000,避免无效操作。
  • 缺少错误检查:代码没有判断popen、fopen的返回值,如果这些调用失败(比如arecord不存在、文件无法创建),程序会直接崩溃。可以加上简单的错误处理:
    if (file == NULL) {
        perror("Failed to open arecord pipe");
        return 1;
    }
    if (fp == NULL) {
        perror("Failed to create record.dat");
        pclose(file);
        return 1;
    }
    
  • 缓冲区可以简化:用i%100复用100个元素的缓冲区没问题,但如果只是临时存储单个采样值,用单个long变量就足够,没必要用数组。

优化后的核心循环示例

修正二进制读取和循环次数后的核心逻辑:

for (i=0; i<32000; i++){ 
    // 检查读取是否成功
    if (fread(&buffer[i%100], sizeof(long), 1, file) != 1) {
        fprintf(stderr, "Failed to read sample at index %d\n", i);
        break;
    }
    fprintf(fp,"%d\t%ld\n", i , buffer[i%100] ) ; 
}

这样修改后,程序就能正确捕获音频采样数据,并用gnuplot画出真实的音频波形了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:55:35