alsa 代码分析

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


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值