alsa sample rate跟踪 <3>
来源:互联网 发布:阿尔法营创意编程 编辑:程序博客网 时间:2024/05/23 17:16
alsa sample rate跟踪 <3>
接着看。
还有一个疑问点,按照之前的分析,如果想要snd_pcm_hw_params被调用,需要调用snd_pcm_rate_open。
但是从上面列出来的函数调用关系没有调用snd_pcm_rate_open,那么这个东东是什么时候被调用的呢?
原来在函数snd_pcm_plug_hw_params中有个判断,如果client params中的参数与slave params中的不一致,将调用snd_pcm_plug_insert_plugins函数。
static int snd_pcm_plug_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params){ snd_pcm_plug_t *plug = pcm->private_data; snd_pcm_t *slave = plug->req_slave; snd_pcm_plug_params_t clt_params, slv_params; snd_pcm_hw_params_t sparams; int err; err = snd_pcm_plug_hw_refine_sprepare(pcm, &sparams); if (err < 0) return err; err = snd_pcm_plug_hw_refine_schange(pcm, params, &sparams); if (err < 0) return err; err = snd_pcm_hw_refine_soft(slave, &sparams); if (err < 0) return err; INTERNAL(snd_pcm_hw_params_get_access)(params, &clt_params.access); INTERNAL(snd_pcm_hw_params_get_format)(params, &clt_params.format); INTERNAL(snd_pcm_hw_params_get_channels)(params, &clt_params.channels); INTERNAL(snd_pcm_hw_params_get_rate)(params, &clt_params.rate, 0); INTERNAL(snd_pcm_hw_params_get_format)(&sparams, &slv_params.format); INTERNAL(snd_pcm_hw_params_get_channels)(&sparams, &slv_params.channels); INTERNAL(snd_pcm_hw_params_get_rate)(&sparams, &slv_params.rate, 0); snd_pcm_plug_clear(pcm); if (!(clt_params.format == slv_params.format && clt_params.channels == slv_params.channels && clt_params.rate == slv_params.rate && !plug->ttable && snd_pcm_hw_params_test_access(slave, &sparams, clt_params.access) >= 0)) { INTERNAL(snd_pcm_hw_params_set_access_first)(slave, &sparams, &slv_params.access); err = snd_pcm_plug_insert_plugins(pcm, &clt_params, &slv_params); if (err < 0) return err; } slave = plug->gen.slave; err = _snd_pcm_hw_params(slave, params); if (err < 0) { snd_pcm_plug_clear(pcm); return err; } snd_pcm_unlink_hw_ptr(pcm, plug->req_slave); snd_pcm_unlink_appl_ptr(pcm, plug->req_slave); snd_pcm_link_hw_ptr(pcm, slave); snd_pcm_link_appl_ptr(pcm, slave); return 0;}
函数snd_pcm_plug_insert_plugins中会通过一个while循环,依次调用plugin进行处理,知道client params和slave params完全一致。
static int snd_pcm_plug_insert_plugins(snd_pcm_t *pcm, snd_pcm_plug_params_t *client, snd_pcm_plug_params_t *slave){ snd_pcm_plug_t *plug = pcm->private_data; static int (*const funcs[])(snd_pcm_t *_pcm, snd_pcm_t **new, snd_pcm_plug_params_t *s, snd_pcm_plug_params_t *d) = {#ifdef BUILD_PCM_PLUGIN_MMAP_EMUL snd_pcm_plug_change_mmap,#endif snd_pcm_plug_change_format,#ifdef BUILD_PCM_PLUGIN_ROUTE snd_pcm_plug_change_channels,#endif#ifdef BUILD_PCM_PLUGIN_RATE snd_pcm_plug_change_rate,#endif#ifdef BUILD_PCM_PLUGIN_ROUTE snd_pcm_plug_change_channels,#endif snd_pcm_plug_change_format, snd_pcm_plug_change_access }; snd_pcm_plug_params_t p = *slave; unsigned int k = 0; plug->ttable_ok = plug->ttable_last = 0; while (client->format != p.format || client->channels != p.channels || client->rate != p.rate || client->access != p.access) { snd_pcm_t *new; int err; if (k >= sizeof(funcs)/sizeof(*funcs)) return -EINVAL; err = funcs[k](pcm, &new, client, &p); if (err < 0) { snd_pcm_plug_clear(pcm); return err; } if (err) { plug->gen.slave = new; pcm->fast_ops = new->fast_ops; pcm->fast_op_arg = new->fast_op_arg; } k++; }...}
其中的snd_pcm_plug_change_rate函数调用了snd_pcm_rate_open函数。
函数snd_pcm_plug_insert_plugins中定义了一个snd_pcm_t指针:snd_pcm_t *new,并将其传给了snd_pcm_plug_change_rate。
snd_pcm_plug_change_rate又将new传给了snd_pcm_rate_open函数。
snd_pcm_rate_open函数中将snd_pcm_rate_ops赋值给了new的ops成员:
pcm->ops = &snd_pcm_rate_ops;
snd_pcm_plug_insert_plugins中判断如果处理都成功,将new赋值给plug->gen.slave:
snd_pcm_plug_t *plug = pcm->private_data; plug->gen.slave = new;
再回到函数snd_pcm_plug_hw_params,其中在调用过snd_pcm_plug_insert_plugins之后,将plug->gen.slave赋值给了slave。
然后以slave为参数调用了函数_snd_pcm_hw_params:
snd_pcm_plug_t *plug = pcm->private_data; slave = plug->gen.slave; err = _snd_pcm_hw_params(slave, params);
函数_snd_pcm_hw_params中会调用slave中ops的hw_params函数:
err = pcm->ops->hw_params(pcm->op_arg, params);
看到这儿,发现alsa lib中通常是以pcm为媒介,在open的时候将根据需要将函数指针挂到pcm上。
后面要用的时候再调用pcm上的函数指针。
既然这样,我们就看看在前面的open流程中都往pcm上挂了哪些东东。
- alsa sample rate跟踪 <3>
- alsa sample rate跟踪 <1>
- alsa sample rate跟踪 <2>
- alsa sample rate跟踪 <4>
- bit rate / frame rate /sample rate等等
- bit rate / frame rate /sample rate等等
- bit rate / frame rate /sample rate等等
- Sample rate 理解
- FM Bandwidth IQ Rate Sample Rate
- convert sample rate from AV_SAMPLE_FMT_FLTP to AV_SAMPLE_FMT_S16
- 视频编码的常见参数基本概念 --bit rate / frame rate /sample rate等等
- OpenCV 团块跟踪sample使用
- Vista Core API: Changing audio device sample rate
- Batch Gradiant Descent - Sample Magnitute and Learning Rate
- LTE以及OFDM中sample rate, fft size, channel bw, subcarrier, number of sample等概念的理解
- Double Data Rate 3 (DDR3)
- ERROR: 98: Error '!obj' trying to fetch default input device's sample rate
- 错误ERROR: 98: Error '!obj' trying to fetch default input device's sample rate
- HttpClient与HttpClient参数paras
- Spring Data Redis实现一个订阅/发布系统
- 关于使用c#调用python脚本文件,脚本文件需要传递参数
- linux下安装jdk
- cocos2D-x关于精灵框架的实现
- alsa sample rate跟踪 <3>
- unity3d开发2d游戏:自动寻路Navmesh入门
- 设计模式之--观察者模式
- jQuery api .next()
- nginx非root用户安装
- OnQueryEndSession 与 OnEndSession
- android中多个applicaiton类需要注册的问题
- 香港成为北京IT服务外包贸易主要地区
- javascript 判断 history.back() 起作用了没