Merge branch 'master' into master

This commit is contained in:
Volker Fischer 2020-05-24 08:27:48 +02:00 committed by GitHub
commit ccf005bde0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 1956 additions and 1391 deletions

View File

@ -4,31 +4,19 @@
3.5.4git 3.5.4git
- introduce genre-based server lists (Ticket #139) - introduce genre-based server lists (#139)
- implement panning for channels, coded by tarmoj (Ticket #52, #145) - implement panning for channels, coded by tarmoj (#52, #145)
- duplicate Central Server type dropdown to Connection Setup (#157) - added an indicator that another client has muted me (#257)
- added vocal bass/tenor/alto/soprano instrument icons created by Alberstein8 (Ticket #131) - move central server type dropdown to connection setup (#157)
- support intermediate Reaper RPP file while recording, coded by pljones (Ticket #170) - added vocal bass/tenor/alto/soprano instrument icons created by Alberstein8 (#131)
- support intermediate Reaper RPP file while recording, coded by pljones (#170)
TODO fix problem with panning and GUI (vertical scroll bar issue in mixer board) - save client settings on Linux cmdline termination signal, coded by pljones (#70)
TODO Keep lrelease? Does it work as expected?
TODO fix Linux deploy script -> gives errors right now
TODO Central Server Address: "Default" results in empty server browser, "Default (North America)" works fine #156
-> made max list smaller from 200 to 150 -> check if that is sufficient to prevent UDP packet fragmentation
TODO WIP support internationalization
TODO show mute state of others
TODO fix incorrect what's this help texts
@ -43,23 +31,23 @@ TODO fix incorrect what's this help texts
- for CoreAudio and 4 channel input, support mixing channels 1&2 with 3&4 - for CoreAudio and 4 channel input, support mixing channels 1&2 with 3&4
- added bassoon/oboe/harp instrument icons created by dszgit, - added bassoon/oboe/harp instrument icons created by dszgit,
congas/bongo created by bspeer (Ticket #131) congas/bongo created by bspeer (#131)
- link to docs from application Help menu (Ticket #90) - link to docs from application Help menu (#90)
- support Mac CoreAudio aggregated devices (Ticket #138) - support Mac CoreAudio aggregated devices (#138)
- added translations: French by trebmuh, Portuguese by Snayler, - added translations: French by trebmuh, Portuguese by Snayler,
Spanish by ignotus666, Dutch by jerogee, German by corrados (Ticket #77) Spanish by ignotus666, Dutch by jerogee, German by corrados (#77)
- new design for the About dialog (Ticket #189) - new design for the About dialog (#189)
- new command line option -d to disconnect all clients on shutdown of the server (Ticket #161) - new command line option -d to disconnect all clients on shutdown of the server (#161)
- bug fix: for mono capture jack audio interface Jamulus complains it - bug fix: for mono capture jack audio interface Jamulus complains it
cannot make connections (Ticket #137) cannot make connections (#137)
- bug fix: fixed that Jamulus segfaults when jackd is restarted (Ticket #122, #127) - bug fix: fixed that Jamulus segfaults when jackd is restarted (#122, #127)
- bug fix: better handling of disconnect message in the client - bug fix: better handling of disconnect message in the client
@ -74,21 +62,21 @@ TODO fix incorrect what's this help texts
- improved Mac installer, coded by doloopuntil - improved Mac installer, coded by doloopuntil
- support to open ASIO driver setup(s) if startup failed due to incorrect driver settings (Ticket #117) - support to open ASIO driver setup(s) if startup failed due to incorrect driver settings (#117)
- added -v/--version command line argument to output version information (Ticket #121) - added -v/--version command line argument to output version information (#121)
- added bodhran and other instrument icons, bodhran created by bomm (Ticket #131) - added bodhran and other instrument icons, bodhran created by bomm (#131)
- bug fix: if small network buffers are used we get much better audio quality when drop outs occur - bug fix: if small network buffers are used we get much better audio quality when drop outs occur
- bug fix: if names given with the -o option were too long, the server registration failed (Ticket #91) - bug fix: if names given with the -o option were too long, the server registration failed (#91)
- bug fix: audio level changes if Buffer Delay is changed (Ticket #106) - bug fix: audio level changes if Buffer Delay is changed (#106)
- bug fix: do not reset fader level meters if number of clients change - bug fix: do not reset fader level meters if number of clients change
- bug fix: fixed a crash with JackRouter 64 bit ASIO driver (Ticket #93, thanks to elliotclee) - bug fix: fixed a crash with JackRouter 64 bit ASIO driver (#93, thanks to elliotclee)
3.5.1 (2020-04-18) 3.5.1 (2020-04-18)
@ -120,21 +108,21 @@ TODO fix incorrect what's this help texts
- the unit of the mixer faders is now dB using the range -50 dB to 0 dB - the unit of the mixer faders is now dB using the range -50 dB to 0 dB
- increased LED luminance (Ticket #71) - increased LED luminance (#71)
- bug fix: the server welcome message may appear twice if the server list was double clicked - bug fix: the server welcome message may appear twice if the server list was double clicked
3.4.7 (2020-04-11) 3.4.7 (2020-04-11)
- added support for alternative Central Servers to solve the 200 server registration limit (Ticket #50) - added support for alternative Central Servers to solve the 200 server registration limit (#50)
- added support for 64 samples frame size in the server (if server runs in 64 or 128 samples - added support for 64 samples frame size in the server (if server runs in 64 or 128 samples
mode it is still compatible to both, 64 and 128 samples frame size clients) mode it is still compatible to both, 64 and 128 samples frame size clients)
- added multichannel CoreAudio support, coded by emlynmac (#44) - added multichannel CoreAudio support, coded by emlynmac (#44)
- fixed server not visible if in same local network, coded by pljones (Ticket #27) - fixed server not visible if in same local network, coded by pljones (#27)
3.4.6 (2020-04-09) 3.4.6 (2020-04-09)
@ -145,7 +133,7 @@ TODO fix incorrect what's this help texts
- store fader mute state in the ini file, coded by doloopuntil - store fader mute state in the ini file, coded by doloopuntil
- fixed low-res icon issue (Ticket #28) - fixed low-res icon issue (#28)
3.4.5 (2020-04-04) 3.4.5 (2020-04-04)
@ -167,7 +155,7 @@ TODO fix incorrect what's this help texts
- added support for controlling the audio mixer faders with a MIDI controller (MacOS and Linux) - added support for controlling the audio mixer faders with a MIDI controller (MacOS and Linux)
- added command line argument for disabling auto jack connection (Ticket #49) - added command line argument for disabling auto jack connection (#49)
- audio recording for the server, coded by pljones - audio recording for the server, coded by pljones

View File

@ -8,8 +8,7 @@ contains(CONFIG, "noupcasename") {
CONFIG += qt \ CONFIG += qt \
thread \ thread \
release \ release
lrelease
QT += widgets \ QT += widgets \
network \ network \
@ -261,7 +260,6 @@ DISTFILES_OBOE += libs/oboe/AUTHORS \
HEADERS += $$OBOE_HEADERS HEADERS += $$OBOE_HEADERS
SOURCES += $$OBOE_SOURCES SOURCES += $$OBOE_SOURCES
DISTFILES += $$DISTFILES_OBOE DISTFILES += $$DISTFILES_OBOE
} else:unix { } else:unix {
# we want to compile with C++11 # we want to compile with C++11
CONFIG += c++11 CONFIG += c++11
@ -291,17 +289,15 @@ DISTFILES_OBOE += libs/oboe/AUTHORS \
DEFINES += WITH_SOUND DEFINES += WITH_SOUND
} }
# Linux is our source distribution, include sources from other OSs isEmpty(PREFIX) {
DISTFILES += mac/sound.h \ PREFIX = /usr/local
mac/sound.cpp \ }
mac/mainicon.icns \ isEmpty(BINDIR) {
windows/sound.h \ BINDIR = bin
windows/sound.cpp \ }
windows/mainicon.rc \ BINDIR = $$absolute_path($$BINDIR, $$PREFIX)
windows/mainicon.ico \ INSTALLS += target
android/AndroidManifest.xml \ target.path = $$BINDIR
android/sound.h \
android/sound.cpp
} }
RCC_DIR = src/res RCC_DIR = src/res
@ -356,7 +352,6 @@ HEADERS_OPUS = libs/opus/celt/arch.h \
libs/opus/celt/kiss_fft.h \ libs/opus/celt/kiss_fft.h \
libs/opus/celt/laplace.h \ libs/opus/celt/laplace.h \
libs/opus/celt/mathops.h \ libs/opus/celt/mathops.h \
libs/opus/celt/mdct.c \
libs/opus/celt/mdct.h \ libs/opus/celt/mdct.h \
libs/opus/celt/mfrngcod.h \ libs/opus/celt/mfrngcod.h \
libs/opus/celt/modes.h \ libs/opus/celt/modes.h \
@ -366,7 +361,6 @@ HEADERS_OPUS = libs/opus/celt/arch.h \
libs/opus/celt/rate.h \ libs/opus/celt/rate.h \
libs/opus/celt/stack_alloc.h \ libs/opus/celt/stack_alloc.h \
libs/opus/celt/static_modes_float.h \ libs/opus/celt/static_modes_float.h \
libs/opus/celt/vq.c \
libs/opus/celt/vq.h \ libs/opus/celt/vq.h \
libs/opus/celt/_kiss_fft_guts.h \ libs/opus/celt/_kiss_fft_guts.h \
libs/opus/include/opus.h \ libs/opus/include/opus.h \
@ -374,7 +368,6 @@ HEADERS_OPUS = libs/opus/celt/arch.h \
libs/opus/include/opus_defines.h \ libs/opus/include/opus_defines.h \
libs/opus/include/opus_types.h \ libs/opus/include/opus_types.h \
libs/opus/silk/API.h \ libs/opus/silk/API.h \
libs/opus/silk/CNG.c \
libs/opus/silk/control.h \ libs/opus/silk/control.h \
libs/opus/silk/debug.h \ libs/opus/silk/debug.h \
libs/opus/silk/define.h \ libs/opus/silk/define.h \
@ -387,10 +380,8 @@ HEADERS_OPUS = libs/opus/celt/arch.h \
libs/opus/silk/MacroDebug.h \ libs/opus/silk/MacroDebug.h \
libs/opus/silk/macros.h \ libs/opus/silk/macros.h \
libs/opus/silk/main.h \ libs/opus/silk/main.h \
libs/opus/silk/NSQ.c \
libs/opus/silk/NSQ.h \ libs/opus/silk/NSQ.h \
libs/opus/silk/pitch_est_defines.h \ libs/opus/silk/pitch_est_defines.h \
libs/opus/silk/PLC.c \
libs/opus/silk/PLC.h \ libs/opus/silk/PLC.h \
libs/opus/silk/resampler_private.h \ libs/opus/silk/resampler_private.h \
libs/opus/silk/resampler_rom.h \ libs/opus/silk/resampler_rom.h \
@ -400,7 +391,6 @@ HEADERS_OPUS = libs/opus/celt/arch.h \
libs/opus/silk/tables.h \ libs/opus/silk/tables.h \
libs/opus/silk/tuning_parameters.h \ libs/opus/silk/tuning_parameters.h \
libs/opus/silk/typedef.h \ libs/opus/silk/typedef.h \
libs/opus/silk/VAD.c \
libs/opus/src/analysis.h \ libs/opus/src/analysis.h \
libs/opus/src/mlp.h \ libs/opus/src/mlp.h \
libs/opus/src/opus_private.h \ libs/opus/src/opus_private.h \
@ -419,24 +409,6 @@ HEADERS_OPUS_X86 = libs/opus/celt/x86/celt_lpc_sse.h \
libs/opus/celt/x86/vq_sse.h \ libs/opus/celt/x86/vq_sse.h \
libs/opus/celt/x86/x86cpu.h libs/opus/celt/x86/x86cpu.h
android {
contains(ANDROID_ARCHITECTURE, arm) | contains(ANDROID_ARCHITECTURE, arm64) {
HEADERS_OPUS += $$HEADERS_OPUS_ARM
} else:contains(ANDROID_ARCHITECTURE, x86) | contains(ANDROID_ARCHITECTURE, x86_64) {
HEADERS_OPUS += $$HEADERS_OPUS_X86
}
} else:win32 | unix | macx {
contains(QT_ARCH, arm) | contains(QT_ARCH, arm64) {
HEADERS_OPUS += $$HEADERS_OPUS_ARM
} else:contains(QT_ARCH, x86) | contains(QT_ARCH, x86_64) {
HEADERS_OPUS += $$HEADERS_OPUS_X86
}
win32 {
HEADERS_OPUS += libs/opus/win32/config.h
}
}
SOURCES += src/audiomixerboard.cpp \ SOURCES += src/audiomixerboard.cpp \
src/buffer.cpp \ src/buffer.cpp \
src/channel.cpp \ src/channel.cpp \
@ -607,28 +579,35 @@ SOURCES_OPUS_X86 = libs/opus/celt/x86/celt_lpc_sse4_1.c \
android { android {
contains(ANDROID_ARCHITECTURE, arm) | contains(ANDROID_ARCHITECTURE, arm64) { contains(ANDROID_ARCHITECTURE, arm) | contains(ANDROID_ARCHITECTURE, arm64) {
HEADERS_OPUS += $$HEADERS_OPUS_ARM
SOURCE_OPUS += $$SOURCES_OPUS_ARM SOURCE_OPUS += $$SOURCES_OPUS_ARM
} else:contains(ANDROID_ARCHITECTURE, x86) | contains(ANDROID_ARCHITECTURE, x86_64) { } else:contains(ANDROID_ARCHITECTURE, x86) | contains(ANDROID_ARCHITECTURE, x86_64) {
HEADERS_OPUS += $$HEADERS_OPUS_X86
SOURCE_OPUS += $$SOURCES_OPUS_X86 SOURCE_OPUS += $$SOURCES_OPUS_X86
} }
} else:win32 | unix | macx { } else:win32 | unix | macx {
contains(QT_ARCH, arm) | contains(QT_ARCH, arm64) { contains(QT_ARCH, arm) | contains(QT_ARCH, arm64) {
HEADERS_OPUS += $$HEADERS_OPUS_ARM
SOURCE_OPUS += $$SOURCES_OPUS_ARM SOURCE_OPUS += $$SOURCES_OPUS_ARM
} else:contains(QT_ARCH, x86) | contains(QT_ARCH, x86_64) { } else:contains(QT_ARCH, x86) | contains(QT_ARCH, x86_64) {
HEADERS_OPUS += $$HEADERS_OPUS_X86
SOURCE_OPUS += $$SOURCES_OPUS_X86 SOURCE_OPUS += $$SOURCES_OPUS_X86
} }
win32 {
HEADERS_OPUS += libs/opus/win32/config.h
}
} }
DISTFILES += ChangeLog \ DISTFILES += ChangeLog \
COPYING \ COPYING \
INSTALL.md \ INSTALL.md \
README.md \ README.md \
android/build.gradle \ src/res/translation/translation_de_DE.qm \
android/gradle/wrapper/gradle-wrapper.jar \ src/res/translation/translation_fr_FR.qm \
android/gradle/wrapper/gradle-wrapper.properties \ src/res/translation/translation_pt_PT.qm \
android/gradlew \ src/res/translation/translation_es_ES.qm \
android/gradlew.bat \ src/res/translation/translation_nl_NL.qm \
android/res/values/libs.xml \ src/res/translation/translation_it_IT.qm \
src/res/CLEDBlack.png \ src/res/CLEDBlack.png \
src/res/CLEDBlackSmall.png \ src/res/CLEDBlackSmall.png \
src/res/CLEDDisabledSmall.png \ src/res/CLEDDisabledSmall.png \

View File

@ -1,6 +1,16 @@
#!/bin/bash #!/bin/bash
# This script is intended to setup a clean Raspberry Pi system for running Jamulus # This script is intended to setup a clean Raspberry Pi system for running Jamulus
# Regarding the old OPUS version (#252): I just tried out the following:
# * Do not use OPUS in shared library but use the version which is included in the jamulus source code:
# instead of 80 % load I get 90 % load on my Raspberry Pi Zero
# * Do not use OPUS in shared libaray but use the version which is included in the Jamulus source code
# but try to compile in fixed-point: I get compilation errors so this is not possible right now
# * I replaced the opus-1.1 with OPUS="opus-1.3.1" in the raspijamulus.sh -> OPUS version 1.3.1 has a
# known bug with the custom interface. If I use that version as a shared libaray, I get a runtime error
# on starting Jamulus. So this is also not possible. We have to wait for the next official OPUS version.
# Therefore it is the best to keep the opus-1.1 version.
OPUS="opus-1.1" OPUS="opus-1.1"
NCORES=$(nproc) NCORES=$(nproc)

View File

@ -41,6 +41,7 @@ CChannelFader::CChannelFader ( QWidget* pNW,
pFader = new QSlider ( Qt::Vertical, pLevelsBox ); pFader = new QSlider ( Qt::Vertical, pLevelsBox );
pPan = new QDial ( pLevelsBox ); pPan = new QDial ( pLevelsBox );
pPanLabel = new QLabel ( tr ( "Pan" ) , pLevelsBox ); pPanLabel = new QLabel ( tr ( "Pan" ) , pLevelsBox );
pInfoLabel = new QLabel ( "", pLevelsBox );
pMuteSoloBox = new QWidget ( pFrame ); pMuteSoloBox = new QWidget ( pFrame );
pcbMute = new QCheckBox ( tr ( "Mute" ), pMuteSoloBox ); pcbMute = new QCheckBox ( tr ( "Mute" ), pMuteSoloBox );
@ -57,6 +58,7 @@ CChannelFader::CChannelFader ( QWidget* pNW,
QHBoxLayout* pLabelGrid = new QHBoxLayout ( pLabelInstBox ); QHBoxLayout* pLabelGrid = new QHBoxLayout ( pLabelInstBox );
QVBoxLayout* pLabelPictGrid = new QVBoxLayout ( ); QVBoxLayout* pLabelPictGrid = new QVBoxLayout ( );
QVBoxLayout* pPanGrid = new QVBoxLayout ( ); QVBoxLayout* pPanGrid = new QVBoxLayout ( );
QHBoxLayout* pPanInfoGrid = new QHBoxLayout ( );
// setup channel level // setup channel level
plbrChannelLevel->setContentsMargins ( 0, 3, 2, 3 ); plbrChannelLevel->setContentsMargins ( 0, 3, 2, 3 );
@ -66,14 +68,16 @@ CChannelFader::CChannelFader ( QWidget* pNW,
pFader->setTickPosition ( QSlider::TicksBothSides ); pFader->setTickPosition ( QSlider::TicksBothSides );
pFader->setRange ( 0, AUD_MIX_FADER_MAX ); pFader->setRange ( 0, AUD_MIX_FADER_MAX );
pFader->setTickInterval ( AUD_MIX_FADER_MAX / 9 ); pFader->setTickInterval ( AUD_MIX_FADER_MAX / 9 );
pFader->setMinimumHeight ( 90 ); pFader->setMinimumHeight ( 75 );
// setup panning control // setup panning control
pPan->setRange ( 0, AUD_MIX_PAN_MAX ); pPan->setRange ( 0, AUD_MIX_PAN_MAX );
pPan->setValue ( AUD_MIX_PAN_MAX / 2 ); pPan->setValue ( AUD_MIX_PAN_MAX / 2 );
pPan->setFixedSize ( 55, 55 ); pPan->setFixedSize ( 50, 50 );
pPan->setNotchesVisible ( true ); pPan->setNotchesVisible ( true );
pPanGrid->addWidget ( pPanLabel, 0, Qt::AlignLeft ); pPanInfoGrid->addWidget ( pPanLabel, 0, Qt::AlignLeft );
pPanInfoGrid->addWidget ( pInfoLabel );
pPanGrid->addLayout ( pPanInfoGrid );
pPanGrid->addWidget ( pPan, 0, Qt::AlignHCenter ); pPanGrid->addWidget ( pPan, 0, Qt::AlignHCenter );
// setup fader tag label (black bold text which is centered) // setup fader tag label (black bold text which is centered)
@ -135,9 +139,16 @@ CChannelFader::CChannelFader ( QWidget* pNW,
pFader->setAccessibleName ( tr ( "Local mix level setting of the current audio " pFader->setAccessibleName ( tr ( "Local mix level setting of the current audio "
"channel at the server" ) ); "channel at the server" ) );
pInfoLabel->setWhatsThis ( "<b>" + tr ( "Status Indicator" ) + ":</b> " + tr (
"Shows a status indication about the client which is assigned to this channel. "
"Supported indicators are:" ) + "<ul><li>" + tr (
"Speaker with cancellation stroke: Indicates that the other client has muted you." ) +
"</li></ul>" );
pInfoLabel->setAccessibleName ( tr ( "Status indicator label" ) );
pPan->setWhatsThis ( "<b>" + tr ( "Panning" ) + ":</b> " + tr ( pPan->setWhatsThis ( "<b>" + tr ( "Panning" ) + ":</b> " + tr (
"Sets the panning position from Left to Right of the channel. " "Sets the panning position from Left to Right of the channel. "
"Works only in stero or preferably mono in/stereo out mode." ) ); "Works only in stereo or preferably mono in/stereo out mode." ) );
pPan->setAccessibleName ( tr ( "Local panning position of the current audio channel at the server" ) ); pPan->setAccessibleName ( tr ( "Local panning position of the current audio channel at the server" ) );
pcbMute->setWhatsThis ( "<b>" + tr ( "Mute" ) + ":</b> " + tr ( pcbMute->setWhatsThis ( "<b>" + tr ( "Mute" ) + ":</b> " + tr (
@ -225,6 +236,7 @@ bool CChannelFader::GetDisplayChannelLevel()
void CChannelFader::SetDisplayPans ( const bool eNDP ) void CChannelFader::SetDisplayPans ( const bool eNDP )
{ {
pInfoLabel->setHidden ( !eNDP );
pPanLabel->setHidden ( !eNDP ); pPanLabel->setHidden ( !eNDP );
pPan->setHidden ( !eNDP ); pPan->setHidden ( !eNDP );
} }
@ -275,6 +287,9 @@ void CChannelFader::SetupFaderTag ( const ESkillLevel eSkillLevel )
void CChannelFader::Reset() void CChannelFader::Reset()
{ {
// general initializations
SetRemoteFaderIsMute ( false );
// init gain and pan value -> maximum value as definition according to server // init gain and pan value -> maximum value as definition according to server
pFader->setValue ( AUD_MIX_FADER_MAX ); pFader->setValue ( AUD_MIX_FADER_MAX );
pPan->setValue ( AUD_MIX_PAN_MAX / 2 ); pPan->setValue ( AUD_MIX_PAN_MAX / 2 );
@ -339,6 +354,22 @@ void CChannelFader::SetFaderIsMute ( const bool bIsMute )
pcbMute->setChecked ( bIsMute ); pcbMute->setChecked ( bIsMute );
} }
void CChannelFader::SetRemoteFaderIsMute ( const bool bIsMute )
{
if ( bIsMute )
{
// show orange utf8 SPEAKER WITH CANCELLATION STROKE (U+1F507)
pInfoLabel->setText ( "<font color=""orange"">&#128263;</font>" );
//QPixmap CancelledSpeakerPixmap ( QString::fromUtf8 ( ":/png/main/res/speakerwithcancellationstroke.png" ) );
//pInfoLabel->setPixmap ( CancelledSpeakerPixmap.scaled ( 15, 15, Qt::KeepAspectRatio ) );
}
else
{
pInfoLabel->setText ( "" );
//pInfoLabel->setPixmap ( QPixmap() );
}
}
void CChannelFader::SendFaderLevelToServer ( const int iLevel ) void CChannelFader::SendFaderLevelToServer ( const int iLevel )
{ {
// if mute flag is set or other channel is on solo, do not apply the new // if mute flag is set or other channel is on solo, do not apply the new
@ -572,19 +603,23 @@ double CChannelFader::CalcFaderGain ( const int value )
* CAudioMixerBoard * * CAudioMixerBoard *
\******************************************************************************/ \******************************************************************************/
CAudioMixerBoard::CAudioMixerBoard ( QWidget* parent, Qt::WindowFlags ) : CAudioMixerBoard::CAudioMixerBoard ( QWidget* parent, Qt::WindowFlags ) :
QScrollArea ( parent ), QGroupBox ( parent ),
vecStoredFaderTags ( MAX_NUM_STORED_FADER_SETTINGS, "" ), vecStoredFaderTags ( MAX_NUM_STORED_FADER_SETTINGS, "" ),
vecStoredFaderLevels ( MAX_NUM_STORED_FADER_SETTINGS, AUD_MIX_FADER_MAX ), vecStoredFaderLevels ( MAX_NUM_STORED_FADER_SETTINGS, AUD_MIX_FADER_MAX ),
vecStoredPanValues ( MAX_NUM_STORED_FADER_SETTINGS, AUD_MIX_PAN_MAX / 2 ), vecStoredPanValues ( MAX_NUM_STORED_FADER_SETTINGS, AUD_MIX_PAN_MAX / 2 ),
vecStoredFaderIsSolo ( MAX_NUM_STORED_FADER_SETTINGS, false ), vecStoredFaderIsSolo ( MAX_NUM_STORED_FADER_SETTINGS, false ),
vecStoredFaderIsMute ( MAX_NUM_STORED_FADER_SETTINGS, false ), vecStoredFaderIsMute ( MAX_NUM_STORED_FADER_SETTINGS, false ),
iNewClientFaderLevel ( 100 ), iNewClientFaderLevel ( 100 ),
bDisplayPans ( false ),
bIsPanSupported ( false ),
bNoFaderVisible ( true ), bNoFaderVisible ( true ),
strServerName ( "" ) strServerName ( "" )
{ {
// add group box and hboxlayout // add group box and hboxlayout
pGroupBox = new QGroupBox(); // will be added to the scroll area which is then the parent QHBoxLayout* pGroupBoxLayout = new QHBoxLayout ( this );
pMainLayout = new QHBoxLayout ( pGroupBox ); QWidget* pMixerWidget = new QWidget(); // will be added to the scroll area which is then the parent
pScrollArea = new CMixerBoardScrollArea ( this );
pMainLayout = new QHBoxLayout ( pMixerWidget );
// set title text (default: no server given) // set title text (default: no server given)
SetServerName ( "" ); SetServerName ( "" );
@ -601,11 +636,15 @@ CAudioMixerBoard::CAudioMixerBoard ( QWidget* parent, Qt::WindowFlags ) :
// insert horizontal spacer // insert horizontal spacer
pMainLayout->addItem ( new QSpacerItem ( 0, 0, QSizePolicy::Expanding ) ); pMainLayout->addItem ( new QSpacerItem ( 0, 0, QSizePolicy::Expanding ) );
// set margins of the layout to zero to get maximum space for the controls
pGroupBoxLayout->setContentsMargins ( 0, 0, 0, 1 ); // note: to avoid problems at the botton, use a small margin for that
// add the group box to the scroll area // add the group box to the scroll area
setMinimumWidth ( 200 ); // at least two faders shall be visible pScrollArea->setMinimumWidth ( 200 ); // at least two faders shall be visible
setWidget ( pGroupBox ); pScrollArea->setWidget ( pMixerWidget );
setWidgetResizable ( true ); // make sure it fills the entire scroll area pScrollArea->setWidgetResizable ( true ); // make sure it fills the entire scroll area
setFrameShape ( QFrame::NoFrame ); pScrollArea->setFrameShape ( QFrame::NoFrame );
pGroupBoxLayout->addWidget ( pScrollArea );
// Connections ------------------------------------------------------------- // Connections -------------------------------------------------------------
@ -646,7 +685,7 @@ void CAudioMixerBoard::SetServerName ( const QString& strNewServerName )
if ( strServerName.isEmpty() ) if ( strServerName.isEmpty() )
{ {
// no connection or connection was reset: show default title // no connection or connection was reset: show default title
pGroupBox->setTitle ( tr ( "Server" ) ); setTitle ( tr ( "Server" ) );
} }
else else
{ {
@ -655,7 +694,7 @@ void CAudioMixerBoard::SetServerName ( const QString& strNewServerName )
// list was received, the connection was successful and the title is updated // list was received, the connection was successful and the title is updated
// with the correct server name. Make sure to choose a "try to connect" title // with the correct server name. Make sure to choose a "try to connect" title
// which is most striking (we use filled blocks and upper case letters). // which is most striking (we use filled blocks and upper case letters).
pGroupBox->setTitle ( u8"\u2588\u2588\u2588\u2588\u2588 " + tr ( "T R Y I N G T O C O N N E C T" ) + u8" \u2588\u2588\u2588\u2588\u2588" ); setTitle ( u8"\u2588\u2588\u2588\u2588\u2588 " + tr ( "T R Y I N G T O C O N N E C T" ) + u8" \u2588\u2588\u2588\u2588\u2588" );
} }
} }
@ -684,20 +723,20 @@ void CAudioMixerBoard::SetDisplayChannelLevels ( const bool eNDCL )
} }
} }
void CAudioMixerBoard::SetPanIsSupported() void CAudioMixerBoard::SetDisplayPans ( const bool eNDP )
{ {
bDisplayPans = eNDP;
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
{ {
vecpChanFader[i]->SetDisplayPans ( true ); vecpChanFader[i]->SetDisplayPans ( eNDP && bIsPanSupported );
} }
} }
void CAudioMixerBoard::resizeEvent ( QResizeEvent* event ) void CAudioMixerBoard::SetPanIsSupported()
{ {
// if after a resize of the main window a vertical scroll bar is required, make bIsPanSupported = true;
// sure that the fader label is visible (scroll down completely) SetDisplayPans ( bDisplayPans );
ensureVisible ( 0, 2000 ); // use a large value here
QScrollArea::resizeEvent ( event );
} }
void CAudioMixerBoard::HideAll() void CAudioMixerBoard::HideAll()
@ -714,7 +753,8 @@ void CAudioMixerBoard::HideAll()
vecpChanFader[i]->Hide(); vecpChanFader[i]->Hide();
} }
// set flag // set flags
bIsPanSupported = false;
bNoFaderVisible = true; bNoFaderVisible = true;
// emit status of connected clients // emit status of connected clients
@ -727,7 +767,7 @@ void CAudioMixerBoard::ApplyNewConClientList ( CVector<CChannelInfo>& vecChanInf
// in the audio mixer board to show a "try to connect" before // in the audio mixer board to show a "try to connect" before
if ( bNoFaderVisible ) if ( bNoFaderVisible )
{ {
pGroupBox->setTitle ( tr ( "Personal Mix at the Server: " ) + strServerName ); setTitle ( tr ( "Personal Mix at the Server: " ) + strServerName );
} }
// get number of connected clients // get number of connected clients
@ -833,6 +873,19 @@ void CAudioMixerBoard::SetFaderLevel ( const int iChannelIdx,
} }
} }
void CAudioMixerBoard::SetRemoteFaderIsMute ( const int iChannelIdx,
const bool bIsMute )
{
// only apply remote mute state if channel index is valid and the fader is visible
if ( ( iChannelIdx >= 0 ) && ( iChannelIdx < MAX_NUM_CHANNELS ) )
{
if ( vecpChanFader[iChannelIdx]->IsVisible() )
{
vecpChanFader[iChannelIdx]->SetRemoteFaderIsMute ( bIsMute );
}
}
}
void CAudioMixerBoard::UpdateSoloStates() void CAudioMixerBoard::UpdateSoloStates()
{ {
// first check if any channel has a solo state active // first check if any channel has a solo state active

View File

@ -66,6 +66,7 @@ public:
void SetPanValue ( const int iPan ); void SetPanValue ( const int iPan );
void SetFaderIsSolo ( const bool bIsSolo ); void SetFaderIsSolo ( const bool bIsSolo );
void SetFaderIsMute ( const bool bIsMute ); void SetFaderIsMute ( const bool bIsMute );
void SetRemoteFaderIsMute ( const bool bIsMute );
int GetFaderLevel() { return pFader->value(); } int GetFaderLevel() { return pFader->value(); }
int GetPanValue() { return pPan->value(); } int GetPanValue() { return pPan->value(); }
void Reset(); void Reset();
@ -86,6 +87,7 @@ protected:
QSlider* pFader; QSlider* pFader;
QDial* pPan; QDial* pPan;
QLabel* pPanLabel; QLabel* pPanLabel;
QLabel* pInfoLabel;
QCheckBox* pcbMute; QCheckBox* pcbMute;
QCheckBox* pcbSolo; QCheckBox* pcbSolo;
@ -129,7 +131,7 @@ class CAudioMixerBoardSlots<0> {};
class CAudioMixerBoard : class CAudioMixerBoard :
public QScrollArea, public QGroupBox,
public CAudioMixerBoardSlots<MAX_NUM_CHANNELS> public CAudioMixerBoardSlots<MAX_NUM_CHANNELS>
{ {
Q_OBJECT Q_OBJECT
@ -142,7 +144,9 @@ public:
void SetServerName ( const QString& strNewServerName ); void SetServerName ( const QString& strNewServerName );
void SetGUIDesign ( const EGUIDesign eNewDesign ); void SetGUIDesign ( const EGUIDesign eNewDesign );
void SetDisplayChannelLevels ( const bool eNDCL ); void SetDisplayChannelLevels ( const bool eNDCL );
void SetDisplayPans ( const bool eNDP );
void SetPanIsSupported(); void SetPanIsSupported();
void SetRemoteFaderIsMute ( const int iChannelIdx, const bool bIsMute );
void SetFaderLevel ( const int iChannelIdx, void SetFaderLevel ( const int iChannelIdx,
const int iValue ); const int iValue );
@ -158,7 +162,20 @@ public:
int iNewClientFaderLevel; int iNewClientFaderLevel;
protected: protected:
void resizeEvent ( QResizeEvent* event ); class CMixerBoardScrollArea : public QScrollArea
{
public:
CMixerBoardScrollArea ( QWidget* parent = nullptr ) : QScrollArea ( parent ) {}
protected:
virtual void resizeEvent ( QResizeEvent* event )
{
// if after a resize of the main window a vertical scroll bar is required, make
// sure that the fader label is visible (scroll down completely)
ensureVisible ( 0, 2000 ); // use a large value here
QScrollArea::resizeEvent ( event );
}
};
bool GetStoredFaderSettings ( const CChannelInfo& ChanInfo, bool GetStoredFaderSettings ( const CChannelInfo& ChanInfo,
int& iStoredFaderLevel, int& iStoredFaderLevel,
@ -173,9 +190,11 @@ protected:
const double dValue ); const double dValue );
CVector<CChannelFader*> vecpChanFader; CVector<CChannelFader*> vecpChanFader;
QGroupBox* pGroupBox; CMixerBoardScrollArea* pScrollArea;
QHBoxLayout* pMainLayout; QHBoxLayout* pMainLayout;
bool bDisplayChannelLevels; bool bDisplayChannelLevels;
bool bDisplayPans;
bool bIsPanSupported;
bool bNoFaderVisible; bool bNoFaderVisible;
QString strServerName; QString strServerName;

View File

@ -90,6 +90,10 @@ qRegisterMetaType<CHostAddress> ( "CHostAddress" );
QObject::connect ( &Protocol, SIGNAL ( ChangeChanPan ( int, double ) ), QObject::connect ( &Protocol, SIGNAL ( ChangeChanPan ( int, double ) ),
this, SLOT ( OnChangeChanPan ( int, double ) ) ); this, SLOT ( OnChangeChanPan ( int, double ) ) );
QObject::connect ( &Protocol,
SIGNAL ( MuteStateHasChangedReceived ( int, bool ) ),
SIGNAL ( MuteStateHasChangedReceived ( int, bool ) ) );
QObject::connect ( &Protocol, SIGNAL ( ChangeChanInfo ( CChannelCoreInfo ) ), QObject::connect ( &Protocol, SIGNAL ( ChangeChanInfo ( CChannelCoreInfo ) ),
this, SLOT ( OnChangeChanInfo ( CChannelCoreInfo ) ) ); this, SLOT ( OnChangeChanInfo ( CChannelCoreInfo ) ) );
@ -258,6 +262,16 @@ void CChannel::SetGain ( const int iChanID,
// set value (make sure channel ID is in range) // set value (make sure channel ID is in range)
if ( ( iChanID >= 0 ) && ( iChanID < MAX_NUM_CHANNELS ) ) if ( ( iChanID >= 0 ) && ( iChanID < MAX_NUM_CHANNELS ) )
{ {
// signal mute change
if ( ( vecdGains[iChanID] == 0 ) && ( dNewGain > 0 ) )
{
emit MuteStateHasChanged ( iChanID, false );
}
if ( ( vecdGains[iChanID] > 0 ) && ( dNewGain == 0 ) )
{
emit MuteStateHasChanged ( iChanID, true );
}
vecdGains[iChanID] = dNewGain; vecdGains[iChanID] = dNewGain;
} }
} }

View File

@ -106,6 +106,7 @@ public:
void CreateReqChanInfoMes() { Protocol.CreateReqChanInfoMes(); } void CreateReqChanInfoMes() { Protocol.CreateReqChanInfoMes(); }
void CreateVersionAndOSMes() { Protocol.CreateVersionAndOSMes(); } void CreateVersionAndOSMes() { Protocol.CreateVersionAndOSMes(); }
void CreateMuteStateHasChangedMes ( const int iChanID, const bool bIsMuted ) { Protocol.CreateMuteStateHasChangedMes ( iChanID, bIsMuted ); }
void SetGain ( const int iChanID, const double dNewGain ); void SetGain ( const int iChanID, const double dNewGain );
double GetGain ( const int iChanID ); double GetGain ( const int iChanID );
@ -277,6 +278,8 @@ signals:
void ReqConnClientsList(); void ReqConnClientsList();
void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo ); void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo );
void ChanInfoHasChanged(); void ChanInfoHasChanged();
void MuteStateHasChanged ( int iChanID, bool bIsMuted );
void MuteStateHasChangedReceived ( int iChanID, bool bIsMuted );
void ReqChanInfo(); void ReqChanInfo();
void ChatTextReceived ( QString strChatText ); void ChatTextReceived ( QString strChatText );
void ReqNetTranspProps(); void ReqNetTranspProps();

View File

@ -79,7 +79,8 @@ CClient::CClient ( const quint16 iPortNumber,
bJitterBufferOK ( true ), bJitterBufferOK ( true ),
strCentralServerAddress ( "" ), strCentralServerAddress ( "" ),
eCentralServerAddressType ( AT_DEFAULT ), eCentralServerAddressType ( AT_DEFAULT ),
iServerSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL ) iServerSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL ),
pSignalHandler ( CSignalHandler::getSingletonP() )
{ {
int iOpusError; int iOpusError;
@ -156,6 +157,10 @@ CClient::CClient ( const quint16 iPortNumber,
SIGNAL ( ChatTextReceived ( QString ) ), SIGNAL ( ChatTextReceived ( QString ) ),
SIGNAL ( ChatTextReceived ( QString ) ) ); SIGNAL ( ChatTextReceived ( QString ) ) );
QObject::connect ( &Channel,
SIGNAL ( MuteStateHasChangedReceived ( int, bool ) ),
SIGNAL ( MuteStateHasChangedReceived ( int, bool ) ) );
QObject::connect ( &Channel, QObject::connect ( &Channel,
SIGNAL ( LicenceRequired ( ELicenceType ) ), SIGNAL ( LicenceRequired ( ELicenceType ) ),
SIGNAL ( LicenceRequired ( ELicenceType ) ) ); SIGNAL ( LicenceRequired ( ELicenceType ) ) );
@ -209,6 +214,10 @@ CClient::CClient ( const quint16 iPortNumber,
QObject::connect ( &Socket, SIGNAL ( InvalidPacketReceived ( CHostAddress ) ), QObject::connect ( &Socket, SIGNAL ( InvalidPacketReceived ( CHostAddress ) ),
this, SLOT ( OnInvalidPacketReceived ( CHostAddress ) ) ); this, SLOT ( OnInvalidPacketReceived ( CHostAddress ) ) );
QObject::connect ( pSignalHandler,
SIGNAL ( HandledSignal ( int ) ),
this, SLOT ( OnHandledSignal ( int ) ) );
// start the socket (it is important to start the socket after all // start the socket (it is important to start the socket after all
// initializations and connections) // initializations and connections)
@ -652,6 +661,27 @@ void CClient::OnCLChannelLevelListReceived ( CHostAddress InetAddr,
emit CLChannelLevelListReceived ( InetAddr, vecLevelList ); emit CLChannelLevelListReceived ( InetAddr, vecLevelList );
} }
void CClient::OnHandledSignal ( int sigNum )
{
#ifdef _WIN32
// Windows does not actually get OnHandledSignal triggered
QCoreApplication::instance()->exit();
Q_UNUSED ( sigNum )
#else
switch ( sigNum )
{
case SIGINT:
case SIGTERM:
// This should trigger OnAboutToQuit
QCoreApplication::instance()->exit();
break;
default:
break;
}
#endif
}
void CClient::Start() void CClient::Start()
{ {
// init object // init object

View File

@ -39,6 +39,7 @@
#include "channel.h" #include "channel.h"
#include "util.h" #include "util.h"
#include "buffer.h" #include "buffer.h"
#include "signalhandler.h"
#ifdef LLCON_VST_PLUGIN #ifdef LLCON_VST_PLUGIN
# include "vstsound.h" # include "vstsound.h"
#else #else
@ -389,7 +390,10 @@ protected:
// for ping measurement // for ping measurement
CPreciseTime PreciseTime; CPreciseTime PreciseTime;
CSignalHandler* pSignalHandler;
public slots: public slots:
void OnHandledSignal ( int sigNum );
void OnSendProtMessage ( CVector<uint8_t> vecMessage ); void OnSendProtMessage ( CVector<uint8_t> vecMessage );
void OnInvalidPacketReceived ( CHostAddress RecHostAddr ); void OnInvalidPacketReceived ( CHostAddress RecHostAddr );
@ -420,6 +424,7 @@ public slots:
signals: signals:
void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo ); void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo );
void ChatTextReceived ( QString strChatText ); void ChatTextReceived ( QString strChatText );
void MuteStateHasChangedReceived ( int iChanID, bool bIsMuted );
void LicenceRequired ( ELicenceType eLicenceType ); void LicenceRequired ( ELicenceType eLicenceType );
void VersionAndOSReceived ( COSUtil::EOpSystemType eOSType, QString strVersion ); void VersionAndOSReceived ( COSUtil::EOpSystemType eOSType, QString strVersion );
void PingTimeReceived ( int iPingTime ); void PingTimeReceived ( int iPingTime );

View File

@ -85,7 +85,7 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
// connect/disconnect button // connect/disconnect button
butConnect->setWhatsThis ( "<b>" + tr ( "Connect/Disconnect Button" ) + ":</b> " + butConnect->setWhatsThis ( "<b>" + tr ( "Connect/Disconnect Button" ) + ":</b> " +
tr ( "Push this button to connect a server. A dialog where you can " tr ( "Push this button to connect to a server. A dialog where you can "
"select a server will open. If you are connected, pressing this " "select a server will open. If you are connected, pressing this "
"button will end the session." ) ); "button will end the session." ) );
@ -123,7 +123,7 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
"sound card and a reverberation effect shall be applied, set the " "sound card and a reverberation effect shall be applied, set the "
"channel selector to right and move the fader upwards until the " "channel selector to right and move the fader upwards until the "
"desired reverberation level is reached." ) + "<br>" + tr ( "desired reverberation level is reached." ) + "<br>" + tr (
"The reverberation effect requires significant CPU so that it should " "The reverberation effect requires significant CPU so it should "
"only be used on fast PCs. If the reverberation level fader is set to " "only be used on fast PCs. If the reverberation level fader is set to "
"minimum (which is the default setting), the reverberation effect is " "minimum (which is the default setting), the reverberation effect is "
"switched off and does not cause any additional CPU usage." ); "switched off and does not cause any additional CPU usage." );
@ -169,7 +169,7 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
"<ul>" "<ul>"
"<li>" + tr ( "The network jitter buffer is not large enough for the current " "<li>" + tr ( "The network jitter buffer is not large enough for the current "
"network/audio interface jitter." ) + "</li>" "network/audio interface jitter." ) + "</li>"
"<li>" + tr ( "The sound card buffer delay (buffer size) is set to a too small " "<li>" + tr ( "The sound card buffer delay (buffer size) is set to too small a "
"value." ) + "</li>" "value." ) + "</li>"
"<li>" + tr ( "The upload or download stream rate is too high for the current " "<li>" + tr ( "The upload or download stream rate is too high for the current "
"available internet bandwidth." ) + "</li>" "available internet bandwidth." ) + "</li>"
@ -466,6 +466,10 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
SIGNAL ( ChatTextReceived ( QString ) ), SIGNAL ( ChatTextReceived ( QString ) ),
this, SLOT ( OnChatTextReceived ( QString ) ) ); this, SLOT ( OnChatTextReceived ( QString ) ) );
QObject::connect ( pClient,
SIGNAL ( MuteStateHasChangedReceived ( int, bool ) ),
this, SLOT ( OnMuteStateHasChangedReceived ( int, bool ) ) );
// This connection is a special case. On receiving a licence required message via the // This connection is a special case. On receiving a licence required message via the
// protocol, a modal licence dialog is opened. Since this blocks the thread, we need // protocol, a modal licence dialog is opened. Since this blocks the thread, we need
// a queued connection to make sure the core protocol mechanism is not blocked, too. // a queued connection to make sure the core protocol mechanism is not blocked, too.
@ -657,6 +661,9 @@ void CClientDlg::UpdateRevSelection()
rbtReverbSelR->setChecked ( true ); rbtReverbSelR->setChecked ( true );
} }
} }
// update visibility of the pan controls in the audio mixer board (pan is not supported for mono)
MainMixerBoard->SetDisplayPans ( pClient->GetAudioChannels() != CC_MONO );
} }
void CClientDlg::OnAudioPanValueChanged ( int value ) void CClientDlg::OnAudioPanValueChanged ( int value )
@ -1171,6 +1178,7 @@ void CClientDlg::SetGUIDesign ( const EGUIDesign eNewDesign )
"QRadioButton { color: rgb(220, 220, 220);" "QRadioButton { color: rgb(220, 220, 220);"
" font: bold; }" " font: bold; }"
"QScrollArea { background: transparent; }" "QScrollArea { background: transparent; }"
".QWidget { background: transparent; }" // note: matches instances of QWidget, but not of its subclasses
"QGroupBox { background: transparent; }" "QGroupBox { background: transparent; }"
"QGroupBox::title { color: rgb(220, 220, 220); }" "QGroupBox::title { color: rgb(220, 220, 220); }"
"QCheckBox::indicator { width: 38px;" "QCheckBox::indicator { width: 38px;"

View File

@ -198,6 +198,9 @@ public slots:
CVector<CChannelInfo> vecChanInfo ) CVector<CChannelInfo> vecChanInfo )
{ ConnectDlg.SetConnClientsList ( InetAddr, vecChanInfo ); } { ConnectDlg.SetConnClientsList ( InetAddr, vecChanInfo ); }
void OnMuteStateHasChangedReceived ( int iChanID, bool bIsMuted )
{ MainMixerBoard->SetRemoteFaderIsMute ( iChanID, bIsMuted ); }
void OnCLChannelLevelListReceived ( CHostAddress /* unused */, void OnCLChannelLevelListReceived ( CHostAddress /* unused */,
CVector<uint16_t> vecLevelList ) CVector<uint16_t> vecLevelList )
{ MainMixerBoard->SetChannelLevels ( vecLevelList ); } { MainMixerBoard->SetChannelLevels ( vecLevelList ); }

View File

@ -41,8 +41,8 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
"(the longer the buffer, the higher the delay)." ) + "<br>" + tr ( "(the longer the buffer, the higher the delay)." ) + "<br>" + tr (
"The jitter buffer size can be manually chosen for the local client " "The jitter buffer size can be manually chosen for the local client "
"and the remote server. For the local jitter buffer, dropouts in the " "and the remote server. For the local jitter buffer, dropouts in the "
"audio stream are indicated by the light on the bottom " "audio stream are indicated by the light below the "
"of the jitter buffer size faders. If the light turns to red, a buffer " "jitter buffer size faders. If the light turns to red, a buffer "
"overrun/underrun took place and the audio stream is interrupted." ) + "<br>" + tr ( "overrun/underrun took place and the audio stream is interrupted." ) + "<br>" + tr (
"The jitter buffer setting is therefore a trade-off between audio " "The jitter buffer setting is therefore a trade-off between audio "
"quality and overall delay." ) + "<br>" + tr ( "quality and overall delay." ) + "<br>" + tr (
@ -61,7 +61,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
"functionality and to lower the jitter buffer size manually by " "functionality and to lower the jitter buffer size manually by "
"using the sliders until your personal acceptable limit of the amount " "using the sliders until your personal acceptable limit of the amount "
"of dropouts is reached. The LED indicator will visualize the audio " "of dropouts is reached. The LED indicator will visualize the audio "
"dropouts of the local jitter buffer by a red light." ) + "dropouts of the local jitter buffer with a red light." ) +
TOOLTIP_COM_END_TEXT; TOOLTIP_COM_END_TEXT;
lblNetBuf->setWhatsThis ( strJitterBufferSize ); lblNetBuf->setWhatsThis ( strJitterBufferSize );
@ -93,7 +93,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
#ifdef _WIN32 #ifdef _WIN32
// set Windows specific tool tip // set Windows specific tool tip
cbxSoundcard->setToolTip ( tr ( "In case the ASIO4ALL driver is used, " cbxSoundcard->setToolTip ( tr ( "If the ASIO4ALL driver is used, "
"please note that this driver usually introduces approx. 10-30 ms of " "please note that this driver usually introduces approx. 10-30 ms of "
"additional audio delay. Using a sound card with a native ASIO driver " "additional audio delay. Using a sound card with a native ASIO driver "
"is therefore recommended." ) + "<br>" + tr ( "If you are using the kX ASIO " "is therefore recommended." ) + "<br>" + tr ( "If you are using the kX ASIO "
@ -126,7 +126,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
"If enabled, the support for very small network audio packets is activated. Very small " "If enabled, the support for very small network audio packets is activated. Very small "
"network packets are only actually used if the sound card buffer delay is smaller than " ) + "network packets are only actually used if the sound card buffer delay is smaller than " ) +
QString().setNum ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ) + tr ( " samples. The " QString().setNum ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ) + tr ( " samples. The "
"smaller the network buffers, the smaller the audio latency. But at the same time " "smaller the network buffers, the lower the audio latency. But at the same time "
"the network load increases and the probability of audio dropouts also increases." ) ); "the network load increases and the probability of audio dropouts also increases." ) );
chbEnableOPUS64->setAccessibleName ( tr ( "Enable small network buffers check box" ) ); chbEnableOPUS64->setAccessibleName ( tr ( "Enable small network buffers check box" ) );
@ -138,14 +138,14 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
"connection properties." ) + "<br>" + tr ( "connection properties." ) + "<br>" + tr (
"Three buffer sizes are supported" ) + "Three buffer sizes are supported" ) +
":<ul>" ":<ul>"
"<li>" + tr ( "64 samples: This is the preferred setting since it gives lowest " "<li>" + tr ( "64 samples: This is the preferred setting since it provides the lowest "
"latency but does not work with all sound cards." ) + "</li>" "latency but does not work with all sound cards." ) + "</li>"
"<li>" + tr ( "128 samples: This setting should work on most of the available " "<li>" + tr ( "128 samples: This setting should work for most available "
"sound cards." ) + "</li>" "sound cards." ) + "</li>"
"<li>" + tr ( "256 samples: This setting should only be used if only a very slow " "<li>" + tr ( "256 samples: This setting should only be used if only a very slow "
"computer or a slow internet connection is available." ) + "</li>" "computer or a slow internet connection is available." ) + "</li>"
"</ul>" + tr ( "</ul>" + tr (
"Some sound card driver do not allow the buffer delay to be changed " "Some sound card drivers do not allow the buffer delay to be changed "
"from within the " ) + APP_NAME + "from within the " ) + APP_NAME +
tr ( " software. In this case the buffer delay setting " tr ( " software. In this case the buffer delay setting "
"is disabled. To change the actual buffer delay, this " "is disabled. To change the actual buffer delay, this "
@ -158,7 +158,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
"performance." ) + "<br>" + tr ( "performance." ) + "<br>" + tr (
"The actual buffer delay has influence on the connection status, the " "The actual buffer delay has influence on the connection status, the "
"current upload rate and the overall delay. The lower the buffer size, " "current upload rate and the overall delay. The lower the buffer size, "
"the higher the probability of red light in the status indicator (drop " "the higher the probability of a red light in the status indicator (drop "
"outs) and the higher the upload rate and the lower the overall " "outs) and the higher the upload rate and the lower the overall "
"delay." ) + "<br>" + tr ( "delay." ) + "<br>" + tr (
"The buffer setting is therefore a trade-off between audio " "The buffer setting is therefore a trade-off between audio "
@ -200,10 +200,10 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
QString strAudioChannels = "<b>" + tr ( "Audio Channels" ) + ":</b> " + tr ( QString strAudioChannels = "<b>" + tr ( "Audio Channels" ) + ":</b> " + tr (
"Select the number of audio channels to be used. There are three " "Select the number of audio channels to be used. There are three "
"modes available. The mono and stereo modes use one and two " "modes available. The mono and stereo modes use one and two "
"audio channels respectively. In the mono-in/stereo-out mode " "audio channels respectively. In mono-in/stereo-out mode "
"the audio signal which is sent to the server is mono but the " "the audio signal which is sent to the server is mono but the "
"return signal is stereo. This is useful for the case that the " "return signal is stereo. This is useful if the "
"sound card puts the instrument on one input channel and the " "sound card has the instrument on one input channel and the "
"microphone on the other channel. In that case the two input signals " "microphone on the other channel. In that case the two input signals "
"can be mixed to one mono channel but the server mix can be heard in " "can be mixed to one mono channel but the server mix can be heard in "
"stereo." ) + "<br>" + tr ( "stereo." ) + "<br>" + tr (
@ -242,24 +242,21 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
edtNewClientLevel->setWhatsThis ( strNewClientLevel ); edtNewClientLevel->setWhatsThis ( strNewClientLevel );
edtNewClientLevel->setAccessibleName ( tr ( "New client level edit box" ) ); edtNewClientLevel->setAccessibleName ( tr ( "New client level edit box" ) );
// central server address // custom central server address
QString strCentrServAddr = "<b>" + tr ( "Central Server Address" ) + ":</b> " + QString strCentrServAddr = "<b>" + tr ( "Custom Central Server Address" ) + ":</b> " +
tr ( "The central server address is the IP address or URL of the central server " tr ( "The custom central server address is the IP address or URL of the central "
"at which the server list of the connection dialog is managed. With the " "server at which the server list of the connection dialog is managed. This "
"central server address type either the local region can be selected of " "address is only used if the custom server list is selected in the connection "
"the default central servers or a manual address can be specified." ); "dialog." );
lblCentralServerAddress->setWhatsThis ( strCentrServAddr ); lblCentralServerAddress->setWhatsThis ( strCentrServAddr );
cbxCentServAddrType->setWhatsThis ( strCentrServAddr );
edtCentralServerAddress->setWhatsThis ( strCentrServAddr ); edtCentralServerAddress->setWhatsThis ( strCentrServAddr );
cbxCentServAddrType->setAccessibleName ( tr ( "Default central server type combo box" ) );
edtCentralServerAddress->setAccessibleName ( tr ( "Central server address line edit" ) ); edtCentralServerAddress->setAccessibleName ( tr ( "Central server address line edit" ) );
// current connection status parameter // current connection status parameter
QString strConnStats = "<b>" + tr ( "Current Connection Status " QString strConnStats = "<b>" + tr ( "Current Connection Status "
"Parameter" ) + ":</b> " + tr ( "The ping time is the time required for the audio " "Parameter" ) + ":</b> " + tr ( "The ping time is the time required for the audio "
"stream to travel from the client to the server and backwards. This " "stream to travel from the client to the server and back again. This "
"delay is introduced by the network. This delay should be as low as " "delay is introduced by the network. This delay should be as low as "
"20-30 ms. If this delay is higher (e.g., 50-60 ms), your distance to " "20-30 ms. If this delay is higher (e.g., 50-60 ms), your distance to "
"the server is too large or your internet connection is not " "the server is too large or your internet connection is not "
@ -344,15 +341,8 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
cbxAudioQuality->addItem ( tr ( "High" ) ); // AQ_HIGH cbxAudioQuality->addItem ( tr ( "High" ) ); // AQ_HIGH
cbxAudioQuality->setCurrentIndex ( static_cast<int> ( pClient->GetAudioQuality() ) ); cbxAudioQuality->setCurrentIndex ( static_cast<int> ( pClient->GetAudioQuality() ) );
// central server address type combo box // custom central server address
cbxCentServAddrType->clear(); edtCentralServerAddress->setText ( pClient->GetServerListCentralServerAddress() );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_CUSTOM ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_DEFAULT ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENERAL_NORTHAMERICA ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_ROCK ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_JAZZ ) );
cbxCentServAddrType->setCurrentIndex ( static_cast<int> ( pClient->GetCentralServerAddressType() ) );
UpdateCentralServerDependency();
// update new client fader level edit box // update new client fader level edit box
edtNewClientLevel->setText ( QString::number ( pClient->iNewClientFaderLevel ) ); edtNewClientLevel->setText ( QString::number ( pClient->iNewClientFaderLevel ) );
@ -433,9 +423,6 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
QObject::connect ( cbxAudioQuality, SIGNAL ( activated ( int ) ), QObject::connect ( cbxAudioQuality, SIGNAL ( activated ( int ) ),
this, SLOT ( OnAudioQualityActivated ( int ) ) ); this, SLOT ( OnAudioQualityActivated ( int ) ) );
QObject::connect ( cbxCentServAddrType, SIGNAL ( activated ( int ) ),
this, SLOT ( OnCentServAddrTypeActivated ( int ) ) );
// buttons // buttons
QObject::connect ( butDriverSetup, SIGNAL ( clicked() ), QObject::connect ( butDriverSetup, SIGNAL ( clicked() ),
this, SLOT ( OnDriverSetupClicked() ) ); this, SLOT ( OnDriverSetupClicked() ) );
@ -445,10 +432,6 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
SIGNAL ( buttonClicked ( QAbstractButton* ) ), this, SIGNAL ( buttonClicked ( QAbstractButton* ) ), this,
SLOT ( OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* ) ) ); SLOT ( OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* ) ) );
QObject::connect ( pClient,
SIGNAL ( CentralServerAddressTypeChanged() ),
this, SLOT ( OnCentralServerAddressTypeChanged() ) );
// Timers ------------------------------------------------------------------ // Timers ------------------------------------------------------------------
// start timer for status bar // start timer for status bar
@ -585,40 +568,6 @@ void CClientSettingsDlg::UpdateSoundChannelSelectionFrame()
#endif #endif
} }
void CClientSettingsDlg::UpdateCentralServerDependency()
{
const bool bCurUseDefCentServAddr = ( pClient->GetCentralServerAddressType() != AT_CUSTOM );
// update server type combo box (because the value may have ben changed
// by a control in another dialog, e.g., the connect dialog),
// since it is just an update, do not fire signals for the update
cbxCentServAddrType->blockSignals ( true );
cbxCentServAddrType->setCurrentIndex ( static_cast<int> ( pClient->GetCentralServerAddressType() ) );
cbxCentServAddrType->blockSignals ( false );
// make sure the line edit does not fire signals when we update the text
edtCentralServerAddress->blockSignals ( true );
{
if ( bCurUseDefCentServAddr )
{
// if the default central server is used, just show a text of the
// server name
edtCentralServerAddress->setText ( tr ( "Predefined Address" ) );
}
else
{
// show the current user defined server address
edtCentralServerAddress->setText (
pClient->GetServerListCentralServerAddress() );
}
}
edtCentralServerAddress->blockSignals ( false );
// the line edit of the central server address is only enabled, if not the
// default address is used
edtCentralServerAddress->setEnabled ( !bCurUseDefCentServAddr );
}
void CClientSettingsDlg::OnDriverSetupClicked() void CClientSettingsDlg::OnDriverSetupClicked()
{ {
pClient->OpenSndCrdDriverSetup(); pClient->OpenSndCrdDriverSetup();
@ -692,15 +641,6 @@ void CClientSettingsDlg::OnAudioQualityActivated ( int iQualityIdx )
UpdateDisplay(); // upload rate will be changed UpdateDisplay(); // upload rate will be changed
} }
void CClientSettingsDlg::OnCentServAddrTypeActivated ( int iTypeIdx )
{
// apply new setting to the client
pClient->SetCentralServerAddressType ( static_cast<ECSAddType> ( iTypeIdx ) );
// update GUI dependencies
UpdateCentralServerDependency();
}
void CClientSettingsDlg::OnAutoJitBufStateChanged ( int value ) void CClientSettingsDlg::OnAutoJitBufStateChanged ( int value )
{ {
pClient->SetDoAutoSockBufSize ( value == Qt::Checked ); pClient->SetDoAutoSockBufSize ( value == Qt::Checked );

View File

@ -73,7 +73,6 @@ protected:
void UpdateJitterBufferFrame(); void UpdateJitterBufferFrame();
void UpdateSoundCardFrame(); void UpdateSoundCardFrame();
void UpdateSoundChannelSelectionFrame(); void UpdateSoundChannelSelectionFrame();
void UpdateCentralServerDependency();
QString GenSndCrdBufferDelayString ( const int iFrameSize, QString GenSndCrdBufferDelayString ( const int iFrameSize,
const QString strAddText = "" ); const QString strAddText = "" );
@ -101,8 +100,6 @@ protected:
void OnROutChanActivated ( int iChanIdx ); void OnROutChanActivated ( int iChanIdx );
void OnAudioChannelsActivated ( int iChanIdx ); void OnAudioChannelsActivated ( int iChanIdx );
void OnAudioQualityActivated ( int iQualityIdx ); void OnAudioQualityActivated ( int iQualityIdx );
void OnCentServAddrTypeActivated ( int iTypeIdx );
void OnCentralServerAddressTypeChanged() { UpdateCentralServerDependency(); }
void OnDriverSetupClicked(); void OnDriverSetupClicked();
signals: signals:

View File

@ -554,20 +554,13 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout">
<item> <item>
<widget class="QLabel" name="lblCentralServerAddress"> <widget class="QLabel" name="lblCentralServerAddress">
<property name="text"> <property name="text">
<string>Central Server Address:</string> <string>Custom Central Server Address:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QComboBox" name="cbxCentServAddrType"/>
</item>
</layout>
</item>
<item> <item>
<widget class="QLineEdit" name="edtCentralServerAddress"> <widget class="QLineEdit" name="edtCentralServerAddress">
<property name="sizePolicy"> <property name="sizePolicy">
@ -735,7 +728,6 @@
<tabstop>edtNewClientLevel</tabstop> <tabstop>edtNewClientLevel</tabstop>
<tabstop>chbGUIDesignFancy</tabstop> <tabstop>chbGUIDesignFancy</tabstop>
<tabstop>chbDisplayChannelLevels</tabstop> <tabstop>chbDisplayChannelLevels</tabstop>
<tabstop>cbxCentServAddrType</tabstop>
<tabstop>edtCentralServerAddress</tabstop> <tabstop>edtCentralServerAddress</tabstop>
</tabstops> </tabstops>
<resources> <resources>

View File

@ -78,11 +78,16 @@ CConnectDlg::CConnectDlg ( CClient* pNCliP,
// central server address type combo box // central server address type combo box
cbxCentServAddrType->clear(); cbxCentServAddrType->clear();
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_CUSTOM ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_DEFAULT ) ); cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_DEFAULT ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENERAL_NORTHAMERICA ) ); cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_ALL_GENRES ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_ROCK ) ); cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_ROCK ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_JAZZ ) ); cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_JAZZ ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_CLASSICAL_FOLK ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_CUSTOM ) );
cbxCentServAddrType->setWhatsThis ( "<b>" + tr ( "Server List Selection" ) + ":</b> " + tr (
"Selects the server list to be shown." ) );
cbxCentServAddrType->setAccessibleName ( tr ( "Server list selection combo box" ) );
// filter // filter
edtFilter->setWhatsThis ( "<b>" + tr ( "Filter" ) + ":</b> " + tr ( "The server " edtFilter->setWhatsThis ( "<b>" + tr ( "Filter" ) + ":</b> " + tr ( "The server "

View File

@ -104,9 +104,10 @@ LED bar: lbr
// default server address and port numbers // default server address and port numbers
#define DEFAULT_SERVER_ADDRESS "jamulus.fischvolk.de" #define DEFAULT_SERVER_ADDRESS "jamulus.fischvolk.de"
#define DEFAULT_PORT_NUMBER 22124 #define DEFAULT_PORT_NUMBER 22124
#define CENTSERV_GENERAL_NORTHAMERICA "jamulus.fischvolk.de:22224" #define CENTSERV_ALL_GENRES "jamulusallgenres.fischvolk.de:22224"
#define CENTSERV_GENRE_ROCK "centralrock.drealm.info:22124" #define CENTSERV_GENRE_ROCK "jamulusrock.fischvolk.de:22424"
#define CENTSERV_GENRE_JAZZ "centraljazz.drealm.info:22224" #define CENTSERV_GENRE_JAZZ "jamulusjazz.fischvolk.de:22324"
#define CENTSERV_GENRE_CLASSICAL_FOLK "jamulusclassical.fischvolk.de:22524"
// getting started and software manual URL // getting started and software manual URL
#define CLIENT_GETTING_STARTED_URL "https://github.com/corrados/jamulus/wiki/Getting-Started" #define CLIENT_GETTING_STARTED_URL "https://github.com/corrados/jamulus/wiki/Getting-Started"

View File

@ -71,6 +71,13 @@ MESSAGES (with connection)
+-------------------+-----------------+ +-------------------+-----------------+
- PROTMESSID_MUTE_STATE_CHANGED: Mute state of your signal at another client has changed
+-------------------+-----------------+
| 1 byte channel ID | 1 byte is muted |
+-------------------+-----------------+
- PROTMESSID_CONN_CLIENTS_LIST: Information about connected clients - PROTMESSID_CONN_CLIENTS_LIST: Information about connected clients
for each connected client append following data: for each connected client append following data:
@ -590,6 +597,10 @@ if ( rand() < ( RAND_MAX / 2 ) ) return false;
bRet = EvaluateChanPanMes ( vecbyMesBodyData ); bRet = EvaluateChanPanMes ( vecbyMesBodyData );
break; break;
case PROTMESSID_MUTE_STATE_CHANGED:
bRet = EvaluateMuteStateHasChangedMes ( vecbyMesBodyData );
break;
case PROTMESSID_CONN_CLIENTS_LIST: case PROTMESSID_CONN_CLIENTS_LIST:
bRet = EvaluateConClientListMes ( vecbyMesBodyData ); bRet = EvaluateConClientListMes ( vecbyMesBodyData );
break; break;
@ -872,6 +883,43 @@ bool CProtocol::EvaluateChanPanMes ( const CVector<uint8_t> &vecData )
return false; // no error return false; // no error
} }
void CProtocol::CreateMuteStateHasChangedMes ( const int iChanID, const bool bIsMuted )
{
CVector<uint8_t> vecData ( 2 ); // 2 bytes of data
int iPos = 0; // init position pointer
// build data vector
// channel ID
PutValOnStream ( vecData, iPos, static_cast<uint32_t> ( iChanID ), 1 );
// mute state
PutValOnStream ( vecData, iPos, static_cast<uint32_t> ( bIsMuted ), 1 );
CreateAndSendMessage ( PROTMESSID_MUTE_STATE_CHANGED, vecData );
}
bool CProtocol::EvaluateMuteStateHasChangedMes ( const CVector<uint8_t> &vecData )
{
int iPos = 0; // init position pointer
// check size
if ( vecData.Size() != 2 )
{
return true; // return error code
}
// channel ID
const int iCurID = static_cast<int> ( GetValFromStream ( vecData, iPos, 1 ) );
// mute state
const bool bIsMuted = static_cast<bool> ( GetValFromStream ( vecData, iPos, 1 ) );
// invoke message action
emit MuteStateHasChangedReceived ( iCurID, bIsMuted );
return false; // no error
}
void CProtocol::CreateConClientListMes ( const CVector<CChannelInfo>& vecChanInfo ) void CProtocol::CreateConClientListMes ( const CVector<CChannelInfo>& vecChanInfo )
{ {
const int iNumClients = vecChanInfo.Size(); const int iNumClients = vecChanInfo.Size();

View File

@ -57,6 +57,7 @@
#define PROTMESSID_REQ_CHANNEL_LEVEL_LIST 28 // request the channel level list #define PROTMESSID_REQ_CHANNEL_LEVEL_LIST 28 // request the channel level list
#define PROTMESSID_VERSION_AND_OS 29 // version number and operating system #define PROTMESSID_VERSION_AND_OS 29 // version number and operating system
#define PROTMESSID_CHANNEL_PAN 30 // set channel pan for mix #define PROTMESSID_CHANNEL_PAN 30 // set channel pan for mix
#define PROTMESSID_MUTE_STATE_CHANGED 31 // mute state of your signal at another client has changed
// message IDs of connection less messages (CLM) // message IDs of connection less messages (CLM)
// DEFINITION -> start at 1000, end at 1999, see IsConnectionLessMessageID // DEFINITION -> start at 1000, end at 1999, see IsConnectionLessMessageID
@ -99,6 +100,7 @@ public:
void CreateReqJitBufMes(); void CreateReqJitBufMes();
void CreateChanGainMes ( const int iChanID, const double dGain ); void CreateChanGainMes ( const int iChanID, const double dGain );
void CreateChanPanMes ( const int iChanID, const double dPan ); void CreateChanPanMes ( const int iChanID, const double dPan );
void CreateMuteStateHasChangedMes ( const int iChanID, const bool bIsMuted );
void CreateConClientListMes ( const CVector<CChannelInfo>& vecChanInfo ); void CreateConClientListMes ( const CVector<CChannelInfo>& vecChanInfo );
void CreateReqConnClientsList(); void CreateReqConnClientsList();
void CreateChanInfoMes ( const CChannelCoreInfo ChanInfo ); void CreateChanInfoMes ( const CChannelCoreInfo ChanInfo );
@ -223,6 +225,7 @@ protected:
bool EvaluateReqJitBufMes(); bool EvaluateReqJitBufMes();
bool EvaluateChanGainMes ( const CVector<uint8_t>& vecData ); bool EvaluateChanGainMes ( const CVector<uint8_t>& vecData );
bool EvaluateChanPanMes ( const CVector<uint8_t>& vecData ); bool EvaluateChanPanMes ( const CVector<uint8_t>& vecData );
bool EvaluateMuteStateHasChangedMes ( const CVector<uint8_t>& vecData );
bool EvaluateConClientListMes ( const CVector<uint8_t>& vecData ); bool EvaluateConClientListMes ( const CVector<uint8_t>& vecData );
bool EvaluateReqConnClientsList(); bool EvaluateReqConnClientsList();
bool EvaluateChanInfoMes ( const CVector<uint8_t>& vecData ); bool EvaluateChanInfoMes ( const CVector<uint8_t>& vecData );
@ -283,6 +286,7 @@ signals:
void ChangeNetwBlSiFact ( int iNewNetwBlSiFact ); void ChangeNetwBlSiFact ( int iNewNetwBlSiFact );
void ChangeChanGain ( int iChanID, double dNewGain ); void ChangeChanGain ( int iChanID, double dNewGain );
void ChangeChanPan ( int iChanID, double dNewPan ); void ChangeChanPan ( int iChanID, double dNewPan );
void MuteStateHasChangedReceived ( int iCurID, bool bIsMuted );
void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo ); void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo );
void ServerFullMesReceived(); void ServerFullMesReceived();
void ReqConnClientsList(); void ReqConnClientsList();

View File

@ -109,6 +109,7 @@ void CJamClient::Disconnect()
CJamSession::CJamSession(QDir recordBaseDir) : CJamSession::CJamSession(QDir recordBaseDir) :
sessionDir (QDir(recordBaseDir.absoluteFilePath("Jam-" + QDateTime().currentDateTimeUtc().toString("yyyyMMdd-HHmmsszzz")))), sessionDir (QDir(recordBaseDir.absoluteFilePath("Jam-" + QDateTime().currentDateTimeUtc().toString("yyyyMMdd-HHmmsszzz")))),
currentFrame (0), currentFrame (0),
chIdDisconnected (-1),
vecptrJamClients (MAX_NUM_CHANNELS), vecptrJamClients (MAX_NUM_CHANNELS),
jamClientConnections() jamClientConnections()
{ {
@ -130,8 +131,6 @@ CJamSession::CJamSession(QDir recordBaseDir) :
// Explicitly set all the pointers to "empty" // Explicitly set all the pointers to "empty"
vecptrJamClients.fill(nullptr); vecptrJamClients.fill(nullptr);
currentFrame = 0;
} }
/** /**
@ -150,6 +149,7 @@ void CJamSession::DisconnectClient(int iChID)
delete vecptrJamClients[iChID]; delete vecptrJamClients[iChID];
vecptrJamClients[iChID] = nullptr; vecptrJamClients[iChID] = nullptr;
chIdDisconnected = iChID;
} }
/** /**
@ -167,6 +167,13 @@ void CJamSession::DisconnectClient(int iChID)
*/ */
void CJamSession::Frame(const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data, int iServerFrameSizeSamples) void CJamSession::Frame(const int iChID, const QString name, const CHostAddress address, const int numAudioChannels, const CVector<int16_t> data, int iServerFrameSizeSamples)
{ {
if ( iChID == chIdDisconnected )
{
// DisconnectClient has just been called for this channel - this frame is "too late"
chIdDisconnected = -1;
return;
}
if (vecptrJamClients[iChID] == nullptr) if (vecptrJamClients[iChID] == nullptr)
{ {
// then we have not seen this client this session // then we have not seen this client this session

View File

@ -128,6 +128,7 @@ private:
const QDir sessionDir; const QDir sessionDir;
qint64 currentFrame; qint64 currentFrame;
int chIdDisconnected;
QVector<CJamClient*> vecptrJamClients; QVector<CJamClient*> vecptrJamClients;
QList<CJamClientConnection*> jamClientConnections; QList<CJamClientConnection*> jamClientConnections;
}; };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -497,6 +497,9 @@ inline void CServer::connectChannelSignalsToServerSlots()
void ( CServer::* pOnChatTextReceivedCh )( QString ) = void ( CServer::* pOnChatTextReceivedCh )( QString ) =
&CServerSlots<slotId>::OnChatTextReceivedCh; &CServerSlots<slotId>::OnChatTextReceivedCh;
void ( CServer::* pOnMuteStateHasChangedCh )( int, bool ) =
&CServerSlots<slotId>::OnMuteStateHasChangedCh;
void ( CServer::* pOnServerAutoSockBufSizeChangeCh )( int ) = void ( CServer::* pOnServerAutoSockBufSizeChangeCh )( int ) =
&CServerSlots<slotId>::OnServerAutoSockBufSizeChangeCh; &CServerSlots<slotId>::OnServerAutoSockBufSizeChangeCh;
@ -516,6 +519,10 @@ inline void CServer::connectChannelSignalsToServerSlots()
QObject::connect ( &vecChannels[iCurChanID], &CChannel::ChatTextReceived, QObject::connect ( &vecChannels[iCurChanID], &CChannel::ChatTextReceived,
this, pOnChatTextReceivedCh ); this, pOnChatTextReceivedCh );
// other mute state has changed
QObject::connect ( &vecChannels[iCurChanID], &CChannel::MuteStateHasChanged,
this, pOnMuteStateHasChangedCh );
// auto socket buffer size change // auto socket buffer size change
QObject::connect ( &vecChannels[iCurChanID], &CChannel::ServerAutoSockBufSizeChange, QObject::connect ( &vecChannels[iCurChanID], &CChannel::ServerAutoSockBufSizeChange,
this, pOnServerAutoSockBufSizeChangeCh ); this, pOnServerAutoSockBufSizeChangeCh );
@ -739,7 +746,7 @@ void CServer::Stop()
void CServer::OnTimer() void CServer::OnTimer()
{ {
int i, j, iUnused; int i, j, iUnused;
int iClientFrameSizeSamples; int iClientFrameSizeSamples = 0; // initialize to avoid a compiler warning
OpusCustomDecoder* CurOpusDecoder; OpusCustomDecoder* CurOpusDecoder;
OpusCustomEncoder* CurOpusEncoder; OpusCustomEncoder* CurOpusEncoder;
unsigned char* pCurCodedData; unsigned char* pCurCodedData;
@ -1310,6 +1317,17 @@ void CServer::CreateAndSendChatTextForAllConChannels ( const int iCurChanID
} }
} }
void CServer::CreateOtherMuteStateChanged ( const int iCurChanID,
const int iOtherChanID,
const bool bIsMuted )
{
if ( vecChannels[iOtherChanID].IsConnected() )
{
// send message
vecChannels[iOtherChanID].CreateMuteStateHasChangedMes ( iCurChanID, bIsMuted );
}
}
int CServer::GetFreeChan() int CServer::GetFreeChan()
{ {
// look for a free channel // look for a free channel

View File

@ -117,10 +117,10 @@ signals:
}; };
#endif #endif
template<unsigned int slotId> template<unsigned int slotId>
class CServerSlots : public CServerSlots<slotId - 1> class CServerSlots : public CServerSlots<slotId - 1>
{ {
public: public:
void OnSendProtMessCh ( CVector<uint8_t> mess ) { SendProtMessage ( slotId - 1, mess ); } void OnSendProtMessCh ( CVector<uint8_t> mess ) { SendProtMessage ( slotId - 1, mess ); }
void OnReqConnClientsListCh() { CreateAndSendChanListForThisChan ( slotId - 1 ); } void OnReqConnClientsListCh() { CreateAndSendChanListForThisChan ( slotId - 1 ); }
@ -130,6 +130,11 @@ public:
CreateAndSendChatTextForAllConChannels ( slotId - 1, strChatText ); CreateAndSendChatTextForAllConChannels ( slotId - 1, strChatText );
} }
void OnMuteStateHasChangedCh ( int iChanID, bool bIsMuted )
{
CreateOtherMuteStateChanged ( slotId - 1, iChanID, bIsMuted );
}
void OnServerAutoSockBufSizeChangeCh ( int iNNumFra ) void OnServerAutoSockBufSizeChangeCh ( int iNNumFra )
{ {
CreateAndSendJitBufMessage ( slotId - 1, iNNumFra ); CreateAndSendJitBufMessage ( slotId - 1, iNNumFra );
@ -144,6 +149,10 @@ protected:
virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID,
const QString& strChatText ) = 0; const QString& strChatText ) = 0;
virtual void CreateOtherMuteStateChanged ( const int iCurChanID,
const int iOtherChanID,
const bool bIsMuted ) = 0;
virtual void CreateAndSendJitBufMessage ( const int iCurChanID, virtual void CreateAndSendJitBufMessage ( const int iCurChanID,
const int iNNumFra ) = 0; const int iNNumFra ) = 0;
}; };
@ -256,6 +265,10 @@ protected:
virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID,
const QString& strChatText ); const QString& strChatText );
virtual void CreateOtherMuteStateChanged ( const int iCurChanID,
const int iOtherChanID,
const bool bIsMuted );
virtual void CreateAndSendJitBufMessage ( const int iCurChanID, virtual void CreateAndSendJitBufMessage ( const int iCurChanID,
const int iNNumFra ); const int iNNumFra );

