-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP][RFC] Test-case: Set PGAs to unity gain in script check-alsabat.sh #437
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interestingly https://sof-ci.01.org/softestpr/PR437/build271/devicetest failed to even start this test on all platforms except BSW_CYN_MAX98090 (which tends to have other, unrelated and severe eMMC issues, I digress).
It suspect the test fails to grep some (PGA?) control and then does not start because of set -e
, did you expect that? Either way I think you should add more explicit error handling because grep
does not print anything when it fails to find anything, in other words:
scale=$(amixer cget name="$cname" | grep "dBscale" || true)
test -n "$scale" || die "dbScale $cname not found"
45fe2f0
to
68e731d
Compare
I'm confused why the script fails in every device in CI. This version uses "set -x". |
@marc-hb @xiulipan Now I think I know what's the problem. The CI system runs the script with command |
This would be simple to fix by testing with appended default path if topology file does not exist but I don't feel that is the proper thing to do. The call of this script does not seem to be in this repository. |
@singalsu The bash function Here‘s what you can do: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tplg_full_path=$(func_lib_get_tplg_path $tplg)
+1
test-case/check-alsabat.sh
Outdated
return | ||
fi | ||
|
||
for pga in $1; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a quoting perspective please make this function whitespace- and globbing- (*?
) safe with "$@"
like this:
for pga in "$@"
...
then you invoke it below without quotes:
CAP_PGAS=$($TPLGREADER "$tplg" -f "snd:$cap_snd" -d pga -v)
# this could need a "I know what I'm doing" shellcheck disable= here
set_pgas_list_to_unity_gain $CAP_PGAS
This keeps the function clean and concentrates whitespace, globbing and shellcheck issues closer to their source (= the TPLGREADER output)
https://google.github.io/styleguide/shellguide.html#s6.7-arrays
Using a single string for multiple command arguments should be avoided, as it inevitably leads to authors using eval or trying to nest quotes inside the string, which does not give reliable or readable results and leads to needless complexity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is confusing, but let's try.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shellcheck complains about line set_pgas_list_to_unity_gain $CAP_PGAS
with SC2086: Double quote to prevent globbing and word splitting. It works OK though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's expected because you should ideally not do that either. You should ideally never use a single string to store multiple, whitespace-separated strings. My suggestion that you applied is only "the lesser of two evils", my suggestion was to do this bad thing only in a single place (here) keeping the set_pgas_list_to_unity_gain()
function clean. Thanks for applying it.
So, ideally CAP_PGAS should be converted to an array. In practice we're going to assume that the output of $TPLGREADER
is safe and you can tell shellcheck that with this:
CAP_PGAS=$($TPLGREADER "$tplg" -f "snd:$cap_snd" -d pga -v)
# Let's assume the output of $TPLGREADER is free of *, other special characters and spurious spaces.
# shellcheck disable=SC2086
set_pgas_list_to_unity_gain $CAP_PGAS
@singalsu I think this would be good for nocodec test case. What about the codec cases? There maybe some volume control in codec. How could we handle those values for test? @keqiaozhang Any comments here for codec test cases? I think in CI framework, we manually tuned each volume gain value to make sure we did not get peak off in record wavs. Maybe we can set all value to 0db, so ideally we should get almost same wav we played. |
@xiulipan The codec based (analog or digital) gains are better to set up per device to be suitable for the (usually hw:1,0) USB sound card and leave them that way. Since the script gets with this patch the PGAs names from topology it fortunately does not alter them at all. In some cases setting codec gain to 0 dB could possibly "overload" the USB sound card A/D converter. There could be another script to automatically set the device D/A and USB A/D gains if adjustable via SW. The procedure would optimize THD+N performance of playback-capture loop. |
f41328f
to
9279531
Compare
done | ||
} | ||
|
||
get_snd_base() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_snd_dev()
?
echo "/dev/snd/pcmC${ncard}D${ndevice}" | ||
} | ||
|
||
get_play_snd() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_play_snd_dev()
?
test-case/check-alsabat.sh
Outdated
return | ||
fi | ||
|
||
for pga in $1; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's expected because you should ideally not do that either. You should ideally never use a single string to store multiple, whitespace-separated strings. My suggestion that you applied is only "the lesser of two evils", my suggestion was to do this bad thing only in a single place (here) keeping the set_pgas_list_to_unity_gain()
function clean. Thanks for applying it.
So, ideally CAP_PGAS should be converted to an array. In practice we're going to assume that the output of $TPLGREADER
is safe and you can tell shellcheck that with this:
CAP_PGAS=$($TPLGREADER "$tplg" -f "snd:$cap_snd" -d pga -v)
# Let's assume the output of $TPLGREADER is free of *, other special characters and spurious spaces.
# shellcheck disable=SC2086
set_pgas_list_to_unity_gain $CAP_PGAS
I agree to set all PGA value to 0dB. But if we do this, I need to retune the related codec kcontrols(like headset volume, DAC volume etc.) for the old platforms we added before to make sure the waveform does not overflow. |
Does it mean that the firmware PGAs have been intentionally set to other than 0 dB gain to compensate for some (non-sufficient?) codec gain controls? I made this PR because I noticed that the alsabat test failed when the capture pipeline was changed to other type (pipe-volume-switch-capture.m4) that has higher max. gain available. So, I mean setting the device for some defaults and relying it to boot with it correctly is rather fragile if like in this case a topology changes. |
SOFCI TEST |
@keqiaozhang There's now two timeouts remaining, one for a CML platform and one for a GLK platform. Those seem to be due to excessive signal level (distortion, multiple sine waves detected). I wonder if I should try a lower digital gain for all platforms. Or can the analog DAC or headphone gains be tuned down in those platforms to enable unity digital gains to pass? The latter would be preferred if possible. |
amixer setting for GLK: For CML, which device has the timeout issue? |
9279531
to
1b5c3c0
Compare
This patch adds find of volume controls for used playback and capture devices and sets them to unity gain (0 dB). The alsabat test fails if e.g. capture PGA is set to their maximum value that can be up to +30 dB. The test sine wave distorts and causes test fail. Signed-off-by: Seppo Ingalsuo <[email protected]>
1b5c3c0
to
6e14cdf
Compare
There is a relatively small number of shellcheck warnings left and most of them seem easy to fix: just missing quotes. While you're testing this script, @singalsu would you mind applying the most obvious shellcheck's suggestions in a separate commit? Don't mind any complex warning or complex quoting issues, any progress is useful. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious: would some UCM make all this easier to solve? I know @plbossart has been complaining about alsa settings since forever.
# check the PCMs before alsabat test | ||
dlogi "check the PCMs before alsabat test" | ||
aplay -Dplug$pcm_p -d 1 /dev/zero -q || die "Failed to play on PCM: $pcm_p" | ||
arecord -Dplug$pcm_c -d 1 /dev/null -q || die "Failed to capture on PCM: $pcm_c" | ||
|
||
# Set PGAs for PCMs to 0 dB value | ||
test -n "$(command -v "$TPLGREADER")" || | ||
die "Command $TPLGREADER is not available." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note #471 Remove sof-test dependency on topology file, use /proc instead
(but I have no idea how it would work here, this is just FYI)
# Get multiplied by 100 values by removing decimal dot | ||
min_x100="${min_db//.}" | ||
step_x100="${step_db//.}" | ||
val=$(printf %d "$(((-min_x100) / step_x100))") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, this would be slightly easier to read with some spaces:
val=$(printf %d "$(( (-min_x100) / step_x100))" )
Why do you need the printf at all?
# Get volume min and step to compute value for cset | ||
# for 0 dB gain. The amixer line looks like | ||
# "| dBscale-min=-50.00dB,step=1.00dB,mute=1" | ||
scale=$(amixer cget name="$cname" | grep "dBscale" || true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|| true
means an empty $scale
is OK. Is it really?
@@ -72,11 +79,83 @@ function __upload_wav_file | |||
done | |||
} | |||
|
|||
set_pga_to_unity_gain() | |||
{ | |||
tmp=$(amixer controls | grep "$1" | grep Volume) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you use very generic variable names, this first line will avoid any collision:
local tmp search cname scale ...
@singalsu @keqiaozhang @libinyang I remember you said the volume value can not be reset by UCM right? Please confirm here |
@singalsu did you forget about this? :-) |
@singalsu is this still relevant or should we close this one? |
@singalsu please re-open when you get a chance. |
tplg_full_path=$(func_lib_get_tplg_path "$tplg") | ||
dlogi "Getting playback PGA information" | ||
play_snd=$(get_play_snd "$pcm_p") | ||
PLAY_PGAS=$($TPLGREADER "$tplg_full_path" -f "snd:$play_snd" -d pga -v) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we talking about the string "pga" in the kcontrol name here? Then yes it is compatible with the tplg2 as well. Take a look at the gain kcontrols in the nocodec tplg https://sof-ci.01.org/linuxpr/PR4937/build2360/devicetest/index.html?model=TGLU_RVP_NOCODEC-ipc4&testcase=verify-tplg-binary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When run on topology v1 files, tools/sof-tplgreader.py
shows a field named pga
. Example:
./tools/sof-tplgreader.py /lib/firmware/intel/sof-tplg/sof-apl-nocodec.tplg -d pga
pga=PGA9.0 PGA5.0;
pga=PGA6.0;
pga=PGA11.0 PGA5.0;
Note the blank lines stand for DMIC and other PCMs without a pga=
field.
What would be the equivalent for topology v2? Is there a v2 compatibility issue with sof-tplgreader.py
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take a look at the gain kcontrols in the nocodec tplg https://sof-ci.01.org/linuxpr/PR4937/build2360/devicetest/index.html?model=TGLU_RVP_NOCODEC-ipc4&testcase=verify-tplg-binary
This device has at least 15 amixer controls with "Volu.." in the name (name=
which may or may not be truncated). That's the list of kcontrols volume tests want, correct?
That log shows a list of pipelines, 3 of them which have cap_name=Gain Capture
.
I don't see the connection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marc-hb i see your problem. Sorry I misundertood the PGA in the picture. Looks like that's the tplgtool printing that the PGA prefix for the kcontrols.
So, yes there's no "pga" string in tplg2 kcontrol names. Infact we consciously removed the widget name from the kcontrol name as well so you have "gain" either. So the question is how to figure out which kcontrols to test?
Can we do this during tplg parsing ie when as we parse the gain widgets, save the kcontrol names for the kcontrols associated with the widget and test only those?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as we parse the gain widgets, save the kcontrol names for the kcontrols associated with the widget and test only those?
Sounds like a plan. Let me take a look.
EDIT: done in
This patch adds find of volume controls for used playback and capture
devices and sets them to unity gain (0 dB). The alsabat test fails
if e.g. capture PGA is set to their maximum value that can be up
to +30 dB. The test sine wave distorts and causes test fail.
Signed-off-by: Seppo Ingalsuo [email protected]