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
- 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)
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
- save client settings on Linux cmdline termination signal, coded by pljones (#70)
@ -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
- 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,
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
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
@ -74,21 +62,21 @@ TODO fix incorrect what's this help texts
- 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 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: 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)
@ -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
- 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
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
mode it is still compatible to both, 64 and 128 samples frame size clients)
- 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)
@ -145,7 +133,7 @@ TODO fix incorrect what's this help texts
- 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)
@ -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 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

View file

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

View file

@ -1,6 +1,16 @@
#!/bin/bash
# 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"
NCORES=$(nproc)

View file

@ -41,6 +41,7 @@ CChannelFader::CChannelFader ( QWidget* pNW,
pFader = new QSlider ( Qt::Vertical, pLevelsBox );
pPan = new QDial ( pLevelsBox );
pPanLabel = new QLabel ( tr ( "Pan" ) , pLevelsBox );
pInfoLabel = new QLabel ( "", pLevelsBox );
pMuteSoloBox = new QWidget ( pFrame );
pcbMute = new QCheckBox ( tr ( "Mute" ), pMuteSoloBox );
@ -57,6 +58,7 @@ CChannelFader::CChannelFader ( QWidget* pNW,
QHBoxLayout* pLabelGrid = new QHBoxLayout ( pLabelInstBox );
QVBoxLayout* pLabelPictGrid = new QVBoxLayout ( );
QVBoxLayout* pPanGrid = new QVBoxLayout ( );
QHBoxLayout* pPanInfoGrid = new QHBoxLayout ( );
// setup channel level
plbrChannelLevel->setContentsMargins ( 0, 3, 2, 3 );
@ -66,14 +68,16 @@ CChannelFader::CChannelFader ( QWidget* pNW,
pFader->setTickPosition ( QSlider::TicksBothSides );
pFader->setRange ( 0, AUD_MIX_FADER_MAX );
pFader->setTickInterval ( AUD_MIX_FADER_MAX / 9 );
pFader->setMinimumHeight ( 90 );
pFader->setMinimumHeight ( 75 );
// setup panning control
pPan->setRange ( 0, AUD_MIX_PAN_MAX );
pPan->setValue ( AUD_MIX_PAN_MAX / 2 );
pPan->setFixedSize ( 55, 55 );
pPan->setFixedSize ( 50, 50 );
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 );
// 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 "
"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 (
"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" ) );
pcbMute->setWhatsThis ( "<b>" + tr ( "Mute" ) + ":</b> " + tr (
@ -225,6 +236,7 @@ bool CChannelFader::GetDisplayChannelLevel()
void CChannelFader::SetDisplayPans ( const bool eNDP )
{
pInfoLabel->setHidden ( !eNDP );
pPanLabel->setHidden ( !eNDP );
pPan->setHidden ( !eNDP );
}
@ -275,6 +287,9 @@ void CChannelFader::SetupFaderTag ( const ESkillLevel eSkillLevel )
void CChannelFader::Reset()
{
// general initializations
SetRemoteFaderIsMute ( false );
// init gain and pan value -> maximum value as definition according to server
pFader->setValue ( AUD_MIX_FADER_MAX );
pPan->setValue ( AUD_MIX_PAN_MAX / 2 );
@ -339,6 +354,22 @@ void CChannelFader::SetFaderIsMute ( const bool 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 )
{
// 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 ( QWidget* parent, Qt::WindowFlags ) :
QScrollArea ( parent ),
QGroupBox ( parent ),
vecStoredFaderTags ( MAX_NUM_STORED_FADER_SETTINGS, "" ),
vecStoredFaderLevels ( MAX_NUM_STORED_FADER_SETTINGS, AUD_MIX_FADER_MAX ),
vecStoredPanValues ( MAX_NUM_STORED_FADER_SETTINGS, AUD_MIX_PAN_MAX / 2 ),
vecStoredFaderIsSolo ( MAX_NUM_STORED_FADER_SETTINGS, false ),
vecStoredFaderIsMute ( MAX_NUM_STORED_FADER_SETTINGS, false ),
iNewClientFaderLevel ( 100 ),
bDisplayPans ( false ),
bIsPanSupported ( false ),
bNoFaderVisible ( true ),
strServerName ( "" )
{
// add group box and hboxlayout
pGroupBox = new QGroupBox(); // will be added to the scroll area which is then the parent
pMainLayout = new QHBoxLayout ( pGroupBox );
QHBoxLayout* pGroupBoxLayout = new QHBoxLayout ( this );
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)
SetServerName ( "" );
@ -601,11 +636,15 @@ CAudioMixerBoard::CAudioMixerBoard ( QWidget* parent, Qt::WindowFlags ) :
// insert horizontal spacer
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
setMinimumWidth ( 200 ); // at least two faders shall be visible
setWidget ( pGroupBox );
setWidgetResizable ( true ); // make sure it fills the entire scroll area
setFrameShape ( QFrame::NoFrame );
pScrollArea->setMinimumWidth ( 200 ); // at least two faders shall be visible
pScrollArea->setWidget ( pMixerWidget );
pScrollArea->setWidgetResizable ( true ); // make sure it fills the entire scroll area
pScrollArea->setFrameShape ( QFrame::NoFrame );
pGroupBoxLayout->addWidget ( pScrollArea );
// Connections -------------------------------------------------------------
@ -646,7 +685,7 @@ void CAudioMixerBoard::SetServerName ( const QString& strNewServerName )
if ( strServerName.isEmpty() )
{
// no connection or connection was reset: show default title
pGroupBox->setTitle ( tr ( "Server" ) );
setTitle ( tr ( "Server" ) );
}
else
{
@ -655,7 +694,7 @@ void CAudioMixerBoard::SetServerName ( const QString& strNewServerName )
// 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
// 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++ )
{
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
// sure that the fader label is visible (scroll down completely)
ensureVisible ( 0, 2000 ); // use a large value here
QScrollArea::resizeEvent ( event );
bIsPanSupported = true;
SetDisplayPans ( bDisplayPans );
}
void CAudioMixerBoard::HideAll()
@ -714,7 +753,8 @@ void CAudioMixerBoard::HideAll()
vecpChanFader[i]->Hide();
}
// set flag
// set flags
bIsPanSupported = false;
bNoFaderVisible = true;
// 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
if ( bNoFaderVisible )
{
pGroupBox->setTitle ( tr ( "Personal Mix at the Server: " ) + strServerName );
setTitle ( tr ( "Personal Mix at the Server: " ) + strServerName );
}
// 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()
{
// first check if any channel has a solo state active

View file

@ -66,6 +66,7 @@ public:
void SetPanValue ( const int iPan );
void SetFaderIsSolo ( const bool bIsSolo );
void SetFaderIsMute ( const bool bIsMute );
void SetRemoteFaderIsMute ( const bool bIsMute );
int GetFaderLevel() { return pFader->value(); }
int GetPanValue() { return pPan->value(); }
void Reset();
@ -86,6 +87,7 @@ protected:
QSlider* pFader;
QDial* pPan;
QLabel* pPanLabel;
QLabel* pInfoLabel;
QCheckBox* pcbMute;
QCheckBox* pcbSolo;
@ -129,7 +131,7 @@ class CAudioMixerBoardSlots<0> {};
class CAudioMixerBoard :
public QScrollArea,
public QGroupBox,
public CAudioMixerBoardSlots<MAX_NUM_CHANNELS>
{
Q_OBJECT
@ -142,7 +144,9 @@ public:
void SetServerName ( const QString& strNewServerName );
void SetGUIDesign ( const EGUIDesign eNewDesign );
void SetDisplayChannelLevels ( const bool eNDCL );
void SetDisplayPans ( const bool eNDP );
void SetPanIsSupported();
void SetRemoteFaderIsMute ( const int iChannelIdx, const bool bIsMute );
void SetFaderLevel ( const int iChannelIdx,
const int iValue );
@ -158,7 +162,20 @@ public:
int iNewClientFaderLevel;
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,
int& iStoredFaderLevel,
@ -173,9 +190,11 @@ protected:
const double dValue );
CVector<CChannelFader*> vecpChanFader;
QGroupBox* pGroupBox;
CMixerBoardScrollArea* pScrollArea;
QHBoxLayout* pMainLayout;
bool bDisplayChannelLevels;
bool bDisplayPans;
bool bIsPanSupported;
bool bNoFaderVisible;
QString strServerName;

View file

@ -90,6 +90,10 @@ qRegisterMetaType<CHostAddress> ( "CHostAddress" );
QObject::connect ( &Protocol, SIGNAL ( ChangeChanPan ( int, double ) ),
this, SLOT ( OnChangeChanPan ( int, double ) ) );
QObject::connect ( &Protocol,
SIGNAL ( MuteStateHasChangedReceived ( int, bool ) ),
SIGNAL ( MuteStateHasChangedReceived ( int, bool ) ) );
QObject::connect ( &Protocol, SIGNAL ( ChangeChanInfo ( CChannelCoreInfo ) ),
this, SLOT ( OnChangeChanInfo ( CChannelCoreInfo ) ) );
@ -258,6 +262,16 @@ void CChannel::SetGain ( const int iChanID,
// set value (make sure channel ID is in range)
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;
}
}

View file

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

View file

@ -79,7 +79,8 @@ CClient::CClient ( const quint16 iPortNumber,
bJitterBufferOK ( true ),
strCentralServerAddress ( "" ),
eCentralServerAddressType ( AT_DEFAULT ),
iServerSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL )
iServerSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL ),
pSignalHandler ( CSignalHandler::getSingletonP() )
{
int iOpusError;
@ -156,6 +157,10 @@ CClient::CClient ( const quint16 iPortNumber,
SIGNAL ( ChatTextReceived ( QString ) ),
SIGNAL ( ChatTextReceived ( QString ) ) );
QObject::connect ( &Channel,
SIGNAL ( MuteStateHasChangedReceived ( int, bool ) ),
SIGNAL ( MuteStateHasChangedReceived ( int, bool ) ) );
QObject::connect ( &Channel,
SIGNAL ( LicenceRequired ( ELicenceType ) ),
SIGNAL ( LicenceRequired ( ELicenceType ) ) );
@ -209,6 +214,10 @@ CClient::CClient ( const quint16 iPortNumber,
QObject::connect ( &Socket, SIGNAL ( InvalidPacketReceived ( 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
// initializations and connections)
@ -652,6 +661,27 @@ void CClient::OnCLChannelLevelListReceived ( CHostAddress InetAddr,
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()
{
// init object

View file

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

View file

@ -85,7 +85,7 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
// connect/disconnect button
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 "
"button will end the session." ) );
@ -123,7 +123,7 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
"sound card and a reverberation effect shall be applied, set the "
"channel selector to right and move the fader upwards until the "
"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 "
"minimum (which is the default setting), the reverberation effect is "
"switched off and does not cause any additional CPU usage." );
@ -169,7 +169,7 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
"<ul>"
"<li>" + tr ( "The network jitter buffer is not large enough for the current "
"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>"
"<li>" + tr ( "The upload or download stream rate is too high for the current "
"available internet bandwidth." ) + "</li>"
@ -466,6 +466,10 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
SIGNAL ( ChatTextReceived ( 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
// 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.
@ -657,6 +661,9 @@ void CClientDlg::UpdateRevSelection()
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 )
@ -1171,6 +1178,7 @@ void CClientDlg::SetGUIDesign ( const EGUIDesign eNewDesign )
"QRadioButton { color: rgb(220, 220, 220);"
" font: bold; }"
"QScrollArea { background: transparent; }"
".QWidget { background: transparent; }" // note: matches instances of QWidget, but not of its subclasses
"QGroupBox { background: transparent; }"
"QGroupBox::title { color: rgb(220, 220, 220); }"
"QCheckBox::indicator { width: 38px;"

View file

@ -198,6 +198,9 @@ public slots:
CVector<CChannelInfo> vecChanInfo )
{ ConnectDlg.SetConnClientsList ( InetAddr, vecChanInfo ); }
void OnMuteStateHasChangedReceived ( int iChanID, bool bIsMuted )
{ MainMixerBoard->SetRemoteFaderIsMute ( iChanID, bIsMuted ); }
void OnCLChannelLevelListReceived ( CHostAddress /* unused */,
CVector<uint16_t> 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 jitter buffer size can be manually chosen for the local client "
"and the remote server. For the local jitter buffer, dropouts in the "
"audio stream are indicated by the light on the bottom "
"of the jitter buffer size faders. If the light turns to red, a buffer "
"audio stream are indicated by the light below the "
"jitter buffer size faders. If the light turns to red, a buffer "
"overrun/underrun took place and the audio stream is interrupted." ) + "<br>" + tr (
"The jitter buffer setting is therefore a trade-off between audio "
"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 "
"using the sliders until your personal acceptable limit of the amount "
"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;
lblNetBuf->setWhatsThis ( strJitterBufferSize );
@ -93,7 +93,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
#ifdef _WIN32
// 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 "
"additional audio delay. Using a sound card with a native ASIO driver "
"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 "
"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 "
"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." ) );
chbEnableOPUS64->setAccessibleName ( tr ( "Enable small network buffers check box" ) );
@ -138,14 +138,14 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
"connection properties." ) + "<br>" + tr (
"Three buffer sizes are supported" ) +
":<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>"
"<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>"
"<li>" + tr ( "256 samples: This setting should only be used if only a very slow "
"computer or a slow internet connection is available." ) + "</li>"
"</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 +
tr ( " software. In this case the buffer delay setting "
"is disabled. To change the actual buffer delay, this "
@ -158,7 +158,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
"performance." ) + "<br>" + tr (
"The actual buffer delay has influence on the connection status, the "
"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 "
"delay." ) + "<br>" + tr (
"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 (
"Select the number of audio channels to be used. There are three "
"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 "
"return signal is stereo. This is useful for the case that the "
"sound card puts the instrument on one input channel and the "
"return signal is stereo. This is useful if the "
"sound card has the instrument on one input channel and the "
"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 "
"stereo." ) + "<br>" + tr (
@ -242,24 +242,21 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
edtNewClientLevel->setWhatsThis ( strNewClientLevel );
edtNewClientLevel->setAccessibleName ( tr ( "New client level edit box" ) );
// central server address
QString strCentrServAddr = "<b>" + tr ( "Central Server Address" ) + ":</b> " +
tr ( "The central server address is the IP address or URL of the central server "
"at which the server list of the connection dialog is managed. With the "
"central server address type either the local region can be selected of "
"the default central servers or a manual address can be specified." );
// custom central server address
QString strCentrServAddr = "<b>" + tr ( "Custom Central Server Address" ) + ":</b> " +
tr ( "The custom central server address is the IP address or URL of the central "
"server at which the server list of the connection dialog is managed. This "
"address is only used if the custom server list is selected in the connection "
"dialog." );
lblCentralServerAddress->setWhatsThis ( strCentrServAddr );
cbxCentServAddrType->setWhatsThis ( strCentrServAddr );
edtCentralServerAddress->setWhatsThis ( strCentrServAddr );
cbxCentServAddrType->setAccessibleName ( tr ( "Default central server type combo box" ) );
edtCentralServerAddress->setAccessibleName ( tr ( "Central server address line edit" ) );
// current connection status parameter
QString strConnStats = "<b>" + tr ( "Current Connection Status "
"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 "
"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 "
@ -344,15 +341,8 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
cbxAudioQuality->addItem ( tr ( "High" ) ); // AQ_HIGH
cbxAudioQuality->setCurrentIndex ( static_cast<int> ( pClient->GetAudioQuality() ) );
// central server address type combo box
cbxCentServAddrType->clear();
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();
// custom central server address
edtCentralServerAddress->setText ( pClient->GetServerListCentralServerAddress() );
// update new client fader level edit box
edtNewClientLevel->setText ( QString::number ( pClient->iNewClientFaderLevel ) );
@ -433,9 +423,6 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
QObject::connect ( cbxAudioQuality, SIGNAL ( activated ( int ) ),
this, SLOT ( OnAudioQualityActivated ( int ) ) );
QObject::connect ( cbxCentServAddrType, SIGNAL ( activated ( int ) ),
this, SLOT ( OnCentServAddrTypeActivated ( int ) ) );
// buttons
QObject::connect ( butDriverSetup, SIGNAL ( clicked() ),
this, SLOT ( OnDriverSetupClicked() ) );
@ -445,10 +432,6 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
SIGNAL ( buttonClicked ( QAbstractButton* ) ), this,
SLOT ( OnSndCrdBufferDelayButtonGroupClicked ( QAbstractButton* ) ) );
QObject::connect ( pClient,
SIGNAL ( CentralServerAddressTypeChanged() ),
this, SLOT ( OnCentralServerAddressTypeChanged() ) );
// Timers ------------------------------------------------------------------
// start timer for status bar
@ -585,40 +568,6 @@ void CClientSettingsDlg::UpdateSoundChannelSelectionFrame()
#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()
{
pClient->OpenSndCrdDriverSetup();
@ -692,15 +641,6 @@ void CClientSettingsDlg::OnAudioQualityActivated ( int iQualityIdx )
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 )
{
pClient->SetDoAutoSockBufSize ( value == Qt::Checked );

View file

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

View file

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

View file

@ -78,11 +78,16 @@ CConnectDlg::CConnectDlg ( CClient* pNCliP,
// central server address type combo box
cbxCentServAddrType->clear();
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_CUSTOM ) );
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_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
edtFilter->setWhatsThis ( "<b>" + tr ( "Filter" ) + ":</b> " + tr ( "The server "

View file

@ -104,9 +104,10 @@ LED bar: lbr
// default server address and port numbers
#define DEFAULT_SERVER_ADDRESS "jamulus.fischvolk.de"
#define DEFAULT_PORT_NUMBER 22124
#define CENTSERV_GENERAL_NORTHAMERICA "jamulus.fischvolk.de:22224"
#define CENTSERV_GENRE_ROCK "centralrock.drealm.info:22124"
#define CENTSERV_GENRE_JAZZ "centraljazz.drealm.info:22224"
#define CENTSERV_ALL_GENRES "jamulusallgenres.fischvolk.de:22224"
#define CENTSERV_GENRE_ROCK "jamulusrock.fischvolk.de:22424"
#define CENTSERV_GENRE_JAZZ "jamulusjazz.fischvolk.de:22324"
#define CENTSERV_GENRE_CLASSICAL_FOLK "jamulusclassical.fischvolk.de:22524"
// getting started and software manual URL
#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
for each connected client append following data:
@ -590,6 +597,10 @@ if ( rand() < ( RAND_MAX / 2 ) ) return false;
bRet = EvaluateChanPanMes ( vecbyMesBodyData );
break;
case PROTMESSID_MUTE_STATE_CHANGED:
bRet = EvaluateMuteStateHasChangedMes ( vecbyMesBodyData );
break;
case PROTMESSID_CONN_CLIENTS_LIST:
bRet = EvaluateConClientListMes ( vecbyMesBodyData );
break;
@ -872,6 +883,43 @@ bool CProtocol::EvaluateChanPanMes ( const CVector<uint8_t> &vecData )
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 )
{
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_VERSION_AND_OS 29 // version number and operating system
#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)
// DEFINITION -> start at 1000, end at 1999, see IsConnectionLessMessageID
@ -99,6 +100,7 @@ public:
void CreateReqJitBufMes();
void CreateChanGainMes ( const int iChanID, const double dGain );
void CreateChanPanMes ( const int iChanID, const double dPan );
void CreateMuteStateHasChangedMes ( const int iChanID, const bool bIsMuted );
void CreateConClientListMes ( const CVector<CChannelInfo>& vecChanInfo );
void CreateReqConnClientsList();
void CreateChanInfoMes ( const CChannelCoreInfo ChanInfo );
@ -223,6 +225,7 @@ protected:
bool EvaluateReqJitBufMes();
bool EvaluateChanGainMes ( 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 EvaluateReqConnClientsList();
bool EvaluateChanInfoMes ( const CVector<uint8_t>& vecData );
@ -283,6 +286,7 @@ signals:
void ChangeNetwBlSiFact ( int iNewNetwBlSiFact );
void ChangeChanGain ( int iChanID, double dNewGain );
void ChangeChanPan ( int iChanID, double dNewPan );
void MuteStateHasChangedReceived ( int iCurID, bool bIsMuted );
void ConClientListMesReceived ( CVector<CChannelInfo> vecChanInfo );
void ServerFullMesReceived();
void ReqConnClientsList();

View file

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

View file

@ -128,6 +128,7 @@ private:
const QDir sessionDir;
qint64 currentFrame;
int chIdDisconnected;
QVector<CJamClient*> vecptrJamClients;
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 ) =
&CServerSlots<slotId>::OnChatTextReceivedCh;
void ( CServer::* pOnMuteStateHasChangedCh )( int, bool ) =
&CServerSlots<slotId>::OnMuteStateHasChangedCh;
void ( CServer::* pOnServerAutoSockBufSizeChangeCh )( int ) =
&CServerSlots<slotId>::OnServerAutoSockBufSizeChangeCh;
@ -516,6 +519,10 @@ inline void CServer::connectChannelSignalsToServerSlots()
QObject::connect ( &vecChannels[iCurChanID], &CChannel::ChatTextReceived,
this, pOnChatTextReceivedCh );
// other mute state has changed
QObject::connect ( &vecChannels[iCurChanID], &CChannel::MuteStateHasChanged,
this, pOnMuteStateHasChangedCh );
// auto socket buffer size change
QObject::connect ( &vecChannels[iCurChanID], &CChannel::ServerAutoSockBufSizeChange,
this, pOnServerAutoSockBufSizeChangeCh );
@ -739,7 +746,7 @@ void CServer::Stop()
void CServer::OnTimer()
{
int i, j, iUnused;
int iClientFrameSizeSamples;
int iClientFrameSizeSamples = 0; // initialize to avoid a compiler warning
OpusCustomDecoder* CurOpusDecoder;
OpusCustomEncoder* CurOpusEncoder;
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()
{
// look for a free channel

View file

@ -117,10 +117,10 @@ signals:
};
#endif
template<unsigned int slotId>
class CServerSlots : public CServerSlots<slotId - 1>
{
public:
void OnSendProtMessCh ( CVector<uint8_t> mess ) { SendProtMessage ( slotId - 1, mess ); }
void OnReqConnClientsListCh() { CreateAndSendChanListForThisChan ( slotId - 1 ); }
@ -130,6 +130,11 @@ public:
CreateAndSendChatTextForAllConChannels ( slotId - 1, strChatText );
}
void OnMuteStateHasChangedCh ( int iChanID, bool bIsMuted )
{
CreateOtherMuteStateChanged ( slotId - 1, iChanID, bIsMuted );
}
void OnServerAutoSockBufSizeChangeCh ( int iNNumFra )
{
CreateAndSendJitBufMessage ( slotId - 1, iNNumFra );
@ -144,6 +149,10 @@ protected:
virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID,
const QString& strChatText ) = 0;
virtual void CreateOtherMuteStateChanged ( const int iCurChanID,
const int iOtherChanID,
const bool bIsMuted ) = 0;
virtual void CreateAndSendJitBufMessage ( const int iCurChanID,
const int iNNumFra ) = 0;
};
@ -256,6 +265,10 @@ protected:
virtual void CreateAndSendChatTextForAllConChannels ( const int iCurChanID,
const QString& strChatText );
virtual void CreateOtherMuteStateChanged ( const int iCurChanID,
const int iOtherChanID,
const bool bIsMuted );
virtual void CreateAndSendJitBufMessage ( const int iCurChanID,
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 "
"itself at the central server so that all " ) + APP_NAME +
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 "
"actually available." ) );
// register server status label
lblRegSvrStatus->setWhatsThis ( "<b>" + tr ( "Register Server Status" ) + ":</b> " +
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
QString strCentrServAddr = "<b>" + tr ( "Central Server Address" ) + ":</b> " +
tr ( "The Central server address is the IP address or URL of the central server "
"at which this server is registered. With the central server address "
"type either the local region can be selected of the default central "
"servers or a manual address can be specified." );
// custom central server address
QString strCentrServAddr = "<b>" + tr ( "Custom Central Server Address" ) + ":</b> " +
tr ( "The custom central server address is the IP address or URL of the central "
"server at which the server list of the connection dialog is managed." );
lblCentralServerAddress->setWhatsThis ( strCentrServAddr );
cbxCentServAddrType->setWhatsThis ( strCentrServAddr );
edtCentralServerAddress->setWhatsThis ( strCentrServAddr );
cbxCentServAddrType->setAccessibleName ( tr ( "Default central server type combo box" ) );
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
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 "
@ -188,11 +188,12 @@ lvwClients->setMinimumHeight ( 140 );
// central server address type combo box
cbxCentServAddrType->clear();
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_CUSTOM ) );
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_JAZZ ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_GENRE_CLASSICAL_FOLK ) );
cbxCentServAddrType->addItem ( csCentServAddrTypeToString ( AT_CUSTOM ) );
cbxCentServAddrType->setCurrentIndex ( static_cast<int> ( pServer->GetCentralServerAddressType() ) );
// update server name line edit

View file

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

View file

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

View file

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

View file

@ -139,7 +139,7 @@ QString CSoundBase::SetDev ( const int iNewDev )
// software anymore
QMessageBox::critical (
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 "
"because of the following error:" ) + " <b>" ) +
strErrorMessage +

View file

@ -705,8 +705,8 @@ CMusProfDlg::CMusProfDlg ( CClient* pNCliP,
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 "
"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 city you live in and the skill level of playing your instrument "
"the instrument you play and a flag of the country you are living in. "
"The city you live in and the skill level playing your instrument "
"may also be added." ) + "<br>" + tr (
"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 "
@ -952,9 +952,10 @@ QString NetworkUtil::GetCentralServerAddress ( const ECSAddType eCentralServerAd
switch ( eCentralServerAddressType )
{
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_JAZZ: return CENTSERV_GENRE_JAZZ;
case AT_GENRE_CLASSICAL_FOLK: return CENTSERV_GENRE_CLASSICAL_FOLK;
default: return DEFAULT_SERVER_ADDRESS; // AT_DEFAULT
}
}
@ -1335,7 +1336,7 @@ ECSAddType CLocale::GetCentralServerAddressType ( const QLocale::Country eCountr
case QLocale::Canada:
case QLocale::Mexico:
case QLocale::Greenland:
return AT_GENERAL_NORTHAMERICA;
return AT_ALL_GENRES;
default:
return AT_DEFAULT;

View file

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

View file

@ -118,7 +118,7 @@ QString CSound::CheckDeviceCapabilities()
( SetSaRateReturn == ASE_NotPresent ) )
{
// 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 "
"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 "
@ -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>" +
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 "
"required. Either your sound card has a native ASIO driver (which "
"is recommended) or you might want to use alternative drivers like "