-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use PlaySound on Windows for notification sounds
Because on at least one Windows 7 system the Qt implementation causes a crash, which is not acceptable for the application making a bloop noise. The implentation is now split between Qt5, Qt6 and Windows, where the latter uses PlaySound from Winmm. The function is loaded dynamically, in case there's systems without that DLL or something, in which case we just don't play back any sound. Since the function doesn't support setting a volume, we load the WAV file into memory and manipulate its samples to change their volume, which is a bit silly, but works.
- Loading branch information
1 parent
23b52d5
commit 6f46b7f
Showing
16 changed files
with
429 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: GPL-3.0-or-later | ||
#ifndef DESKTOP_UTILS_SOUNDPLAYER_H | ||
#define DESKTOP_UTILS_SOUNDPLAYER_H | ||
#include "libshared/util/qtcompat.h" | ||
#include <QString> | ||
|
||
// Wrapper around different sound playing implementations. Qt5 and Qt6 work | ||
// differently here, so they have separate implementations. On Windows, we use a | ||
// custom implementation that uses PlaySound directly, since Qt's implementation | ||
// is known to crash on at least one Windows 7 system, so this is safer. | ||
class SoundPlayer final { | ||
COMPAT_DISABLE_COPY_MOVE(SoundPlayer) | ||
public: | ||
SoundPlayer(); | ||
~SoundPlayer(); | ||
|
||
void playSound(const QString &path, int volume); | ||
bool isPlaying() const; | ||
|
||
private: | ||
struct Private; | ||
Private *d; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// SPDX-License-Identifier: GPL-3.0-or-later | ||
#include "desktop/utils/soundplayer.h" | ||
#include <QAudioOutput> | ||
#include <QMediaContent> | ||
#include <QMediaPlayer> | ||
#include <QUrl> | ||
|
||
struct SoundPlayer::Private { | ||
QMediaPlayer *player = nullptr; | ||
}; | ||
|
||
SoundPlayer::SoundPlayer() | ||
: d(new Private) | ||
{ | ||
} | ||
|
||
SoundPlayer::~SoundPlayer() | ||
{ | ||
delete d->player; | ||
delete d; | ||
} | ||
|
||
void SoundPlayer::playSound(const QString &path, int volume) | ||
{ | ||
if(!path.isEmpty()) { | ||
QMediaContent media(QUrl::fromLocalFile(path)); | ||
if(!media.isNull()) { | ||
if(!d->player) { | ||
d->player = new QMediaPlayer; | ||
} | ||
d->player->stop(); | ||
d->player->setMedia(media); | ||
d->player->setVolume(volume); | ||
d->player->setPosition(0); | ||
d->player->play(); | ||
} | ||
} | ||
} | ||
|
||
bool SoundPlayer::isPlaying() const | ||
{ | ||
return d->player && d->player->state() == QMediaPlayer::PlayingState; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// SPDX-License-Identifier: GPL-3.0-or-later | ||
#include "desktop/utils/soundplayer.h" | ||
#include <QAudioOutput> | ||
#include <QMediaPlayer> | ||
#include <QUrl> | ||
|
||
struct SoundPlayer::Private { | ||
QMediaPlayer *player = nullptr; | ||
QAudioOutput *output = nullptr; | ||
}; | ||
|
||
SoundPlayer::SoundPlayer() | ||
: d(new Private) | ||
{ | ||
} | ||
|
||
SoundPlayer::~SoundPlayer() | ||
{ | ||
delete d->output; | ||
delete d->player; | ||
delete d; | ||
} | ||
|
||
void SoundPlayer::playSound(const QString &path, int volume) | ||
{ | ||
if(!path.isEmpty()) { | ||
QUrl url = QUrl::fromLocalFile(path); | ||
if(url.isValid()) { | ||
if(!d->player) { | ||
d->player = new QMediaPlayer; | ||
d->output = new QAudioOutput(d->player); | ||
d->player->setAudioOutput(d->output); | ||
} | ||
d->player->stop(); | ||
d->player->setSource(url); | ||
d->output->setVolume(qreal(volume) / 100.0); | ||
d->player->setPosition(0); | ||
d->player->play(); | ||
} | ||
} | ||
} | ||
|
||
bool SoundPlayer::isPlaying() const | ||
{ | ||
return d->player && | ||
d->player->playbackState() == QMediaPlayer::PlayingState; | ||
} |
Oops, something went wrong.