pcm_nantive.c 里面,就是应用层调下来的地方
open = snd_pcm_playback_open
下面说明一下open
snd_pcm_playback_open
nonseekable_open 文件操作读写模式
snd_lookup_minor_data(iminor(inode),SNDRV_DEVICE_TYPE_PCM_CAPTURE) 根据 节点号找到pcm 数据
snd_pcm_open 这个是整个open重点
snd_card_file_add 文件增加到card链表里面
try_module_get(pcm->card->module) 判断module模块是否处于活动状态,然后通过local_inc()宏将该模块的引用计数加1
snd_pcm_open_file
snd_pcm_open_substream
snd_pcm_open_substream 参数1 snd_pcm结构体 参数2 file 参数3 返回获取的substream
snd_pcm_attach_substream 找到对应的substream 并初始化数据结构
runtime->status->state = SNDRV_PCM_STATE_OPEN;
substream->runtime = runtime;
substream->private_data = pcm->private_data;
substream->ref_count = 1;
substream->f_flags = file->f_flags;
substream->pid = get_pid(task_pid(current));
pstr->substream_opened++;
substream->ops->open(substream)) 这个地方就是调用平台相关的ops->open ,我们这里是ic1_pcm_open
我们这里只做了一些runtime 参数 初始化工作
snd_pcm_hw_constraints_init 初始化一些值,并且绑定runtime 参数设置的函数
ioctrl snd_pcm_playback_ioctl
snd_pcm_playback_ioctl1 设置一些参数值
snd_pcm_write
下面是得到这个节点的数据
pcm_file = file->private_data;
substream = pcm_file->substream;
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
runtime = substream->runtime;
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
count = bytes_to_frames(runtime, count);//获取byte
result = snd_pcm_lib_write(substream, buf, count);
err = pcm_sanity_check(substream); 判断驱动有没有实现 copy 或则dma方式
snd_pcm_lib_write1(substream, (unsigned long)buf, size, nonblock,snd_pcm_lib_write_transfer);
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
snd_pcm_update_hw_ptr(substream);//正在运行中,就进入
snd_pcm_update_hw_ptr0 更新硬件指针
pos = substream->ops->pointer(substream);//获取指针位置 调用平台相关的 pointer ,我这里是ic1_pcm_pointer
if (pos == SNDRV_PCM_POS_XRUN) { //数据有没有空,没有空的处理
xrun(substream);
snd_pcm_stop 停止喂数据
return -EPIPE;
}
pos -= pos % runtime->min_align; 对齐获取pos
hw_base = runtime->hw_ptr_base;
new_hw_ptr = hw_base + pos;
通道数(channel):该参数为1表示单声道,2则是立体声。
桢(frame):桢记录了一个声音单元,其长度为样本长度与通道数的乘积。
采样率(rate):每秒钟采样次数,该次数是针对桢而言。
周期(period):音频设备一次处理所需要的桢数,对于音频设备的数据访问以及音频数据的存储,都是以此为单位中断间隔,就是靠periods决定的,有函数来设置periods,buffer 8192个frame 而 periods是8个frame