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
|
||||
}
|
||||
|
||||
ScStwLibraries_Raspi {
|
||||
LIBS += -lasound
|
||||
DEFINES += ScStwLibraries_Raspi
|
||||
}
|
||||
|
||||
INCLUDEPATH += $$PWD/headers $$PWD
|
||||
|
||||
SOURCES += \
|
||||
|
|
|
@ -27,9 +27,10 @@
|
|||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
#include <QSoundEffect>
|
||||
#include <QAudioDeviceInfo>
|
||||
|
||||
#ifdef RASPI
|
||||
#include <QProcess>
|
||||
#ifdef ScStwLibraries_Raspi
|
||||
#include <alsa/asoundlib.h>
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
@ -60,6 +61,11 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
|
||||
bool _setSoundVolume(double volume);
|
||||
|
||||
void _initializeSondEffect();
|
||||
|
||||
/*!
|
||||
* \brief A map containing all sound files
|
||||
* 0: AtYourMarksSound
|
||||
|
@ -74,6 +80,8 @@ private:
|
|||
*/
|
||||
QSoundEffect *soundEffect;
|
||||
|
||||
QAudioDeviceInfo *_audioOutputDevice;
|
||||
|
||||
/*!
|
||||
* \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(FalseStart, {{"path","qrc:/sound/FalseStartSound.wav"}, {"duration", 2000}});
|
||||
|
||||
this->soundEffect = new QSoundEffect(this);
|
||||
this->soundEffect->setLoopCount(1);
|
||||
this->_initializeSondEffect();
|
||||
|
||||
connect(this, &ScStwSoundPlayer::playbackStarted, 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
|
||||
this->currentlyPlayingSound = sound;
|
||||
|
||||
#ifdef RASPI
|
||||
// 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";
|
||||
if(!this->_setSoundVolume(volume))
|
||||
return Error;
|
||||
}
|
||||
|
||||
this->soundEffect->setVolume(1);
|
||||
#else
|
||||
this->soundEffect->setVolume(volume);
|
||||
#endif
|
||||
|
||||
// load
|
||||
this->soundEffect->setSource(this->soundFiles[sound]["path"].toString());
|
||||
|
@ -145,3 +124,89 @@ ScStwSoundPlayer::PlayResult ScStwSoundPlayer::waitForSoundFinish(double *timeOf
|
|||
bool ScStwSoundPlayer::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