⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.c

📁 自己根据lkd和情境分析
💻 C
📖 第 1 页 / 共 5 页
字号:
                        } else {                                retval = -EINVAL;                        }                        break;                case SNDCTL_DSP_SETFMT:                        /* need to decode into encoding, precision */                        get_user(i, (int *)arg);	                            /* handle special case here */                        if (i == AFMT_QUERY) {                                j = drv->ops->get_output_encoding(drv);                                k = drv->ops->get_output_precision(drv);                                if (j == AUDIO_ENCODING_DVI) {                                        i = AFMT_IMA_ADPCM;                                } else if (k == 8) {                                        switch (j) {                                        case AUDIO_ENCODING_ULAW:                                                i = AFMT_MU_LAW;                                                break;                                        case AUDIO_ENCODING_ALAW:                                                i = AFMT_A_LAW;                                                break;                                        case AUDIO_ENCODING_LINEAR8:                                                i = AFMT_U8;                                                break;                                        };                                } else if (k == 16) {                                        switch (j) {                                        case AUDIO_ENCODING_LINEAR:                                                i = AFMT_S16_BE;                                                break;                                        case AUDIO_ENCODING_LINEARLE:                                                i = AFMT_S16_LE;                                                break;                                        };                                }                                 put_user(i, (int *)arg);                                break;                        }                        /* Without these there's no point in trying */                        if (!drv->ops->set_input_precision ||                            !drv->ops->set_input_encoding ||                            !drv->ops->set_output_precision ||                            !drv->ops->set_output_encoding) {                                eprintk(("missing set routines: failed\n"));                                retval = -EINVAL;                                break;                        }                        if (drv->ops->get_formats) {                                if (!(drv->ops->get_formats(drv) & i)) {                                        dprintk(("format not supported\n"));                                        return -EINVAL;                                }                        }                        switch (i) {                        case AFMT_S16_LE:                                ainfo.record.precision = ainfo.play.precision = 16;                                ainfo.record.encoding = ainfo.play.encoding =                                        AUDIO_ENCODING_LINEARLE;                                break;                        case AFMT_S16_BE:                                ainfo.record.precision = ainfo.play.precision = 16;                                ainfo.record.encoding = ainfo.play.encoding =                                        AUDIO_ENCODING_LINEAR;                                break;                        case AFMT_MU_LAW:                                ainfo.record.precision = ainfo.play.precision = 8;                                ainfo.record.encoding = ainfo.play.encoding =                                        AUDIO_ENCODING_ULAW;                                break;                        case AFMT_A_LAW:                                ainfo.record.precision = ainfo.play.precision = 8;                                ainfo.record.encoding = ainfo.play.encoding =                                        AUDIO_ENCODING_ALAW;                                break;                        case AFMT_U8:                                ainfo.record.precision = ainfo.play.precision = 8;                                ainfo.record.encoding = ainfo.play.encoding =                                        AUDIO_ENCODING_LINEAR8;                                break;                        };                        tprintk(("setting fmt to enc %d pr %d\n",                                 ainfo.play.encoding,                                 ainfo.play.precision));                        if ((drv->ops->set_input_precision(drv,                                                           ainfo.record.precision)                              < 0) ||                            (drv->ops->set_output_precision(drv,                                                            ainfo.play.precision)                               < 0) ||                            (drv->ops->set_input_encoding(drv,                                                          ainfo.record.encoding)                             < 0) ||                            (drv->ops->set_output_encoding(drv,                                                           ainfo.play.encoding)                             < 0)) {                                dprintk(("setting format: failed\n"));                                return -EINVAL;                        }                        put_user(i, (int *)arg);                        break;                case SNDCTL_DSP_CHANNELS:                        if ((!drv->ops->set_output_channels) &&                             (!drv->ops->set_input_channels)) {                                retval = -EINVAL;                                break;                        }                        get_user(i, (int *)arg);                        drv->ops->set_input_channels(drv, i);                        drv->ops->set_output_channels(drv, i);                        i = drv->ops->get_output_channels(drv);                        put_user(i, (int *)arg);                        break;                case SNDCTL_DSP_STEREO:                        if ((!drv->ops->set_output_channels) &&                             (!drv->ops->set_input_channels)) {                                retval = -EINVAL;                                break;                        }                        get_user(i, (int *)arg);                        drv->ops->set_input_channels(drv, (i + 1));                        drv->ops->set_output_channels(drv, (i + 1));                        i = ((drv->ops->get_output_channels(drv)) - 1);                        put_user(i, (int *)arg);                        break;                case SNDCTL_DSP_POST:                case SNDCTL_DSP_SYNC:                case AUDIO_DRAIN:                        /* Deal with weirdness so we can fill buffers */                        if (drv->output_offset) {                                drv->output_offset = 0;                                drv->output_rear = (drv->output_rear + 1)                                        % drv->num_output_buffers;                                drv->output_count++;                        }                        if (drv->output_count > 0) {                                sparcaudio_sync_output(drv);                                /* Only pause for DRAIN/SYNC, not POST */                                if (cmd != SNDCTL_DSP_POST) {                                        interruptible_sleep_on(&drv->output_drain_wait);                                        retval = (signal_pending(current)) ? -EINTR : 0;                                }                        }                        break;                case I_FLUSH:                case I_FLUSH_SOLARIS:                        if (((unsigned int)arg == FLUSHW) ||                             ((unsigned int)arg == FLUSHRW)) {                                if (file->f_mode & FMODE_WRITE) {                                        sparcaudio_sync_output(drv);                                        if (drv->output_active) {                                                wake_up_interruptible(&drv->output_write_wait);                                                drv->ops->stop_output(drv);                                        }                                        drv->output_offset = 0;                                        drv->output_active = 0;                                        drv->output_front = 0;                                        drv->output_rear = 0;                                        drv->output_count = 0;                                        drv->output_size = 0;                                        drv->playing_count = 0;                                        drv->output_eof = 0;                                }                        }                        if (((unsigned int)arg == FLUSHR) ||                             ((unsigned int)arg == FLUSHRW)) {                                if (drv->input_active && (file->f_mode & FMODE_READ)) {                                        wake_up_interruptible(&drv->input_read_wait);                                        drv->ops->stop_input(drv);                                        drv->input_active = 0;                                        drv->input_front = 0;                                        drv->input_rear = 0;                                        drv->input_count = 0;                                        drv->input_size = 0;                                        drv->input_offset = 0;                                        drv->recording_count = 0;                                }                                if ((file->f_mode & FMODE_READ) &&                                     (drv->flags & SDF_OPEN_READ)) {                                        if (drv->duplex == 2)                                                drv->input_count = drv->output_count;                                        drv->ops->start_input(drv,                                                               drv->input_buffers[drv->input_front],                                                              drv->input_buffer_size);                                        drv->input_active = 1;                                }                        }                        if (((unsigned int)arg == FLUSHW) ||                             ((unsigned int)arg == FLUSHRW)) {                                if ((file->f_mode & FMODE_WRITE) &&                                     !(drv->flags & SDF_OPEN_WRITE)) {                                        kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);                                        sparcaudio_sync_output(drv);                                }                        }                        break;                case SNDCTL_DSP_RESET:                case AUDIO_FLUSH:                        if (drv->output_active && (file->f_mode & FMODE_WRITE)) {                                wake_up_interruptible(&drv->output_write_wait);                                drv->ops->stop_output(drv);                                drv->output_active = 0;                                drv->output_front = 0;                                drv->output_rear = 0;                                drv->output_count = 0;                                drv->output_size = 0;                                drv->playing_count = 0;                                drv->output_offset = 0;                                drv->output_eof = 0;                        }                        if (drv->input_active && (file->f_mode & FMODE_READ)) {                                wake_up_interruptible(&drv->input_read_wait);                                drv->ops->stop_input(drv);                                drv->input_active = 0;                                drv->input_front = 0;                                drv->input_rear = 0;                                drv->input_count = 0;                                drv->input_size = 0;                                drv->input_offset = 0;                                drv->recording_count = 0;                        }                        if ((file->f_mode & FMODE_READ) &&                             !(drv->flags & SDF_OPEN_READ)) {                                drv->ops->start_input(drv,                                                       drv->input_buffers[drv->input_front],                                                      drv->input_buffer_size);                                drv->input_active = 1;                        }                        if ((file->f_mode & FMODE_WRITE) &&                             !(drv->flags & SDF_OPEN_WRITE)) {                                sparcaudio_sync_output(drv);                        }                        break;                case AUDIO_GETDEV:                        if (drv->ops->sunaudio_getdev) {                                audio_device_t tmp;	                                      retval = verify_area(VERIFY_WRITE, (void *)arg,                                                      sizeof(audio_device_t));                                if (!retval)                                        drv->ops->sunaudio_getdev(drv, &tmp);                                copy_to_user((audio_device_t *)arg, &tmp, sizeof(tmp));                        } else {                                retval = -EINVAL;                        }                        break;                case AUDIO_GETDEV_SUNOS:                        if (drv->ops->sunaudio_getdev_sunos) {                                int tmp = drv->ops->sunaudio_getdev_sunos(drv);                                retval = verify_area(VERIFY_WRITE, (void *)arg, sizeof(int));                                if (!retval)                                        copy_to_user((int *)arg, &tmp, sizeof(tmp));                        } else {                                retval = -EINVAL;                        }                        break;                case AUDIO_GETINFO:                        AUDIO_INITINFO(&ainfo);                        if (drv->ops->get_input_rate)                                ainfo.record.sample_rate =                                        drv->ops->get_input_rate(drv);                        else                                ainfo.record.sample_rate = (8000);                        if (drv->ops->get_input_channels)                                ainfo.record.channels =                                        drv->ops->get_input_channels(drv);                        else                                ainfo.record.channels = (1);                        if (drv->ops->get_input_precision)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -