Skip to content

Commit

Permalink
Accessibility: Add audio alerts for join/leave/chat
Browse files Browse the repository at this point in the history
Plays sound when someone joins/leaves.
Plays sound when receiving a new message.

Uses QtMultimedia for playback.

Sounds are from Freesound (licensed CC0):
- new_message.wav from https://freesound.org/people/zrrion_the_insect/sounds/469014/
- new_user.wav from https://freesound.org/people/deleted_user_4772965/sounds/256513/

Co-authored-by: henkdegroot <[email protected]>
Co-authored-by: Christian Hoffmann <[email protected]>
Co-authored-by: Peter L Jones <[email protected]>
  • Loading branch information
4 people committed Jul 2, 2022
1 parent 1c7b0a3 commit feea2bf
Show file tree
Hide file tree
Showing 21 changed files with 134 additions and 25 deletions.
14 changes: 13 additions & 1 deletion .github/autobuild/android.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,20 @@ setup_qt() {
else
echo "Installing Qt..."
python3 -m pip install "aqtinstall==${AQTINSTALL_VERSION}"
local qtmultimedia=()
if [[ ! "${QT_VERSION}" =~ 5\..* ]]; then
# From Qt6 onwards, qtmultimedia is a module and cannot be installed
# as an archive anymore.
qtmultimedia=("--modules")
fi
qtmultimedia+=("qtmultimedia")

python3 -m aqt install-qt --outputdir "${QT_BASEDIR}" linux android "${QT_VERSION}" \
--archives qtbase qttools qttranslations qtandroidextras
--archives qtbase qttools qttranslations qtandroidextras \
"${qtmultimedia[@]}"
# Delete libraries, which we don't use, but which bloat the resulting package and might introduce unwanted dependencies.
find "${QT_BASEDIR}" -name 'libQt5*Quick*.so' -delete
rm -r "${QT_BASEDIR}/${QT_VERSION}/android/qml/"
fi
}

