alsa声卡devsndpcmC0D0p的open打开流程

上传人:平*** 文档编号:11121655 上传时间:2017-10-12 格式:DOC 页数:10 大小:42.28KB
返回 下载 相关 举报
alsa声卡devsndpcmC0D0p的open打开流程_第1页
第1页 / 共10页
alsa声卡devsndpcmC0D0p的open打开流程_第2页
第2页 / 共10页
alsa声卡devsndpcmC0D0p的open打开流程_第3页
第3页 / 共10页
alsa声卡devsndpcmC0D0p的open打开流程_第4页
第4页 / 共10页
alsa声卡devsndpcmC0D0p的open打开流程_第5页
第5页 / 共10页
点击查看更多>>
资源描述

《alsa声卡devsndpcmC0D0p的open打开流程》由会员分享,可在线阅读,更多相关《alsa声卡devsndpcmC0D0p的open打开流程(10页珍藏版)》请在金锄头文库上搜索。

1、alsa声卡/dev/snd/pcmC0D0p的open打开流程 原文地址:http:/ main= snd_pcm_open(&handle, pcm_name, stream, open_mode); / 打开一路pcm,刷新config配置如果是default,同时type 等于SND_CONFIG_TYPE_COMPOUND那么这里对应emptystatic const char *const build_in_pcms = adpcm, alaw, copy, dmix, file, hooks, hw, ladspa, lfloat,linear, meter, mulaw, mu

2、lti, null, empty, plug, rate, route, share,shm, dsnoop, dshare, asym, iec958, softvol, mmap_emul,NULL;_snd_pcm_empty_open和snd_pcm_open_named_slave= snd_pcm_open_conf(pcmp, name, root, conf, stream, mode);= open_func = snd_dlobj_cache_lookup(open_name);将获得lib库中_snd_pcm_empty_open 函数所以open_func将等于_snd

3、_pcm_empty_open_snd_pcm_empty_open_snd_pcm_asym_open_snd_pcm_plug_open_snd_pcm_softvol_open_snd_pcm_dmix_open_snd_pcm_hw_open= snd_pcm_hw_open(pcmp, name, card, device, subdevice, stream,mode | (nonblock ? SND_PCM_NONBLOCK : 0),0, sync_ptr_ioctl);= snd_ctl_hw_openfilename等于/dev/snd/controlC0= snd_op

4、en_device(filename, fmode);ctl-ops = &snd_ctl_hw_ops;ctl-private_data = hw;ctl-poll_fd = fd;*handle = ctl;filename等于/dev/snd/pcmC0D0p= fd = snd_open_device(filename, fmode);= return snd_pcm_hw_open_fd(pcmp, name, fd, 0, sync_ptr_ioctl);= snd_pcm_new(&pcm, SND_PCM_TYPE_HW, name, info.stream, mode);pc

5、m-ops = &snd_pcm_hw_ops;pcm-fast_ops = &snd_pcm_hw_fast_ops;static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm)snd_pcm_hw_t *hw = pcm-private_data;void *ptr;int err;if (hw-sync_ptr = NULL) / 如果还没有mmap, 那么执行mmap映射内核空间驱动使用的声音缓冲区ptr = mmap(NULL, page_align(sizeof(struct sndrv_pcm_mmap_control),PROT_READ

6、|PROT_WRITE, MAP_FILE|MAP_SHARED, hw-fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);if (ptr = MAP_FAILED | ptr = NULL) err = -errno;SYSMSG(control mmap failed);return err;hw-mmap_control = ptr; / 声卡驱动头部填充了一个结构体sndrv_pcm_mmap_control,类似qvfb显示原理./ struct sndrv_pcm_mmap_control / sndrv_pcm_uframes_t appl_ptr; /* R

7、W: appl ptr (0.boundary-1) */ sndrv_pcm_uframes_t avail_min; /* RW: min available frames for wakeup */ ; else hw-mmap_control-avail_min = 1;snd_pcm_set_appl_ptr(pcm, &hw-mmap_control-appl_ptr, hw-fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);return 0;snd_pcm_mmapswitch (i-type) case SND_PCM_AREA_MMAP: / 表示为数据区

8、分配驱动内存,在snd_pcm_hw_channel_info中设置了typeptr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, i-u.mmap.fd, i-u.mmap.offset);/*mmap= snd_pcm_mmap_data= snd_pcm_default_mmap/ mmap the DMA buffer on RAMstatic int snd_pcm_default_mmap(struct snd_pcm_substream *substream,struct vm_area_struct

9、*area)area-vm_ops = &snd_pcm_vm_ops_data; / vma操作函数,当应用程序向该 area读写不存在的内存数据时,area-vm_private_data = substream; / 将执行snd_pcm_vm_ops_data中的fault/ 函数snd_pcm_mmap_data_fault进一步以页为单位申请内存空 间,所以如果用户程序需要64k,那么将执行16次,每次申请4k空间luther.gliethttp.area-vm_flags |= VM_RESERVED;atomic_inc(&substream-mmap_count);retur

10、n 0;*/if (ptr = MAP_FAILED) SYSERR(mmap failed);return -errno;i-addr = ptr;= snd_pcm_mmap_controlstatic int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,struct vm_area_struct *area)struct snd_pcm_runtime *runtime;long size;if (!(area-vm_flags & VM_READ)return -EINVAL;r

11、untime = substream-runtime;size = area-vm_end - area-vm_start;if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)return -EINVAL;area-vm_ops = &snd_pcm_vm_ops_control; / 当对 ( area-vm_start,area-vm_end)之间空间操作,发生area-vm_private_data = substream; / 缺页时,内核将调用该vm_ops方法来处理fault异常,area-vm_flags |= VM

12、_RESERVED; / 进而执行snd_pcm_mmap_control_fault 申请1个page空间return 0;= writei_func = snd_pcm_writei;= playback(argvoptind+);= playback_go(fd, dtawave, pbrec_count, FORMAT_WAVE, name);= pcm_write(audiobuf, l);= writei_func(handle, data, count);就是调用上面的snd_pcm_writei= snd_pcm_writei= _snd_pcm_writei= pcm-fas

13、t_ops-writei(pcm-fast_op_arg, buffer, size);= snd_pcm_plugin_writei= snd_pcm_write_areas(pcm, areas, 0, size, snd_pcm_plugin_write_areas);= avail = snd_pcm_avail_update(pcm); / 获取可用缓 冲区位置偏移索引值= func()就是snd_pcm_plugin_write_areas函数发送1024帧音频数据,一帧对应一次完整采样, 比如stereo 立体声,24bits量化,那么这里一帧对应3*2字节数据,即一次完整采样所

14、需空间luther.gliethttp.= plugin-write(pcm, areas, offset, frames,slave_areas, slave_offset, &slave_frames);即调用snd_pcm_linear_write_areas函数将areas中的frames频数据拷贝到slave_areas内存区= pcm-fast_ops-mmap_commit(pcm-fast_op_arg, offset, frames);= snd_pcm_dmix_mmap_commit= snd_pcm_dmix_sync_area/* synchronize shm ri

15、ng buffer with hardware*/static void snd_pcm_dmix_sync_area(snd_pcm_t *pcm)= /* add sample areas here */src_areas = snd_pcm_mmap_areas(pcm);dst_areas = snd_pcm_mmap_areas(dmix-spcm); / 添加= mix_areas(dmix, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);if (dmix-interleaved) / 可以将缓冲中的音频数据填充到硬件中 luther.gliethttp/* process all areas in one loop* it optimizes the memory accesses for this case*/do_mix_areas(size * channels,(unsigned char *)dst_a

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号