factory: Use HiFi ucm to replace audio.conf |
||||||
Issue descriptionCurrently the factory audio tests rely on a YAML or JSON "audio.conf" to initialize audio interfaces (dmic, spk, headphone, ...). This is because the audio bring up process is: - Factory needs audio for initial build - Audio vendor provides audio.conf - Later on, release images need config for cras in later builds like EVT/DVT/PVT. - Audio vendor provides HiFi ucm files. audio.conf and HiFi ucm are very similar, so it's probably a duplicated effort for vendor to provide audio.conf. It's also confusing to explain how the audio.conf should look like to new vendors. And it also makes factory toolkit need to have explicit correct audio.conf files before it can test audio on a device. As a result, we think it may be better to directly support UCM file in factory audio component and deprecate audio.conf, so we can always request for UCM to use. And when a toolkit runs on a device without audio.conf, it can try to look for system hifi ucm to init audio interfaces. P.S: We may also need additional logic to "guess" card name just like Chrome does, for example trying "Internal Speaker" first than other names.
,
Mar 23 2017
p.s: you can use alsaucm to apply the ucm config, but we should not add extra dependency to cras. Just the config files so it's easier for cherry-picking into factory branches.
,
May 18 2017
Reassign to petershih since yhong may be busy at HWID.
,
Jul 14 2017
,
Aug 16 2017
According to the above comments, I'd like to set the goal to: * Factory toolkit uses alsa ucm config directly, so vendor no longer needs to provide audio.conf. If it is allowed to use the 'alsaucm' binary, the steps might be something like: 1. Use 'alsaucm' to enable the device # alsaucm -n -b - <<EOM > open kblrt5514rt5663max > set _verb HiFi > set _enadev Speaker > EOM 2. Play the wav file: # aplay -t wav foo.wav 3. Disable the speaker (should we do this? any other cleanup command?) # alsaucm -n -b - <<EOM > open kblrt5514rt5663max > set _verb HiFi > set _disdev Speaker > EOM Is this process sounds okay? And, some more questions: Question 1: There might be multiple sound card names under /usr/share/alsa/ucm, which should be used? Further, multiple verbs (e.g., 'Record', 'Hifi', 'Voice', 'Voice_Call' in SDP4430.conf) and multiple devices (e.g., 'Speaker', 'Headphone', 'Internal mic', 'Mic', 'HDMI1', etc.) might be defined , which should be used? I think this differs on different boards, and depend on which device we're controlling (e.g., speaker, left headphone, right headphone, left mic, right mic, etc.). (If the answer is yes, we still need a config file to specify the 'card-name', 'verb' and 'device_name', which is similar to the current audio.conf) Question 2: Can we depend on the binary 'alsaucm' (like stated above) for bring up? Question 3: Is it possible that a vendor can only provide audio.conf, but cannot provide ucm configs? If no, should we deprecate audio.conf?
,
Aug 16 2017
Q1 => ask audio team how do they select for chrome? Correct me if I'm wrong, but I think today in audio.conf we simply create a list of verb & devies, while the real thing to test or use verb is given from test list arguments. So it should make no difference when you move to ucm? Q2 => I'm ok with using alsaucm if it's available on chromebook test images. But can it take files not in /usr/share/alsa/ucm? We may need to override files for manufacturing process. Q3 => I think all vendors will need to provide ucm in the end for release images, so we may be able to deprecate in future.
,
Aug 17 2017
So maybe two more questions: Question 4: Will the binary 'alsaucm' be ready when bring up a board? Question 5: Can the binary 'alsaucm' reads configures outside of /usr/share/alsa/ucm. Q5 => I guess the answer is no. In this case, maybe we can use bind mount, just as what we do for /etc/chrome_dev.conf?
,
Aug 17 2017
Some conclusions of an offline discussions with hychao@. Facts about UCM files: 1. UCM is a format defined by ALSA. All audio devices used in Chrome OS are ALSA devices. 2. Chrome OS adds some customized fields in UCM format (e.g., the 'default-gain' field mentioned in the meeting) 3. The binary 'alsaucm' can be used to control the devices regarding to UCM files. But according to audio team's experience, this binary might not be stable/reliable enough. (Further, it does not parse the customized fields mentioned in the previous point) Facts about cras: 1. It's a service maintained by the audio team, so it's well supported. 2. It's included in the test image, and is stable/reliable enough to use in factory bring up process (even when the audio driver is still under development). 3. It provides dbus interface to list audio devices. Suggestions from audio team: * Use 'cras' service to control audio devices. So factory team don't bother to parse UCM files, and list/map/control all audio devices. Detail steps might be something like: 1. Use dbus interface to list all audio devices. 2. Use 'cras_test_client --select_output' to choose the output device 3. Use 'cras_test_client --playback_file' to play a raw audio file. From factory's point of view, several tasks need to be done: 1. Mute a specific device (e.g., left speaker, right speaker, head phone, mic, ext mic, etc.) 2. Enable/Disable a specific device 3. Set speaker volume (possibly to a 'raw' value) 4. Playback a raw/wav file 5. (maybe more...)
,
Aug 18 2017
Different methods to get it done:
1. Parse UCM files manually
* Can refer to alsa-lib source code
* 'cras' use alsa-lib, so they didn't do the parse themselves
Pros:
* Only depends on aplay, amixer, arecord
Cons:
* Need to write parse code manually.
* Need to rewrite if UCM file format is changed (not likely to happen).
* Need to know the device name (e.g., 'kblrt5514rt5663max'), so we can locate the UCM conf (e.g., /usr/share/alsa/ucm/kblrt5514rt5663max/HiFi.conf'). Maybe 'aplay -L' helps
* See 'get_sysdefault_playback_device' in https://chromium.googlesource.com/chromiumos/third_party/autotest/+/master/client/cros/audio/alsa_utils.py
* Or a darg parameter for the pytest
* How to map the 'SectionDevice' in a UCM config file?
* SectionDevice."Speaker".0
* SectionDevice."Headphone".0
* etc.
2. Use alsa-lib to parse/apply UCM files
* cras uses this way by calling snd_use_case_* interfaces
See https://chromium.googlesource.com/chromiumos/third_party/adhd/+/master/cras/src/server/cras_alsa_ucm.c
Pros:
* No need to write parser manually
Cons:
* Alsa-lib is all in C, which depends on other C libraries.
* Factory toolkit don't want to build C code (cross-platform issue, dependency, complicate the build process, etc...)
3. Use 'alsaucm' binary to parse/apply UCM files
Pros:
* 'alsaucm' exports several commands of alsa-lib interfaces. We can use it to parse/apply UCM configs.
Cons:
* Depend on 'alsaucm' binary.
* We don't control the real command via 'amixer -c' anymore; alsaucm will do that.
* Hard to debug if something goes wrong (because we don't know alsaucm invokes which 'amixer -c' commands).
4. Depends on cras service
* dbus-send --system --type=method_call --print-reply --dest=org.chromium.cras /org/chromium/cras org.chromium.cras.Control.GetNodes
* Output like:
array [
dict entry(
string "IsInput"
variant boolean false
)
dict entry(
string "Id"
variant uint64 21474836480
)
dict entry(
string "DeviceName"
variant string "kblrt5514rt5663max: :0,0"
)
dict entry(
string "StableDeviceId"
variant uint64 1923447123
)
dict entry(
string "StableDeviceIdNew"
variant uint64 1923447123
)
dict entry(
string "Type"
variant string "INTERNAL_SPEAKER"
)
dict entry(
string "Name"
variant string "Speaker"
)
dict entry(
string "MicPositions"
variant string ""
)
dict entry(
string "Active"
variant boolean false
)
dict entry(
string "PluggedTime"
variant uint64 1502876121538032
)
dict entry(
string "NodeVolume"
variant uint64 4
)
dict entry(
string "NodeCaptureGain"
variant int64 0
)
dict entry(
string "HotwordModels"
variant string ""
)
]
Pros:
* Easy to use.
Cons:
* Depends on cras. If there's an issue in cras, it blocks the factory test.
* The 'Id' is used in other command like 'adjust-volume' or 'mute'. This is not the device id 'amixer -c' uses.
* Need to rewrite the audio testing suite to use cras to select device, play sound, and record sound.
* More issues if we depend on cras. E.g., how to detect headphone jack is plugged in? how to adjust the 'raw' volume value?
In conclusion, Method 1 should be the best solution for factory team.
* audio.conf and UCM HiFi.conf are actually identical.
* phonenixshen@ has some experience to convert a HiFi.conf to the audio.conf.
* We gain fully control over the audio devices.
,
Aug 18 2017
For option 2, we can safely assume libasound.so and all dependencies exists on dut (commands like amixer/aplay depend on it), and use ctypes to wrap libasound.so. So no need to compile c code. Not sure if this will be easier than option 1. Cons: need extra efforts to make this work on station mode.
,
Aug 21 2017
More thoughts on parsing/applying UCM configs manually or not...
Option 1: Parse/Apply UCM configs manually
Pros:
* Easily load other UCM configs outside /usr/share/alsa/ucm
* Easily trace all amixer commands
Cons:
* Need to parse/apply UCM configs
* Reference: http://www.alsa-project.org/alsa-doc/alsa-lib/group__ucm.html
* More details at alsa-lib/src/ucm/parser.c
* Need some maintenance effort in factory team
Option 2: Parse/Apply UCM configs by libasound.so or alsaucm
Pros:
* No need to parse/apply UCM configs manually.
Cons:
* How to load UCM configs outside /usr/share/alsa/ucm? Bind mount should work.
* Cannot trace all amixer commands
* We can trace libasound.so / alsaucm commands. They invokes amixer commands for us.
* Cras service also depends on libasound.so. So this information should be sufficient for audio team / factory to debug.
,
Aug 21 2017
Reply #10: Yes. It's much easier than parsing/applying UCM configs by ourselves. Also, considering the extra effort on station mode as you mentioned, Option 3 seems to be a (strictly) better option.
,
Aug 23 2017
Sorted out several core usages for alsaucm. After entering alsaucm in interaction mode (option -i), one can do: List all UCM configs: > listcards Assume we are dealing with card 'kblrt5514rt5663max' List all verbs: > open kblrt5514rt5663max > list _verbs List all devices under a verb 'HiFi': > open kblrt5514rt5663max > set _verb HiFi > list _devices All devices under the verb will be listed. For example: 0: Speaker 1: Headphone 2: Internal Mic 3: Mic 4: HDMI1 5: HDMI2 6: HDMI3 Enable the device 'Speaker': > open kblrt5514rt5663max > set _verb HiFi > set _enadev Speaker Reset sound card to default state: > open kblrt5514rt5663max > reset Get playback PCM for device 'Speaker': > open kblrt5514rt5663max > set _verb HiFi > get PlaybackPCM/Speaker Output looks like: PlaybackPCM/Speaker=hw:kblrt5514rt5663,0 Get capture PCM for device 'Mic': > open kblrt5514rt5663max > set _verb HiFi > get CapturePCM/Mic Output looks like: CapturePCM/Mic=hw:kblrt5514rt5663,1 Jack name of device 'Mic' can also be fetched: > open kblrt5514rt5663max > set _verb HiFi > get JackName/Mic Output looks like: JackName/Mic=kblrt5514rt5663max Headset Jack And for its jack type: > open kblrt5514rt5663max > set _verb HiFi > get JackType/Mic Output looks like: JackType/Mic=gpio The playback/capture PCM should be of form: hw:card-name,<num> The <num> is the device index, which can be used for aplay/arecord. References: 1. https://chromium.googlesource.com/chromiumos/third_party/adhd/+/master/cras/src/server/cras_alsa_ucm.c 2. https://patchwork.kernel.org/patch/9468495/
,
Aug 24 2017
The audio conf (i.e., audio.conf / audio.json) we defined in our factory flow supports following operations: 1. Initialize sound card 2. Enable / Disable a certain device 3. Mute a certain device 4. Adjust volume for a certain device 5. Do customized amixer commands 6. Invoke customized script A UCM config file can ONLY cover the first two operations. That is: 1. Initialize the sound card 2. Enable/Disable a certain device For operations 3 and 4, they are not commonly used (e.g., they are not used in a recent board). And in case they are needed, we need to ask vendors to provide the amixer commands, which is basically the audio.conf. For operation 5 and 6, they are customized amixer commands, so we need to prepare the audio.conf. So, in conclusion, we need audio.conf to support operation 3~6. But, in most of the use case, we don't need it for a normal factory flow. A new class will be implemented to use UCM files to support operation 1 and 2. An optional audio.conf can be passed to this new class to support operations 3~6.
,
Sep 1 2017
Question: How to get a good guess for UCM config names? UCM config names are the folder basename under /usr/share/alsa/ucm For example: localhost / # ls -al /usr/share/alsa/ucm total 60 drwxr-xr-x. 15 root root 4096 Aug 23 18:03 . drwxr-xr-x. 9 root root 4096 Aug 23 17:51 .. drwxr-xr-x. 2 root root 4096 Aug 16 16:31 'Chat 150 C' drwxr-xr-x. 2 root root 4096 Aug 17 17:04 DB410c drwxr-xr-x. 2 root root 4096 Jul 17 02:50 GoogleNyan drwxr-xr-x. 2 root root 4096 Jul 17 02:50 'Jabra SPEAK 810' drwxr-xr-x. 2 root root 4096 Jul 17 02:50 PAZ00 drwxr-xr-x. 2 root root 4096 Jul 17 02:50 PandaBoard drwxr-xr-x. 2 root root 4096 Jul 17 02:50 PandaBoardES drwxr-xr-x. 2 root root 4096 Aug 16 17:22 SDP4430 drwxr-xr-x. 2 root root 4096 Jul 17 02:50 VEYRON-I2S drwxr-xr-x. 2 root root 4096 Aug 16 17:23 broadwell-rt286 drwxr-xr-x. 2 root root 4096 Sep 1 11:55 kblrt5514rt5663max drwxr-xr-x. 2 root root 4096 Jul 17 02:50 skylake-rt286 drwxr-xr-x. 2 root root 4096 Jul 17 02:50 tegraalc5632 The question is, how can we get a good guess to choose a folder? Answer: Thanks hychao@ to provide this. For playback devices, use aplay -l. For example: localhost kblrt5514rt5663max # aplay -l **** List of PLAYBACK Hardware Devices **** card 0: kblrt5514rt5663 [kblrt5514rt5663max], device 0: Audio (*) [] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: kblrt5514rt5663 [kblrt5514rt5663max], device 4: Hdmi1 (*) [] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: kblrt5514rt5663 [kblrt5514rt5663max], device 5: Hdmi2 (*) [] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: kblrt5514rt5663 [kblrt5514rt5663max], device 6: Hdmi3 (*) [] Subdevices: 1/1 Subdevice #0: subdevice #0 The strings in the brackets should be the name. Similarly, for recording devices, use arecord -l: localhost kblrt5514rt5663max # arecord -l **** List of CAPTURE Hardware Devices **** card 0: kblrt5514rt5663 [kblrt5514rt5663max], device 1: Audio Record (*) [] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: kblrt5514rt5663 [kblrt5514rt5663max], device 2: Wake on Voice (*) [] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: kblrt5514rt5663 [kblrt5514rt5663max], device 3: dmiccap (*) [] Subdevices: 1/1 Subdevice #0: subdevice #0
,
Sep 1 2017
Re #14, > 5. Do customized amixer commands Is there any example for this? Most of the commands in audio.schema.json are covered by case 1~4, except last few items like "headphone_jack_detect", but I don't think we are using these now. > 6. Invoke customized script This is only for audio_quality test which needs to deal with special fixture, We should remove this from audio api, and find a better place for them.
,
Sep 1 2017
Re #16: > > 5. Do customized amixer commands > Is there any example for this? > Most of the commands in audio.schema.json are covered by case 1~4, > except last few items like "headphone_jack_detect", but I don't think we are > using these now. To best of my knowledge, no customized amixer commands are spotted in our factory flow. But, the design of the audio.conf can indeed support these kind of operations. This is the only reason why I listed here. > > 6. Invoke customized script > This is only for audio_quality test which needs to deal with special fixture, > We should remove this from audio api, and find a better place for them. Great! After we did that, we can possibly remove audio.conf thoroughly. Although one of the motivation is to remove audio.conf at all. But, at least for the first few CLs, I'd like to keep audio.conf for several reasons: 1. Backward compatibility 2. Able to do customized amixer commands As mentioned, this should not be necessary in normal cases. However, anythings can happen during an audio driver bring-up. I think it might be good to have a structured way to perform amixer commands, this is exactly what audio.conf does. 3. Still has great improvement. No audio.conf needed in most of the cases Audio.conf is now considered as an overwrite setting over UCM configs. So, in most of the cases, we still don't need audio.conf at all to control the audio devices. This matches our original motivation.
,
Sep 9 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromiumos/platform/factory/+/3f24c8d7d062b0c1c6f7a41009aa43337c36c67a commit 3f24c8d7d062b0c1c6f7a41009aa43337c36c67a Author: Shen-En Shih <petershih@chromium.org> Date: Sat Sep 09 07:14:06 2017 audio: Define device type Define supported input and output audio devices. TEST=make test BUG= chromium:704439 Change-Id: I07b9b8a32742109e65b70ca51fc19c4ca9d58544 Reviewed-on: https://chromium-review.googlesource.com/650267 Commit-Ready: Shen-En Shih <petershih@chromium.org> Tested-by: Shen-En Shih <petershih@chromium.org> Reviewed-by: Hung-Te Lin <hungte@chromium.org> [modify] https://crrev.com/3f24c8d7d062b0c1c6f7a41009aa43337c36c67a/py/device/audio/base.py
,
Sep 22 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromiumos/platform/factory/+/cf65e6b6a1421b1095f2c783c960255cc829fec8 commit cf65e6b6a1421b1095f2c783c960255cc829fec8 Author: Shen-En Shih <petershih@chromium.org> Date: Fri Sep 22 13:10:09 2017 audio: Refactor out MixerController and ConfigManager Separate out the following two parts: 1. Dealing with mixer controller 2. Parse config files To support this, two base classes are defined. One of them deals with mixer controller, and the other one deals with logics to parse and apply the audio config files. BUG= chromium:704439 TEST=make test TEST=manually test Change-Id: Ic095d1f42912914e7a9bcd0d1734810613f2e1e8 Reviewed-on: https://chromium-review.googlesource.com/650268 Commit-Ready: Shen-En Shih <petershih@chromium.org> Tested-by: Shen-En Shih <petershih@chromium.org> Reviewed-by: Shen-En Shih <petershih@chromium.org> [modify] https://crrev.com/cf65e6b6a1421b1095f2c783c960255cc829fec8/py/device/audio/alsa.py [add] https://crrev.com/cf65e6b6a1421b1095f2c783c960255cc829fec8/py/device/audio/config_manager.py [modify] https://crrev.com/cf65e6b6a1421b1095f2c783c960255cc829fec8/py/device/audio/base.py [modify] https://crrev.com/cf65e6b6a1421b1095f2c783c960255cc829fec8/py/device/audio/tinyalsa.py
,
Sep 22 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromiumos/platform/factory/+/5e7af863810bad16d3f1bf56f949ade866399df5 commit 5e7af863810bad16d3f1bf56f949ade866399df5 Author: Shen-En Shih <petershih@chromium.org> Date: Fri Sep 22 13:10:09 2017 audio: Refine return behavior for ApplyAudioConfig The return behavior of ApplyAudioConfig is now refined as follows: 1. Return False if the operation is not defined in the config file. 2. Raise exception if the operations is failed to apply. 3. Return True if the operations are applied successfully. BUG= chromium:704439 TEST=make test Change-Id: I0037fdd960586cacbb01ff1a4f68b0d6dbf5e551 Reviewed-on: https://chromium-review.googlesource.com/650269 Commit-Ready: Shen-En Shih <petershih@chromium.org> Tested-by: Shen-En Shih <petershih@chromium.org> Reviewed-by: Shen-En Shih <petershih@chromium.org> [modify] https://crrev.com/5e7af863810bad16d3f1bf56f949ade866399df5/py/device/audio/config_manager.py [modify] https://crrev.com/5e7af863810bad16d3f1bf56f949ade866399df5/py/device/audio/base.py
,
Sep 22 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromiumos/platform/factory/+/8e9d319b1f6c98f0e8091cf9a14b56a8c108e172 commit 8e9d319b1f6c98f0e8091cf9a14b56a8c108e172 Author: Shen-En Shih <petershih@chromium.org> Date: Fri Sep 22 15:08:56 2017 audio: Implement UCM config manager Implement the UCM config manager to control sound cards according to UCM config files. BUG= chromium:704439 TEST=make test TEST=manually test Change-Id: I775c00ac082cf66065af4fc486f5b8729f956289 Reviewed-on: https://chromium-review.googlesource.com/650270 Commit-Ready: Shen-En Shih <petershih@chromium.org> Tested-by: Shen-En Shih <petershih@chromium.org> Reviewed-by: Hung-Te Lin <hungte@chromium.org> [modify] https://crrev.com/8e9d319b1f6c98f0e8091cf9a14b56a8c108e172/py/device/audio/alsa.py [modify] https://crrev.com/8e9d319b1f6c98f0e8091cf9a14b56a8c108e172/py/device/audio/config_manager.py
,
Sep 22 2017
,
Oct 6 2017
So now if a project does not define audio.conf, can we still run audio tests using system HiFi? Can you update the audio test doc to explain what to do?
,
Jan 22 2018
,
Jan 23 2018
|
||||||
►
Sign in to add a comment |
||||||
Comment 1 by hungte@chromium.org
, Mar 23 2017