-
Notifications
You must be signed in to change notification settings - Fork 61
Expand file tree
/
Copy pathcheck-volume-levels.sh
More file actions
executable file
·341 lines (288 loc) · 8.42 KB
/
check-volume-levels.sh
File metadata and controls
executable file
·341 lines (288 loc) · 8.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
#!/usr/bin/env bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2020 Intel Corporation. All rights reserved.
set -e
##
## Case Name: check-volume-levels
## Preconditions:
## topology is nocodec with loopack in PCM0P -> PCM0C
## aplay should work
## arecord should work
## PCM0C capture PGA supports -50 - +30 dB range
## PCM0C capture PGA supports mute switch
## Description:
## Set volume and mute switch to various values, measure
## volume gain from the actual levels and compare to set gains.
## Case step:
## 1. Start aplay
## 2a. Capture 1st wav file
## 2b. Capture 2nd wav file
## 2c. Capture 3rd wav file
## 3. Measure volume gains
## Expect result:
## command line check with $? without error
##
TESTDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
# shellcheck source=case-lib/lib.sh
source "$TESTDIR/case-lib/lib.sh"
OPT_NAME['t']='tplg' OPT_DESC['t']='tplg file, default value is env TPLG: $''TPLG'
OPT_HAS_ARG['t']=1 OPT_VAL['t']="$TPLG"
func_opt_parse_option "$@"
tplg=${OPT_VAL['t']}
TPLGREADER="$TESTDIR"/tools/sof-tplgreader.py
PCM_ID=0
CAP_FORMAT="S16_LE"
CAP_RATE="48000"
VOL_P30DB=80
VOL_P10DB=60
VOL_0DB=50
VOL_M10DB=40
VOL_M20DB=30
VOL_M30DB=20
VOL_MAX=$VOL_P30DB
VOL_MIN=1
VOL_MUTE=0
VOL_NOM=$VOL_0DB
APLAY_WAV=$(mktemp --suffix=.wav)
ARECORD_WAV1=$(mktemp --suffix=.wav)
ARECORD_WAV2=$(mktemp --suffix=.wav)
ARECORD_WAV3=$(mktemp --suffix=.wav)
start_test
#
# Main test procedure
#
main () {
# Preparations
do_preparations
generate_sine
# Start sine playback
test -f "$APLAY_WAV" || die "Error: File $APLAY_WAV does not exist"
dlogi "Playing file $APLAY_WAV"
timeout -k 5 120 aplay -D "$PLAY_HW" "$APLAY_WAV" & aplayPID=$!
nap
# Do capture tests
run_test_1
run_test_2
run_test_3
# Stop sine playback and do cleanup
nap
dlogi "The test procedure is now complete. Killing the aplay process $aplayPID."
kill $aplayPID
# Measure, delete unnecessary wav files if passed
if measure_levels; then
dlogi "Deleting temporary files"
rm -f "$APLAY_WAV" "$ARECORD_WAV1" "$ARECORD_WAV2" "$ARECORD_WAV3"
fi
sof-kernel-log-check.sh "$KERNEL_CHECKPOINT"
}
#
# Test #1 volume and mute switch controls
#
# 0...1s channels 1-4 max gain
# 1...2s channels 1-4 different gains
# 2...3s channels 1-4 nominal gain
# 3...4s channels 1-4 muted
# 4...5s channels 1-4 nominal gain
# 5...7s channels 1-4 muted
# 7...8s channels 1-4 max gain
# 8...9s channels 1-4 muted gain
# 9..10s channels 1-4 min gain
# 10..11s channels 1-4 different gains
run_test_1 () {
cset_max; cset_unmute; nap
arecord_helper "$ARECORD_WAV1" "$CAP_CHANNELS" 11 & arecordPID=$!
nap
cset_volume_diff1 "$CAP_CHANNELS"; nap
cset_nom; nap
cset_mute; nap
cset_unmute; nap
cset_mute; nap
cset_max; nap
cset_unmute; nap
cset_mutevol; nap
cset_min; nap
cset_volume_diff2 "$CAP_CHANNELS"
# Wait for arecord process to complete
dlogi "Waiting $arecordPID"
wait $arecordPID
dlogi "Ready."
}
#
# Test #2, check gains preservation from previous to next
#
# 0..1s channels 1-4 previous gains
# 1..2s channels 1-4 different mute switches
# 2..3s channels 1-4 all muted
run_test_2 () {
arecord_helper "$ARECORD_WAV2" "$CAP_CHANNELS" 4 & arecordPID=$!
nap
cset_nom; cset_mute_diff1 "$CAP_CHANNELS"; nap
cset_mute; nap
dlogi "Waiting $arecordPID"
wait $arecordPID
dlogi "Ready."
}
#
# Test #3, test mute switch preservation from previous to next
#
# 0..1s channels 1-4 muted
# 1..2s channels 1-4 nominal gain
# 2..3s different mute switches
# 3..4s channels 1-4 nominal gain
run_test_3 () {
arecord_helper "$ARECORD_WAV3" "$CAP_CHANNELS" 4 & arecordPID=$!
nap
cset_nom; nap
cset_mute_diff2 "$CAP_CHANNELS"; nap
cset_unmute
dlogi "Waiting $arecordPID"
wait $arecordPID
dlogi "Ready."
}
#
# Helper functions
#
cset_nom () {
dlogi "Set nominal volume"
amixer cset name="$CAP_VOLUME" $VOL_NOM
}
cset_max () {
dlogi "Set maximum volume"
amixer cset name="$CAP_VOLUME" $VOL_MAX
}
cset_min () {
dlogi "Set minimum volume"
amixer cset name="$CAP_VOLUME" $VOL_MIN
}
cset_mutevol () {
dlogi "Set mute via volume"
amixer cset name="$CAP_VOLUME" $VOL_MUTE
}
cset_mute () {
dlogi "Set mute via switch"
amixer cset name="$CAP_SWITCH" off
}
cset_unmute () {
dlogi "Set unmute"
amixer cset name="$CAP_SWITCH" on
}
nap () {
dlogi "Sleeping"
sleep 1
}
cset_mute_diff1 () {
dlogi "Set switch pattern 1"
case "$1" in
4)
amixer cset name="$CAP_SWITCH" off,on,on,off ;;
2)
amixer cset name="$CAP_SWITCH" off,on ;;
1)
amixer cset name="$CAP_SWITCH" off ;;
esac
}
cset_mute_diff2 () {
dlogi "Set switch pattern 2"
case "$1" in
4)
amixer cset name="$CAP_SWITCH" on,off,off,on ;;
2)
amixer cset name="$CAP_SWITCH" on,off ;;
1)
amixer cset name="$CAP_SWITCH" on ;;
esac
}
cset_volume_diff1 () {
dlogi "Set volume pattern 1"
case "$1" in
4)
amixer cset name="$CAP_VOLUME" $VOL_P10DB,$VOL_0DB,$VOL_M10DB,$VOL_M30DB ;;
2)
amixer cset name="$CAP_VOLUME" $VOL_P10DB,$VOL_0DB ;;
1)
amixer cset name="$CAP_VOLUME" $VOL_P10DB ;;
esac
}
cset_volume_diff2 () {
dlogi "Set volume pattern 2"
case "$1" in
4)
amixer cset name="$CAP_VOLUME" $VOL_M10DB,$VOL_P10DB,$VOL_0DB,$VOL_M20DB ;;
2)
amixer cset name="$CAP_VOLUME" $VOL_M10DB,$VOL_P10DB ;;
1)
amixer cset name="$CAP_VOLUME" $VOL_M10DB ;;
esac
}
arecord_helper () {
dlogi "Capturing file $1"
timeout -k 5 30 arecord -D "$CAP_HW" -f $CAP_FORMAT -r $CAP_RATE -c "$2" -d "$3" "$1"
}
do_preparations () {
if [[ "$tplg" != *"nocodec"* ]]; then
# Return special value 2 with exit
dlogi "This test is executed only with nocodec topologies. Returning Not Applicable."
exit 2
fi
test -n "$(command -v octave)" || {
dlogi "Octave not found (need octave and octave-signal packages). Returning Not Applicable."
exit 2
}
# Get max. channels count to use from capture device
# remove xargs after the trailing blank from tplgreader is fixed
CAP_CHANNELS=$($TPLGREADER "$tplg" -f "id:$PCM_ID & type:capture" -d ch_max -v)
CAP_HW=$($TPLGREADER "$tplg" -f "id:$PCM_ID & type:capture" -d dev -v)
PLAY_HW=$($TPLGREADER "$tplg" -f "id:$PCM_ID & type:playback" -d dev -v)
CAP_PGA=$($TPLGREADER "$tplg" -f "id:$PCM_ID & type:capture" -d pga -v)
PLAY_PGA=$($TPLGREADER "$tplg" -f "id:$PCM_ID & type:playback" -d pga -v)
export CAP_CHANNELS
export CAP_HW
export PLAY_HW
dlogi "Test uses $CAP_CHANNELS channels"
dlogi "Playback device is $PLAY_HW"
dlogi "Playback PGA is $PLAY_PGA"
dlogi "Capture device is $CAP_HW"
dlogi "Capture PGA is $CAP_PGA"
# Find amixer controls for capture, error if more than one PGA
numpga=${#CAP_PGA[@]}
test "$numpga" = 1 || die "Error: more than one capture PGA found."
tmp=$(amixer controls | grep -e "$CAP_PGA.*Volume" || true )
test -n "$tmp" || die "No control with name Volume found in $CAP_PGA"
search="name="
CAP_VOLUME=${tmp#*"$search"}
export CAP_VOLUME
dlogi "Capture volume control name is $CAP_VOLUME"
tmp=$(amixer controls | grep -e "$CAP_PGA.*Switch" || true )
test -n "$tmp" || die "No control with name Switch found in $CAP_PGA"
CAP_SWITCH=${tmp#*"$search"}
export CAP_SWITCH
dlogi "Capture switch control name is $CAP_SWITCH"
# Check needed controls
amixer cget name="$CAP_VOLUME" || die "Error: failed capture volume get command"
amixer cget name="$CAP_SWITCH" || die "Error: failed capture switch get command"
for pga in $PLAY_PGA; do
tmp=$(amixer controls | grep "$pga" | grep Volume)
search="name="
play_volume=${tmp#*"$search"}
dlogi "Set $play_volume to 100%"
amixer cset name="$play_volume" 100% || die "Error: failed play volume set command"
done
}
generate_sine () {
dlogi "Creating sine wave file"
cd "$TESTDIR"/tools
octave --silent --no-gui --eval "check_volume_levels('generate', '$APLAY_WAV')" ||
die "Error: failed sine wave generate."
}
measure_levels () {
dlogi "Measuring volume gains"
cd "$TESTDIR"/tools
octave --silent --no-gui --eval "check_volume_levels('measure', '$ARECORD_WAV1', '$ARECORD_WAV2', '$ARECORD_WAV3')" || {
dloge "Error: Failed one or more tests in volume levels check."
die "Please inspect files: $ARECORD_WAV1, $ARECORD_WAV2, and $ARECORD_WAV3."
}
}
#
# Start test
#
main "$@"