View File

@ -66,29 +66,29 @@ CServerDlg::CServerDlg ( CServer* pNServP,
tr ( "If the Make My Server Public check box is checked, this server registers " tr ( "If the Make My Server Public check box is checked, this server registers "
"itself at the central server so that all " ) + APP_NAME + "itself at the central server so that all " ) + APP_NAME +
tr ( " users can see the server in the connect dialog server list and " tr ( " users can see the server in the connect dialog server list and "
"connect to it. The registering of the server is renewed periodically " "connect to it. The registration of the server is renewed periodically "
"to make sure that all servers in the connect dialog server list are " "to make sure that all servers in the connect dialog server list are "
"actually available." ) ); "actually available." ) );
// register server status label // register server status label
lblRegSvrStatus->setWhatsThis ( "<b>" + tr ( "Register Server Status" ) + ":</b> " + lblRegSvrStatus->setWhatsThis ( "<b>" + tr ( "Register Server Status" ) + ":</b> " +
tr ( "If the Make My Server Public check box is checked, this will show " tr ( "If the Make My Server Public check box is checked, this will show "
"the success of registration with the central server." ) ); "whether registration with the central server is successful. If the "
"registration failed, please choose another server list." ) );
// central server address // custom central server address
QString strCentrServAddr = "<b>" + tr ( "Central Server Address" ) + ":</b> " + QString strCentrServAddr = "<b>" + tr ( "Custom Central Server Address" ) + ":</b> " +
tr ( "The Central server address is the IP address or URL of the central server " tr ( "The custom central server address is the IP address or URL of the central "
"at which this server is registered. With the central server address " "server at which the server list of the connection dialog is managed." );
"type either the local region can be selected of the default central "
"servers or a manual address can be specified." );
lblCentralServerAddress->setWhatsThis ( strCentrServAddr ); lblCentralServerAddress->setWhatsThis ( strCentrServAddr );
cbxCentServAddrType->setWhatsThis ( strCentrServAddr );
edtCentralServerAddress->setWhatsThis ( strCentrServAddr ); edtCentralServerAddress->setWhatsThis ( strCentrServAddr );
cbxCentServAddrType->setAccessibleName ( tr ( "Default central server type combo box" ) );
edtCentralServerAddress->setAccessibleName ( tr ( "Central server address line edit" ) ); edtCentralServerAddress->setAccessibleName ( tr ( "Central server address line edit" ) );
cbxCentServAddrType->setWhatsThis ( "<b>" + tr ( "Server List Selection" ) + ":</b> " + tr (
"Selects the server list (i.e. central server address) in which your server will be added." ) );
cbxCentServAddrType->setAccessibleName ( tr ( "Server list selection combo box" ) );
// server name // server name
QString strServName = "<b>" + tr ( "Server Name" ) + ":</b> " + tr ( "The server name identifies " QString strServName = "<b>" + tr ( "Server Name" ) + ":</b> " + tr ( "The server name identifies "
"your server in the connect dialog server list at the clients. If no " "your server in the connect dialog server list at the clients. If no "
@ -188,11 +188,12 @@ lvwClients->setMinimumHeight ( 140 );
// central server address type combo box // central server address type combo box
cbxCentServAddrType->clear(); cbxCentServAddrType->clear();
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_CUSTOM ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_DEFAULT ) ); cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_DEFAULT ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENERAL_NORTHAMERICA ) ); cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_ALL_GENRES ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_ROCK ) ); cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_ROCK ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_JAZZ ) ); cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_JAZZ ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_CLASSICAL_FOLK ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_CUSTOM ) );
cbxCentServAddrType->setCurrentIndex ( static_cast<int> ( pServer->GetCentralServerAddressType() ) ); cbxCentServAddrType->setCurrentIndex ( static_cast<int> ( pServer->GetCentralServerAddressType() ) );
// update server name line edit // update server name line edit

