📄 audio.c
字号:
ainfo.record.precision = drv->ops->get_input_precision(drv); else ainfo.record.precision = (8); if (drv->ops->get_input_encoding) ainfo.record.encoding = drv->ops->get_input_encoding(drv); else ainfo.record.encoding = (AUDIO_ENCODING_ULAW); if (drv->ops->get_input_volume) ainfo.record.gain = drv->ops->get_input_volume(drv); else ainfo.record.gain = (0); if (drv->ops->get_input_port) ainfo.record.port = drv->ops->get_input_port(drv); else ainfo.record.port = (0); if (drv->ops->get_input_ports) ainfo.record.avail_ports = drv->ops->get_input_ports(drv); else ainfo.record.avail_ports = (0); /* To make e.g. vat happy, we let them think they control this */ ainfo.record.buffer_size = drv->buffer_size; if (drv->ops->get_input_samples) ainfo.record.samples = drv->ops->get_input_samples(drv); else ainfo.record.samples = 0; /* This is undefined in the record context in Solaris */ ainfo.record.eof = 0; if (drv->ops->get_input_pause) ainfo.record.pause = drv->ops->get_input_pause(drv); else ainfo.record.pause = 0; if (drv->ops->get_input_error) ainfo.record.error = (unsigned char) drv->ops->get_input_error(drv); else ainfo.record.error = 0; ainfo.record.waiting = 0; if (drv->ops->get_input_balance) ainfo.record.balance = (unsigned char) drv->ops->get_input_balance(drv); else ainfo.record.balance = (unsigned char)(AUDIO_MID_BALANCE); ainfo.record.minordev = 4 + (minor << SPARCAUDIO_DEVICE_SHIFT); ainfo.record.open = (drv->flags & SDF_OPEN_READ); ainfo.record.active = 0; if (drv->ops->get_output_rate) ainfo.play.sample_rate = drv->ops->get_output_rate(drv); else ainfo.play.sample_rate = (8000); if (drv->ops->get_output_channels) ainfo.play.channels = drv->ops->get_output_channels(drv); else ainfo.play.channels = (1); if (drv->ops->get_output_precision) ainfo.play.precision = drv->ops->get_output_precision(drv); else ainfo.play.precision = (8); if (drv->ops->get_output_encoding) ainfo.play.encoding = drv->ops->get_output_encoding(drv); else ainfo.play.encoding = (AUDIO_ENCODING_ULAW); if (drv->ops->get_output_volume) ainfo.play.gain = drv->ops->get_output_volume(drv); else ainfo.play.gain = (0); if (drv->ops->get_output_port) ainfo.play.port = drv->ops->get_output_port(drv); else ainfo.play.port = (0); if (drv->ops->get_output_ports) ainfo.play.avail_ports = drv->ops->get_output_ports(drv); else ainfo.play.avail_ports = (0); /* This is not defined in the play context in Solaris */ ainfo.play.buffer_size = 0; if (drv->ops->get_output_samples) ainfo.play.samples = drv->ops->get_output_samples(drv); else ainfo.play.samples = 0; ainfo.play.eof = drv->output_eof; if (drv->ops->get_output_pause) ainfo.play.pause = drv->ops->get_output_pause(drv); else ainfo.play.pause = 0; if (drv->ops->get_output_error) ainfo.play.error = (unsigned char)drv->ops->get_output_error(drv); else ainfo.play.error = 0; ainfo.play.waiting = waitqueue_active(&drv->open_wait); if (drv->ops->get_output_balance) ainfo.play.balance = (unsigned char)drv->ops->get_output_balance(drv); else ainfo.play.balance = (unsigned char)(AUDIO_MID_BALANCE); ainfo.play.minordev = 4 + (minor << SPARCAUDIO_DEVICE_SHIFT); ainfo.play.open = (drv->flags & SDF_OPEN_WRITE); ainfo.play.active = drv->output_active; if (drv->ops->get_monitor_volume) ainfo.monitor_gain = drv->ops->get_monitor_volume(drv); else ainfo.monitor_gain = (0); if (drv->ops->get_output_muted) ainfo.output_muted = (unsigned char)drv->ops->get_output_muted(drv); else ainfo.output_muted = (unsigned char)(0); retval = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct audio_info)); if (retval < 0) break; copy_to_user((struct audio_info *)arg, &ainfo, sizeof(ainfo)); break; case AUDIO_SETINFO: { audio_info_t curinfo, newinfo; if (verify_area(VERIFY_READ, (audio_info_t *)arg, sizeof(audio_info_t))) { dprintk(("verify_area failed\n")); return -EINVAL; } copy_from_user(&ainfo, (audio_info_t *)arg, sizeof(audio_info_t)); /* Without these there's no point in trying */ if (!drv->ops->get_input_precision || !drv->ops->get_input_channels || !drv->ops->get_input_rate || !drv->ops->get_input_encoding || !drv->ops->get_output_precision || !drv->ops->get_output_channels || !drv->ops->get_output_rate || !drv->ops->get_output_encoding) { eprintk(("missing get routines: failed\n")); retval = -EINVAL; break; } /* Do bounds checking for things which always apply. * Follow with enforcement of basic tenets of certain * encodings. Everything over and above generic is * enforced by the driver, which can assume that * Martian cases are taken care of here. */ if (Modify(ainfo.play.gain) && ((ainfo.play.gain > AUDIO_MAX_GAIN) || (ainfo.play.gain < AUDIO_MIN_GAIN))) { /* Need to differentiate this from e.g. the above error */ eprintk(("play gain bounds: failed %d\n", ainfo.play.gain)); retval = -EINVAL; break; } if (Modify(ainfo.record.gain) && ((ainfo.record.gain > AUDIO_MAX_GAIN) || (ainfo.record.gain < AUDIO_MIN_GAIN))) { eprintk(("rec gain bounds: failed %d\n", ainfo.record.gain)); retval = -EINVAL; break; } if (Modify(ainfo.monitor_gain) && ((ainfo.monitor_gain > AUDIO_MAX_GAIN) || (ainfo.monitor_gain < AUDIO_MIN_GAIN))) { eprintk(("monitor gain bounds: failed\n")); retval = -EINVAL; break; } /* Don't need to check less than zero on these */ if (Modifyc(ainfo.play.balance) && (ainfo.play.balance > AUDIO_RIGHT_BALANCE)) { eprintk(("play balance bounds: %d failed\n", (int)ainfo.play.balance)); retval = -EINVAL; break; } if (Modifyc(ainfo.record.balance) && (ainfo.record.balance > AUDIO_RIGHT_BALANCE)) { eprintk(("rec balance bounds: failed\n")); retval = -EINVAL; break; } /* If any of these changed, record them all, then make * changes atomically. If something fails, back it all out. */ if (Modify(ainfo.record.precision) || Modify(ainfo.record.sample_rate) || Modify(ainfo.record.channels) || Modify(ainfo.record.encoding) || Modify(ainfo.play.precision) || Modify(ainfo.play.sample_rate) || Modify(ainfo.play.channels) || Modify(ainfo.play.encoding)) { /* If they're trying to change something we * have no routine for, they lose. */ if ((!drv->ops->set_input_encoding && Modify(ainfo.record.encoding)) || (!drv->ops->set_input_rate && Modify(ainfo.record.sample_rate)) || (!drv->ops->set_input_precision && Modify(ainfo.record.precision)) || (!drv->ops->set_input_channels && Modify(ainfo.record.channels))) { eprintk(("rec set no routines: failed\n")); retval = -EINVAL; break; } curinfo.record.encoding = drv->ops->get_input_encoding(drv); curinfo.record.sample_rate = drv->ops->get_input_rate(drv); curinfo.record.precision = drv->ops->get_input_precision(drv); curinfo.record.channels = drv->ops->get_input_channels(drv); newinfo.record.encoding = Modify(ainfo.record.encoding) ? ainfo.record.encoding : curinfo.record.encoding; newinfo.record.sample_rate = Modify(ainfo.record.sample_rate) ? ainfo.record.sample_rate : curinfo.record.sample_rate; newinfo.record.precision = Modify(ainfo.record.precision) ? ainfo.record.precision : curinfo.record.precision; newinfo.record.channels = Modify(ainfo.record.channels) ? ainfo.record.channels : curinfo.record.channels; switch (newinfo.record.encoding) { case AUDIO_ENCODING_ALAW: case AUDIO_ENCODING_ULAW: if (newinfo.record.precision != 8) { eprintk(("rec law precision bounds: " "failed\n")); retval = -EINVAL; break; } if (newinfo.record.channels != 1) { eprintk(("rec law channel bounds: " "failed\n")); retval = -EINVAL; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -