📄 audio.c
字号:
} 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 + -