当前位置:网站首页>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设备
边栏推荐
猜你喜欢

Clang Code Model: Error: The clangbackend executable “X:/clangbackend.exe“ could not be started

Three 】 【 yolov7 series of actual combat from 0 to build training data sets

To break the bottleneck of transactional work, the gentleman signs the electronic contract to release the "source power" of HR!

网络安全培训机构哪家好?排名怎么选择?

Where can machine learning be applied?What is machine learning useful for?

What is ensemble learning in machine learning?

Provincial level of Echart maps, as well as all prefecture-level download and use

校园兼职平台项目反思

LeetCode刷题第11天字符串系列之《 58最后一个单词长度》

"98 BST and Its Verification" of the 13th day of leetcode brushing series of binary tree series
随机推荐
What are port 80 and port 443?What's the difference?
获取Qt的安装信息:包括安装目录及各种宏地址
[Note] Is the value of BatchSize the bigger the better?
关于数据分页显示
Bubble sort and heap sort
"104 Maximum Depth of Binary Trees" in LeetCode's Day 12 Binary Tree Series
The FTP error code list
Get Qt installation information: including installation directory and various macro addresses
力扣——青蛙跳台阶问题
LeetCode814算题第15天二叉树系列值《814 二叉树剪枝》
Mysql中事件和定时任务
1815. Get the maximum number of groups of fresh donuts state compression
洛谷P2245 星际导航
移动端地图开发选择哪家?
《卫星界》刊评“星辰大海”计划:孙宇晨为太空旅游带来新的机遇
leetCode刷题14天二叉树系列之《 110 平衡二叉树判断》
【FPGA】day22-SPI protocol loopback
【ImageNet】数据集1000个类的名称
干货:服务器网卡组技术原理与实践
Harvesting of radio frequency energy