WIP 64 samples frame size support in the server, not yet working
This commit is contained in:
parent
57f203502c
commit
c310aa16cd
3 changed files with 110 additions and 31 deletions
|
@ -5,10 +5,16 @@
|
||||||
|
|
||||||
TODO support OPUS 64 in the server as a first step towards official 64 samples frame size support
|
TODO support OPUS 64 in the server as a first step towards official 64 samples frame size support
|
||||||
|
|
||||||
TODO client: larger sound card buffers are managed by conversion buffer, not in processintern for loop (note iSndCrdFrameSizeFactor!)
|
TODO merge mixer LED from pljones
|
||||||
|
|
||||||
|
TODO offer the Jamulus ASIO settingspanel in case of an ASIO ERROR to fix, e.g., incorrect sample rate (https://sourceforge.net/p/llcon/discussion/533517/thread/777663cf94/#035f)
|
||||||
|
|
||||||
TODO #12 A server in the same NAT region as the client is not visible (https://sourceforge.net/p/llcon/bugs/12/)
|
TODO #12 A server in the same NAT region as the client is not visible (https://sourceforge.net/p/llcon/bugs/12/)
|
||||||
|
|
||||||
|
TODO client: larger sound card buffers are managed by conversion buffer, not in processintern for loop (note iSndCrdFrameSizeFactor!)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -614,7 +614,7 @@ QString UsageArguments ( char **argv )
|
||||||
" -g, --pingservers ping servers in list to keep NAT port open\n"
|
" -g, --pingservers ping servers in list to keep NAT port open\n"
|
||||||
" (central server only)\n"
|
" (central server only)\n"
|
||||||
" -h, -?, --help this help text\n"
|
" -h, -?, --help this help text\n"
|
||||||
" -i, --inifile initialization file name (client only)\n"
|
" -i, --inifile initialization file name\n"
|
||||||
" -j, --nojackconnect disable auto Jack connections (client only)\n"
|
" -j, --nojackconnect disable auto Jack connections (client only)\n"
|
||||||
" -l, --log enable logging, set file name\n"
|
" -l, --log enable logging, set file name\n"
|
||||||
" -L, --licence a licence must be accepted on a new\n"
|
" -L, --licence a licence must be accepted on a new\n"
|
||||||
|
|
131
src/server.cpp
131
src/server.cpp
|
@ -847,6 +847,7 @@ void CServer::Stop()
|
||||||
void CServer::OnTimer()
|
void CServer::OnTimer()
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
int iCurRawDataLen;
|
||||||
OpusCustomDecoder* CurOpusDecoder;
|
OpusCustomDecoder* CurOpusDecoder;
|
||||||
OpusCustomEncoder* CurOpusEncoder;
|
OpusCustomEncoder* CurOpusEncoder;
|
||||||
unsigned char* pCurCodedData;
|
unsigned char* pCurCodedData;
|
||||||
|
@ -886,16 +887,39 @@ 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 and select the opus decoder
|
// get and store number of audio channels
|
||||||
vecNumAudioChannels[i] = vecChannels[iCurChanID].GetNumAudioChannels();
|
vecNumAudioChannels[i] = vecChannels[iCurChanID].GetNumAudioChannels();
|
||||||
|
|
||||||
if ( vecNumAudioChannels[i] == 1 )
|
// select the opus decoder and raw audio frame length
|
||||||
|
if ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS )
|
||||||
{
|
{
|
||||||
CurOpusDecoder = OpusDecoderMono[iCurChanID];
|
iCurRawDataLen = DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES;
|
||||||
|
|
||||||
|
if ( vecNumAudioChannels[i] == 1 )
|
||||||
|
{
|
||||||
|
CurOpusDecoder = OpusDecoderMono[iCurChanID];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurOpusDecoder = OpusDecoderStereo[iCurChanID];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 )
|
||||||
|
{
|
||||||
|
iCurRawDataLen = SYSTEM_FRAME_SIZE_SAMPLES_SMALL;
|
||||||
|
|
||||||
|
if ( vecNumAudioChannels[i] == 1 )
|
||||||
|
{
|
||||||
|
CurOpusDecoder = Opus64DecoderMono[iCurChanID];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurOpusDecoder = Opus64DecoderStereo[iCurChanID];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CurOpusDecoder = OpusDecoderStereo[iCurChanID];
|
CurOpusDecoder = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get gains of all connected channels
|
// get gains of all connected channels
|
||||||
|
@ -920,10 +944,14 @@ const bool bIsClientDoubleFrameSize = !bUseDoubleSystemFrameSize && ( vecChannel
|
||||||
const bool bIsCompatibleFramesSize = !( bIsServerDoubleFrameSize || bIsClientDoubleFrameSize );
|
const bool bIsCompatibleFramesSize = !( bIsServerDoubleFrameSize || bIsClientDoubleFrameSize );
|
||||||
//bUseDoubleSystemFrameSize
|
//bUseDoubleSystemFrameSize
|
||||||
//ConvBuf
|
//ConvBuf
|
||||||
CConvBuf<uint8_t> ConvBufIn; // TEST NOT WORKING!!!!
|
//CConvBuf<uint8_t> ConvBufIn; // TEST NOT WORKING!!!!
|
||||||
|
|
||||||
//ConvBufIn.Put ( );
|
//ConvBufIn.Put ( );
|
||||||
int iNumInBlocks = 1;
|
int iNumInBlocks = 1;
|
||||||
|
if ( bIsServerDoubleFrameSize )
|
||||||
|
{
|
||||||
|
iNumInBlocks = 2;
|
||||||
|
}
|
||||||
|
|
||||||
for ( int iB = 0; iB < iNumInBlocks; iB++ )
|
for ( int iB = 0; iB < iNumInBlocks; iB++ )
|
||||||
{
|
{
|
||||||
|
@ -955,19 +983,29 @@ int iNumInBlocks = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OPUS decode received data stream
|
// OPUS decode received data stream
|
||||||
// SYSTEM_FRAME_SIZE_SAMPLES_SMALL
|
if ( CurOpusDecoder != nullptr )
|
||||||
// DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES
|
|
||||||
|
|
||||||
if ( ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS ) ||
|
|
||||||
( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 ) )
|
|
||||||
{
|
{
|
||||||
opus_custom_decode ( CurOpusDecoder,
|
opus_custom_decode ( CurOpusDecoder,
|
||||||
pCurCodedData,
|
pCurCodedData,
|
||||||
iCeltNumCodedBytes,
|
iCeltNumCodedBytes,
|
||||||
&vecvecsData[i][0],
|
&vecvecsData[i][iB * SYSTEM_FRAME_SIZE_SAMPLES_SMALL * vecNumAudioChannels[i]],
|
||||||
SYSTEM_FRAME_SIZE_SAMPLES );
|
iCurRawDataLen );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TEST
|
||||||
|
// fid=fopen('v.dat','r');x=fread(fid,'int16');fclose(fid);
|
||||||
|
static FILE* pFileDelay = fopen("c:\\temp\\test2.dat", "wb");
|
||||||
|
short sData[2];
|
||||||
|
for (int i1 = 0; i1 < iNumInBlocks * SYSTEM_FRAME_SIZE_SAMPLES_SMALL; i1++)
|
||||||
|
{
|
||||||
|
sData[0] = (short) vecvecsData[i][i1];
|
||||||
|
fwrite(&sData, size_t(2), size_t(1), pFileDelay);
|
||||||
|
}
|
||||||
|
fflush(pFileDelay);
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// a channel is now disconnected, take action on it
|
// a channel is now disconnected, take action on it
|
||||||
|
@ -1015,37 +1053,72 @@ int iNumInBlocks = 1;
|
||||||
// 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();
|
||||||
|
|
||||||
// select the opus encoder
|
// select the opus encoder and raw audio frame length
|
||||||
if ( vecChannels[iCurChanID].GetNumAudioChannels() == 1 )
|
if ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS )
|
||||||
{
|
{
|
||||||
CurOpusEncoder = OpusEncoderMono[iCurChanID];
|
iCurRawDataLen = DOUBLE_SYSTEM_FRAME_SIZE_SAMPLES;
|
||||||
|
|
||||||
|
if ( vecChannels[iCurChanID].GetNumAudioChannels() == 1 )
|
||||||
|
{
|
||||||
|
CurOpusEncoder = OpusEncoderMono[iCurChanID];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurOpusEncoder = OpusEncoderStereo[iCurChanID];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 )
|
||||||
|
{
|
||||||
|
iCurRawDataLen = SYSTEM_FRAME_SIZE_SAMPLES_SMALL;
|
||||||
|
|
||||||
|
if ( vecChannels[iCurChanID].GetNumAudioChannels() == 1 )
|
||||||
|
{
|
||||||
|
CurOpusEncoder = Opus64EncoderMono[iCurChanID];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurOpusEncoder = Opus64EncoderStereo[iCurChanID];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CurOpusEncoder = OpusEncoderStereo[iCurChanID];
|
CurOpusEncoder = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OPUS encoding
|
// TODO copied code from above!!!
|
||||||
if ( ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS ) ||
|
const bool bIsServerDoubleFrameSize = bUseDoubleSystemFrameSize && ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 );
|
||||||
( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS64 ) )
|
const bool bIsClientDoubleFrameSize = !bUseDoubleSystemFrameSize && ( vecChannels[iCurChanID].GetAudioCompressionType() == CT_OPUS );
|
||||||
|
const bool bIsCompatibleFramesSize = !( bIsServerDoubleFrameSize || bIsClientDoubleFrameSize );
|
||||||
|
|
||||||
|
int iNumInBlocks = 1;
|
||||||
|
if ( bIsServerDoubleFrameSize )
|
||||||
|
{
|
||||||
|
iNumInBlocks = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int iB = 0; iB < iNumInBlocks; iB++ )
|
||||||
{
|
{
|
||||||
|
// OPUS encoding
|
||||||
|
if ( CurOpusEncoder != nullptr )
|
||||||
|
{
|
||||||
// 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 ( CurOpusEncoder,
|
opus_custom_encoder_ctl ( CurOpusEncoder,
|
||||||
OPUS_SET_BITRATE ( CalcBitRateBitsPerSecFromCodedBytes ( iCeltNumCodedBytes ) ) );
|
OPUS_SET_BITRATE ( CalcBitRateBitsPerSecFromCodedBytes ( iCeltNumCodedBytes ) ) );
|
||||||
|
|
||||||
opus_custom_encode ( CurOpusEncoder,
|
opus_custom_encode ( CurOpusEncoder,
|
||||||
&vecsSendData[0],
|
&vecsSendData[iB * SYSTEM_FRAME_SIZE_SAMPLES_SMALL * vecChannels[iCurChanID].GetNumAudioChannels()],
|
||||||
SYSTEM_FRAME_SIZE_SAMPLES,
|
iCurRawDataLen,
|
||||||
&vecbyCodedData[0],
|
&vecbyCodedData[0],
|
||||||
iCeltNumCodedBytes );
|
iCeltNumCodedBytes );
|
||||||
}
|
}
|
||||||
|
|
||||||
// send separate mix to current clients
|
// send separate mix to current clients
|
||||||
vecChannels[iCurChanID].PrepAndSendPacket ( &Socket,
|
vecChannels[iCurChanID].PrepAndSendPacket ( &Socket,
|
||||||
vecbyCodedData,
|
vecbyCodedData,
|
||||||
iCeltNumCodedBytes );
|
iCeltNumCodedBytes );
|
||||||
|
}
|
||||||
|
|
||||||
// update socket buffer size
|
// update socket buffer size
|
||||||
vecChannels[iCurChanID].UpdateSocketBufferSize();
|
vecChannels[iCurChanID].UpdateSocketBufferSize();
|
||||||
|
|
Loading…
Reference in a new issue