View File

@ -69,6 +69,9 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QComboBox" name="cbxCentServAddrType"/>
</item>
<item> <item>
<spacer> <spacer>
<property name="orientation"> <property name="orientation">
@ -99,16 +102,13 @@
<item> <item>
<widget class="QLabel" name="lblCentralServerAddress"> <widget class="QLabel" name="lblCentralServerAddress">
<property name="text"> <property name="text">
<string>Central Server Address:</string> <string>Custom Central Server Address:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="edtCentralServerAddress"/> <widget class="QLineEdit" name="edtCentralServerAddress"/>
</item> </item>
<item>
<widget class="QComboBox" name="cbxCentServAddrType"/>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@ -210,8 +210,8 @@
<tabstop>chbStartOnOSStart</tabstop> <tabstop>chbStartOnOSStart</tabstop>
<tabstop>chbUseCCLicence</tabstop> <tabstop>chbUseCCLicence</tabstop>
<tabstop>chbRegisterServer</tabstop> <tabstop>chbRegisterServer</tabstop>
<tabstop>edtCentralServerAddress</tabstop>
<tabstop>cbxCentServAddrType</tabstop> <tabstop>cbxCentServAddrType</tabstop>
<tabstop>edtCentralServerAddress</tabstop>
<tabstop>edtServerName</tabstop> <tabstop>edtServerName</tabstop>
<tabstop>edtLocationCity</tabstop> <tabstop>edtLocationCity</tabstop>
<tabstop>cbxLocationCountry</tabstop> <tabstop>cbxLocationCountry</tabstop>

