Linux 音视频入门到实战专栏(音频篇)基于alsa api的音频播放/录制流程
沉淀、分享、成长,让自己和他人都能有所收获!😄
📢本篇将介绍如何调用alsa api来进行音频数据的播放和录制。
一、简介
1.1、音频播放流程
音频播放流程主要包括打开设备、设置参数、写入数据和关闭设备等步骤。
步骤 1: 打开音频设备
使用 snd_pcm_open() 函数打开 PCM 设备。通常,设备类型为 SND_PCM_STREAM_PLAYBACK。
snd_pcm_t *handle;
int err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
fprintf(stderr, "PCM device open error: %s\n", snd_strerror(err));
return -1;
}
步骤 2: 配置设备参数
使用 snd_pcm_set_params() 设置音频参数,如采样率、通道数、采样格式和缓冲区大小等。
err = snd_pcm_set_params(handle,
SND_PCM_FORMAT_S16_LE, // 采样格式,16位小端字节序
SND_PCM_ACCESS_RW_INTERLEAVED, // 交错访问
2, // 通道数,立体声
44100, // 采样率
1, // 1个周期即为一个音频块
500000); // 500ms超时
if (err < 0) {
fprintf(stderr, "PCM set params error: %s\n", snd_strerror(err));
return -1;
}
步骤 3: 播放音频数据
使用 snd_pcm_writei() 将音频数据写入设备。
short buffer[128];
while (1) {
// 填充音频数据到缓冲区
err = snd_pcm_writei(handle, buffer, 128);
if (err == -EPIPE) {
// 如果缓冲区溢出,重新准备设备
snd_pcm_prepare(handle);
} else if (err < 0) {
fprintf(stderr, "Write error: %s\n", snd_strerror(err));
}
}
步骤 4: 关闭音频设备
播放结束后,关闭 PCM 设备。
snd_pcm_close(handle);
1.2、音频录制流程
音频录制的流程类似,包括打开设备、配置参数、读取数据和关闭设备等步骤。
步骤 1: 打开音频设备
使用 snd_pcm_open() 打开 PCM 设备,设备类型为 SND_PCM_STREAM_CAPTURE。
snd_pcm_t *handle;
int err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0);
if (err < 0) {
fprintf(stderr, "PCM device open error: %s\n", snd_strerror(err));
return -1;
}
步骤 2: 配置设备参数
使用 snd_pcm_set_params() 设置音频参数,类似播放时的设置。
err = snd_pcm_set_params(handle,
SND_PCM_FORMAT_S16_LE, // 采样格式
SND_PCM_ACCESS_RW_INTERLEAVED, // 交错访问
2, // 通道数
44100, // 采样率
1, // 1个周期
500000); // 500ms超时
if (err < 0) {
fprintf(stderr, "PCM set params error: %s\n", snd_strerror(err));
return -1;
}
步骤 3: 读取音频数据
使用 snd_pcm_readi() 从 PCM 设备中读取音频数据。
short buffer[128];
while (1) {
err = snd_pcm_readi(handle, buffer, 128);
if (err == -EPIPE) {
// 如果发生溢出,重新准备设备
snd_pcm_prepare(handle);
} else if (err < 0) {
fprintf(stderr, "Read error: %s\n", snd_strerror(err));
}
// 处理读取的数据
}
步骤 4: 关闭音频设备
录制完成后,关闭 PCM 设备。
snd_pcm_close(handle);
二、播放音频示例
播放音频主要流程为:
- 打开设备
- 设置参数
- 写入数据
- 关闭设备
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
void main (int argc, char *argv[])
{
int i;
int err;
short buf[128];
snd_pcm_t *playback_handle;
snd_pcm_hw_params_t *hw_params;
if ((err = snd_pcm_open (&playback_handle, argv[1], SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
fprintf (stderr, "cannot open audio device %s (%s)\n",
argv[1],
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
fprintf (stderr, "cannot set access type (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
fprintf (stderr, "cannot set sample format (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, 44100, 0)) < 0) {
fprintf (stderr, "cannot set sample rate (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
fprintf (stderr, "cannot set channel count (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
fprintf (stderr, "cannot set parameters (%s)\n",
snd_strerror (err));
exit (1);
}
snd_pcm_hw_params_free (hw_params);
if ((err = snd_pcm_prepare (playback_handle)) < 0) {
fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
snd_strerror (err));
exit (1);
}
for (i = 0; i < 10; ++i) {
if ((err = snd_pcm_writei (playback_handle, buf, 128)) != 128) {
fprintf (stderr, "write to audio interface failed (%s)\n",
snd_strerror (err));
exit (1);
}
}
snd_pcm_close (playback_handle);
exit (0);
}
三、录制音频示例
录制音频与写入基本类似,只是写入改为读取。
#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
void main (int argc, char *argv[])
{
int i;
int err;
short buf[128];
snd_pcm_t *capture_handle;
snd_pcm_hw_params_t *hw_params;
if ((err = snd_pcm_open (&capture_handle, argv[1], SND_PCM_STREAM_CAPTURE, 0)) < 0) {
fprintf (stderr, "cannot open audio device %s (%s)\n",
argv[1],
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_any (capture_handle, hw_params)) < 0) {
fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
fprintf (stderr, "cannot set access type (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_format (capture_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
fprintf (stderr, "cannot set sample format (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, 44100, 0)) < 0) {
fprintf (stderr, "cannot set sample rate (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params_set_channels (capture_handle, hw_params, 2)) < 0) {
fprintf (stderr, "cannot set channel count (%s)\n",
snd_strerror (err));
exit (1);
}
if ((err = snd_pcm_hw_params (capture_handle, hw_params)) < 0) {
fprintf (stderr, "cannot set parameters (%s)\n",
snd_strerror (err));
exit (1);
}
snd_pcm_hw_params_free (hw_params);
if ((err = snd_pcm_prepare (capture_handle)) < 0) {
fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
snd_strerror (err));
exit (1);
}
for (i = 0; i < 10; ++i) {
if ((err = snd_pcm_readi (capture_handle, buf, 128)) != 128) {
fprintf (stderr, "read from audio interface failed (%s)\n",
snd_strerror (err));
exit (1);
}
}
snd_pcm_close (capture_handle);
exit (0);
}
原文地址:https://blog.csdn.net/qq_33487044/article/details/145150442
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!