parent
c70db51a5b
commit
e6bb12abfa
7 changed files with 1 additions and 153 deletions
@ -1,3 +1 @@ |
|||||||
test |
|
||||||
play_sound |
|
||||||
test_sound |
test_sound |
||||||
|
@ -1,30 +0,0 @@ |
|||||||
#include <QApplication> |
|
||||||
#include <QSoundEffect> |
|
||||||
#include <QTimer> |
|
||||||
#include <QDebug> |
|
||||||
|
|
||||||
int main(int argc, char **argv) { |
|
||||||
|
|
||||||
QApplication a(argc, argv); |
|
||||||
|
|
||||||
QTimer::singleShot(0, [=]{ |
|
||||||
QSoundEffect s; |
|
||||||
const char *vol = getenv("VOLUME"); |
|
||||||
s.setVolume(vol ? atof(vol) : 1.0); |
|
||||||
for (int i = 1; i < argc; i++) { |
|
||||||
QString fn = argv[i]; |
|
||||||
qDebug() << "playing" << fn; |
|
||||||
|
|
||||||
QEventLoop loop; |
|
||||||
s.setSource(QUrl::fromLocalFile(fn)); |
|
||||||
QEventLoop::connect(&s, &QSoundEffect::loadedChanged, &loop, &QEventLoop::quit); |
|
||||||
loop.exec(); |
|
||||||
s.play(); |
|
||||||
QEventLoop::connect(&s, &QSoundEffect::playingChanged, &loop, &QEventLoop::quit); |
|
||||||
loop.exec(); |
|
||||||
} |
|
||||||
QCoreApplication::exit(); |
|
||||||
}); |
|
||||||
|
|
||||||
return a.exec(); |
|
||||||
} |
|
@ -1,49 +0,0 @@ |
|||||||
#!/usr/bin/env python3 |
|
||||||
import os |
|
||||||
import random |
|
||||||
import subprocess |
|
||||||
import time |
|
||||||
from pathlib import Path |
|
||||||
from common.basedir import BASEDIR |
|
||||||
|
|
||||||
os.environ["LD_LIBRARY_PATH"] = "" |
|
||||||
|
|
||||||
# pull this from the provisioning tests |
|
||||||
play_sound = os.path.join(BASEDIR, "selfdrive/ui/test/play_sound") |
|
||||||
waste = os.path.join(BASEDIR, "scripts/waste") |
|
||||||
sound_path = Path(os.path.join(BASEDIR, "selfdrive/assets/sounds")) |
|
||||||
|
|
||||||
def sound_test(): |
|
||||||
|
|
||||||
# max volume |
|
||||||
vol = 15 |
|
||||||
sound_files = [p.absolute() for p in sound_path.iterdir() if str(p).endswith(".wav")] |
|
||||||
|
|
||||||
# start waste |
|
||||||
p = subprocess.Popen([waste], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) |
|
||||||
|
|
||||||
start_time = time.monotonic() |
|
||||||
frame = 0 |
|
||||||
while True: |
|
||||||
# start a few processes |
|
||||||
procs = [] |
|
||||||
for _ in range(random.randint(5, 20)): |
|
||||||
sound = random.choice(sound_files) |
|
||||||
p = subprocess.Popen([play_sound, str(sound), str(vol)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) |
|
||||||
procs.append(p) |
|
||||||
time.sleep(random.uniform(0, 0.75)) |
|
||||||
|
|
||||||
# and kill them |
|
||||||
time.sleep(random.uniform(0, 5)) |
|
||||||
for p in procs: |
|
||||||
p.terminate() |
|
||||||
|
|
||||||
# write stats |
|
||||||
stats = f"running time {time.monotonic() - start_time}s, cycle {frame}" |
|
||||||
with open("/tmp/sound_stats.txt", "a") as f: |
|
||||||
f.write(stats) |
|
||||||
print(stats) |
|
||||||
frame +=1 |
|
||||||
|
|
||||||
if __name__ == "__main__": |
|
||||||
sound_test() |
|
@ -1,69 +0,0 @@ |
|||||||
#!/usr/bin/env python3 |
|
||||||
import subprocess |
|
||||||
import time |
|
||||||
import unittest |
|
||||||
|
|
||||||
from cereal import log, car |
|
||||||
import cereal.messaging as messaging |
|
||||||
from selfdrive.test.helpers import phone_only, with_processes |
|
||||||
# TODO: rewrite for unittest |
|
||||||
from common.realtime import DT_CTRL |
|
||||||
from selfdrive.hardware import HARDWARE |
|
||||||
|
|
||||||
AudibleAlert = car.CarControl.HUDControl.AudibleAlert |
|
||||||
|
|
||||||
SOUNDS = { |
|
||||||
# sound: total writes |
|
||||||
AudibleAlert.none: 0, |
|
||||||
AudibleAlert.chimeEngage: 173, |
|
||||||
AudibleAlert.chimeDisengage: 173, |
|
||||||
AudibleAlert.chimeError: 173, |
|
||||||
AudibleAlert.chimePrompt: 173, |
|
||||||
AudibleAlert.chimeWarning1: 163, |
|
||||||
AudibleAlert.chimeWarning2: 216, |
|
||||||
AudibleAlert.chimeWarning2Repeat: 470, |
|
||||||
AudibleAlert.chimeWarningRepeat: 468, |
|
||||||
} |
|
||||||
|
|
||||||
def get_total_writes(): |
|
||||||
audio_flinger = subprocess.check_output('dumpsys media.audio_flinger', shell=True, encoding='utf-8').strip() |
|
||||||
write_lines = [l for l in audio_flinger.split('\n') if l.strip().startswith('Total writes')] |
|
||||||
return sum([int(l.split(':')[1]) for l in write_lines]) |
|
||||||
|
|
||||||
class TestSoundd(unittest.TestCase): |
|
||||||
def test_sound_card_init(self): |
|
||||||
assert HARDWARE.get_sound_card_online() |
|
||||||
|
|
||||||
@phone_only |
|
||||||
@with_processes(['soundd']) |
|
||||||
def test_alert_sounds(self): |
|
||||||
pm = messaging.PubMaster(['controlsState']) |
|
||||||
|
|
||||||
# make sure they're all defined |
|
||||||
alert_sounds = {v: k for k, v in car.CarControl.HUDControl.AudibleAlert.schema.enumerants.items()} |
|
||||||
diff = set(SOUNDS.keys()).symmetric_difference(alert_sounds.keys()) |
|
||||||
assert len(diff) == 0, f"not all sounds defined in test: {diff}" |
|
||||||
|
|
||||||
# wait for procs to init |
|
||||||
time.sleep(1) |
|
||||||
|
|
||||||
for sound, expected_writes in SOUNDS.items(): |
|
||||||
print(f"testing {alert_sounds[sound]}") |
|
||||||
start_writes = get_total_writes() |
|
||||||
|
|
||||||
for _ in range(int(9 / DT_CTRL)): |
|
||||||
msg = messaging.new_message('controlsState') |
|
||||||
msg.controlsState.alertSound = sound |
|
||||||
msg.controlsState.alertType = str(sound) |
|
||||||
msg.controlsState.alertText1 = "Testing Sounds" |
|
||||||
msg.controlsState.alertText2 = f"playing {alert_sounds[sound]}" |
|
||||||
msg.controlsState.alertSize = log.ControlsState.AlertSize.mid |
|
||||||
pm.send('controlsState', msg) |
|
||||||
time.sleep(DT_CTRL) |
|
||||||
|
|
||||||
tolerance = (expected_writes % 100) * 2 |
|
||||||
actual_writes = get_total_writes() - start_writes |
|
||||||
assert abs(expected_writes - actual_writes) <= tolerance, f"{alert_sounds[sound]}: expected {expected_writes} writes, got {actual_writes}" |
|
||||||
|
|
||||||
if __name__ == "__main__": |
|
||||||
unittest.main() |
|
Loading…
Reference in new issue