On Sat, 2014-02-15 at 10:08 +0100, David Henningsson wrote: > On 02/14/2014 01:51 PM, Tanu Kaskinen wrote: > > On Fri, 2014-02-14 at 11:55 +0100, David Henningsson wrote: > >> I don't understand this argument. A mute control *is* a volume control > >> (with two distinct values). > > > > That doesn't change the fact that the volume and mute controls should be > > separate: I don't want to bundle two volume controls together either. > > > > However, I'd be ok with adding a possibly-NULL reference from a volume > > control object to a mute control object and vice versa. There are other > > ways to correlate a volume control with a mute control, but direct > > reference would definitely make it easier. > > Mute controls and volume controls should be the same type of objects. > They will share a lot of logic internally and it would lead to a lot of > copy-pasting if they were two different kind of objects. > > I'd prefer if they also were the same object, because I think that would > make it simpler for volume control UIs instead of having to follow links > between objects. Let's discuss first whether volume and mute should be bundled in the same object. Bundling them together limits the flexibility: you can't cleanly represent entities (e.g. devices) that have only volume or mute control, and you can't represent a situation where a stream's volume and mute follow different grouping rules. For example, it doesn't sound insane to me that someone would want to enable volume grouping and restoring in module-stream-restore, but disable grouping and restoring the stream mute status. By the way, I take back the suggestion of adding a pointer from a volume control to a mute control and vice versa. Routing is another kind of control that UIs may want to show grouped with the volume and mute, and I don't want to add mutual pointers between each of volume, mute and routing controls. There could be even more "groupable" control types in the future (I'm thinking of any kind of processing, like equalizer), and this approach of adding mutual references between every control type makes the number of references grow exponentially. UIs can easily do the grouping without these extra references, because the UI probably anyway gets first a list of e.g. streams and then shows the controls for those streams. The stream object will have references to the volume control and the mute control (and maybe in the future, references also to the routing node, equalizer control etc.). > >> The concept "volume class" does not exist in module-stream-restore, at > >> least not with that name. > >> > >> Could you give a clear definition of what "volume classes" are? If it's > >> just a way of grouping volume control objects, then volume control > >> objects could just have some property of what class they belong to. > > > > An attempt at a definition: a volume class is a named set of rules for > > grouping volumes. > > > > "A way of grouping volume control objects" is not an entirely accurate > > description. You probably were thinking of a setup where each stream has > > a volume control object, and those are somehow grouped by a volume > > class. In my proposal streams whose volume is governed by the volume > > class do not have their own volume control objects. Instead, the streams > > reference the volume control object of the volume class. > > > > This is not a very important distinction, however, because your > > suggestion of using a property works either way. You could set a > > "volume_class = event" property on a volume control to tell clients that > > this volume control object controls the volume of event sounds. > > I'm still confused. > > * Is there a 1:1 relation between volume control objects and volume > classes? If so we don't need an additional object, they can just be the > same object. No, there are volume control objects that aren't part of any class. Device volumes very rarely are part of any volume class. > * Or can several volume control objects belong to the same class? If so > "the volume control object of the volume class" does not make sense > because there can be many. Not simultaneously. Think about this: you write a UI for controlling the event sound volume class. If there are two volume control objects for the same class, I suppose you could show two volume sliders for the user, but the user is going to be very confused. The volume control object that is associated with a volume class can change during runtime, however. On the N9, there were two volume classes (a bit simplified): "call" and "everything else". When audio was routed to the integrated speakers, the "call" volume class was associated with the "speakers/call" volume control, and when audio was routed to headphones, the "call" volume class was associated with the "headphones/call" volume control. That is, there were volume controls for each pair of routing and volume class. If you generalize the N9 volume model for any random hardware, it could also happen on a machine that doesn't have any integrated audio output devices that there are volume classes for "call" and "everything else", but those volume classes are not associated with any volume control, because there are no output devices. Only once you plug in e.g. a USB sound card, the volume classes will get associated with volume controls. > * Or can a volume control object belong to several classes? If so the > property on a volume control does not work (unless you do something like > "volume_classes = foo,bar"). I can imagine that someone would define hierarchical volume classes: if we standardize some volume class semantics based on e.g. the media role, a system could expose these per-role volume classes for applications that want to show per-role volumes, but the system could also expose more coarse-grained non-standard volume classes (like "call" and "everything else"). In this case the volume class for the "phone" media role would point to the same volume control object as the "call" volume class, and all other media role volume classes would point to the volume control object of the "everything else" volume class. After all this talk about volume classes, I've come to the conclusion that I don't actually want a concept called "volume class". I want a bit more general concept: "audio group". An audio group like a volume class, but instead of only being associated with a volume control, the audio group is also associated with mute and routing controls (by routing control, I mean a routing node). This idea arose from the fact that I didn't want to add mutual references between all the different control types, but it should still be easy for UIs to show the volume, mute and routing grouped together for abstract things like "music", "event sounds", etc. It would still be possible to have audio groups that are equivalent to volume classes, if you want different grouping for volume than for mute and routing: just set the mute and routing controls of the audio group to null. This also avoids the need to worry about adding mute classes and routing classes in the future, since they're all covered by the same concept. struct pa_audio_group_info { uint32_t index; char *name; char *description; uint32_t volume_control; uint32_t mute_control; uint32_t routing_node; }; > About taking things in iterations, would it work for you to get started > on the volume control objects and skip the volume classes for the time > being? And postpone that to a later iteration. Yes, I can and I will start the implementation from the volume control objects, but let's not stop the discussion about volume classes / audio groups, because I will need to implement a client API for working with volume classes anyway. The sooner I know how to do it, the better. -- Tanu