snd_pcm_open Linux,杂记asla-lib库函数snd_pcm_open打开流程

杂记asla-lib库函数snd_pcm_open打开流程

浅析ac97声卡intel8x0的DMA内存substream->dma_buffer什么时候被赋值

浅析ac97声卡intel8x0的runtime->dma_area是怎么获取的

浅析ac97声卡intel8x0的pci总线DMA物理地址填充和音频数据发送流程

aplay.c

==> main

==> snd_pcm_open(&handle, pcm_name, stream, open_mode); // 打开一路pcm,刷新config配置

如果是"default",同时type等于SND_CONFIG_TYPE_COMPOUND那么这里对应"empty"

static const char *const build_in_pcms[] = {

"adpcm", "alaw", "copy", "dmix", "file", "hooks", "hw", "ladspa", "lfloat",

"linear", "meter", "mulaw", "multi", "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_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_open

filename等于"/dev/snd/controlC0"

==> snd_open_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);

pcm->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|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;    /* RW: 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_mmap

switch (i->type) {

case SND_PCM_AREA_MMAP: // 表示为数据区分配驱动内存,在snd_pcm_hw_channel_info中设置了type

ptr = 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 RAM

static int snd_pcm_default_mmap(struct snd_

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值