Linux Audio开发-使用ALSA驱动进行录音和播放(Ubuntu22)
# 使用ALSA驱动进行录音和播放(Ubuntu22)
本文介绍了ALSA的最简单的使用案例,包含录音和播放。
# 安装ALSA开发库
sudo apt update
sudo apt install libasound2-dev
1
2
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(¶ms);
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
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(¶ms);
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
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
2
运行:
- 录音:
./record
(按Ctrl+C停止) - 播放:
./play
# 参数说明:
SAMPLE_RATE
: 44100Hz (CD音质)CHANNELS
: 2 (立体声)FORMAT
: 16位小端格式BUFFER_FRAMES
: ALSA缓冲区大小
# 文件格式:
- 使用原始PCM格式(无文件头)
- 可用Audacity导入:
文件 > 导入 > 原始数据
,参数设置与代码中一致
编辑 (opens new window)
- 02
- Linux Audio开发-ALSA API列表08-17
- 03
- Linux Audio开发-介绍和名词解释08-17