|
|
@ -18,7 +18,7 @@ class Sound : public QObject { |
|
|
|
public: |
|
|
|
public: |
|
|
|
explicit Sound(QObject *parent = 0) { |
|
|
|
explicit Sound(QObject *parent = 0) { |
|
|
|
// TODO: merge again and add EQ in the amp config
|
|
|
|
// TODO: merge again and add EQ in the amp config
|
|
|
|
const QString sound_asset_path = Hardware::TICI ? "../assets/sounds_tici/" : "../assets/sounds/"; |
|
|
|
const QString sound_asset_path = Hardware::TICI() ? "../assets/sounds_tici/" : "../assets/sounds/"; |
|
|
|
std::tuple<AudibleAlert, QString, bool> sound_list[] = { |
|
|
|
std::tuple<AudibleAlert, QString, bool> sound_list[] = { |
|
|
|
{AudibleAlert::CHIME_DISENGAGE, sound_asset_path + "disengaged.wav", false}, |
|
|
|
{AudibleAlert::CHIME_DISENGAGE, sound_asset_path + "disengaged.wav", false}, |
|
|
|
{AudibleAlert::CHIME_ENGAGE, sound_asset_path + "engaged.wav", false}, |
|
|
|
{AudibleAlert::CHIME_ENGAGE, sound_asset_path + "engaged.wav", false}, |
|
|
@ -30,9 +30,10 @@ public: |
|
|
|
{AudibleAlert::CHIME_PROMPT, sound_asset_path + "error.wav", false} |
|
|
|
{AudibleAlert::CHIME_PROMPT, sound_asset_path + "error.wav", false} |
|
|
|
}; |
|
|
|
}; |
|
|
|
for (auto &[alert, fn, loops] : sound_list) { |
|
|
|
for (auto &[alert, fn, loops] : sound_list) { |
|
|
|
sounds[alert].first.setSource(QUrl::fromLocalFile(fn)); |
|
|
|
QSoundEffect *s = new QSoundEffect(this); |
|
|
|
sounds[alert].second = loops ? QSoundEffect::Infinite : 0; |
|
|
|
QObject::connect(s, &QSoundEffect::statusChanged, this, &Sound::checkStatus); |
|
|
|
QObject::connect(&sounds[alert].first, &QSoundEffect::statusChanged, this, &Sound::checkStatus); |
|
|
|
s->setSource(QUrl::fromLocalFile(fn)); |
|
|
|
|
|
|
|
sounds[alert] = {s, loops ? QSoundEffect::Infinite : 0}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sm = new SubMaster({"carState", "controlsState"}); |
|
|
|
sm = new SubMaster({"carState", "controlsState"}); |
|
|
@ -47,9 +48,8 @@ public: |
|
|
|
|
|
|
|
|
|
|
|
private slots: |
|
|
|
private slots: |
|
|
|
void checkStatus() { |
|
|
|
void checkStatus() { |
|
|
|
for (auto &[alert, kv] : sounds) { |
|
|
|
QSoundEffect *s = qobject_cast<QSoundEffect*>(sender()); |
|
|
|
assert(kv.first.status() != QSoundEffect::Error); |
|
|
|
assert(s->status() != QSoundEffect::Error); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void update() { |
|
|
|
void update() { |
|
|
@ -75,20 +75,19 @@ private slots: |
|
|
|
if (!alert.equal(a)) { |
|
|
|
if (!alert.equal(a)) { |
|
|
|
alert = a; |
|
|
|
alert = a; |
|
|
|
// stop sounds
|
|
|
|
// stop sounds
|
|
|
|
for (auto &kv : sounds) { |
|
|
|
for (auto &[s, loops] : sounds) { |
|
|
|
// Only stop repeating sounds
|
|
|
|
// Only stop repeating sounds
|
|
|
|
auto &[sound, loops] = kv.second; |
|
|
|
if (s->loopsRemaining() == QSoundEffect::Infinite) { |
|
|
|
if (sound.loopsRemaining() == QSoundEffect::Infinite) { |
|
|
|
s->stop(); |
|
|
|
sound.stop(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// play sound
|
|
|
|
// play sound
|
|
|
|
if (alert.sound != AudibleAlert::NONE) { |
|
|
|
if (alert.sound != AudibleAlert::NONE) { |
|
|
|
auto &[sound, loops] = sounds[alert.sound]; |
|
|
|
auto &[s, loops] = sounds[alert.sound]; |
|
|
|
sound.setLoopCount(loops); |
|
|
|
s->setLoopCount(loops); |
|
|
|
sound.setVolume(volume); |
|
|
|
s->setVolume(volume); |
|
|
|
sound.play(); |
|
|
|
s->play(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -96,7 +95,7 @@ private slots: |
|
|
|
private: |
|
|
|
private: |
|
|
|
Alert alert; |
|
|
|
Alert alert; |
|
|
|
float volume = Hardware::MIN_VOLUME; |
|
|
|
float volume = Hardware::MIN_VOLUME; |
|
|
|
std::map<AudibleAlert, std::pair<QSoundEffect, int>> sounds; |
|
|
|
QMap<AudibleAlert, QPair<QSoundEffect*, int>> sounds; |
|
|
|
SubMaster *sm; |
|
|
|
SubMaster *sm; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|