📄 audio.c
字号:
drv->ops->set_input_pause(drv, 1); } if ((arg & PCM_ENABLE_OUTPUT) && drv->ops->get_output_pause && drv->ops->set_output_pause) { if (drv->ops->get_output_pause(drv)) drv->ops->set_output_pause(drv, 0); } else { if (!drv->ops->get_output_pause(drv)) drv->ops->set_output_pause(drv, 1); } break; case SNDCTL_DSP_GETTRIGGER: j = 0; if (drv->ops->get_input_pause) { if (drv->ops->get_input_pause(drv)) j = PCM_ENABLE_INPUT; } if (drv->ops->get_output_pause) { if (drv->ops->get_output_pause(drv)) j |= PCM_ENABLE_OUTPUT; } COPY_OUT(arg, j); break; case SNDCTL_DSP_GETBLKSIZE: j = drv->input_buffer_size; COPY_OUT(arg, j); break; case SNDCTL_DSP_SPEED: if ((!drv->ops->set_output_rate) && (!drv->ops->set_input_rate)) { retval = -EINVAL; break; } COPY_IN(arg, i); tprintk(("setting speed to %d\n", i)); drv->ops->set_input_rate(drv, i); drv->ops->set_output_rate(drv, i); j = drv->ops->get_output_rate(drv); COPY_OUT(arg, j); break; case SNDCTL_DSP_GETCAPS: /* All Sparc audio hardware is full duplex. * 4231 supports DMA pointer reading, 7930 is byte at a time. * Pause functionality emulates trigger */ j = DSP_CAP_DUPLEX | DSP_CAP_TRIGGER | DSP_CAP_REALTIME; COPY_OUT(arg, j); break; case SNDCTL_DSP_GETFMTS: if (drv->ops->get_formats) { j = drv->ops->get_formats(drv); COPY_OUT(arg, j); } else { retval = -EINVAL; } break; case SNDCTL_DSP_SETFMT: /* need to decode into encoding, precision */ COPY_IN(arg, i); /* 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; }; } COPY_OUT(arg, i); 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; } COPY_OUT(arg, i); break; case SNDCTL_DSP_CHANNELS: if ((!drv->ops->set_output_channels) && (!drv->ops->set_input_channels)) { retval = -EINVAL; break; } COPY_IN(arg, i); drv->ops->set_input_channels(drv, i); drv->ops->set_output_channels(drv, i); i = drv->ops->get_output_channels(drv); COPY_OUT(arg, i); break; case SNDCTL_DSP_STEREO: if ((!drv->ops->set_output_channels) && (!drv->ops->set_input_channels)) { retval = -EINVAL; break; } COPY_IN(arg, i); drv->ops->set_input_channels(drv, (i + 1)); drv->ops->set_output_channels(drv, (i + 1)); i = ((drv->ops->get_output_channels(drv)) - 1); COPY_OUT(arg, i); 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -