aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/sound/pcm/dsp.c
diff options
context:
space:
mode:
authorFlorian Walpen <dev@submerge.ch>2023-11-25 00:04:34 +0000
committerEd Maste <emaste@FreeBSD.org>2024-01-16 21:05:44 +0000
commit61c831679615d2a03a494bd7f3627fb945f2795c (patch)
treef666225a87fed480ff69056192652c79d16f2a3f /sys/dev/sound/pcm/dsp.c
parent80044c785cb040a2cf73779d23f9e1e81a00c6c3 (diff)
downloadsrc-61c831679615d2a03a494bd7f3627fb945f2795c.tar.gz
src-61c831679615d2a03a494bd7f3627fb945f2795c.zip
sound: Fix OSS API requests for more than 8 channels
Audio devices with more than 8 channels need bitperfect mode to operate, the vchan processing chain is limited to 8 channels. For these devices, let applications properly select a certain number of channels supported by the driver, instead of mapping the request to a vchan format. Reviewed by: emaste Pull Request: https://github.com/freebsd/freebsd-src/pull/914
Diffstat (limited to 'sys/dev/sound/pcm/dsp.c')
-rw-r--r--sys/dev/sound/pcm/dsp.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index 5aa7979b98c9..9040c77893d4 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -1502,24 +1502,31 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
case SOUND_PCM_WRITE_CHANNELS:
/* case SNDCTL_DSP_CHANNELS: ( == SOUND_PCM_WRITE_CHANNELS) */
- if (*arg_i < 0) {
+ if (*arg_i < 0 || *arg_i > AFMT_CHANNEL_MAX) {
*arg_i = 0;
ret = EINVAL;
break;
}
if (*arg_i != 0) {
- struct pcmchan_matrix *m;
- uint32_t ext;
+ uint32_t ext = 0;
tmp = 0;
- if (*arg_i > SND_CHN_MAX)
- *arg_i = SND_CHN_MAX;
+ /*
+ * Map channel number to surround sound formats.
+ * Devices that need bitperfect mode to operate
+ * (e.g. more than SND_CHN_MAX channels) are not
+ * subject to any mapping.
+ */
+ if (!(dsp_get_flags(i_dev) & SD_F_BITPERFECT)) {
+ struct pcmchan_matrix *m;
- m = feeder_matrix_default_channel_map(*arg_i);
- if (m != NULL)
- ext = m->ext;
- else
- ext = 0;
+ if (*arg_i > SND_CHN_MAX)
+ *arg_i = SND_CHN_MAX;
+
+ m = feeder_matrix_default_channel_map(*arg_i);
+ if (m != NULL)
+ ext = m->ext;
+ }
PCM_ACQUIRE_QUICK(d);
if (wrch) {