当前位置:网站首页>ALSA音频架构 -- aplay播放流程分析
ALSA音频架构 -- aplay播放流程分析
2022-08-11 04:30:00 【c-coder】
引言
上文ALSA音频架构 – snd_pcm_open函数分析已经获取了aplay中对应的播放API writei_func = snd_pcm_writei;,本文将具体分析该API在哪里调用。
aplay处理数据流顺序图

代码详细分析
1、对参数进行解析,存储在全局变量hwparams,配置回调writei_func = snd_pcm_writei;
2、调用snd_pcm_open打开PCM设备,将回调关联具体的写入接口snd_pcm_hw_writei
3、调用playback根据文件类型选择具体的播放API,本文以PCM数据流为例,所以具体的接口为playback_raw
4、playback_raw对具体的数据进行解析
playback_raw的函数原型如下
static int playback_raw(char *name, int *loaded)
{
init_raw_data();
pbrec_count = calc_count();
playback_go(fd, *loaded, pbrec_count, FORMAT_RAW, name);
return 0;
}
playback_raw主要完成的工作
调用calc_count获取数据流大小
调用playback_go进行具体的操作
5、playback_go首先会调用set_params进行具体的参数配置,然后调用pcm_write进行写入数据流set_params主要设置了播放的数据流的文件格式、通道数、采样率等,函数原型如下
static void set_params(void)
{
snd_pcm_hw_params_t *params;
snd_pcm_sw_params_t *swparams;
snd_pcm_uframes_t buffer_size;
int err;
size_t n;
unsigned int rate;
snd_pcm_uframes_t start_threshold, stop_threshold;
snd_pcm_hw_params_alloca(¶ms); // 分配结构体snd_pcm_hw_params_t
snd_pcm_sw_params_alloca(&swparams);
err = snd_pcm_hw_params_any(handle, params);
...
err = snd_pcm_hw_params_set_access(handle, params, // 设置存取权限
SND_PCM_ACCESS_RW_INTERLEAVED);
...
err = snd_pcm_hw_params_set_format(handle, params, hwparams.format); // 设置文件格式
if (err < 0) {
error(_("Sample format non available"));
show_available_sample_formats(params);
prg_exit(EXIT_FAILURE);
}
err = snd_pcm_hw_params_set_channels(handle, params, hwparams.channels); // 设置通道数
if (err < 0) {
error(_("Channels count non available"));
prg_exit(EXIT_FAILURE);
}
rate = hwparams.rate;
err = snd_pcm_hw_params_set_rate_near(handle, params, &hwparams.rate, 0); // 设置码率
...
err = snd_pcm_hw_params(handle, params);
...
snd_pcm_hw_params_get_period_size(params, &chunk_size, 0);
snd_pcm_hw_params_get_buffer_size(params, &buffer_size); // 获取一个周期有多少帧数据
pcm_write调用函数指针writei_func 即snd_pcm_hw_writei完成数据流的写入,函数原型如下
static ssize_t pcm_write(u_char *data, size_t count)
{
...
while (count > 0 && !in_aborting) {
if (test_position)
do_test_position();
check_stdin();
r = writei_func(handle, data, count); //写入数据
...
}
}
至此aplay的播放在用户空间层面的操作已经完成,接下来即进入驱动层进行具体的操作。
aplay的播放流程
1、snd_pcm_open通过SND_PCM_STREAM_PLAYBACK打开设备获取snd_pcm_t句柄
2、snd_pcm_hw_params_alloca分配snd_pcm_hw_params_t PCM设备属性
3、snd_pcm_hw_params_any 初始化PCM设备属性
4、snd_pcm_hw_params_set_access设置存取权限
5、snd_pcm_hw_params_set_format设置格式
6、snd_pcm_hw_params_set_channels设置通道
7、snd_pcm_hw_params_set_rate_near设置码率
8、snd_pcm_hw_params将snd_pcm_hw_params_t PCM设备属性回写设备
9、snd_pcm_hw_params_get_period_size获取每周期的数据帧数
10、snd_pcm_writei按帧写入数据
11、snd_pcm_drain、snd_pcm_close关闭PCM设备
边栏推荐
- 「转」“搜索”的原理,架构,实现,实践,面试不用再怕了
- 机器学习怎么学?机器学习流程
- 【人话版】WEB3将至之“权益的游戏”
- About data paging display
- Get Qt installation information: including installation directory and various macro addresses
- Jetson Orin平台4-16路 GMSL2/GSML1相机采集套件推荐
- Pinduoduo store business license related issues
- 力扣——青蛙跳台阶问题
- C# 一周入门高级编程之《C#-LINQ》Day Four
- 快速使用UE4制作”大场景游戏“
猜你喜欢
随机推荐
Harvesting of radio frequency energy
"104 Maximum Depth of Binary Trees" in LeetCode's Day 12 Binary Tree Series
直播软件搭建,流式布局,支持单选、多选等
简历里写了会代码,却依然过不了面试这一关
【FPGA】day21- moving average filter
监听U盘插入 拔出 消息,获得U盘盘符
【FPGA】abbreviation
.NET service registration
无线电射频能量的收集
蹭个热度-请勿打开
破解事务性工作瓶颈,君子签电子合同释放HR“源动力”!
Get Qt installation information: including installation directory and various macro addresses
"125 Palindrome Verification" of the 10th day string series of LeetCode brushing questions
洛谷P4032 火锅盛宴
二叉堆的基础~
如何进行AI业务诊断,快速识别降本提效增长点?
"3 Longest Substring Without Repeating Characters" on the 17th day of LeetCode brushing
0 Basic software test for career change, self-study for 3 months, 12k*13 salary offer
1815. Get the maximum number of groups of fresh donuts state compression
关于数据分页显示

![[C Language] Getting Started](/img/5e/484e3d426a6f1cc0d792a9ba330695.png)







