The branch main has been updated by emaste:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=61c831679615d2a03a494bd7f3627fb945f2795c

commit 61c831679615d2a03a494bd7f3627fb945f2795c
Author:     Florian Walpen <[email protected]>
AuthorDate: 2023-11-25 00:04:34 +0000
Commit:     Ed Maste <[email protected]>
CommitDate: 2024-01-16 21:05:44 +0000

    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
---
 sys/dev/sound/pcm/dsp.c | 27 +++++++++++++++++----------
 1 file 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) {

Reply via email to