如何在Linux下使用ALSA同时录音和播放

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>

#define FRAME_SIZE 480

int main() {
    int err;
    snd_pcm_t *capture_handle;
    snd_pcm_t *playback_handle;
    snd_pcm_hw_params_t *hw_params;
    DenoiseState *st;

    // 初始化RNNoise
    st = rnnoise_create(NULL);

    // 打开录音设备
    if ((err = snd_pcm_open(&capture_handle, "hw:1,0", SND_PCM_STREAM_CAPTURE, 0)) < 0) {
        fprintf(stderr, "无法打开录音设备: %s\n", snd_strerror(err));
        return 1;
    }

    // 设置录音设备参数
    snd_pcm_hw_params_alloca(&hw_params);
    snd_pcm_hw_params_any(capture_handle, hw_params);
    snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(capture_handle, hw_params, SND_PCM_FORMAT_S16_LE);
    snd_pcm_hw_params_set_rate(capture_handle, hw_params, 48000, 0);
    snd_pcm_hw_params_set_channels(capture_handle, hw_params, 1);
    snd_pcm_hw_params(capture_handle, hw_params);

    // 打开播放设备
    if ((err = snd_pcm_open(&playback_handle, "hw:1,0", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
        fprintf(stderr, "无法打开播放设备: %s\n", snd_strerror(err));
        return 1;
    }

    // 设置播放设备参数
    snd_pcm_hw_params_any(playback_handle, hw_params);
    snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(playback_handle, hw_params, SND_PCM_FORMAT_S16_LE);
    snd_pcm_hw_params_set_rate(playback_handle, hw_params, 48000, 0);
    snd_pcm_hw_params_set_channels(playback_handle, hw_params, 1);
    snd_pcm_hw_params(playback_handle, hw_params);

    int16_t buffer[FRAME_SIZE];
    float float_buffer[FRAME_SIZE];

    // 开始录音和播放
    while (1) {
        // 从录音设备读取音频数据
        if ((err = snd_pcm_readi(capture_handle, buffer, FRAME_SIZE)) != FRAME_SIZE) {
            if(err == -EPIPE){
                snd_pcm_prepare(capture_handle);
            }else{
                fprintf(stderr, "读取音频数据错误: %s\n", snd_strerror(err));
                break;
            }

        }

        // 将处理后的音频数据写入播放设备
        if ((err = snd_pcm_writei(playback_handle, buffer, FRAME_SIZE)) != FRAME_SIZE) {
            if(err == -EPIPE){
                snd_pcm_prepare(playback_handle);
            }else{
                fprintf(stderr, "播放音频数据错误: %s\n", snd_strerror(err));
                break;
            }

        }
    }

    // 关闭设备并释放资源
    snd_pcm_close(capture_handle);
    snd_pcm_close(playback_handle);
    rnnoise_destroy(st);

    return 0;
}

修复在播放的时候提示 Broken pipe

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值