diff --git a/src/blackcore/context/contextaudioimpl.cpp b/src/blackcore/context/contextaudioimpl.cpp index d6d0a9dff..266aa8b1c 100644 --- a/src/blackcore/context/contextaudioimpl.cpp +++ b/src/blackcore/context/contextaudioimpl.cpp @@ -79,9 +79,6 @@ namespace BlackCore m_audioMixer->makeMixerConnection(IAudioMixer::InputVoiceChannel2, IAudioMixer::OutputOutputDevice1); this->setVoiceOutputVolume(90); - // Load sounds (init), not possible in own thread - QTimer::singleShot(10 * 1000, this, &CContextAudio::initNotificationSounds); - m_unusedVoiceChannels.push_back(m_channel1); m_unusedVoiceChannels.push_back(m_channel2); @@ -452,13 +449,7 @@ namespace BlackCore } } - CSoundGenerator::playNotificationSound(90, notification); - } - - void CContextAudio::initNotificationSounds() - { - // not possible in own thread - CSoundGenerator::playNotificationSound(0, CNotificationSounds::LoadSounds); + m_notificationPlayer.play(notification, 90); } void CContextAudio::enableAudioLoopback(bool enable) diff --git a/src/blackcore/context/contextaudioimpl.h b/src/blackcore/context/contextaudioimpl.h index 1b90fe4b8..2e25143b6 100644 --- a/src/blackcore/context/contextaudioimpl.h +++ b/src/blackcore/context/contextaudioimpl.h @@ -30,6 +30,7 @@ #include "blackmisc/settingscache.h" #include "blackmisc/icons.h" #include "blacksound/selcalplayer.h" +#include "blacksound/notificationplayer.h" #include #include @@ -118,9 +119,6 @@ namespace BlackCore CContextAudio *registerWithDBus(BlackMisc::CDBusServer *server); private: - //! Init notification sounds - void initNotificationSounds(); - //! \copydoc IVoice::connectionStatusChanged //! \sa IContextAudio::changedVoiceRooms void onConnectionStatusChanged(IVoiceChannel::ConnectionStatus oldStatus, IVoiceChannel::ConnectionStatus newStatus); @@ -159,6 +157,7 @@ namespace BlackCore QHash> m_voiceChannelMapping; QHash, IAudioMixer::OutputPort> m_voiceChannelOutputPortMapping; BlackSound::CSelcalPlayer *m_selcalPlayer = nullptr; + BlackSound::CNotificationPlayer m_notificationPlayer; // settings BlackMisc::CSetting m_audioSettings { this }; diff --git a/src/blackmisc/audio/notificationsounds.cpp b/src/blackmisc/audio/notificationsounds.cpp index d03ff4e4f..76e481a2b 100644 --- a/src/blackmisc/audio/notificationsounds.cpp +++ b/src/blackmisc/audio/notificationsounds.cpp @@ -41,7 +41,6 @@ namespace BlackMisc case NotificationVoiceRoomLeft: return left; case NotificationNoAudioTransmission: return noaudiotx; case PTTClickKeyDown: return ptt; - case LoadSounds: return load; default: break; } return unknown; @@ -59,7 +58,6 @@ namespace BlackMisc if (notification.testFlag(NotificationNoAudioTransmission)) n << flagToString(NotificationNoAudioTransmission); if (notification.testFlag(NotificationVoiceRoomJoined)) n << flagToString(NotificationVoiceRoomJoined); if (notification.testFlag(NotificationVoiceRoomLeft)) n << flagToString(NotificationVoiceRoomLeft); - if (notification.testFlag(LoadSounds)) n << flagToString(LoadSounds); return n.join(", "); } } // ns diff --git a/src/blackmisc/audio/notificationsounds.h b/src/blackmisc/audio/notificationsounds.h index 81188cb00..eb25d5272 100644 --- a/src/blackmisc/audio/notificationsounds.h +++ b/src/blackmisc/audio/notificationsounds.h @@ -48,7 +48,6 @@ namespace BlackMisc NotificationNoAudioTransmission = 1 << 8, PTTClickKeyDown = 1 << 9, PTTClickKeyUp = 1 << 10, - LoadSounds = 1 << 11, //!< end marker and force loading of sounds, keep as last element AllTextNotifications = NotificationTextMessagePrivate | NotificationTextCallsignMentioned | NotificationTextMessageSupervisor, AllLoginNotifications = NotificationLogin | NotificationLogoff, AllVoiceRoomNotifications = NotificationVoiceRoomJoined | NotificationVoiceRoomLeft | NotificationNoAudioTransmission, diff --git a/src/blacksound/notificationplayer.cpp b/src/blacksound/notificationplayer.cpp new file mode 100644 index 000000000..01d6b6680 --- /dev/null +++ b/src/blacksound/notificationplayer.cpp @@ -0,0 +1,77 @@ +/* Copyright (C) 2016 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +#include "notificationplayer.h" +#include "blackmisc/directoryutils.h" +#include + +using namespace BlackMisc; +using namespace BlackMisc::Audio; + +namespace BlackSound +{ + + CNotificationPlayer::CNotificationPlayer(QObject *parent) : + QObject(parent) + { + QSoundEffect *effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/error.wav")); + m_effects[CNotificationSounds::NotificationError] = effect; + + effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/login.wav")); + m_effects[CNotificationSounds::NotificationLogin] = effect; + + effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/logoff.wav")); + m_effects[CNotificationSounds::NotificationLogoff] = effect; + + effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/privatemessage.wav")); + m_effects[CNotificationSounds::NotificationTextMessagePrivate] = effect; + + effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/supervisormessage.wav")); + m_effects[CNotificationSounds::NotificationTextMessageSupervisor] = effect; + + effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/callsignmentioned.wav")); + m_effects[CNotificationSounds::NotificationTextCallsignMentioned] = effect; + + effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/voiceroomjoined.wav")); + m_effects[CNotificationSounds::NotificationVoiceRoomJoined] = effect; + + effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/voiceroomleft.wav")); + m_effects[CNotificationSounds::NotificationVoiceRoomLeft] = effect; + + effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/noaudiotransmission.wav")); + m_effects[CNotificationSounds::NotificationNoAudioTransmission] = effect; + + effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/pttclick.wav")); + m_effects[CNotificationSounds::PTTClickKeyDown] = effect; + + effect = new QSoundEffect(this); + effect->setSource(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/pttclick.wav")); + m_effects[CNotificationSounds::PTTClickKeyUp] = effect; + } + + void CNotificationPlayer::play(Audio::CNotificationSounds::NotificationFlag notification, int volume) const + { + QSoundEffect *effect = m_effects.value(notification, nullptr); + if (effect) + { + effect->setVolume(volume / 100.0); + effect->play(); + } + } + +} diff --git a/src/blacksound/notificationplayer.h b/src/blacksound/notificationplayer.h new file mode 100644 index 000000000..c418a781b --- /dev/null +++ b/src/blacksound/notificationplayer.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2019 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKSOUND_NOTIFICATIONPLAYER_H +#define BLACKSOUND_NOTIFICATIONPLAYER_H + +#include "blacksoundexport.h" +#include "blackmisc/audio/notificationsounds.h" + +#include +#include +#include + +class QTimer; + +namespace BlackSound +{ + //! Player for notification sounds + class BLACKSOUND_EXPORT CNotificationPlayer : public QObject + { + Q_OBJECT + + public: + //! Constructor + CNotificationPlayer(QObject *parent = nullptr); + + //! Destructor + virtual ~CNotificationPlayer() override {} + + //! Play notification sound + void play(BlackMisc::Audio::CNotificationSounds::NotificationFlag notification, int volume = 100) const; + + private: + QHash m_effects; + }; +} + +#endif // guard diff --git a/src/blacksound/soundgenerator.cpp b/src/blacksound/soundgenerator.cpp index a3282f09b..da6a728a7 100644 --- a/src/blacksound/soundgenerator.cpp +++ b/src/blacksound/soundgenerator.cpp @@ -16,12 +16,9 @@ #include #include #include -#include -#include #include -#include #include -#include +#include using namespace BlackMisc; using namespace BlackMisc::Aviation; @@ -445,7 +442,6 @@ namespace BlackSound tones << t1 << t2 << t3; } CSoundGenerator::playSignalInBackground(volume, tones, device); - // CSoundGenerator::playSignalRecorded(volume, tones, device); } void CSoundGenerator::playSelcal(int volume, const CSelcal &selcal, const CAudioDeviceInfo &audioDevice) @@ -455,50 +451,11 @@ namespace BlackSound CSoundGenerator::playSelcal(volume, selcal, CSoundGenerator::findClosestOutputDevice(audioDevice)); } - void CSoundGenerator::playNotificationSound(int volume, CNotificationSounds::NotificationFlag notification) - { - QMediaPlayer *mediaPlayer = CSoundGenerator::mediaPlayer(); - if (mediaPlayer->state() == QMediaPlayer::PlayingState) return; - QMediaPlaylist *playlist = mediaPlayer->playlist(); - if (!playlist || playlist->isEmpty()) - { - // order here is crucial, needs to be the same as in CSoundGenerator::Notification - if (!playlist) playlist = new QMediaPlaylist(mediaPlayer); - bool success = true; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/error.wav")) && success; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/login.wav")) && success; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/logoff.wav")) && success; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/privatemessage.wav")) && success; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/supervisormessage.wav")) && success; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/callsignmentioned.wav")) && success; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/voiceroomjoined.wav")) && success; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/voiceroomleft.wav")) && success; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/noaudiotransmission.wav")) && success; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/pttclick.wav")) && success; - success = playlist->addMedia(QUrl::fromLocalFile(CDirectoryUtils::soundFilesDirectory() + "/pttclick.wav")) && success; - - Q_ASSERT(success); - playlist->setPlaybackMode(QMediaPlaylist::CurrentItemOnce); - mediaPlayer->setPlaylist(playlist); - } - if (notification == CNotificationSounds::LoadSounds) { return; } - if (notification == CNotificationSounds::NoNotifications) { return; } - - const int index = qRound(std::log2(static_cast(notification))); - playlist->setCurrentIndex(index); - mediaPlayer->setVolume(volume); // 0-100 - mediaPlayer->play(); - } - void CSoundGenerator::playFile(int volume, const QString &file, bool removeFileAfterPlaying) { if (!QFile::exists(file)) { return; } - QMediaPlayer *mediaPlayer = CSoundGenerator::mediaPlayer(); - QUrl url(file); - QMediaContent media(url); - mediaPlayer->setMedia(media); - mediaPlayer->setVolume(volume); // 0-100 - mediaPlayer->play(); + Q_UNUSED(volume); + QSound::play(file); // I cannot delete the file here, only after it has been played if (removeFileAfterPlaying) { new CTimedFileDeleter(file, 1000 * 60, QCoreApplication::instance()); } } diff --git a/src/blacksound/soundgenerator.h b/src/blacksound/soundgenerator.h index d6b0f5043..d8a783763 100644 --- a/src/blacksound/soundgenerator.h +++ b/src/blacksound/soundgenerator.h @@ -158,11 +158,6 @@ namespace BlackSound //! \param removeFileAfterPlaying delete the file, after it has been played static void playFile(int volume, const QString &file, bool removeFileAfterPlaying); - //! Play notification - //! \param volume 0-100 - //! \param notification - static void playNotificationSound(int volume, BlackMisc::Audio::CNotificationSounds::NotificationFlag notification); - //! For debugging purposes static void printAllQtSoundDevices(QTextStream &qtout); @@ -243,13 +238,6 @@ namespace BlackSound DataHeader data; }; - //! "My" media player - static QMediaPlayer *mediaPlayer() - { - static QMediaPlayer *mediaPlayer = new QMediaPlayer(); - return mediaPlayer; - } - //! Duration of these tones static qint64 calculateDurationMs(const QList &tones);