Fix issues with changing default audio device
This commit is contained in:
parent
43b809d5d6
commit
9dad927239
3 changed files with 103 additions and 25 deletions
|
@ -15,6 +15,11 @@ ScStwLibraries_ClientLibs {
|
||||||
DEFINES += ScStwLibraries_ClientLibs
|
DEFINES += ScStwLibraries_ClientLibs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScStwLibraries_Raspi {
|
||||||
|
LIBS += -lasound
|
||||||
|
DEFINES += ScStwLibraries_Raspi
|
||||||
|
}
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/headers $$PWD
|
INCLUDEPATH += $$PWD/headers $$PWD
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
|
|
@ -27,9 +27,10 @@
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QSoundEffect>
|
#include <QSoundEffect>
|
||||||
|
#include <QAudioDeviceInfo>
|
||||||
|
|
||||||
#ifdef RASPI
|
#ifdef ScStwLibraries_Raspi
|
||||||
#include <QProcess>
|
#include <alsa/asoundlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -60,6 +61,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
bool _setSoundVolume(double volume);
|
||||||
|
|
||||||
|
void _initializeSondEffect();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief A map containing all sound files
|
* \brief A map containing all sound files
|
||||||
* 0: AtYourMarksSound
|
* 0: AtYourMarksSound
|
||||||
|
@ -74,6 +80,8 @@ private:
|
||||||
*/
|
*/
|
||||||
QSoundEffect *soundEffect;
|
QSoundEffect *soundEffect;
|
||||||
|
|
||||||
|
QAudioDeviceInfo *_audioOutputDevice;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The QEventLoop used to wait for the sound to finish
|
* \brief The QEventLoop used to wait for the sound to finish
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -28,8 +28,7 @@ ScStwSoundPlayer::ScStwSoundPlayer(QObject *parent) : QObject(parent)
|
||||||
this->soundFiles.insert(Start, {{"path","qrc:/sound/StartsignalSoundExtended.wav"}, {"duration", 3200}});
|
this->soundFiles.insert(Start, {{"path","qrc:/sound/StartsignalSoundExtended.wav"}, {"duration", 3200}});
|
||||||
this->soundFiles.insert(FalseStart, {{"path","qrc:/sound/FalseStartSound.wav"}, {"duration", 2000}});
|
this->soundFiles.insert(FalseStart, {{"path","qrc:/sound/FalseStartSound.wav"}, {"duration", 2000}});
|
||||||
|
|
||||||
this->soundEffect = new QSoundEffect(this);
|
this->_initializeSondEffect();
|
||||||
this->soundEffect->setLoopCount(1);
|
|
||||||
|
|
||||||
connect(this, &ScStwSoundPlayer::playbackStarted, this->waitLoop, &QEventLoop::quit);
|
connect(this, &ScStwSoundPlayer::playbackStarted, this->waitLoop, &QEventLoop::quit);
|
||||||
connect(this->soundEffect, &QSoundEffect::playingChanged, this->waitLoop, &QEventLoop::quit);
|
connect(this->soundEffect, &QSoundEffect::playingChanged, this->waitLoop, &QEventLoop::quit);
|
||||||
|
@ -48,28 +47,8 @@ ScStwSoundPlayer::PlayResult ScStwSoundPlayer::play(ScStwSoundPlayer::StartSound
|
||||||
// update currently playing action
|
// update currently playing action
|
||||||
this->currentlyPlayingSound = sound;
|
this->currentlyPlayingSound = sound;
|
||||||
|
|
||||||
#ifdef RASPI
|
if(!this->_setSoundVolume(volume))
|
||||||
// set volume on raspi using amixer
|
|
||||||
QProcess soundProcess;
|
|
||||||
|
|
||||||
// determine current audio output device
|
|
||||||
soundProcess.start("amixer", {"scontrols"});
|
|
||||||
soundProcess.waitForFinished();
|
|
||||||
QStringList outputDeviceNameList = QString(soundProcess.readAllStandardOutput()).split("'");
|
|
||||||
|
|
||||||
if(outputDeviceNameList.length() == 3) {
|
|
||||||
QString outputDeviceName = outputDeviceNameList[1];
|
|
||||||
soundProcess.execute("amixer", {"sset", outputDeviceName, QString::number(volume * 100, 'f', 0) + "%"});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qDebug() << "[WARNING][SoundPlayer] Could not determine output device to set volume";
|
|
||||||
return Error;
|
return Error;
|
||||||
}
|
|
||||||
|
|
||||||
this->soundEffect->setVolume(1);
|
|
||||||
#else
|
|
||||||
this->soundEffect->setVolume(volume);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// load
|
// load
|
||||||
this->soundEffect->setSource(this->soundFiles[sound]["path"].toString());
|
this->soundEffect->setSource(this->soundFiles[sound]["path"].toString());
|
||||||
|
@ -145,3 +124,89 @@ ScStwSoundPlayer::PlayResult ScStwSoundPlayer::waitForSoundFinish(double *timeOf
|
||||||
bool ScStwSoundPlayer::isPlaying() {
|
bool ScStwSoundPlayer::isPlaying() {
|
||||||
return this->soundEffect->isPlaying();
|
return this->soundEffect->isPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ScStwLibraries_Raspi
|
||||||
|
void ScStwSoundPlayer::_initializeSondEffect() {
|
||||||
|
this->_audioOutputDevice = nullptr;
|
||||||
|
for(QAudioDeviceInfo info : QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)) {
|
||||||
|
qDebug() << info.deviceName();
|
||||||
|
if(info.deviceName().contains("Headphones"))
|
||||||
|
this->_audioOutputDevice = new QAudioDeviceInfo(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this->_audioOutputDevice == nullptr)
|
||||||
|
this->_audioOutputDevice = new QAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice());
|
||||||
|
|
||||||
|
this->soundEffect = new QSoundEffect(*this->_audioOutputDevice, this);
|
||||||
|
this->soundEffect->setLoopCount(1);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void ScStwSoundPlayer::_initializeSondEffect() {
|
||||||
|
this->_audioOutputDevice = new QAudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice());
|
||||||
|
this->soundEffect = new QSoundEffect(*this->_audioOutputDevice, this);
|
||||||
|
this->soundEffect->setLoopCount(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ScStwLibraries_Raspi
|
||||||
|
bool ScStwSoundPlayer::_setSoundVolume(double volume) {
|
||||||
|
|
||||||
|
QString cardName = this->_audioOutputDevice->deviceName();
|
||||||
|
QStringRef shortCardName = cardName.midRef(cardName.indexOf(QLatin1String("="), 0) + 1);
|
||||||
|
|
||||||
|
int cardIndex = snd_card_get_index(shortCardName.toLocal8Bit().constData());
|
||||||
|
QString soundDevice = QString(QLatin1String("hw:%1")).arg(cardIndex);
|
||||||
|
qDebug() << "[INFO][SoundPlayer] Using audio device: " << soundDevice;
|
||||||
|
|
||||||
|
long min, max;
|
||||||
|
snd_mixer_t *handle;
|
||||||
|
snd_mixer_selem_id_t *sid;
|
||||||
|
snd_mixer_elem_t *elem;
|
||||||
|
|
||||||
|
if(snd_mixer_open(&handle, 0) < 0) {
|
||||||
|
qDebug() << "[ERROR][SoundPlayer] Could not open mixer";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(snd_mixer_selem_register(handle, NULL, NULL) < 0) {
|
||||||
|
qDebug() << "[ERROR][SoundPlayer] Could not register selem";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(snd_mixer_attach(handle, soundDevice.toStdString().c_str()) < 0) {
|
||||||
|
qDebug() << "[ERROR][SoundPlayer] Could not attach mixer";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(snd_mixer_load(handle) < 0) {
|
||||||
|
qDebug() << "[ERROR][SoundPlayer] Could not load mixer";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set volume for all channels
|
||||||
|
snd_mixer_selem_id_alloca(&sid);
|
||||||
|
bool success = false;
|
||||||
|
for (elem = snd_mixer_first_elem(handle); elem; elem = snd_mixer_elem_next(elem)) {
|
||||||
|
snd_mixer_selem_get_id(elem, sid);
|
||||||
|
if (!snd_mixer_selem_is_active(elem))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
elem = snd_mixer_find_selem(handle, sid);
|
||||||
|
if(!elem)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
|
||||||
|
snd_mixer_selem_set_playback_volume_all(elem, min + (volume) * (max - min));
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_mixer_close(handle);
|
||||||
|
|
||||||
|
this->soundEffect->setVolume(1);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
bool ScStwSoundPlayer::_setSoundVolume(double volume) {
|
||||||
|
this->soundEffect->setVolume(volume);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
Reference in a new issue