WIP on support of 64/128 samples frame size in the server
This commit is contained in:
parent
0bdf6a45ae
commit
57f203502c
5 changed files with 170 additions and 175 deletions
|
@ -346,18 +346,12 @@ void CChannel::OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTranspor
|
||||||
// only the server shall act on network transport properties message
|
// only the server shall act on network transport properties message
|
||||||
if ( bIsServer )
|
if ( bIsServer )
|
||||||
{
|
{
|
||||||
// OPUS codec is the only supported codec right now
|
// OPUS and OPUS64 codecs are the only supported codecs right now
|
||||||
#if ( SYSTEM_FRAME_SIZE_SAMPLES == 64 )
|
if ( ( NetworkTransportProps.eAudioCodingType != CT_OPUS ) &&
|
||||||
if ( NetworkTransportProps.eAudioCodingType != CT_OPUS64 )
|
( NetworkTransportProps.eAudioCodingType != CT_OPUS64 ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if ( NetworkTransportProps.eAudioCodingType != CT_OPUS )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Mutex.lock();
|
Mutex.lock();
|
||||||
{
|
{
|
||||||
|
|
|
@ -98,7 +98,9 @@ LED bar: lbr
|
||||||
// System block size, this is the block size on which the audio coder works.
|
// System block size, this is the block size on which the audio coder works.
|
||||||
// All other block sizes must be a multiple of this size.
|
// All other block sizes must be a multiple of this size.
|
||||||
// Note that the UpdateAutoSetting() function assumes a value of 128.
|
// Note that the UpdateAutoSetting() function assumes a value of 128.
|
||||||
#define SYSTEM_FRAME_SIZE_SAMPLES 128
|
#define SYSTEM_FRAME_SIZE_SAMPLES_SMALL 64 // TODO this is temporary and shall be replaced by SYSTEM_FRAME_SIZE_SAMPLES later on
|
||||||
|
#define DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES ( 2 * SYSTEM_FRAME_SIZE_SAMPLES_SMALL )
|
||||||
|
#define SYSTEM_FRAME_SIZE_SAMPLES 128
|
||||||
|
|
||||||
// default server address
|
// default server address
|
||||||
#define DEFAULT_SERVER_ADDRESS "jamulus.fischvolk.de"
|
#define DEFAULT_SERVER_ADDRESS "jamulus.fischvolk.de"
|
||||||
|
|
|
@ -513,6 +513,10 @@ int main ( int argc, char** argv )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
const bool bUseDoubleSystemFrameSize = true; // TODO for now this value is fixed but has to be changeable by command line argument
|
||||||
|
|
||||||
// Server:
|
// Server:
|
||||||
// actual server object
|
// actual server object
|
||||||
CServer Server ( iNumServerChannels,
|
CServer Server ( iNumServerChannels,
|
||||||
|
@ -528,6 +532,7 @@ int main ( int argc, char** argv )
|
||||||
strRecordingDirName,
|
strRecordingDirName,
|
||||||
bCentServPingServerInList,
|
bCentServPingServerInList,
|
||||||
bDisconnectAllClients,
|
bDisconnectAllClients,
|
||||||
|
bUseDoubleSystemFrameSize,
|
||||||
eLicenceType );
|
eLicenceType );
|
||||||
if ( bUseGUI )
|
if ( bUseGUI )
|
||||||
{
|
{
|
||||||
|
|
310
src/server.cpp
310
src/server.cpp
|
@ -27,11 +27,12 @@
|
||||||
|
|
||||||
// CHighPrecisionTimer implementation ******************************************
|
// CHighPrecisionTimer implementation ******************************************
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
CHighPrecisionTimer::CHighPrecisionTimer()
|
CHighPrecisionTimer::CHighPrecisionTimer ( const bool bNewUseDoubleSystemFrameSize ) :
|
||||||
|
bUseDoubleSystemFrameSize ( bNewUseDoubleSystemFrameSize )
|
||||||
{
|
{
|
||||||
// add some error checking, the high precision timer implementation only
|
// add some error checking, the high precision timer implementation only
|
||||||
// supports 64 and 128 samples frame size at 48 kHz sampling rate
|
// supports 64 and 128 samples frame size at 48 kHz sampling rate
|
||||||
#if ( SYSTEM_FRAME_SIZE_SAMPLES != 64 ) && ( SYSTEM_FRAME_SIZE_SAMPLES != 128 )
|
#if ( SYSTEM_FRAME_SIZE_SAMPLES_SMALL != 64 ) && ( DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES != 128 )
|
||||||
# error "Only system frame size of 64 and 128 samples is supported by this module"
|
# error "Only system frame size of 64 and 128 samples is supported by this module"
|
||||||
#endif
|
#endif
|
||||||
#if ( SYSTEM_SAMPLE_RATE_HZ != 48000 )
|
#if ( SYSTEM_SAMPLE_RATE_HZ != 48000 )
|
||||||
|
@ -68,13 +69,16 @@ void CHighPrecisionTimer::Start()
|
||||||
iCurPosInVector = 0;
|
iCurPosInVector = 0;
|
||||||
iIntervalCounter = 0;
|
iIntervalCounter = 0;
|
||||||
|
|
||||||
#if ( SYSTEM_FRAME_SIZE_SAMPLES == 64 )
|
if ( bUseDoubleSystemFrameSize )
|
||||||
// start internal timer with 1 ms resolution for 64 samples frame size
|
{
|
||||||
Timer.start ( 1 );
|
// start internal timer with 2 ms resolution for 128 samples frame size
|
||||||
#else
|
Timer.start ( 2 );
|
||||||
// start internal timer with 2 ms resolution for 128 samples frame size
|
}
|
||||||
Timer.start ( 2 );
|
else
|
||||||
#endif
|
{
|
||||||
|
// start internal timer with 1 ms resolution for 64 samples frame size
|
||||||
|
Timer.start ( 1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHighPrecisionTimer::Stop()
|
void CHighPrecisionTimer::Stop()
|
||||||
|
@ -110,13 +114,22 @@ void CHighPrecisionTimer::OnTimer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else // Mac and Linux
|
#else // Mac and Linux
|
||||||
CHighPrecisionTimer::CHighPrecisionTimer() :
|
CHighPrecisionTimer::CHighPrecisionTimer ( const bool bUseDoubleSystemFrameSize ) :
|
||||||
bRun ( false )
|
bRun ( false )
|
||||||
{
|
{
|
||||||
// calculate delay in ns
|
// calculate delay in ns
|
||||||
const uint64_t iNsDelay =
|
const uint64_t iNsDelay;
|
||||||
( (uint64_t) SYSTEM_FRAME_SIZE_SAMPLES * 1000000000 ) /
|
|
||||||
(uint64_t) SYSTEM_SAMPLE_RATE_HZ; // in ns
|
if ( bUseDoubleSystemFrameSize )
|
||||||
|
{
|
||||||
|
iNsDelay = ( (uint64_t) DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES * 1000000000 ) /
|
||||||
|
(uint64_t) SYSTEM_SAMPLE_RATE_HZ; // in ns
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iNsDelay = ( (uint64_t) SYSTEM_FRAME_SIZE_SAMPLES_SMALL * 1000000000 ) /
|
||||||
|
(uint64_t) SYSTEM_SAMPLE_RATE_HZ; // in ns
|
||||||
|
}
|
||||||
|
|
||||||
#if defined ( __APPLE__ ) || defined ( __MACOSX )
|
#if defined ( __APPLE__ ) || defined ( __MACOSX )
|
||||||
// calculate delay in mach absolute time
|
// calculate delay in mach absolute time
|
||||||
|
@ -219,81 +232,69 @@ CServer::CServer ( const int iNewMaxNumChan,
|
||||||
const QString& strRecordingDirName,
|
const QString& strRecordingDirName,
|
||||||
const bool bNCentServPingServerInList,
|
const bool bNCentServPingServerInList,
|
||||||
const bool bNDisconnectAllClients,
|
const bool bNDisconnectAllClients,
|
||||||
|
const bool bNUseDoubleSystemFrameSize,
|
||||||
const ELicenceType eNLicenceType ) :
|
const ELicenceType eNLicenceType ) :
|
||||||
iMaxNumChannels ( iNewMaxNumChan ),
|
bUseDoubleSystemFrameSize ( bNUseDoubleSystemFrameSize ),
|
||||||
Socket ( this, iPortNumber ),
|
iMaxNumChannels ( iNewMaxNumChan ),
|
||||||
Logging ( iMaxDaysHistory ),
|
Socket ( this, iPortNumber ),
|
||||||
JamRecorder ( strRecordingDirName ),
|
Logging ( iMaxDaysHistory ),
|
||||||
bEnableRecording ( !strRecordingDirName.isEmpty() ),
|
JamRecorder ( strRecordingDirName ),
|
||||||
bWriteStatusHTMLFile ( false ),
|
bEnableRecording ( !strRecordingDirName.isEmpty() ),
|
||||||
ServerListManager ( iPortNumber,
|
bWriteStatusHTMLFile ( false ),
|
||||||
strCentralServer,
|
HighPrecisionTimer ( bNUseDoubleSystemFrameSize ),
|
||||||
strServerInfo,
|
ServerListManager ( iPortNumber,
|
||||||
iNewMaxNumChan,
|
strCentralServer,
|
||||||
bNCentServPingServerInList,
|
strServerInfo,
|
||||||
&ConnLessProtocol ),
|
iNewMaxNumChan,
|
||||||
bAutoRunMinimized ( false ),
|
bNCentServPingServerInList,
|
||||||
strWelcomeMessage ( strNewWelcomeMessage ),
|
&ConnLessProtocol ),
|
||||||
eLicenceType ( eNLicenceType ),
|
bAutoRunMinimized ( false ),
|
||||||
bDisconnectAllClients ( bNDisconnectAllClients )
|
strWelcomeMessage ( strNewWelcomeMessage ),
|
||||||
|
eLicenceType ( eNLicenceType ),
|
||||||
|
bDisconnectAllClients ( bNDisconnectAllClients )
|
||||||
{
|
{
|
||||||
int iOpusError;
|
int iOpusError;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// create CELT encoder/decoder for each channel (must be done before
|
// create OPUS encoder/decoder for each channel (must be done before
|
||||||
// enabling the channels), create a mono and stereo encoder/decoder
|
// enabling the channels), create a mono and stereo encoder/decoder
|
||||||
// for each channel
|
// for each channel
|
||||||
for ( i = 0; i < iMaxNumChannels; i++ )
|
for ( i = 0; i < iMaxNumChannels; i++ )
|
||||||
{
|
{
|
||||||
// init audio endocder/decoder (mono)
|
// init OPUS -----------------------------------------------------------
|
||||||
OpusMode[i] = opus_custom_mode_create ( SYSTEM_SAMPLE_RATE_HZ,
|
OpusMode[i] = opus_custom_mode_create ( SYSTEM_SAMPLE_RATE_HZ,
|
||||||
SYSTEM_FRAME_SIZE_SAMPLES,
|
DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES,
|
||||||
&iOpusError );
|
&iOpusError );
|
||||||
|
|
||||||
OpusEncoderMono[i] = opus_custom_encoder_create ( OpusMode[i],
|
Opus64Mode[i] = opus_custom_mode_create ( SYSTEM_SAMPLE_RATE_HZ,
|
||||||
1,
|
SYSTEM_FRAME_SIZE_SAMPLES_SMALL,
|
||||||
&iOpusError );
|
&iOpusError );
|
||||||
|
|
||||||
OpusDecoderMono[i] = opus_custom_decoder_create ( OpusMode[i],
|
// init audio encoders and decoders
|
||||||
1,
|
OpusEncoderMono[i] = opus_custom_encoder_create ( OpusMode[i], 1, &iOpusError ); // mono encoder legacy
|
||||||
&iOpusError );
|
OpusDecoderMono[i] = opus_custom_decoder_create ( OpusMode[i], 1, &iOpusError ); // mono decoder legacy
|
||||||
|
OpusEncoderStereo[i] = opus_custom_encoder_create ( OpusMode[i], 2, &iOpusError ); // stereo encoder legacy
|
||||||
|
OpusDecoderStereo[i] = opus_custom_decoder_create ( OpusMode[i], 2, &iOpusError ); // stereo decoder legacy
|
||||||
|
Opus64EncoderMono[i] = opus_custom_encoder_create ( Opus64Mode[i], 1, &iOpusError ); // mono encoder OPUS64
|
||||||
|
Opus64DecoderMono[i] = opus_custom_decoder_create ( Opus64Mode[i], 1, &iOpusError ); // mono decoder OPUS64
|
||||||
|
Opus64EncoderStereo[i] = opus_custom_encoder_create ( Opus64Mode[i], 2, &iOpusError ); // stereo encoder OPUS64
|
||||||
|
Opus64DecoderStereo[i] = opus_custom_decoder_create ( Opus64Mode[i], 2, &iOpusError ); // stereo decoder OPUS64
|
||||||
|
|
||||||
// we require a constant bit rate
|
// we require a constant bit rate
|
||||||
opus_custom_encoder_ctl ( OpusEncoderMono[i],
|
opus_custom_encoder_ctl ( OpusEncoderMono[i], OPUS_SET_VBR ( 0 ) );
|
||||||
OPUS_SET_VBR ( 0 ) );
|
opus_custom_encoder_ctl ( OpusEncoderStereo[i], OPUS_SET_VBR ( 0 ) );
|
||||||
|
opus_custom_encoder_ctl ( Opus64EncoderMono[i], OPUS_SET_VBR ( 0 ) );
|
||||||
|
opus_custom_encoder_ctl ( Opus64EncoderStereo[i], OPUS_SET_VBR ( 0 ) );
|
||||||
|
|
||||||
// we want as low delay as possible
|
// we want as low delay as possible
|
||||||
opus_custom_encoder_ctl ( OpusEncoderMono[i],
|
opus_custom_encoder_ctl ( OpusEncoderMono[i], OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) );
|
||||||
OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) );
|
opus_custom_encoder_ctl ( OpusEncoderStereo[i], OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) );
|
||||||
|
opus_custom_encoder_ctl ( Opus64EncoderMono[i], OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) );
|
||||||
|
opus_custom_encoder_ctl ( Opus64EncoderStereo[i], OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) );
|
||||||
|
|
||||||
#if ( SYSTEM_FRAME_SIZE_SAMPLES == 128 )
|
|
||||||
// set encoder low complexity for legacy 128 samples frame size
|
// set encoder low complexity for legacy 128 samples frame size
|
||||||
opus_custom_encoder_ctl ( OpusEncoderMono[i],
|
opus_custom_encoder_ctl ( OpusEncoderMono[i], OPUS_SET_COMPLEXITY ( 1 ) );
|
||||||
OPUS_SET_COMPLEXITY ( 1 ) );
|
opus_custom_encoder_ctl ( OpusEncoderStereo[i], OPUS_SET_COMPLEXITY ( 1 ) );
|
||||||
#endif
|
|
||||||
|
|
||||||
// init audio endocder/decoder (stereo)
|
|
||||||
OpusEncoderStereo[i] = opus_custom_encoder_create ( OpusMode[i],
|
|
||||||
2,
|
|
||||||
&iOpusError );
|
|
||||||
|
|
||||||
OpusDecoderStereo[i] = opus_custom_decoder_create ( OpusMode[i],
|
|
||||||
2,
|
|
||||||
&iOpusError );
|
|
||||||
|
|
||||||
// we require a constant bit rate
|
|
||||||
opus_custom_encoder_ctl ( OpusEncoderStereo[i],
|
|
||||||
OPUS_SET_VBR ( 0 ) );
|
|
||||||
|
|
||||||
// we want as low delay as possible
|
|
||||||
opus_custom_encoder_ctl ( OpusEncoderStereo[i],
|
|
||||||
OPUS_SET_APPLICATION ( OPUS_APPLICATION_RESTRICTED_LOWDELAY ) );
|
|
||||||
|
|
||||||
#if ( SYSTEM_FRAME_SIZE_SAMPLES == 128 )
|
|
||||||
// set encoder low complexity for legacy 128 samples frame size
|
|
||||||
opus_custom_encoder_ctl ( OpusEncoderStereo[i],
|
|
||||||
OPUS_SET_COMPLEXITY ( 1 ) );
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// define colors for chat window identifiers
|
// define colors for chat window identifiers
|
||||||
|
@ -312,7 +313,7 @@ CServer::CServer ( const int iNewMaxNumChan,
|
||||||
// the worst case here:
|
// the worst case here:
|
||||||
|
|
||||||
// we always use stereo audio buffers (which is the worst case)
|
// we always use stereo audio buffers (which is the worst case)
|
||||||
vecsSendData.Init ( 2 * SYSTEM_FRAME_SIZE_SAMPLES );
|
vecsSendData.Init ( 2 /* stereo */ * DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES /* worst case buffer size */ );
|
||||||
|
|
||||||
// allocate worst case memory for the temporary vectors
|
// allocate worst case memory for the temporary vectors
|
||||||
vecChanIDsCurConChan.Init ( iMaxNumChannels );
|
vecChanIDsCurConChan.Init ( iMaxNumChannels );
|
||||||
|
@ -326,7 +327,7 @@ CServer::CServer ( const int iNewMaxNumChan,
|
||||||
vecvecdGains[i].Init ( iMaxNumChannels );
|
vecvecdGains[i].Init ( iMaxNumChannels );
|
||||||
|
|
||||||
// we always use stereo audio buffers (see "vecsSendData")
|
// we always use stereo audio buffers (see "vecsSendData")
|
||||||
vecvecsData[i].Init ( 2 * SYSTEM_FRAME_SIZE_SAMPLES );
|
vecvecsData[i].Init ( 2 /* stereo */ * DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES /* worst case buffer size */ );
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate worst case memory for the coded data
|
// allocate worst case memory for the coded data
|
||||||
|
@ -845,7 +846,10 @@ void CServer::Stop()
|
||||||
|
|
||||||
void CServer::OnTimer()
|
void CServer::OnTimer()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
OpusCustomDecoder* CurOpusDecoder;
|
||||||
|
OpusCustomEncoder* CurOpusEncoder;
|
||||||
|
unsigned char* pCurCodedData;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// TEST do a timer jitter measurement
|
// TEST do a timer jitter measurement
|
||||||
|
@ -882,9 +886,17 @@ JitterMeas.Measure();
|
||||||
// get actual ID of current channel
|
// get actual ID of current channel
|
||||||
const int iCurChanID = vecChanIDsCurConChan[i];
|
const int iCurChanID = vecChanIDsCurConChan[i];
|
||||||
|
|
||||||
// get and store number of audio channels
|
// get and store number of audio channels and select the opus decoder
|
||||||
const int iCurNumAudChan = vecChannels[iCurChanID].GetNumAudioChannels();
|
vecNumAudioChannels[i] = vecChannels[iCurChanID].GetNumAudioChannels();
|
||||||
vecNumAudioChannels[i] = iCurNumAudChan;
|
|
||||||
|
if ( vecNumAudioChannels[i] == 1 )
|
||||||
|
{
|
||||||
|
CurOpusDecoder = OpusDecoderMono[iCurChanID];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurOpusDecoder = OpusDecoderStereo[iCurChanID];
|
||||||
|
}
|
||||||
|
|
||||||
// get gains of all connected channels
|
// get gains of all connected channels
|
||||||
for ( j = 0; j < iNumClients; j++ )
|
for ( j = 0; j < iNumClients; j++ )
|
||||||
|
@ -902,74 +914,58 @@ JitterMeas.Measure();
|
||||||
// get current number of CELT coded bytes
|
// get current number of CELT coded bytes
|
||||||
const int iCeltNumCodedBytes = vecChannels[iCurChanID].GetNetwFrameSize();
|
const int iCeltNumCodedBytes = vecChannels[iCurChanID].GetNetwFrameSize();
|
||||||
|
|
||||||
// get data
|
// TODO
|
||||||
const EGetDataStat eGetStat =
|
const bool bIsServerDoubleFrameSize = bUseDoubleSystemFrameSize && ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 );
|
||||||
vecChannels[iCurChanID].GetData ( vecbyCodedData,
|
const bool bIsClientDoubleFrameSize = !bUseDoubleSystemFrameSize && ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS );
|
||||||
iCeltNumCodedBytes );
|
const bool bIsCompatibleFramesSize = !( bIsServerDoubleFrameSize || bIsClientDoubleFrameSize );
|
||||||
|
//bUseDoubleSystemFrameSize
|
||||||
|
//ConvBuf
|
||||||
|
CConvBuf<uint8_t> ConvBufIn; // TEST NOT WORKING!!!!
|
||||||
|
|
||||||
// if channel was just disconnected, set flag that connected
|
//ConvBufIn.Put ( );
|
||||||
// client list is sent to all other clients
|
int iNumInBlocks = 1;
|
||||||
// and emit the client disconnected signal
|
|
||||||
if ( eGetStat == GS_CHAN_NOW_DISCONNECTED )
|
for ( int iB = 0; iB < iNumInBlocks; iB++ )
|
||||||
{
|
{
|
||||||
if ( bEnableRecording )
|
// get data
|
||||||
|
const EGetDataStat eGetStat = vecChannels[iCurChanID].GetData ( vecbyCodedData, iCeltNumCodedBytes );
|
||||||
|
|
||||||
|
// if channel was just disconnected, set flag that connected
|
||||||
|
// client list is sent to all other clients
|
||||||
|
// and emit the client disconnected signal
|
||||||
|
if ( eGetStat == GS_CHAN_NOW_DISCONNECTED )
|
||||||
{
|
{
|
||||||
emit ClientDisconnected ( iCurChanID ); // TODO do this outside the mutex lock?
|
if ( bEnableRecording )
|
||||||
|
{
|
||||||
|
emit ClientDisconnected ( iCurChanID ); // TODO do this outside the mutex lock?
|
||||||
|
}
|
||||||
|
|
||||||
|
bChannelIsNowDisconnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bChannelIsNowDisconnected = true;
|
// get pointer to coded data
|
||||||
}
|
if ( eGetStat == GS_BUFFER_OK )
|
||||||
|
{
|
||||||
|
pCurCodedData = &vecbyCodedData[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// for lost packets use null pointer as coded input data
|
||||||
|
pCurCodedData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OPUS decode received data stream
|
||||||
|
// SYSTEM_FRAME_SIZE_SAMPLES_SMALL
|
||||||
|
// DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES
|
||||||
|
|
||||||
// OPUS decode received data stream
|
|
||||||
if ( eGetStat == GS_BUFFER_OK )
|
|
||||||
{
|
|
||||||
if ( ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS ) ||
|
if ( ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS ) ||
|
||||||
( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 ) )
|
( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 ) )
|
||||||
{
|
{
|
||||||
if ( iCurNumAudChan == 1 )
|
opus_custom_decode ( CurOpusDecoder,
|
||||||
{
|
pCurCodedData,
|
||||||
// mono
|
iCeltNumCodedBytes,
|
||||||
opus_custom_decode ( OpusDecoderMono[iCurChanID],
|
&vecvecsData[i][0],
|
||||||
&vecbyCodedData[0],
|
SYSTEM_FRAME_SIZE_SAMPLES );
|
||||||
iCeltNumCodedBytes,
|
|
||||||
&vecvecsData[i][0],
|
|
||||||
SYSTEM_FRAME_SIZE_SAMPLES );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// stereo
|
|
||||||
opus_custom_decode ( OpusDecoderStereo[iCurChanID],
|
|
||||||
&vecbyCodedData[0],
|
|
||||||
iCeltNumCodedBytes,
|
|
||||||
&vecvecsData[i][0],
|
|
||||||
SYSTEM_FRAME_SIZE_SAMPLES );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// lost packet
|
|
||||||
if ( ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS ) ||
|
|
||||||
( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 ) )
|
|
||||||
{
|
|
||||||
if ( iCurNumAudChan == 1 )
|
|
||||||
{
|
|
||||||
// mono
|
|
||||||
opus_custom_decode ( OpusDecoderMono[iCurChanID],
|
|
||||||
nullptr,
|
|
||||||
iCeltNumCodedBytes,
|
|
||||||
&vecvecsData[i][0],
|
|
||||||
SYSTEM_FRAME_SIZE_SAMPLES );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// stereo
|
|
||||||
opus_custom_decode ( OpusDecoderStereo[iCurChanID],
|
|
||||||
nullptr,
|
|
||||||
iCeltNumCodedBytes,
|
|
||||||
&vecvecsData[i][0],
|
|
||||||
SYSTEM_FRAME_SIZE_SAMPLES );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1017,45 +1013,33 @@ JitterMeas.Measure();
|
||||||
iNumClients );
|
iNumClients );
|
||||||
|
|
||||||
// get current number of CELT coded bytes
|
// get current number of CELT coded bytes
|
||||||
const int iCeltNumCodedBytes =
|
const int iCeltNumCodedBytes = vecChannels[iCurChanID].GetNetwFrameSize();
|
||||||
vecChannels[iCurChanID].GetNetwFrameSize();
|
|
||||||
|
// select the opus encoder
|
||||||
|
if ( vecChannels[iCurChanID].GetNumAudioChannels() == 1 )
|
||||||
|
{
|
||||||
|
CurOpusEncoder = OpusEncoderMono[iCurChanID];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurOpusEncoder = OpusEncoderStereo[iCurChanID];
|
||||||
|
}
|
||||||
|
|
||||||
// OPUS encoding
|
// OPUS encoding
|
||||||
if ( ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS ) ||
|
if ( ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS ) ||
|
||||||
( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 ) )
|
( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 ) )
|
||||||
{
|
{
|
||||||
if ( vecChannels[iCurChanID].GetNumAudioChannels() == 1 )
|
|
||||||
{
|
|
||||||
// mono:
|
|
||||||
|
|
||||||
// TODO find a better place than this: the setting does not change all the time
|
// TODO find a better place than this: the setting does not change all the time
|
||||||
// so for speed optimization it would be better to set it only if the network
|
// so for speed optimization it would be better to set it only if the network
|
||||||
// frame size is changed
|
// frame size is changed
|
||||||
opus_custom_encoder_ctl ( OpusEncoderMono[iCurChanID],
|
opus_custom_encoder_ctl ( CurOpusEncoder,
|
||||||
OPUS_SET_BITRATE ( CalcBitRateBitsPerSecFromCodedBytes ( iCeltNumCodedBytes ) ) );
|
OPUS_SET_BITRATE ( CalcBitRateBitsPerSecFromCodedBytes ( iCeltNumCodedBytes ) ) );
|
||||||
|
|
||||||
opus_custom_encode ( OpusEncoderMono[iCurChanID],
|
opus_custom_encode ( CurOpusEncoder,
|
||||||
&vecsSendData[0],
|
&vecsSendData[0],
|
||||||
SYSTEM_FRAME_SIZE_SAMPLES,
|
SYSTEM_FRAME_SIZE_SAMPLES,
|
||||||
&vecbyCodedData[0],
|
&vecbyCodedData[0],
|
||||||
iCeltNumCodedBytes );
|
iCeltNumCodedBytes );
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// stereo:
|
|
||||||
|
|
||||||
// TODO find a better place than this: the setting does not change all the time
|
|
||||||
// so for speed optimization it would be better to set it only if the network
|
|
||||||
// frame size is changed
|
|
||||||
opus_custom_encoder_ctl ( OpusEncoderStereo[iCurChanID],
|
|
||||||
OPUS_SET_BITRATE ( CalcBitRateBitsPerSecFromCodedBytes ( iCeltNumCodedBytes ) ) );
|
|
||||||
|
|
||||||
opus_custom_encode ( OpusEncoderStereo[iCurChanID],
|
|
||||||
&vecsSendData[0],
|
|
||||||
SYSTEM_FRAME_SIZE_SAMPLES,
|
|
||||||
&vecbyCodedData[0],
|
|
||||||
iCeltNumCodedBytes );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// send separate mix to current clients
|
// send separate mix to current clients
|
||||||
|
|
14
src/server.h
14
src/server.h
|
@ -55,7 +55,7 @@ class CHighPrecisionTimer : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CHighPrecisionTimer();
|
CHighPrecisionTimer ( const bool bNewUseDoubleSystemFrameSize );
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
@ -66,6 +66,7 @@ protected:
|
||||||
CVector<int> veciTimeOutIntervals;
|
CVector<int> veciTimeOutIntervals;
|
||||||
int iCurPosInVector;
|
int iCurPosInVector;
|
||||||
int iIntervalCounter;
|
int iIntervalCounter;
|
||||||
|
bool bUseDoubleSystemFrameSize;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnTimer();
|
void OnTimer();
|
||||||
|
@ -88,7 +89,7 @@ class CHighPrecisionTimer : public QThread
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CHighPrecisionTimer();
|
CHighPrecisionTimer ( const bool bUseDoubleSystemFrameSize );
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
@ -131,6 +132,7 @@ public:
|
||||||
const QString& strRecordingDirName,
|
const QString& strRecordingDirName,
|
||||||
const bool bNCentServPingServerInList,
|
const bool bNCentServPingServerInList,
|
||||||
const bool bNDisconnectAllClients,
|
const bool bNDisconnectAllClients,
|
||||||
|
const bool bNUseDoubleSystemFrameSize,
|
||||||
const ELicenceType eNLicenceType );
|
const ELicenceType eNLicenceType );
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
|
@ -220,6 +222,9 @@ protected:
|
||||||
|
|
||||||
virtual void customEvent ( QEvent* pEvent );
|
virtual void customEvent ( QEvent* pEvent );
|
||||||
|
|
||||||
|
// if server mode is normal or double system frame size
|
||||||
|
bool bUseDoubleSystemFrameSize;
|
||||||
|
|
||||||
// do not use the vector class since CChannel does not have appropriate
|
// do not use the vector class since CChannel does not have appropriate
|
||||||
// copy constructor/operator
|
// copy constructor/operator
|
||||||
CChannel vecChannels[MAX_NUM_CHANNELS];
|
CChannel vecChannels[MAX_NUM_CHANNELS];
|
||||||
|
@ -228,6 +233,11 @@ protected:
|
||||||
QMutex Mutex;
|
QMutex Mutex;
|
||||||
|
|
||||||
// audio encoder/decoder
|
// audio encoder/decoder
|
||||||
|
OpusCustomMode* Opus64Mode[MAX_NUM_CHANNELS];
|
||||||
|
OpusCustomEncoder* Opus64EncoderMono[MAX_NUM_CHANNELS];
|
||||||
|
OpusCustomDecoder* Opus64DecoderMono[MAX_NUM_CHANNELS];
|
||||||
|
OpusCustomEncoder* Opus64EncoderStereo[MAX_NUM_CHANNELS];
|
||||||
|
OpusCustomDecoder* Opus64DecoderStereo[MAX_NUM_CHANNELS];
|
||||||
OpusCustomMode* OpusMode[MAX_NUM_CHANNELS];
|
OpusCustomMode* OpusMode[MAX_NUM_CHANNELS];
|
||||||
OpusCustomEncoder* OpusEncoderMono[MAX_NUM_CHANNELS];
|
OpusCustomEncoder* OpusEncoderMono[MAX_NUM_CHANNELS];
|
||||||
OpusCustomDecoder* OpusDecoderMono[MAX_NUM_CHANNELS];
|
OpusCustomDecoder* OpusDecoderMono[MAX_NUM_CHANNELS];
|
||||||
|
|
Loading…
Reference in a new issue