[PATCH] ALSA: usb-audio: Filter out unsupported sample rates on Focusrite devices
Many Focusrite devices supports a limited set of sample rates per altsetting. This includes interfaces with ADAT ports and interfaces with dedicated feedback channels: - Scarlett 18i6, 18i8 1st gen, 18i20 1st gen; - Scarlett 18i8 2nd gen, 18i20 2nd gen; - all Scarlett 3rd gen devices (feedback channels works only up to 96 kHz); - Clarett 2Pre USB, 4Pre USB, 8Pre USB.
Tested-by: Alexey Skobkin skobkin-ru@ya.ru Signed-off-by: Alexander Tsoy alexander@tsoy.me --- sound/usb/format.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)
diff --git a/sound/usb/format.c b/sound/usb/format.c index 50e1874c847c..5ffb457cc88c 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -277,6 +277,52 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp, return false; }
+/* + * Many Focusrite devices supports a limited set of sampling rates per + * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type + * descriptor which has a non-standard bLength = 10. + */ +static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, + struct audioformat *fp, + unsigned int rate) +{ + struct usb_interface *iface; + struct usb_host_interface *alts; + unsigned char *fmt; + unsigned int max_rate; + + iface = usb_ifnum_to_if(chip->dev, fp->iface); + if (!iface) + return true; + + alts = &iface->altsetting[fp->altset_idx]; + fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, + NULL, UAC_FORMAT_TYPE); + if (!fmt) + return true; + + if (fmt[0] == 10) { /* bLength */ + max_rate = combine_quad(&fmt[6]); + + /* Validate max rate */ + if (max_rate != 48000 && + max_rate != 96000 && + max_rate != 192000 && + max_rate != 384000) { + + usb_audio_info(chip, + "%u:%d : unexpected max rate: %u\n", + fp->iface, fp->altsetting, max_rate); + + return true; + } + + return rate <= max_rate; + } + + return true; +} + /* * Helper function to walk the array of sample rate triplets reported by * the device. The problem is that we need to parse whole array first to @@ -319,6 +365,11 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip, !s1810c_valid_sample_rate(fp, rate)) goto skip_rate;
+ /* Filter out invalid rates on Focusrite devices */ + if (USB_ID_VENDOR(chip->usb_id) == 0x1235 && + !focusrite_valid_sample_rate(chip, fp, rate)) + goto skip_rate; + if (fp->rate_table) fp->rate_table[nr_rates] = rate; if (!fp->rate_min || rate < fp->rate_min)
В Сб, 18/04/2020 в 20:19 +0300, Alexander Tsoy пишет:
Many Focusrite devices supports a limited set of sample rates per altsetting. This includes interfaces with ADAT ports and interfaces with dedicated feedback channels:
- Scarlett 18i6, 18i8 1st gen, 18i20 1st gen;
- Scarlett 18i8 2nd gen, 18i20 2nd gen;
- all Scarlett 3rd gen devices (feedback channels works only up to
96 kHz);
I might be wrong here. It seems that 3rd gen Scarletts other than 18i8 and 18i20 doesn't expose any additional altsettings to limit number of channels. I'll resend this patch with updated description.
participants (1)
-
Alexander Tsoy