View File

@ -82,7 +82,7 @@ void CSettings::Load()
{ {
if ( GetNumericIniSet ( IniXMLDocument, "client", if ( GetNumericIniSet ( IniXMLDocument, "client",
QString ( "storedpanvalue%1" ).arg ( iIdx ), QString ( "storedpanvalue%1" ).arg ( iIdx ),
0, AUD_MIX_PAN_MAX/2, iValue ) ) 0, AUD_MIX_PAN_MAX, iValue ) )
{ {
pClient->vecStoredPanValues[iIdx] = iValue; pClient->vecStoredPanValues[iIdx] = iValue;
} }
@ -299,7 +299,7 @@ void CSettings::Load()
// central server address type // central server address type
if ( GetNumericIniSet ( IniXMLDocument, "client", "centservaddrtype", if ( GetNumericIniSet ( IniXMLDocument, "client", "centservaddrtype",
0, 4 /* AT_GENRE_JAZZ */, iValue ) ) 0, static_cast<int> ( AT_CUSTOM ), iValue ) )
{ {
pClient->SetCentralServerAddressType ( static_cast<ECSAddType> ( iValue ) ); pClient->SetCentralServerAddressType ( static_cast<ECSAddType> ( iValue ) );
} }
@ -370,7 +370,7 @@ if ( GetFlagIniSet ( IniXMLDocument, "client", "defcentservaddr", bValue ) )
// central server address type (note that it is important // central server address type (note that it is important
// to set this setting prior to the "central server address") // to set this setting prior to the "central server address")
if ( GetNumericIniSet ( IniXMLDocument, "server", "centservaddrtype", if ( GetNumericIniSet ( IniXMLDocument, "server", "centservaddrtype",
0, 4 /* AT_GENRE_JAZZ */, iValue ) ) 0, static_cast<int> ( AT_CUSTOM ), iValue ) )
{ {
pServer->SetCentralServerAddressType ( static_cast<ECSAddType> ( iValue ) ); pServer->SetCentralServerAddressType ( static_cast<ECSAddType> ( iValue ) );
} }

View File

@ -32,6 +32,7 @@
#include "global.h" #include "global.h"
#include "client.h" #include "client.h"
#include "server.h" #include "server.h"
#include "util.h"
/* Classes ********************************************************************/ /* Classes ********************************************************************/

View File

@ -139,7 +139,7 @@ QString CSoundBase::SetDev ( const int iNewDev )
// software anymore // software anymore
QMessageBox::critical ( QMessageBox::critical (
nullptr, APP_NAME, QString ( tr ( "The audio driver properties " nullptr, APP_NAME, QString ( tr ( "The audio driver properties "
"have changed to a state which is incompatible to this " "have changed to a state which is incompatible with this "
"software. The selected audio device could not be used " "software. The selected audio device could not be used "
"because of the following error:" ) + " <b>" ) + "because of the following error:" ) + " <b>" ) +
strErrorMessage + strErrorMessage +

View File

@ -705,8 +705,8 @@ CMusProfDlg::CMusProfDlg ( CClient* pNCliP,
QString strFaderTag = "<b>" + tr ( "Musician Profile" ) + ":</b> " + tr ( QString strFaderTag = "<b>" + tr ( "Musician Profile" ) + ":</b> " + tr (
"Set your name or an alias here so that the other musicians you want to play with " "Set your name or an alias here so that the other musicians you want to play with "
"know who you are. Additionally you may set an instrument picture of " "know who you are. Additionally you may set an instrument picture of "
"the instrument you play and a flag of the country you are living. " "the instrument you play and a flag of the country you are living in. "
"The city you live in and the skill level of playing your instrument " "The city you live in and the skill level playing your instrument "
"may also be added." ) + "<br>" + tr ( "may also be added." ) + "<br>" + tr (
"What you set here will appear at your fader on the mixer board when " "What you set here will appear at your fader on the mixer board when "
"you are connected to a " ) + APP_NAME + tr ( " server. This tag will " "you are connected to a " ) + APP_NAME + tr ( " server. This tag will "
@ -952,9 +952,10 @@ QString NetworkUtil::GetCentralServerAddress ( const ECSAddType eCentralServerAd
switch ( eCentralServerAddressType ) switch ( eCentralServerAddressType )
{ {
case AT_CUSTOM: return strCentralServerAddress; case AT_CUSTOM: return strCentralServerAddress;
case AT_GENERAL_NORTHAMERICA: return CENTSERV_GENERAL_NORTHAMERICA; case AT_ALL_GENRES: return CENTSERV_ALL_GENRES;
case AT_GENRE_ROCK: return CENTSERV_GENRE_ROCK; case AT_GENRE_ROCK: return CENTSERV_GENRE_ROCK;
case AT_GENRE_JAZZ: return CENTSERV_GENRE_JAZZ; case AT_GENRE_JAZZ: return CENTSERV_GENRE_JAZZ;
case AT_GENRE_CLASSICAL_FOLK: return CENTSERV_GENRE_CLASSICAL_FOLK;
default: return DEFAULT_SERVER_ADDRESS; // AT_DEFAULT default: return DEFAULT_SERVER_ADDRESS; // AT_DEFAULT
} }
} }
@ -1335,7 +1336,7 @@ ECSAddType CLocale::GetCentralServerAddressType ( const QLocale::Country eCountr
case QLocale::Canada: case QLocale::Canada:
case QLocale::Mexico: case QLocale::Mexico:
case QLocale::Greenland: case QLocale::Greenland:
return AT_GENERAL_NORTHAMERICA; return AT_ALL_GENRES;
default: default:
return AT_DEFAULT; return AT_DEFAULT;

View File

@ -506,7 +506,7 @@ private:
// Audio channel configuration ------------------------------------------------- // Audio channel configuration -------------------------------------------------
enum EAudChanConf enum EAudChanConf
{ {
// used for settings -> enum values must be fixed! // used for settings -> enum values should be fixed
CC_MONO = 0, CC_MONO = 0,
CC_MONO_IN_STEREO_OUT = 1, CC_MONO_IN_STEREO_OUT = 1,
CC_STEREO = 2 CC_STEREO = 2
@ -547,7 +547,7 @@ enum EGetDataStat
// GUI design enum ------------------------------------------------------------- // GUI design enum -------------------------------------------------------------
enum EGUIDesign enum EGUIDesign
{ {
// used for settings -> enum values must be fixed! // used for settings -> enum values should be fixed
GD_STANDARD = 0, GD_STANDARD = 0,
GD_ORIGINAL = 1 GD_ORIGINAL = 1
}; };
@ -565,12 +565,13 @@ enum ELicenceType
// Central server address type ------------------------------------------------- // Central server address type -------------------------------------------------
enum ECSAddType enum ECSAddType
{ {
// used for settings -> enum values must be fixed! // used for settings -> enum values should be fixed
AT_CUSTOM = 0, AT_DEFAULT = 0,
AT_DEFAULT = 1, AT_ALL_GENRES = 1,
AT_GENERAL_NORTHAMERICA = 2, AT_GENRE_ROCK = 2,
AT_GENRE_ROCK = 3, AT_GENRE_JAZZ = 3,
AT_GENRE_JAZZ = 4 AT_GENRE_CLASSICAL_FOLK = 4,
AT_CUSTOM = 5 // Must be the last entry!
}; };
inline QString csCentServAddrTypeToString ( ECSAddType eAddrType ) inline QString csCentServAddrTypeToString ( ECSAddType eAddrType )
@ -580,7 +581,7 @@ inline QString csCentServAddrTypeToString ( ECSAddType eAddrType )
case AT_CUSTOM: case AT_CUSTOM:
return QCoreApplication::translate ( "CClientSettingsDlg", "Custom" ); return QCoreApplication::translate ( "CClientSettingsDlg", "Custom" );
case AT_GENERAL_NORTHAMERICA: case AT_ALL_GENRES:
return QCoreApplication::translate ( "CClientSettingsDlg", "All Genres" ); return QCoreApplication::translate ( "CClientSettingsDlg", "All Genres" );
case AT_GENRE_ROCK: case AT_GENRE_ROCK:
@ -589,6 +590,9 @@ inline QString csCentServAddrTypeToString ( ECSAddType eAddrType )
case AT_GENRE_JAZZ: case AT_GENRE_JAZZ:
return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Jazz" ); return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Jazz" );
case AT_GENRE_CLASSICAL_FOLK:
return QCoreApplication::translate ( "CClientSettingsDlg", "Genre Classical/Folk/Choir" );
default: // AT_DEFAULT default: // AT_DEFAULT
return QCoreApplication::translate ( "CClientSettingsDlg", "Default" ); return QCoreApplication::translate ( "CClientSettingsDlg", "Default" );
} }

View File

@ -118,7 +118,7 @@ QString CSound::CheckDeviceCapabilities()
( SetSaRateReturn == ASE_NotPresent ) ) ( SetSaRateReturn == ASE_NotPresent ) )
{ {
// return error string // return error string
return tr ( "The audio device does not support to set the required sampling " return tr ( "The audio device does not support setting the required sampling "
"rate. This error can happen if you have an audio interface like the " "rate. This error can happen if you have an audio interface like the "
"Roland UA-25EX where you set the sample rate with a hardware switch " "Roland UA-25EX where you set the sample rate with a hardware switch "
"on the audio device. If this is the case, please change the sample rate " "on the audio device. If this is the case, please change the sample rate "
@ -517,7 +517,7 @@ CSound::CSound ( void (*fpNewCallback) ( CVector<int16_t>& psData, voi
{ {
throw CGenErr ( "<b>" + tr ( "No ASIO audio device (driver) found." ) + "</b><br><br>" + throw CGenErr ( "<b>" + tr ( "No ASIO audio device (driver) found." ) + "</b><br><br>" +
tr ( "The " ) + APP_NAME + tr ( " software requires the low latency audio " tr ( "The " ) + APP_NAME + tr ( " software requires the low latency audio "
"interface ASIO to work properly. This is no standard " "interface ASIO to work properly. This is not a standard "
"Windows audio interface and therefore a special audio driver is " "Windows audio interface and therefore a special audio driver is "
"required. Either your sound card has a native ASIO driver (which " "required. Either your sound card has a native ASIO driver (which "
"is recommended) or you might want to use alternative drivers like " "is recommended) or you might want to use alternative drivers like "