- /* Device parameters apparently depend on each other in undocumented
- ways (not to imply that there is any real documentation). Be
- careful when reordering the calls below. */
- if (sd->sample_size > 0
- && ioctl (sd->fd, SNDCTL_DSP_SAMPLESIZE, &sd->sample_size) < 0)
- sound_perror ("Setting sample size");
+ /* On GNU/Linux, it seems that the device driver doesn't like to be
+ interrupted by a signal. Block the ones we know to cause
+ troubles. */
+ turn_on_atimers (0);
+#ifdef SIGIO
+ sigblock (sigmask (SIGIO));
+#endif
+
+ val = sd->format;
+ if (ioctl (sd->fd, SNDCTL_DSP_SETFMT, &sd->format) < 0
+ || val != sd->format)
+ sound_perror ("Set sound format");
+
+ val = sd->channels != 1;
+ if (ioctl (sd->fd, SNDCTL_DSP_STEREO, &val) < 0
+ || val != (sd->channels != 1))
+ sound_perror ("Set stereo/mono");
+
+ /* I think bps and sampling_rate are the same, but who knows.
+ Check this. and use SND_DSP_SPEED for both. */
+ if (sd->sample_rate > 0)
+ {
+ val = sd->sample_rate;
+ if (ioctl (sd->fd, SNDCTL_DSP_SPEED, &sd->sample_rate) < 0
+ || val != sd->sample_rate)
+ sound_perror ("Set sound speed");
+ }
+
+ if (sd->volume > 0)
+ {
+ int volume = sd->volume & 0xff;
+ volume |= volume << 8;
+ /* This may fail if there is no mixer. Ignore the failure. */
+ ioctl (sd->fd, SOUND_MIXER_WRITE_PCM, &volume);
+ }