Expand Down
9 changes: 8 additions & 1 deletion .github/autobuild/ios.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ setup() {
echo "Installing Qt"
python3 -m pip install "aqtinstall==${AQTINSTALL_VERSION}"
# Install actual ios Qt:
python3 -m aqt install-qt --outputdir "${QT_DIR}" mac ios "${QT_VERSION}" --archives qtbase qttools qttranslations
local qtmultimedia=()
if [[ ! "${QT_VERSION}" =~ 5\..* ]]; then
# From Qt6 onwards, qtmultimedia is a module and cannot be installed
# as an archive anymore.
qtmultimedia=("--modules")
fi
qtmultimedia+=("qtmultimedia")
python3 -m aqt install-qt --outputdir "${QT_DIR}" mac ios "${QT_VERSION}" --archives qtbase qttools qttranslations "${qtmultimedia[@]}"
if [[ ! "${QT_VERSION}" =~ 5\..* ]]; then
# Starting with Qt6, ios' qtbase install does no longer include a real qmake binary.
# Instead, it is a script which invokes the mac desktop qmake.
Expand Down
4 changes: 2 additions & 2 deletions .github/autobuild/linux_deb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ setup() {

echo "Installing dependencies..."
sudo apt-get -qq update
sudo apt-get -qq --no-install-recommends -y install devscripts build-essential debhelper fakeroot libjack-jackd2-dev qtbase5-dev qttools5-dev-tools
sudo apt-get -qq --no-install-recommends -y install devscripts build-essential debhelper fakeroot libjack-jackd2-dev qtbase5-dev qttools5-dev-tools qtmultimedia5-dev

setup_cross_compiler
}
Expand All @@ -46,7 +46,7 @@ setup_cross_compiler() {
return
fi
local GCC_VERSION=7 # 7 is the default on 18.04, there is no reason not to update once 18.04 is out of support
sudo apt install -qq -y --no-install-recommends "g++-${GCC_VERSION}-${ABI_NAME}" "qt5-qmake:${TARGET_ARCH}" "qtbase5-dev:${TARGET_ARCH}" "libjack-jackd2-dev:${TARGET_ARCH}"
sudo apt install -qq -y --no-install-recommends "g++-${GCC_VERSION}-${ABI_NAME}" "qt5-qmake:${TARGET_ARCH}" "qtbase5-dev:${TARGET_ARCH}" "libjack-jackd2-dev:${TARGET_ARCH}" "qtmultimedia5-dev:${TARGET_ARCH}"
sudo update-alternatives --install "/usr/bin/${ABI_NAME}-g++" g++ "/usr/bin/${ABI_NAME}-g++-${GCC_VERSION}" 10
sudo update-alternatives --install "/usr/bin/${ABI_NAME}-gcc" gcc "/usr/bin/${ABI_NAME}-gcc-${GCC_VERSION}" 10

Expand Down
9 changes: 8 additions & 1 deletion .github/autobuild/mac.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ setup() {
else
echo "Installing Qt..."
python3 -m pip install "aqtinstall==${AQTINSTALL_VERSION}"
python3 -m aqt install-qt --outputdir "${QT_DIR}" mac desktop "${QT_VERSION}" --archives qtbase qttools qttranslations
local qtmultimedia=()
if [[ ! "${QT_VERSION}" =~ 5\..* ]]; then
# From Qt6 onwards, qtmultimedia is a module and cannot be installed
# as an archive anymore.
qtmultimedia=("--modules")
fi
qtmultimedia+=("qtmultimedia")
python3 -m aqt install-qt --outputdir "${QT_DIR}" mac desktop "${QT_VERSION}" --archives qtbase qttools qttranslations "${qtmultimedia[@]}"
fi
}

Expand Down
7 changes: 7 additions & 0 deletions .github/autobuild/windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ Function Install-Qt
"$QtArch",
"--archives", "qtbase", "qttools", "qttranslations"
)
if ( $QtVersion -notmatch '^5\.' )
{
# From Qt6 onwards, qtmultimedia is a module and cannot be installed
# as an archive anymore.
$Args += ("--modules")
}
$Args += ("qtmultimedia")
aqt install-qt @Args
if ( !$? )
{
Expand Down
3 changes: 2 additions & 1 deletion COMPILING.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Then run `git clone [email protected]:jamulussoftware/jamulus` in Terminal to get t

### Install dependencies

On Debian 11+ you can install the dependencies by issuing the following command: `sudo apt-get -qq --no-install-recommends -y install devscripts build-essential debhelper fakeroot libjack-jackd2-dev qtbase5-dev qttools5-dev-tools`
On Debian 11+ you can install the dependencies by issuing the following command: `sudo apt-get -qq --no-install-recommends -y install devscripts build-essential debhelper fakeroot libjack-jackd2-dev qtbase5-dev qttools5-dev-tools qtmultimedia5-dev`

**Note:** The exact dependencies might be different for older distributions. See [this comment by softins](https://github.com/jamulussoftware/jamulus/pull/2267#issuecomment-1022127426)

Expand All @@ -34,6 +34,7 @@ On Debian 11+ you can install the dependencies by issuing the following command:
- qt5-qtbase
- jack-audio-connection-kit-devel
- qt5-linguist
- qt5-qtmultimedia

### For all desktop distributions

Expand Down
1 change: 1 addition & 0 deletions Jamulus.pro
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ contains(CONFIG, "headless") {
QT -= gui
} else {
QT += widgets
QT += multimedia
}

LRELEASE_DIR = src/translation
Expand Down
1 change: 0 additions & 1 deletion android/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
Remove the comment if you do not require these default features. -->
<!-- %%INSERT_FEATURES -->
<uses-feature android:name="android.hardware.microphone" android:required="true"/>
<uses-feature android:name="android.hardware.audio.output" android:required="true"/>

<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
Expand Down
1 change: 1 addition & 0 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ CClient::CClient ( const quint16 iPortNumber,
bFraSiFactSafeSupported ( false ),
eGUIDesign ( GD_ORIGINAL ),
eMeterStyle ( MT_LED_STRIPE ),
bEnableAudioAlerts ( false ),
bEnableOPUS64 ( false ),
bJitterBufferOK ( true ),
bEnableIPv6 ( bNEnableIPv6 ),
Expand Down
1 change: 1 addition & 0 deletions src/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ class CClient : public QObject

EGUIDesign eGUIDesign;
EMeterStyle eMeterStyle;
bool bEnableAudioAlerts;
bool bEnableOPUS64;

bool bJitterBufferOK;
Expand Down
20 changes: 20 additions & 0 deletions src/clientdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
// set window title (with no clients connected -> "0")
SetMyWindowTitle ( 0 );

// track number of clients to detect joins/leaves for audio alerts
iClients = 0;

// prepare Mute Myself info label (invisible by default)
lblGlobalInfoLabel->setStyleSheet ( ".QLabel { background: red; }" );
lblGlobalInfoLabel->hide();
Expand Down Expand Up @@ -822,6 +825,12 @@ void CClientDlg::OnCLVersionAndOSReceived ( CHostAddress, COSUtil::EOpSystemType

void CClientDlg::OnChatTextReceived ( QString strChatText )
{
if ( pSettings->bEnableAudioAlerts )
{
QSoundEffect* sf = new QSoundEffect();
sf->setSource ( QUrl::fromLocalFile ( ":sounds/res/sounds/new_message.wav" ) );
sf->play();
}
ChatDlg.AddChatText ( strChatText );

// Open chat dialog. If a server welcome message is received, we force
Expand Down Expand Up @@ -876,6 +885,17 @@ void CClientDlg::OnConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo

void CClientDlg::OnNumClientsChanged ( int iNewNumClients )
{
if ( pSettings->bEnableAudioAlerts && iNewNumClients > iClients )
{
QSoundEffect* sf = new QSoundEffect();
sf->setSource ( QUrl::fromLocalFile ( ":sounds/res/sounds/new_user.wav" ) );
sf->play();
}

// iNewNumClients will be zero on the first trigger of this signal handler when connecting to a new server.
// Subsequent triggers will thus sound the alert (if enabled).
iClients = iNewNumClients;

// update window title
SetMyWindowTitle ( iNewNumClients );
}
Expand Down
2 changes: 2 additions & 0 deletions src/clientdlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <QMessageBox>
#include <QFileDialog>
#include <QActionGroup>
#include <QSoundEffect>
#if QT_VERSION >= QT_VERSION_CHECK( 5, 6, 0 )
# include <QVersionNumber>
#endif
Expand Down Expand Up @@ -101,6 +102,7 @@ class CClientDlg : public CBaseDlg, private Ui_CClientDlgBase
CClient* pClient;
CClientSettings* pSettings;

int iClients;
bool bConnected;
bool bConnectDlgWasShown;
bool bMIDICtrlUsed;
Expand Down
15 changes: 15 additions & 0 deletions src/clientsettingsdlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,14 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, CClientSettings* pNSet
chbDetectFeedback->setWhatsThis ( strDetectFeedback );
chbDetectFeedback->setAccessibleName ( tr ( "Feedback Protection check box" ) );

// audio alerts
QString strAudioAlerts = "<b>" + tr ( "Audio Alerts" ) + ":</b> " +
tr ( "Enable audio alert when receiving a chat message and when a new client joins the session. "
"A second sound device may be required to hear the alerts." );
lblAudioAlerts->setWhatsThis ( strAudioAlerts );
chbAudioAlerts->setWhatsThis ( strAudioAlerts );
chbAudioAlerts->setAccessibleName ( tr ( "Audio Alerts check box" ) );

// init driver button
#if defined( _WIN32 ) && !defined( WITH_JACK )
butDriverSetup->setText ( tr ( "ASIO Device Settings" ) );
Expand Down Expand Up @@ -470,6 +478,9 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, CClientSettings* pNSet
// init number of mixer rows
spnMixerRows->setValue ( pSettings->iNumMixerPanelRows );

// init audio alerts
chbAudioAlerts->setCheckState ( pSettings->bEnableAudioAlerts ? Qt::Checked : Qt::Unchecked );

// update feedback detection
chbDetectFeedback->setCheckState ( pSettings->bEnableFeedbackDetection ? Qt::Checked : Qt::Unchecked );

Expand Down Expand Up @@ -633,6 +644,8 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, CClientSettings* pNSet

QObject::connect ( chbDetectFeedback, &QCheckBox::stateChanged, this, &CClientSettingsDlg::OnFeedbackDetectionChanged );

QObject::connect ( chbAudioAlerts, &QCheckBox::stateChanged, this, &CClientSettingsDlg::OnAudioAlertsChanged );

// line edits
QObject::connect ( edtNewClientLevel, &QLineEdit::editingFinished, this, &CClientSettingsDlg::OnNewClientLevelEditingFinished );

Expand Down Expand Up @@ -984,6 +997,8 @@ void CClientSettingsDlg::OnMeterStyleActivated ( int iMeterStyleIdx )
UpdateDisplay();
}

void CClientSettingsDlg::OnAudioAlertsChanged ( int value ) { pSettings->bEnableAudioAlerts = value == Qt::Checked; }

void CClientSettingsDlg::OnAutoJitBufStateChanged ( int value )
{
pClient->SetDoAutoSockBufSize ( value == Qt::Checked );
Expand Down
2 changes: 2 additions & 0 deletions src/clientsettingsdlg.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public slots:
void OnAudioQualityActivated ( int iQualityIdx );
void OnGUIDesignActivated ( int iDesignIdx );
void OnMeterStyleActivated ( int iMeterStyleIdx );
void OnAudioAlertsChanged ( int value );
void OnLanguageChanged ( QString strLanguage ) { pSettings->strLanguage = strLanguage; }
void OnAliasTextChanged ( const QString& strNewName );
void OnInstrumentActivated ( int iCntryListItem );
Expand All @@ -114,6 +115,7 @@ public slots:
signals:
void GUIDesignChanged();
void MeterStyleChanged();
void AudioAlertsChanged();
void AudioChannelsChanged();
void CustomDirectoriesChanged();
void NumMixerPanelRowsChanged ( int value );
Expand Down
15 changes: 15 additions & 0 deletions src/clientsettingsdlgbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,13 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblAudioAlerts">
<property name="text">
<string>Audio Alerts</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
Expand Down Expand Up @@ -281,6 +288,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chbAudioAlerts">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
Expand Down Expand Up @@ -1283,6 +1297,7 @@
<tabstop>cbxMeterStyle</tabstop>
<tabstop>cbxLanguage</tabstop>
<tabstop>spnMixerRows</tabstop>
<tabstop>chbAudioAlerts</tabstop>
<tabstop>cbxSoundcard</tabstop>
<tabstop>butDriverSetup</tabstop>
<tabstop>cbxLInChan</tabstop>
Expand Down
Binary file added src/res/sounds/new_message.wav
Binary file not shown.
Binary file added src/res/sounds/new_user.wav
Binary file not shown.
4 changes: 4 additions & 0 deletions src/resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,8 @@
<file>res/flags/zm.png</file>
<file>res/flags/zw.png</file>
</qresource>
<qresource prefix="/sounds">
<file>res/sounds/new_user.wav</file>
<file>res/sounds/new_message.wav</file>
</qresource>
</RCC>
9 changes: 9 additions & 0 deletions src/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,12 @@ void CClientSettings::ReadSettingsFromXML ( const QDomDocument& IniXMLDocument,
iNumMixerPanelRows = iValue;
}

// audio alerts
if ( GetFlagIniSet ( IniXMLDocument, "client", "enableaudioalerts", bValue ) )
{
bEnableAudioAlerts = bValue;
}

// name
pClient->ChannelInfo.strName = FromBase64ToString (
GetIniSetting ( IniXMLDocument, "client", "name_base64", ToBase64 ( QCoreApplication::translate ( "CMusProfDlg", "No Name" ) ) ) );
Expand Down Expand Up @@ -634,6 +640,9 @@ void CClientSettings::WriteSettingsToXML ( QDomDocument& IniXMLDocument )
// number of mixer panel rows
SetNumericIniSet ( IniXMLDocument, "client", "numrowsmixpan", iNumMixerPanelRows );

// audio alerts
SetFlagIniSet ( IniXMLDocument, "client", "enableaudioalerts", bEnableAudioAlerts );

// name
PutIniSetting ( IniXMLDocument, "client", "name_base64", ToBase64 ( pClient->ChannelInfo.strName ) );

Expand Down
2 changes: 2 additions & 0 deletions src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ class CClientSettings : public CSettings
vstrDirectoryAddress ( MAX_NUM_SERVER_ADDR_ITEMS, "" ),
eDirectoryType ( AT_DEFAULT ),
bEnableFeedbackDetection ( true ),
bEnableAudioAlerts ( false ),
vecWindowPosSettings(), // empty array
vecWindowPosChat(), // empty array
vecWindowPosConnect(), // empty array
Expand Down Expand Up @@ -163,6 +164,7 @@ class CClientSettings : public CSettings
EDirectoryType eDirectoryType;
int iCustomDirectoryIndex; // index of selected custom directory server
bool bEnableFeedbackDetection;
bool bEnableAudioAlerts;

// window position/state settings
QByteArray vecWindowPosSettings;
Expand Down
40 changes: 22 additions & 18 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,26 +593,27 @@ CAboutDlg::CAboutDlg ( QWidget* parent ) : CBaseDlg ( parent )
"</font></p>" );

// libraries used by this compilation
txvLibraries->setText ( tr ( "This app uses the following libraries, resources or code snippets:" ) + "<br><p>" +
tr ( "Qt cross-platform application framework" ) +
", <i><a href=\"https://www.qt.io\">https://www.qt.io</a></i></p>"
"<p>Opus Interactive Audio Codec"
", <i><a href=\"https://www.opus-codec.org\">https://www.opus-codec.org</a></i></p>"
txvLibraries->setText (
tr ( "This app uses the following libraries, resources or code snippets:" ) + "<br><p>" + tr ( "Qt cross-platform application framework" ) +
", <i><a href=\"https://www.qt.io\">https://www.qt.io</a></i></p>"
"<p>Opus Interactive Audio Codec"
", <i><a href=\"https://www.opus-codec.org\">https://www.opus-codec.org</a></i></p>"
# if defined( _WIN32 ) && !defined( WITH_JACK )
"<p>ASIO (Audio Stream I/O) SDK"
", <i><a href=\"https://www.steinberg.net/developers/\">https://www.steinberg.net/developers</a></i><br>" +
"ASIO is a trademark and software of Steinberg Media Technologies GmbH</p>"
"<p>ASIO (Audio Stream I/O) SDK"
", <i><a href=\"https://www.steinberg.net/developers/\">https://www.steinberg.net/developers</a></i><br>" +
"ASIO is a trademark and software of Steinberg Media Technologies GmbH</p>"
# endif
"<p>" +
tr ( "Audio reverberation code by Perry R. Cook and Gary P. Scavone" ) +
", 1995 - 2021, <i><a href=\"https://ccrma.stanford.edu/software/stk\">"
"The Synthesis ToolKit in C++ (STK)</a></i></p>"
"<p>" +
tr ( "Some pixmaps are from the" ) +
" Open Clip Art Library (OCAL), "
"<i><a href=\"https://openclipart.org\">https://openclipart.org</a></i></p>"
"<p>" +
tr ( "Flag icons by Mark James" ) + ", <i><a href=\"http://www.famfamfam.com\">http://www.famfamfam.com</a></i></p>" );
"<p>" +
tr ( "Audio reverberation code by Perry R. Cook and Gary P. Scavone" ) +
", 1995 - 2021, <i><a href=\"https://ccrma.stanford.edu/software/stk\">"
"The Synthesis ToolKit in C++ (STK)</a></i></p>"
"<p>" +
tr ( "Some pixmaps are from the" ) +
" Open Clip Art Library (OCAL), "
"<i><a href=\"https://openclipart.org\">https://openclipart.org</a></i></p>"
"<p>" +
tr ( "Flag icons by Mark James" ) + ", <i><a href=\"http://www.famfamfam.com\">http://www.famfamfam.com</a></i></p>" + "<p>" +
tr ( "Some sound samples are from" ) + " Freesound, " + "<i><a href=\"https://freesound.org\">https://freesound.org</a></i></p>" );

// contributors list
txvContributors->setText (
Expand Down Expand Up @@ -1613,6 +1614,9 @@ QString GetVersionAndNameStr ( const bool bDisplayInGui )
strVersionText += "\n *** Flag icons by Mark James";
strVersionText += "\n *** <http://www.famfamfam.com>";
strVersionText += "\n *** ";
strVersionText += "\n *** Some sound samples are from Freesound";
strVersionText += "\n *** <https://freesound.org>";
strVersionText += "\n *** ";
strVersionText += "\n *** Copyright (C) 2005-2022 The Jamulus Development Team";
strVersionText += "\n";
}
Expand Down

0 comments on commit feea2bf

Please sign in to comment.