At Thu, 19 May 2011 08:45:43 +0200, Felix Homann wrote:
Am 19.05.2011 07:42, schrieb Takashi Iwai:
I see no big reason to make things more complex. If you want to avoid the standard audio parsing after quirk but only parse mixer, just call snd_usb_create_mixer() in your quirk function.
Maybe I'm misunderstanding your point. But I think your suggestion is making things more complex.
I don't want to avoid the standard audio parsing. I want to use standard quirks if possible and still would like a means to call snd_usb_create_mixer(). That's all.
First off, there is no "standard" quirk per definition :) There can be common quirks used by multiple devices, but this doesn't justify the fact that it's no standard USB-audio.
In principle, quirks are provided to be self-contained. If it's not compliant to standard usb-audio, handle everything there -- that's the whole policy. If we add yet another condition here and there in the main path for specific devices, it'll make readability worse.
(Or, think like OO implementation: if you want to implement a variant, you wouldn't put new conditional branch, but usually override the necessary parts.)
In this particular case, you can call snd_usb_create_mixer() then create your mixer elements in addition in your quirk function. This is more straightforward than adding branches in multiple points.
Of course, there can be some room for refactoring to share codes between different quirks. But it's a thing to be done in quirk codes.
The device in question can be handled by a standard quirks (QUIRK_ANY_INTERFACE, QUIRK_COMPOSITE, QUIRK_AUDIO_FIXED_ENDPOINT). There's no hook for calling snd_usb_create_mixer() by the respective quirk functions, is there? Should I really need not to use those standard quirks just to call snd_usb_create_mixer()?
Moreover, I can't believe that the Fast Track Ultra devices are the only ones in the world which have a standard USB mixer without exposing it through the descriptors. (I've often read something like "but the mixer won't work") A simple generic standard way to handle those devices would be nice to have.
Take a look at it from my perspective: I'm just a layman on all of this. I full heartedly confess, that I don't actually understand all those functions involved in making a mixer work. I don't understand usb control messages an so on. For example, take a look at the snd_nativeinstruments_control_put() function as Daniel suggested. There's a line
usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, cpu_to_le16(wValue), cpu_to_le16(wIndex), NULL, 0, 1000);
What is it? How is anyone not deeply involved with USB programming and/or audio device programming supposed to understand it? How is anybody supposed to help Alsa development to get his device working without deeply diving into all this stuff *which should not be needed*?
But being a layman I could still understand that the mixer unit in my device is there and that it is controlled by standard usb commands (control messages?). So what to do next?
For the capture, playback and MIDI side it's already simple: If you have a device that you suspect to be more or less standard compliant but just doesn't tell the world about it he can just try some combinations of QUIRK_AUDIO_FIXED_ENDPOINT, QUIRK_AUDIO_STANDARD_INTERFACE, QUIRK_MIDI_FIXED_ENDPOINT etc. (which by the way are still not easy to understand due to lack of documentation!).
For mixers, there isn't such a standard way. That's what I would like to have! And that's what I have at least sketched with my patch. (While the standard way to tell the driver to call snd_usb_create_mixer() is still missing.)
Take a look at my (maybe naive?) snd_ftu_controls_create() function. It's easy to understand, it's simple: I essentially just pass channel numbers, and names to build_named_mixer_unit_ctl() which is a slightly modified version of build_mixer_unit_ctl() and voila: I get a volume control for the respective mixer channel, just as if the control had been known from a descriptor. That's a lot easier to understand than fiddling around with usb_control_msg(), isn't it?
So, at the end as stated above, I would like to see a simple, easy to understand standard way to handle a mixer that essentially *is* a standard USB audio mixer but doesn't tell the world about it...And of course, it should work with my device ;-)
What I'm thinking is also to keep the thing simple. My points are: - Try to avoid conditional branches, don't touch the main path as much as possible - You can call the standard parsers in the quirk itself - You can create additional mixer contents in the quirk as well (so just use your simplified snd_ftu_controls_create()).
thanks,
Takashi