| Summary: | ioctl(SNDCTL_DSP_SPEED) returns -1 when fall back to orignal sample rate | ||
|---|---|---|---|
| Product: | Base System | Reporter: | huangant <huangant> |
| Component: | kern | Assignee: | sound |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | CC: | huangant |
| Priority: | Normal | ||
| Version: | 4.3-BETA2 | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-bugs->sound Sound-related PR. State Changed From-To: open->closed Applied, albeit very late after submission! With the feeder code these days do automatic rate and format conversion, this isn't a particular problem now. Thanks. |
When I am trying to set output sample rate that my sound card not support (my sound card is fixed at 48khz), the ioctl(SNDCTL_DSP_SPEED) return -1 and the value passed into ioctl() keep unchanged. According to OSS programming guide, the ioctl() should ONLY return -1 when critical/serious fault happens. When fails on setting sample rates, it should return 0 (no error) and change the value passed into ioctl() to the sample rate previous used. This problem will happen on some fixed sample rate sound chips, for example, VIA 82C686 AC'97 Codec, and cause some media player (such as 'xmms') caused an incorrect sound output. This problem exists in 4.3-BETA2, RC, and 20010412-CURRENT. Fix: Here is a very sample patch to solve this problem. The patch is just return correct value when sample rate falling back to previous rate caused by setting unsupported sample rate. PS. This patch is generate based on 4.3-BETA2, but it has been tested on 4.3-RC(OK) and 20010412-CURRENT(with some offset). === cut here === After applying this patch, result of above test code shows: trying setting 44100hz...[48000] on my VIA 82C686 AC'97 Codec.:)--CCUFcW6DTA6DchyE0AGr0mELoFPxf7yJHc2Iy6XrDJerZjgl Content-Type: text/plain; name="file.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="file.diff" --- sys/dev/sound/pcm/channel.c.old Fri Apr 13 11:55:53 2001 +++ sys/dev/sound/pcm/channel.c Fri Apr 13 11:56:14 2001 @@ -1178,7 +1178,7 @@ r = chn_tryspeed(c, speed); if (r) { DEB(printf("Failed to set speed %d falling back to %d\n", speed, oldspeed)); - chn_tryspeed(c, oldspeed); + r = chn_tryspeed(c, oldspeed); } return r; } === cut here === How-To-Repeat: Run following piece of the code: === cut here === #include <stdio.h> #include <fcntl.h> #include <sys/soundcard.h> int main() { int fd, freq; if((fd = open("/dev/dsp", O_WRONLY))==-1) { printf("open %s failed.\n", "/dev/dsp"); return(-1); } freq = 44100; printf("trying setting 44100hz..."); if(ioctl(fd, SNDCTL_DSP_SPEED, &freq)==-1) freq = -1; printf("[%d]\n", freq); close(fd); return(0); } === cut here === When setting 44.1khz as sample rate, ioctl() will return -1 and keep freq==44100 on my VIA82C686 AC'97 Codec. Before applying any patches, result of this code shows: trying setting 44100hz...[-1]