Linux系统上C++使用alsa库播放声音文件

84 篇文章 1 订阅
25 篇文章 2 订阅

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

平常读麦克风的场景居多,有时候也需要播放一个声音文件,这里就介绍怎么处理。


一、命令行

1.ffmpeg

ffmpeg -i <filename.wav> -f alsa default

2.aplay

aplay -i <filename.wav>

如果提示找不到aplay就安装工具:

sudo apt install alsa-utils

二、代码实现

main.cpp

#include <alsa/asoundlib.h>
#include <iostream>
#include <fstream>

#define PCM_DEVICE "default"//默认的播放设备,你可以在settings里面调换

int main(int argc, char *argv[]) {
    const char *audioFilename = "../wakeup.wav";

    // 配置ALSA参数
    snd_pcm_t *pcmHandle;
    if (snd_pcm_open(&pcmHandle, PCM_DEVICE, SND_PCM_STREAM_PLAYBACK, 0) < 0) {
        std::cerr << "Error: Failed to open PCM device" << std::endl;
        return 1;
    }

    snd_pcm_hw_params_t *params;
    snd_pcm_hw_params_alloca(&params);
    snd_pcm_hw_params_any(pcmHandle, params);
    snd_pcm_hw_params_set_access(pcmHandle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(pcmHandle, params, SND_PCM_FORMAT_S16_LE);
    snd_pcm_hw_params_set_channels(pcmHandle, params, 2);
    unsigned int sampleRate = 48000;
    snd_pcm_hw_params_set_rate_near(pcmHandle, params, &sampleRate, nullptr);
    snd_pcm_uframes_t bufferSize = 512;
    snd_pcm_hw_params_set_buffer_size_near(pcmHandle, params, &bufferSize);
    snd_pcm_hw_params(pcmHandle, params);

    std::ifstream ifs("../wakeup.wav");
    if (ifs.is_open()) {
        std::string data;
        size_t size;
        char buffer[8192];
        while ((size = ifs.readsome(buffer, 8192)) > 0) {
            data.append(buffer, size);
        }
        snd_pcm_sframes_t err = snd_pcm_writei(pcmHandle, (const void *) data.c_str(),
                                               data.size()); 
        if (err < 0) {
            std::cerr << "Error: Failed to write PCM device" << std::endl;
        }
        ifs.close();
    }

    // 关闭PCM设备和文件
    snd_pcm_close(pcmHandle);
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(write_speaker)

set(CMAKE_CXX_STANDARD 11)

add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} asound)

总结

1、不算太难

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux系统使用ALSA(Advanced Linux Sound Architecture)进行录音是一个相对简单的过程。ALSALinux内核的一种音频驱动框架,提供了对音频硬件的底层控制和访问接口。 要使用ALSA录音,需要进行以下步骤: 1. 打开音频设备:首先需要打开音频设备以开始录音。可以使用`snd_pcm_open()`函数来打开默认音频设备。例如,可以使用如下代码打开默认的音频捕获设备: ```C++ snd_pcm_t* handle; int err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE,0); if(err < 0) { // 错误处理 } ``` 2. 配置硬件参数:在打开音频设备后,需要通过设置硬件参数来配置录音质量。可以使用`snd_pcm_hw_params_t`类型的变量来设置参数。例如,可以使用如下代码配置采样率为44.1kHz,通道数为2的参数: ```C++ snd_pcm_hw_params_t *params; int err = snd_pcm_hw_params_malloc(&params); if (err < 0) { // 错误处理 } err = snd_pcm_hw_params_any(handle, params); if (err < 0) { // 错误处理 } err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { // 错误处理 } err = snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); if (err < 0) { // 错误处理 } unsigned int rate = 44100; err = snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0); if (err < 0) { // 错误处理 } unsigned int channels = 2; err = snd_pcm_hw_params_set_channels(handle, params, channels); if (err < 0) { // 错误处理 } err = snd_pcm_hw_params(handle, params); if (err < 0) { // 错误处理 } ``` 3. 录音处理:在配置完硬件参数后,可以使用`snd_pcm_readi()`函数来读取音频数据进行录音。例如,可以使用如下代码读取音频数据并输出到文件: ```C++ FILE *file; file = fopen("recording.wav", "w"); if (file == NULL) { // 错误处理 } char buffer[1024]; int frames = 1024; int err; while (1) { err = snd_pcm_readi(handle, buffer, frames); if (err == -EPIPE) { // 捕获到溢出错误,需要进行错误处理 } else if (err < 0) { // 其他错误处理 } else { fwrite(buffer, sizeof(char), frames, file); } } fclose(file); ``` 4. 关闭音频设备:录音完成后,需要关闭音频设备以释放资源。可以使用`snd_pcm_close()`函数来关闭音频设备。例如,可以使用如下代码关闭音频设备: ```C++ snd_pcm_close(handle); ``` 以上就是在Linux系统使用ALSA录音的简要步骤。通过控制音频设备和配置参数,我们可以实现自定义的录音功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值