[alsa-devel] UCM representation questions
Liam,
I have a few more questions how to represent things in UCM.
The Tegra boards I'm dealing with are set up like this:
hw:0,0 >--wm8903--> headphones ---> speakers hw:0,1 >----------> hdmi
The WM8903 allows the audio stream to be routed to neither, one, or both of headphones and speakers.
hw:0,0 <--wm8903--< Analog Mic (AMIC) ----< Digital Mic (DMIC)
The WM8903 can capture from one or the other or AMIC/DMIC, but not both.
1)
How to indicate when certain devices can be used together, or are mutually exclusive?
Note that Headphone/Speakers/HDMI can be used in any combination, but AMIC/DMIC are mutually exclusive.
use_case.h indicates that neither Devices nor Modifiers are mutually exclusive, so neither alone can be used to represent this.
I suppose you could just create a separate use-case for each legal set of combinations. Taking a capture-only case, we'd end up with separate "Capture AMIC" and "Capture DMIC" cases. However, a "HiFi" or "Music" case could simply list all 3 devices in a single case since they all can operate at once.
2)
Let's then consider a "VoIP" use-case that wants to both play and capture audio. If we represent the exclusivity in the same way, we'd end up with 2 more cases "VoIP AMIC" and "VoIP DMIC", each listing 3 devices for playback, and 1 device for capture.
It seems like switching between these two cases while a call was active would be problematic. In particular, in my current UCM files, there is e.g.:
SectionDevice."Speakers".0 { Comment "Internal Speakers"
EnableSequence [ cdev "hw:0" cset "name='Speaker Switch' on,on" cset "name='Int Spk Switch' on" ]
DisableSequence [ cdev "hw:0" cset "name='Speaker Switch' off,off" cset "name='Int Spk Switch' off" ] ...
Wouldn't the DisableSequence get run for this device when leaving the "VoIP AMIC" case, and the EnableSequence get run when entering the "VoIP DMIC" case; that would cause a glitch in the receive side of the call even though we were just switching the transmission side between mics.
Perhaps the UCM library is intelligent enough to realize that the same device is active in both the old and new case, and then doesn't execute the Enable/DisableSequence in that case. But, that seems dangerous; the sequences might have required effects in some case.
I can't omit the DisableSequence to make this work, or disabling the Speakers device (e.g. to switch to just headphones) wouldn't actually disable anything. I suppose I could put the Speaker disable logic in the Headphone EnableSequence, but then I wouldn't be able to use both together. Perhaps the answer is a "virtual" Device "Speakers and Headphones" which enables both. I couldn't correctly represent the device-specific volume controls or PCMs then. Plus, this approach would quickly lead to an explosion of Devices; 8 SectionDevices in my the case of my 3 physical IOs.
3)
It seems like there's a lot of potential for duplication in the UCM file content. If I have "VoIP Low Quality", "VoIP High Quality", and "Hifi" cases, the latter with a modifier to allow capture of voice e.g. for voice commands, and each somehow supporting capture from either AMIC or DMIC (ignoring how to represent mutual exclusivity) then the UCM file for each case has to include the cset actions to switch between AMIC and DMIC:
SectionDevice."Capture AMIC".0 { Comment "Analog Microphone Jack"
EnableSequence [ cdev "hw:0" cset "name='ADC Input' 'ADC'" cset "name='Left Capture Mux' 'Right'" cset "name='Right Capture Mux' 'Right'" ] ...
SectionDevice."Capture DMIC".0 { Comment "Internal Digital Microphone"
EnableSequence [ cdev "hw:0" cset "name='ADC Input' 'DMIC'" cset "name='Left Capture Mux' 'Left'" cset "name='Right Capture Mux' 'Right'" ] ...
Is there any way to avoid this cut/paste?
I initially expected the UCM file format defining Devices outside of Verbs, and Verbs to list which devices were associated with the verb by reference rather than inclusion, and perhaps also configuring some additional properties of those devices, but not duplicating the raw "how to route this device to the PCM" instructions.
4)
Is listing multiple CaptureVolumes in a single Device's Value section legal. For example, for a stereo analog mic:
SectionModifier."Capture AMIC".0 { Comment "Analog Microphone Jack"
Value { CaptureVolume "Left Input PGA Volume" CaptureVolume "Right Input PGA Volume" } }
... since the WM8903 exposes separate controls for the L/R channels, and I'd expect applications would want to expose a single control to users, and set them both to the same value all the time.
Thanks again for any answers.
On 20/05/11 22:48, Stephen Warren wrote:
Liam,
I have a few more questions how to represent things in UCM.
The Tegra boards I'm dealing with are set up like this:
hw:0,0 >--wm8903--> headphones ---> speakers hw:0,1 >----------> hdmi
The WM8903 allows the audio stream to be routed to neither, one, or both of headphones and speakers.
hw:0,0 <--wm8903--< Analog Mic (AMIC) ----< Digital Mic (DMIC)
The WM8903 can capture from one or the other or AMIC/DMIC, but not both.
How to indicate when certain devices can be used together, or are mutually exclusive?
Atm, I don't think we can do this with devices. We can do it with modifiers though (i.e. a modifier can list it's supported devices). It does sound like a useful feature and probably could be based on the modifier supported device code.
Note that Headphone/Speakers/HDMI can be used in any combination, but AMIC/DMIC are mutually exclusive.
use_case.h indicates that neither Devices nor Modifiers are mutually exclusive, so neither alone can be used to represent this.
I suppose you could just create a separate use-case for each legal set of combinations. Taking a capture-only case, we'd end up with separate "Capture AMIC" and "Capture DMIC" cases. However, a "HiFi" or "Music" case could simply list all 3 devices in a single case since they all can operate at once.
You could, but it may be nicer to eventually add the ability to UCM so we can represent this relationship.
Let's then consider a "VoIP" use-case that wants to both play and capture audio. If we represent the exclusivity in the same way, we'd end up with 2 more cases "VoIP AMIC" and "VoIP DMIC", each listing 3 devices for playback, and 1 device for capture.
The intention for UCM here is to have a single use case verb for your VOIP use case with UCM AMIC, DMIC, Headphone and Speaker UCM devices. So your VOIP app would know about the available devices, but not that the AMIC and DMIC were mutually exclusive without the UCM "supported device" feature discussed above.
It seems like switching between these two cases while a call was active would be problematic. In particular, in my current UCM files, there is e.g.:
SectionDevice."Speakers".0 { Comment "Internal Speakers"
EnableSequence [ cdev "hw:0" cset "name='Speaker Switch' on,on" cset "name='Int Spk Switch' on" ] DisableSequence [ cdev "hw:0" cset "name='Speaker Switch' off,off" cset "name='Int Spk Switch' off" ]
...
Wouldn't the DisableSequence get run for this device when leaving the "VoIP AMIC" case, and the EnableSequence get run when entering the "VoIP DMIC" case; that would cause a glitch in the receive side of the call even though we were just switching the transmission side between mics.
I don't see why the speaker disable sequence would be run when switching between AMIC/DMIC. If it is, then it sounds like a bug.
Perhaps the UCM library is intelligent enough to realize that the same device is active in both the old and new case, and then doesn't execute the Enable/DisableSequence in that case. But, that seems dangerous; the sequences might have required effects in some case.
There is limited intelligence in UCM core, it merely executes the application requests (if the current UCM data permits it to).
I can't omit the DisableSequence to make this work, or disabling the Speakers device (e.g. to switch to just headphones) wouldn't actually disable anything. I suppose I could put the Speaker disable logic in the Headphone EnableSequence, but then I wouldn't be able to use both together. Perhaps the answer is a "virtual" Device "Speakers and Headphones" which enables both. I couldn't correctly represent the device-specific volume controls or PCMs then. Plus, this approach would quickly lead to an explosion of Devices; 8 SectionDevices in my the case of my 3 physical IOs.
It seems like there's a lot of potential for duplication in the UCM file content. If I have "VoIP Low Quality", "VoIP High Quality", and "Hifi" cases, the latter with a modifier to allow capture of voice e.g. for voice commands, and each somehow supporting capture from either AMIC or DMIC (ignoring how to represent mutual exclusivity) then the UCM file for each case has to include the cset actions to switch between AMIC and DMIC:
SectionDevice."Capture AMIC".0 { Comment "Analog Microphone Jack"
EnableSequence [ cdev "hw:0" cset "name='ADC Input' 'ADC'" cset "name='Left Capture Mux' 'Right'" cset "name='Right Capture Mux' 'Right'" ]
...
SectionDevice."Capture DMIC".0 { Comment "Internal Digital Microphone"
EnableSequence [ cdev "hw:0" cset "name='ADC Input' 'DMIC'" cset "name='Left Capture Mux' 'Left'" cset "name='Right Capture Mux' 'Right'" ]
...
Is there any way to avoid this cut/paste?
Not atm, the UCM parser is quite simple and doesn't yet understand the concept of #include ;)
I initially expected the UCM file format defining Devices outside of Verbs, and Verbs to list which devices were associated with the verb by reference rather than inclusion, and perhaps also configuring some additional properties of those devices, but not duplicating the raw "how to route this device to the PCM" instructions.
This was one of my original assumptions too, but it turned out that some audio devices have several different routes to each device (and this route could depend on use case), hence this had to be simply represented in the file format.
Is listing multiple CaptureVolumes in a single Device's Value section legal. For example, for a stereo analog mic:
SectionModifier."Capture AMIC".0 { Comment "Analog Microphone Jack"
Value { CaptureVolume "Left Input PGA Volume" CaptureVolume "Right Input PGA Volume" } }
Oh, not atm. We should be able to express thing like Left and Right wrt to Volume and Mark did mention the need for improvement in the Volume aliasing at the conference. I do have a note against my name to look at it, but I cant give any time scales atm.
... since the WM8903 exposes separate controls for the L/R channels, and I'd expect applications would want to expose a single control to users, and set them both to the same value all the time.
Thanks again for any answers.
Regards
Liam
Liam Girdwood wrote at Saturday, May 21, 2011 10:20 AM:
On 20/05/11 22:48, Stephen Warren wrote:
I have a few more questions how to represent things in UCM. ... The WM8903 can capture from one or the other or AMIC/DMIC, but not both. ... How to indicate when certain devices can be used together, or are mutually exclusive?
Atm, I don't think we can do this with devices. We can do it with modifiers though (i.e. a modifier can list it's supported devices). It does sound like a useful feature and probably could be based on the modifier supported device code.
OK, it looks pretty easy to modify the code to parse and implement something like:
SectionDevice."AMIC".0 { Comment "Analog Microphone Jack"
ConflictingDevice [ "DMIC", "foo" ] ... }
SectionDevice."DMIC".0 { Comment "Internal Digital Microphone"
ConflictingDevice [ "AMIC" ] ... }
Does that look reasonable?
However, the application is going to want to query these conflict lists, and probably a modifier's SupportedDevice list too.
Should snd_use_case_get be modified to accept a query on e.g.:
_SupportedDevice/${modifier} _ConflictingDevice/${device}
Both returning say a comma separate list of strings i.e. "DMIC,foo". I guess the "get" code could reserve any string starting with "_" for this kind of "system" value looking instead of user-defined Value[] lookup.
How does that sound?
If that's good, I'll try to make time to implement this.
On 25/05/11 23:38, Stephen Warren wrote:
Liam Girdwood wrote at Saturday, May 21, 2011 10:20 AM:
On 20/05/11 22:48, Stephen Warren wrote:
I have a few more questions how to represent things in UCM. ... The WM8903 can capture from one or the other or AMIC/DMIC, but not both. ... How to indicate when certain devices can be used together, or are mutually exclusive?
Atm, I don't think we can do this with devices. We can do it with modifiers though (i.e. a modifier can list it's supported devices). It does sound like a useful feature and probably could be based on the modifier supported device code.
OK, it looks pretty easy to modify the code to parse and implement something like:
SectionDevice."AMIC".0 { Comment "Analog Microphone Jack"
ConflictingDevice [ "DMIC", "foo" ]
... }
SectionDevice."DMIC".0 { Comment "Internal Digital Microphone"
ConflictingDevice [ "AMIC" ]
... }
Does that look reasonable?
Yes, although does it make more sense using "SupportedDevice" instead ?
However, the application is going to want to query these conflict lists, and probably a modifier's SupportedDevice list too.
Should snd_use_case_get be modified to accept a query on e.g.:
_SupportedDevice/${modifier} _ConflictingDevice/${device}
Both returning say a comma separate list of strings i.e. "DMIC,foo". I guess the "get" code could reserve any string starting with "_" for this kind of "system" value looking instead of user-defined Value[] lookup.
How does that sound?
Yeah, this sounds like it would be useful and let the apps know the correct device dependencies.
If that's good, I'll try to make time to implement this.
Ok, sounds good.
Liam
Liam Girdwood wrote at Thursday, May 26, 2011 5:02 AM:
On 25/05/11 23:38, Stephen Warren wrote:
Liam Girdwood wrote at Saturday, May 21, 2011 10:20 AM:
On 20/05/11 22:48, Stephen Warren wrote:
I have a few more questions how to represent things in UCM. ... The WM8903 can capture from one or the other or AMIC/DMIC, but not both. ... How to indicate when certain devices can be used together, or are mutually exclusive?
Atm, I don't think we can do this with devices. We can do it with modifiers though (i.e. a modifier can list it's supported devices). It does sound like a useful feature and probably could be based on the modifier supported device code.
OK, it looks pretty easy to modify the code to parse and implement something like:
SectionDevice."AMIC".0 { Comment "Analog Microphone Jack"
ConflictingDevice [ "DMIC", "foo" ]
... }
SectionDevice."DMIC".0 { Comment "Internal Digital Microphone"
ConflictingDevice [ "AMIC" ]
... }
Does that look reasonable?
Yes, although does it make more sense using "SupportedDevice" instead ?
I assume a SupportedDevice list would be all devices in the current verb that are compatible with the SectionDevice being defined, i.e. you're talking about different semantics, rather than just a different textual name for the section.
My thought process here was that conflicting devices are probably less common than non-conflicting devices. At least, it seems like that'd be the default assumption of someone writing a UCM file. So, if we list ConflictingDevice(s), then that would often map to an empty list, and you could eliminate the section. If we had to list all compatible devices, by default you'd have to list every device in the UCM verb in almost all cases. That seems like more work.
Plus, adding an optional ConflictingDevice list maintains backwards Compatibility with any existing UCM files, whereas adding a mandatory SupportedDevice list doesn't.
Still, explicitly listing SupportedDevice(s) might be safer?
I wonder if allowing all lists of devices to be either inclusive SupportedDevice or exclusive ConflictingDevice makes sense, with the default being ConflictingDevice being empty, and SupportedDevice being the entire set of devices? Seems more complex, but probably still workable.
I'll go with whatever call you want to make.
On Thu, May 26, 2011 at 10:13:21AM -0700, Stephen Warren wrote:
My thought process here was that conflicting devices are probably less common than non-conflicting devices. At least, it seems like that'd be the default assumption of someone writing a UCM file. So, if we list ConflictingDevice(s), then that would often map to an empty list, and you could eliminate the section. If we had to list all compatible devices, by default you'd have to list every device in the UCM verb in almost all cases. That seems like more work.
Plus, adding an optional ConflictingDevice list maintains backwards Compatibility with any existing UCM files, whereas adding a mandatory SupportedDevice list doesn't.
I tend to agree with this - the usual case is that you can have as many devices as you like running, the reason for restricting things is more normally usefulness rather than physical possibility.
I wonder if allowing all lists of devices to be either inclusive SupportedDevice or exclusive ConflictingDevice makes sense, with the default being ConflictingDevice being empty, and SupportedDevice being the entire set of devices? Seems more complex, but probably still workable.
That makes sense too - if either directive is used we require an explicit list, otherwise we assume everything is compatible.
On 27/05/11 02:31, Mark Brown wrote:
On Thu, May 26, 2011 at 10:13:21AM -0700, Stephen Warren wrote:
My thought process here was that conflicting devices are probably less common than non-conflicting devices. At least, it seems like that'd be the default assumption of someone writing a UCM file. So, if we list ConflictingDevice(s), then that would often map to an empty list, and you could eliminate the section. If we had to list all compatible devices, by default you'd have to list every device in the UCM verb in almost all cases. That seems like more work.
Plus, adding an optional ConflictingDevice list maintains backwards Compatibility with any existing UCM files, whereas adding a mandatory SupportedDevice list doesn't.
I tend to agree with this - the usual case is that you can have as many devices as you like running, the reason for restricting things is more normally usefulness rather than physical possibility.
I wonder if allowing all lists of devices to be either inclusive SupportedDevice or exclusive ConflictingDevice makes sense, with the default being ConflictingDevice being empty, and SupportedDevice being the entire set of devices? Seems more complex, but probably still workable.
That makes sense too - if either directive is used we require an explicit list, otherwise we assume everything is compatible.
Ok, sounds fine to me too. I just wanted to make sure we had explored both options here.
Thanks
Liam
participants (3)
-
Liam Girdwood
-
Mark Brown
-
Stephen Warren