创建pcm device
来源:互联网 发布:支持java的虚拟主机 编辑:程序博客网 时间:2024/06/16 07:07
声卡下面有多种device,最重要的是pcm和control两类。
先看pcm device
创建pcm
创建device最终使用的都是snd_device_new。常使用的是snd_pcm_new来创建pcm device。(类似的还有snd_ctl_create)
先贴下调用关系
snd_soc_register_card snd_soc_instantiate_cardsoc_probe_link_dais soc_new_pcmsnd_pcm_new _snd_pcm_newsnd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count)snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)rtd->ops.open = soc_pcm_open;
在创建pcm是可以看到如下log
sprd-codec-v3-i2s <-> vbc-r2p0 mapping oksprd-codec-v3-vaudio <-> vaudio mapping okcodec-i2s-ext <-> vbc-r2p0-ad23 mapping okcodec-vaudio-ext <-> vaudio-ad23 mapping oksprd-codec-v3-fm <-> vbc-dfm mapping oknull-codec-dai <-> i2s.0 mapping ok
分别对应vbc_r2p0_codec_v3_dai和all_i2s_dai两个dai.这里vbc_r2p0_codec_v3_dai中platform_name是sprd-pcm-audio。
注意snd_device_new最后一个参数
static struct snd_device_ops ops = { .dev_free = snd_pcm_dev_free, .dev_register = snd_pcm_dev_register, .dev_disconnect = snd_pcm_dev_disconnect,}; static int snd_pcm_dev_register(struct snd_device *device){ err = snd_register_device_for_dev(devtype, pcm->card, pcm->device, &snd_pcm_f_ops[cidx], pcm, str, dev);}const struct file_operations snd_pcm_f_ops[2] = { { .owner = THIS_MODULE, .write = snd_pcm_write, .aio_write = snd_pcm_aio_write, .open = snd_pcm_playback_open, .release = snd_pcm_release, .llseek = no_llseek, .poll = snd_pcm_playback_poll, .unlocked_ioctl = snd_pcm_playback_ioctl, .compat_ioctl = snd_pcm_ioctl_compat, .mmap = snd_pcm_mmap, .fasync = snd_pcm_fasync, .get_unmapped_area = snd_pcm_get_unmapped_area, }, { .owner = THIS_MODULE, .read = snd_pcm_read, .aio_read = snd_pcm_aio_read, .open = snd_pcm_capture_open, .release = snd_pcm_release, .llseek = no_llseek, .poll = snd_pcm_capture_poll, .unlocked_ioctl = snd_pcm_capture_ioctl, .compat_ioctl = snd_pcm_ioctl_compat, .mmap = snd_pcm_mmap, .fasync = snd_pcm_fasync, .get_unmapped_area = snd_pcm_get_unmapped_area, } };
用户态打开pcm device(pcmC0D0p)就会调用这里的函数
看snd_pcm_write
snd_pcm_write snd_pcm_lib_write snd_pcm_lib_write1 snd_pcm_start snd_pcm_action snd_pcm_action_start snd_pcm_do_start substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);这个substream又来自那?
看snd_pcm_write
snd_pcm_write{ struct snd_pcm_file *pcm_file; pcm_file = file->private_data; substream = pcm_file->substream;}关键是这个pcm_file,其实是来自snd_pcm_open_file
snd_pcm_open_substream(pcm, stream, file, &substream);pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);pcm_file->substream = substream;而snd_pcm_open_file被snd_pcm_open调用,再往上是snd_pcm_playback_open
snd_pcm_playback_open是snd_pcm_f_ops的一个open函数
再回到snd_soc_register_card,这里注册的card的dai中是.platform_name = "sprd-pcm-audio",
这个sprd-pcm-audio对于的pcm操作在那?
static struct snd_pcm_ops sprd_pcm_ops = { .open = sprd_pcm_open, .close = sprd_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = sprd_pcm_hw_params, .hw_free = sprd_pcm_hw_free, .prepare = sprd_pcm_prepare, .trigger = sprd_pcm_trigger, .pointer = sprd_pcm_pointer, .mmap = sprd_pcm_mmap,};static struct platform_driver sprd_pcm_driver = { .driver = { .name = "sprd-pcm-audio", .owner = THIS_MODULE, .of_match_table = of_match_ptr(sprd_pcm_of_match), }, .probe = sprd_soc_platform_probe, .remove = sprd_soc_platform_remove,};
platform怎么和substream联系起来那?
看snd_soc_instantiate_card。这个函数先调用soc_bind_dai_link,找到dai对应的platform,放到rtd中。
而substream来自与soc_new_pcm.soc_new_pcm第一个参数就是这个rtd
snd_soc_instantiate_card soc_bind_dai_link <strong>rtd</strong>->platform = platform;soc_probe_link_dais soc_new_pcm(<strong>rtd</strong>, num);
DroidPhone的blog中有几个图片非常好,这里转一下
pcm的数据结构
创建pcm device
用户写数据的流程
0 0
- 创建pcm device
- Android音频驱动-ASOC之PCM Device创建
- PCM
- PCM
- PCM
- PCM
- PCM
- PCM
- 创建Android Virtual Device
- 创建control device
- Linux ALSA声卡驱动之三:PCM设备的创建
- Linux ALSA声卡驱动之三:PCM设备的创建
- Linux ALSA声卡驱动之三:PCM设备的创建
- Linux ALSA声卡驱动之三:PCM设备的创建
- Linux ALSA声卡驱动之三:PCM设备的创建
- Linux ALSA声卡驱动之三:PCM设备的创建
- Linux ALSA声卡驱动之三:PCM设备的创建
- Linux ALSA声卡驱动之三:PCM设备的创建
- poj-1330
- Android布局大全
- 安卓学习之XML布局
- mysql表的清空、删除和修改操作详解
- iOS 如何选择delegate、notification、KVO?
- 创建pcm device
- Android 使用Bundle在Activity间传递数据
- 看CUDA遇到的一些文章和概念
- ArrayAdapter
- puts putchar printf
- 二叉树 - 数据结构
- Java编程基础-正则表达式进阶
- 用OpenNI录制和重播影像
- mac os x 10.9 安装 Command Line Tools ( xCode6 居然不能直接下载这工具 -_-!! )