Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15531643
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2009-11-19 14:08:18

snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const char *ptr, snd_pcm_uframes_t frames, int in_kernel)
{
    struct snd_pcm_runtime *runtime = substream->runtime;
    int ret;
    while (1) {
        if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
            runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
#ifdef OSS_DEBUG
            if (runtime->status->state == SNDRV_PCM_STATE_XRUN)
                printk(KERN_DEBUG "pcm_oss: write: "
                       "recovering from XRUN\n");
            else
                printk(KERN_DEBUG "pcm_oss: write: "
                       "recovering from SUSPEND\n");
#endif
            ret = snd_pcm_oss_prepare(substream);// 调用snd_pcm_kernel_ioctl发送SNDRV_PCM_IOCTL_PREPARE
            if (ret < 0) // 准备就绪,音频数据从现在开始可以操作了[luther.gliethttp]
                break;
        }
        if (in_kernel) {
            // get_fs()和set_fs()位于include/asm-generic/uaccess.h
            mm_segment_t fs; 《浅析get_fs()和set_fs()设置user用户空间所能访问的最大虚拟地址》
            fs = snd_enter_user(); // 设置fs的addr_limit最大可访问地址为0xffffffff,而非原来正常的0xc0000000, 应用程序所能访问的最大虚拟地址[luther.gliethttp]
            ret = snd_pcm_lib_write(substream, (void __user *)ptr, frames); 《浅析alsa声卡驱动snd_pcm_lib_write函数》
            snd_leave_user(fs);
        } else {
            ret = snd_pcm_lib_write(substream, (void __user *)ptr, frames); 《浅析alsa声卡驱动snd_pcm_lib_write函数》
        }
        if (ret != -EPIPE && ret != -ESTRPIPE)
            break;
        /* test, if we can't store new data, because the stream */
        /* has not been started */
        if (runtime->status->state == SNDRV_PCM_STATE_PREPARED)
            return -EAGAIN;
    }
    return ret;
}
阅读(1669) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~