长生栈 长生栈
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Living Team

编程技术分享
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 计算机视觉

  • ESP32开发

  • Linux系统移植

  • 快速开始

  • 多媒体(Mutimedia)

  • 音频开发(Audio)

    • Linux Audio开发-介绍和名词解释
    • Linux Audio开发-ALSA API列表
    • Linux Audio开发-使用ALSA驱动进行录音和播放(Ubuntu22)
      • 安装ALSA开发库
      • 最简示例代码
        • 1. 录音示例代码(record.c)
        • 2.播放示例代码(play.c)
        • 编译和运行
        • 参数说明:
        • 文件格式:
    • Linux Audio开发-ALSA使用内存映射(MMAP)的录音实现(Ubuntu22)
  • 编程小知识

  • 技术
  • 音频开发(Audio)
DC Wang
2025-08-17
目录

Linux Audio开发-使用ALSA驱动进行录音和播放(Ubuntu22)

# 使用ALSA驱动进行录音和播放(Ubuntu22)

本文介绍了ALSA的最简单的使用案例,包含录音和播放。

# 安装ALSA开发库

sudo apt update
sudo apt install libasound2-dev
1
2

# 最简示例代码

# 1. 录音示例代码(record.c)

#include <alsa/asoundlib.h>
#include <signal.h>

unsigned int SAMPLE_RATE = 44100;
#define CHANNELS 2
#define FORMAT SND_PCM_FORMAT_S16_LE
#define BUFFER_FRAMES 1024

volatile sig_atomic_t stop_recording = 0;

void handle_signal(int sig) {
    stop_recording = 1;
}

int main() {
    snd_pcm_t *handle;
    snd_pcm_hw_params_t *params;
    FILE *file = fopen("audio.raw", "wb");

    // 打开默认录音设备
    if (snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0) < 0) {
        fprintf(stderr, "无法打开PCM设备\n");
        return 1;
    }

    // 分配硬件参数结构体
    snd_pcm_hw_params_alloca(&params);
    snd_pcm_hw_params_any(handle, params);

    // 设置参数
    snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(handle, params, FORMAT);
    snd_pcm_hw_params_set_channels(handle, params, CHANNELS);
    snd_pcm_hw_params_set_rate_near(handle, params, &SAMPLE_RATE, 0);

    // 应用参数
    if (snd_pcm_hw_params(handle, params) < 0) {
        fprintf(stderr, "无法设置参数\n");
        return 1;
    }

    char buffer[BUFFER_FRAMES * CHANNELS * 2]; // 16位 = 2字节
    printf("开始录音... 按Enter停止\n");

    while (!stop_recording) {
        int frames = snd_pcm_readi(handle, buffer, BUFFER_FRAMES);
        if (frames < 0) frames = snd_pcm_recover(handle, frames, 0);
        if (frames < 0) break;
        
        fwrite(buffer, sizeof(char), frames * CHANNELS * 2, file);
    }

    // 清理
    snd_pcm_drop(handle);
    snd_pcm_close(handle);
    fclose(file);
    printf("录音完成!保存为audio.raw\n");
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# 2.播放示例代码(play.c)

#include <alsa/asoundlib.h>

unsigned int SAMPLE_RATE = 44100;
#define CHANNELS 2
#define FORMAT SND_PCM_FORMAT_S16_LE
#define BUFFER_FRAMES 1024

int main() {
    snd_pcm_t *handle;
    snd_pcm_hw_params_t *params;
    FILE *file = fopen("audio.raw", "rb");

    // 打开默认播放设备
    if (snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) {
        fprintf(stderr, "无法打开PCM设备\n");
        return 1;
    }

    // 设置参数(与录音参数一致)
    snd_pcm_hw_params_alloca(&params);
    snd_pcm_hw_params_any(handle, params);
    
    snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(handle, params, FORMAT);
    snd_pcm_hw_params_set_channels(handle, params, CHANNELS);
    snd_pcm_hw_params_set_rate_near(handle, params, &SAMPLE_RATE, 0);

    if (snd_pcm_hw_params(handle, params) < 0) {
        fprintf(stderr, "无法设置参数\n");
        return 1;
    }

    char buffer[BUFFER_FRAMES * CHANNELS * 2];
    printf("开始播放...\n");

    while (!feof(file)) {
        size_t read = fread(buffer, sizeof(char), sizeof(buffer), file);
        if (read == 0) break;
        
        int frames = read / (CHANNELS * 2);
        int written = snd_pcm_writei(handle, buffer, frames);
        if (written < 0) written = snd_pcm_recover(handle, written, 0);
        if (written < 0) break;
    }

    // 清理
    snd_pcm_drain(handle);
    snd_pcm_close(handle);
    fclose(file);
    printf("播放完成!\n");
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

# 编译和运行

编译:

gcc record.c -o record -lasound
gcc play.c -o play -lasound
1
2

运行:

  1. 录音:./record(按Ctrl+C停止)
  2. 播放:./play

# 参数说明:

  • SAMPLE_RATE: 44100Hz (CD音质)
  • CHANNELS: 2 (立体声)
  • FORMAT: 16位小端格式
  • BUFFER_FRAMES: ALSA缓冲区大小

# 文件格式:

  • 使用原始PCM格式(无文件头)
  • 可用Audacity导入:文件 > 导入 > 原始数据,参数设置与代码中一致
编辑 (opens new window)
#Audio
Linux Audio开发-ALSA API列表
Linux Audio开发-ALSA使用内存映射(MMAP)的录音实现(Ubuntu22)

← Linux Audio开发-ALSA API列表 Linux Audio开发-ALSA使用内存映射(MMAP)的录音实现(Ubuntu22)→

最近更新
01
Linux Audio开发-ALSA使用内存映射(MMAP)的录音实现(Ubuntu22)
08-17
02
Linux Audio开发-ALSA API列表
08-17
03
Linux Audio开发-介绍和名词解释
08-17
更多文章>
Theme by Vdoing | Copyright © 2019-2025 DC Wang All right reserved | 辽公网安备21029602001058号 | 吉ICP备20001966号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式