preparations for stereo support
This commit is contained in:
parent
c7f1992890
commit
7173108c77
7 changed files with 272 additions and 75 deletions
|
@ -31,7 +31,8 @@ CChannel::CChannel ( const bool bNIsServer ) :
|
|||
vecdGains ( USED_NUM_CHANNELS, (double) 1.0 ),
|
||||
bIsEnabled ( false ),
|
||||
iNetwFrameSizeFact ( FRAME_SIZE_FACTOR_DEFAULT ),
|
||||
iNetwFrameSize ( 20 ) // must be > 0 and should be close to a valid size
|
||||
iNetwFrameSize ( 20 ), // must be > 0 and should be close to a valid size
|
||||
iNumAudioChannels ( 1 ) // mono
|
||||
{
|
||||
// initial value for connection time out counter, we calculate the total
|
||||
// number of samples here and subtract the number of samples of the block
|
||||
|
@ -132,13 +133,15 @@ void CChannel::SetEnable ( const bool bNEnStat )
|
|||
}
|
||||
}
|
||||
|
||||
void CChannel::SetNetwFrameSizeAndFact ( const int iNewNetwFrameSize,
|
||||
const int iNewNetwFrameSizeFact )
|
||||
void CChannel::SetAudioStreamProperties ( const int iNewNetwFrameSize,
|
||||
const int iNewNetwFrameSizeFact,
|
||||
const int iNewNumAudioChannels )
|
||||
{
|
||||
// this function is intended for the server (not the client)
|
||||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
// store new values
|
||||
iNumAudioChannels = iNewNumAudioChannels;
|
||||
iNetwFrameSize = iNewNetwFrameSize;
|
||||
iNetwFrameSizeFact = iNewNetwFrameSizeFact;
|
||||
|
||||
|
@ -291,6 +294,7 @@ void CChannel::OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTranspor
|
|||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
// store received parameters
|
||||
iNumAudioChannels = NetworkTransportProps.iNumAudioChannels;
|
||||
iNetwFrameSizeFact = NetworkTransportProps.iBlockSizeFact;
|
||||
iNetwFrameSize =
|
||||
NetworkTransportProps.iBaseNetworkPacketSize;
|
||||
|
@ -314,10 +318,10 @@ void CChannel::CreateNetTranspPropsMessFromCurrentSettings()
|
|||
CNetworkTransportProps NetworkTransportProps (
|
||||
iNetwFrameSize,
|
||||
iNetwFrameSizeFact,
|
||||
1, // right now we only use mono
|
||||
iNumAudioChannels,
|
||||
SYSTEM_SAMPLE_RATE,
|
||||
CT_CELT, // always CELT coding
|
||||
0,
|
||||
0, // version of the codec
|
||||
0 );
|
||||
|
||||
// send current network transport properties
|
||||
|
|
|
@ -99,10 +99,12 @@ public:
|
|||
double GetTimingStdDev() { return CycleTimeVariance.GetStdDev(); }
|
||||
|
||||
// set/get network out buffer size and size factor
|
||||
void SetNetwFrameSizeAndFact ( const int iNewNetwFrameSize,
|
||||
const int iNewNetwFrameSizeFact );
|
||||
void SetAudioStreamProperties ( const int iNewNetwFrameSize,
|
||||
const int iNewNetwFrameSizeFact,
|
||||
const int iNewNumAudioChannels );
|
||||
int GetNetwFrameSizeFact() const { return iNetwFrameSizeFact; }
|
||||
int GetNetwFrameSize() const { return iNetwFrameSize; }
|
||||
int GetNumAudioChannels() const { return iNumAudioChannels; }
|
||||
|
||||
double GetJitterBufferErrorRate() { return SockBuf.GetErrorRate(); }
|
||||
|
||||
|
@ -161,6 +163,8 @@ protected:
|
|||
int iNetwFrameSizeFact;
|
||||
int iNetwFrameSize;
|
||||
|
||||
int iNumAudioChannels;
|
||||
|
||||
QMutex Mutex;
|
||||
|
||||
public slots:
|
||||
|
|
|
@ -55,15 +55,28 @@ CClient::CClient ( const quint16 iPortNumber ) :
|
|||
iSndCardMonoBlockSizeSamConvBuff ( 0 )
|
||||
{
|
||||
// init audio endocder/decoder (mono)
|
||||
CeltMode = celt_mode_create (
|
||||
CeltModeMono = celt_mode_create (
|
||||
SYSTEM_SAMPLE_RATE, 1, SYSTEM_FRAME_SIZE_SAMPLES, NULL );
|
||||
|
||||
CeltEncoder = celt_encoder_create ( CeltMode );
|
||||
CeltDecoder = celt_decoder_create ( CeltMode );
|
||||
CeltEncoderMono = celt_encoder_create ( CeltModeMono );
|
||||
CeltDecoderMono = celt_decoder_create ( CeltModeMono );
|
||||
|
||||
#ifdef USE_LOW_COMPLEXITY_CELT_ENC
|
||||
// set encoder low complexity
|
||||
celt_encoder_ctl(CeltEncoder,
|
||||
celt_encoder_ctl ( CeltEncoderMono,
|
||||
CELT_SET_COMPLEXITY_REQUEST, celt_int32_t ( 1 ) );
|
||||
#endif
|
||||
|
||||
// init audio endocder/decoder (stereo)
|
||||
CeltModeStereo = celt_mode_create (
|
||||
SYSTEM_SAMPLE_RATE, 2, SYSTEM_FRAME_SIZE_SAMPLES, NULL );
|
||||
|
||||
CeltEncoderStereo = celt_encoder_create ( CeltModeStereo );
|
||||
CeltDecoderStereo = celt_decoder_create ( CeltModeStereo );
|
||||
|
||||
#ifdef USE_LOW_COMPLEXITY_CELT_ENC
|
||||
// set encoder low complexity
|
||||
celt_encoder_ctl ( CeltEncoderStereo,
|
||||
CELT_SET_COMPLEXITY_REQUEST, celt_int32_t ( 1 ) );
|
||||
#endif
|
||||
|
||||
|
@ -511,8 +524,9 @@ void CClient::Init()
|
|||
vecbyNetwData.Init ( iCeltNumCodedBytes );
|
||||
|
||||
// set the channel network properties
|
||||
Channel.SetNetwFrameSizeAndFact ( iCeltNumCodedBytes,
|
||||
iSndCrdFrameSizeFactor );
|
||||
Channel.SetAudioStreamProperties ( iCeltNumCodedBytes,
|
||||
iSndCrdFrameSizeFactor,
|
||||
1 /* only mono right now */ );
|
||||
}
|
||||
|
||||
void CClient::AudioCallback ( CVector<int16_t>& psData, void* arg )
|
||||
|
@ -610,18 +624,25 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
|
|||
}
|
||||
else
|
||||
{
|
||||
const double dAttFact =
|
||||
static_cast<double> ( AUD_FADER_IN_MIDDLE - abs ( AUD_FADER_IN_MIDDLE - iAudioInFader ) ) /
|
||||
AUD_FADER_IN_MIDDLE;
|
||||
// make sure that in the middle position the two channels are
|
||||
// amplified by 1/2, if the pan is set to one channel, this
|
||||
// channel should have an amplification of 1
|
||||
const double dAttFact = static_cast<double> (
|
||||
AUD_FADER_IN_MIDDLE - abs ( AUD_FADER_IN_MIDDLE - iAudioInFader ) ) /
|
||||
AUD_FADER_IN_MIDDLE / 2;
|
||||
|
||||
const double dAmplFact = 0.5 + static_cast<double> (
|
||||
abs ( AUD_FADER_IN_MIDDLE - iAudioInFader ) ) /
|
||||
AUD_FADER_IN_MIDDLE / 2;
|
||||
|
||||
if ( iAudioInFader > AUD_FADER_IN_MIDDLE )
|
||||
{
|
||||
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )
|
||||
{
|
||||
// attenuation on right channel
|
||||
vecsNetwork[i] =
|
||||
Double2Short ( ( vecdAudioStereo[j] +
|
||||
dAttFact * vecdAudioStereo[j + 1] ) / 2 );
|
||||
vecsNetwork[i] = Double2Short (
|
||||
dAmplFact * vecdAudioStereo[j] +
|
||||
dAttFact * vecdAudioStereo[j + 1] );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -629,9 +650,9 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
|
|||
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )
|
||||
{
|
||||
// attenuation on left channel
|
||||
vecsNetwork[i] =
|
||||
Double2Short ( ( vecdAudioStereo[j + 1] +
|
||||
dAttFact * vecdAudioStereo[j] ) / 2 );
|
||||
vecsNetwork[i] = Double2Short (
|
||||
dAmplFact * vecdAudioStereo[j + 1] +
|
||||
dAttFact * vecdAudioStereo[j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -639,7 +660,7 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
|
|||
for ( i = 0; i < iSndCrdFrameSizeFactor; i++ )
|
||||
{
|
||||
// encode current audio frame with CELT encoder
|
||||
celt_encode ( CeltEncoder,
|
||||
celt_encode ( CeltEncoderMono,
|
||||
&vecsNetwork[i * SYSTEM_FRAME_SIZE_SAMPLES],
|
||||
NULL,
|
||||
&vecCeltData[0],
|
||||
|
@ -670,7 +691,7 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
|
|||
// CELT decoding
|
||||
if ( bReceiveDataOk )
|
||||
{
|
||||
celt_decode ( CeltDecoder,
|
||||
celt_decode ( CeltDecoderMono,
|
||||
&vecbyNetwData[0],
|
||||
iCeltNumCodedBytes,
|
||||
&vecsAudioSndCrdMono[i * SYSTEM_FRAME_SIZE_SAMPLES] );
|
||||
|
@ -678,7 +699,7 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
|
|||
else
|
||||
{
|
||||
// lost packet
|
||||
celt_decode ( CeltDecoder,
|
||||
celt_decode ( CeltDecoderMono,
|
||||
NULL,
|
||||
0,
|
||||
&vecsAudioSndCrdMono[i * SYSTEM_FRAME_SIZE_SAMPLES] );
|
||||
|
|
|
@ -223,9 +223,12 @@ protected:
|
|||
bool bDoAutoSockBufSize;
|
||||
|
||||
// audio encoder/decoder
|
||||
CELTMode* CeltMode;
|
||||
CELTEncoder* CeltEncoder;
|
||||
CELTDecoder* CeltDecoder;
|
||||
CELTMode* CeltModeMono;
|
||||
CELTEncoder* CeltEncoderMono;
|
||||
CELTDecoder* CeltDecoderMono;
|
||||
CELTMode* CeltModeStereo;
|
||||
CELTEncoder* CeltEncoderStereo;
|
||||
CELTDecoder* CeltDecoderStereo;
|
||||
int iCeltNumCodedBytes;
|
||||
bool bCeltDoHighQuality;
|
||||
CVector<unsigned char> vecCeltData;
|
||||
|
|
|
@ -897,7 +897,8 @@ bool CProtocol::EvaluateNetwTranspPropsMes ( const CVector<uint8_t>& vecData )
|
|||
return true;
|
||||
}
|
||||
|
||||
// number of channels of the audio signal, e.g. "2" is stereo (1 byte)
|
||||
// number of channels of the audio signal, only mono (1 channel) or
|
||||
// stereo (2 channels) allowed (1 byte)
|
||||
ReceivedNetwTranspProps.iNumAudioChannels =
|
||||
static_cast<uint32_t> ( GetValFromStream ( vecData, iPos, 1 ) );
|
||||
|
||||
|
|
241
src/server.cpp
241
src/server.cpp
|
@ -175,19 +175,33 @@ CServer::CServer ( const QString& strLoggingFileName,
|
|||
int i;
|
||||
|
||||
// create CELT encoder/decoder for each channel (must be done before
|
||||
// enabling the channels)
|
||||
// enabling the channels), create a mono and stereo encoder/decoder
|
||||
// for each channel
|
||||
for ( i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
// init audio endocder/decoder (mono)
|
||||
CeltMode[i] = celt_mode_create (
|
||||
CeltModeMono[i] = celt_mode_create (
|
||||
SYSTEM_SAMPLE_RATE, 1, SYSTEM_FRAME_SIZE_SAMPLES, NULL );
|
||||
|
||||
CeltEncoder[i] = celt_encoder_create ( CeltMode[i] );
|
||||
CeltDecoder[i] = celt_decoder_create ( CeltMode[i] );
|
||||
CeltEncoderMono[i] = celt_encoder_create ( CeltModeMono[i] );
|
||||
CeltDecoderMono[i] = celt_decoder_create ( CeltModeMono[i] );
|
||||
|
||||
#ifdef USE_LOW_COMPLEXITY_CELT_ENC
|
||||
// set encoder low complexity
|
||||
celt_encoder_ctl(CeltEncoder[i],
|
||||
celt_encoder_ctl ( CeltEncoderMono[i],
|
||||
CELT_SET_COMPLEXITY_REQUEST, celt_int32_t ( 1 ) );
|
||||
#endif
|
||||
|
||||
// init audio endocder/decoder (stereo)
|
||||
CeltModeStereo[i] = celt_mode_create (
|
||||
SYSTEM_SAMPLE_RATE, 2, SYSTEM_FRAME_SIZE_SAMPLES, NULL );
|
||||
|
||||
CeltEncoderStereo[i] = celt_encoder_create ( CeltModeStereo[i] );
|
||||
CeltDecoderStereo[i] = celt_decoder_create ( CeltModeStereo[i] );
|
||||
|
||||
#ifdef USE_LOW_COMPLEXITY_CELT_ENC
|
||||
// set encoder low complexity
|
||||
celt_encoder_ctl ( CeltEncoderStereo[i],
|
||||
CELT_SET_COMPLEXITY_REQUEST, celt_int32_t ( 1 ) );
|
||||
#endif
|
||||
}
|
||||
|
@ -376,6 +390,7 @@ void CServer::OnTimer()
|
|||
CVector<int> vecChanID;
|
||||
CVector<CVector<double> > vecvecdGains;
|
||||
CVector<CVector<int16_t> > vecvecsData;
|
||||
CVector<int> vecNumAudioChannels;
|
||||
|
||||
// Get data from all connected clients -------------------------------------
|
||||
bool bChannelIsNowDisconnected = false;
|
||||
|
@ -399,17 +414,24 @@ void CServer::OnTimer()
|
|||
const int iNumCurConnChan = vecChanID.Size();
|
||||
|
||||
// init temporary vectors
|
||||
vecvecdGains.Init ( iNumCurConnChan );
|
||||
vecvecsData.Init ( iNumCurConnChan );
|
||||
vecvecdGains.Init ( iNumCurConnChan );
|
||||
vecvecsData.Init ( iNumCurConnChan );
|
||||
vecNumAudioChannels.Init ( iNumCurConnChan );
|
||||
|
||||
for ( i = 0; i < iNumCurConnChan; i++ )
|
||||
{
|
||||
// get actual ID of current channel
|
||||
const int iCurChanID = vecChanID[i];
|
||||
|
||||
// get and store number of audio channels
|
||||
const int iCurNumAudChan =
|
||||
vecChannels[iCurChanID].GetNumAudioChannels();
|
||||
|
||||
vecNumAudioChannels[i] = iCurNumAudChan;
|
||||
|
||||
// init vectors storing information of all channels
|
||||
vecvecdGains[i].Init ( iNumCurConnChan );
|
||||
vecvecsData[i].Init ( SYSTEM_FRAME_SIZE_SAMPLES );
|
||||
vecvecsData[i].Init ( iCurNumAudChan * SYSTEM_FRAME_SIZE_SAMPLES );
|
||||
|
||||
// get gains of all connected channels
|
||||
for ( j = 0; j < iNumCurConnChan; j++ )
|
||||
|
@ -442,18 +464,42 @@ void CServer::OnTimer()
|
|||
// CELT decode received data stream
|
||||
if ( eGetStat == GS_BUFFER_OK )
|
||||
{
|
||||
celt_decode ( CeltDecoder[iCurChanID],
|
||||
&vecbyData[0],
|
||||
iCeltNumCodedBytes,
|
||||
&vecvecsData[i][0] );
|
||||
if ( iCurNumAudChan == 1 )
|
||||
{
|
||||
// mono
|
||||
celt_decode ( CeltDecoderMono[iCurChanID],
|
||||
&vecbyData[0],
|
||||
iCeltNumCodedBytes,
|
||||
&vecvecsData[i][0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
// stereo
|
||||
celt_decode ( CeltDecoderStereo[iCurChanID],
|
||||
&vecbyData[0],
|
||||
iCeltNumCodedBytes,
|
||||
&vecvecsData[i][0] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// lost packet
|
||||
celt_decode ( CeltDecoder[iCurChanID],
|
||||
NULL,
|
||||
0,
|
||||
&vecvecsData[i][0] );
|
||||
if ( iCurNumAudChan == 1 )
|
||||
{
|
||||
// mono
|
||||
celt_decode ( CeltDecoderMono[iCurChanID],
|
||||
NULL,
|
||||
0,
|
||||
&vecvecsData[i][0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
// stereo
|
||||
celt_decode ( CeltDecoderStereo[iCurChanID],
|
||||
NULL,
|
||||
0,
|
||||
&vecvecsData[i][0] );
|
||||
}
|
||||
}
|
||||
|
||||
// send message for get status (for GUI)
|
||||
|
@ -491,7 +537,10 @@ void CServer::OnTimer()
|
|||
|
||||
// generate a sparate mix for each channel
|
||||
// actual processing of audio data -> mix
|
||||
vecsSendData = ProcessData ( vecvecsData, vecvecdGains[i] );
|
||||
vecsSendData = ProcessData ( i,
|
||||
vecvecsData,
|
||||
vecvecdGains[i],
|
||||
vecNumAudioChannels );
|
||||
|
||||
// get current number of CELT coded bytes
|
||||
const int iCeltNumCodedBytes =
|
||||
|
@ -500,11 +549,24 @@ void CServer::OnTimer()
|
|||
// CELT encoding
|
||||
CVector<unsigned char> vecCeltData ( iCeltNumCodedBytes );
|
||||
|
||||
celt_encode ( CeltEncoder[iCurChanID],
|
||||
&vecsSendData[0],
|
||||
NULL,
|
||||
&vecCeltData[0],
|
||||
iCeltNumCodedBytes );
|
||||
if ( vecChannels[iCurChanID].GetNumAudioChannels() == 1 )
|
||||
{
|
||||
// mono
|
||||
celt_encode ( CeltEncoderMono[iCurChanID],
|
||||
&vecsSendData[0],
|
||||
NULL,
|
||||
&vecCeltData[0],
|
||||
iCeltNumCodedBytes );
|
||||
}
|
||||
else
|
||||
{
|
||||
// stereo
|
||||
celt_encode ( CeltEncoderStereo[iCurChanID],
|
||||
&vecsSendData[0],
|
||||
NULL,
|
||||
&vecCeltData[0],
|
||||
iCeltNumCodedBytes );
|
||||
}
|
||||
|
||||
// send separate mix to current clients
|
||||
Socket.SendPacket (
|
||||
|
@ -523,39 +585,136 @@ void CServer::OnTimer()
|
|||
CycleTimeVariance.Update();
|
||||
}
|
||||
|
||||
CVector<int16_t> CServer::ProcessData ( CVector<CVector<int16_t> >& vecvecsData,
|
||||
CVector<double>& vecdGains )
|
||||
CVector<int16_t> CServer::ProcessData ( const int iCurIndex,
|
||||
CVector<CVector<int16_t> >& vecvecsData,
|
||||
CVector<double>& vecdGains,
|
||||
CVector<int>& vecNumAudioChannels )
|
||||
{
|
||||
int i;
|
||||
int i, j, k;
|
||||
|
||||
// get number of audio channels of current channel
|
||||
const int iCurNumAudChan = vecNumAudioChannels[iCurIndex];
|
||||
|
||||
// number of samples for output vector
|
||||
const int iNumOutSamples = iCurNumAudChan * SYSTEM_FRAME_SIZE_SAMPLES;
|
||||
|
||||
// init return vector with zeros since we mix all channels on that vector
|
||||
|
||||
// TODO speed optimization: avoid using the zero vector, use the first valid
|
||||
// data vector for initialization instead (take care of gain of this data, too!)
|
||||
|
||||
CVector<int16_t> vecsOutData ( SYSTEM_FRAME_SIZE_SAMPLES, 0 );
|
||||
CVector<int16_t> vecsOutData ( iNumOutSamples, 0 );
|
||||
|
||||
const int iNumClients = vecvecsData.Size();
|
||||
|
||||
// mix all audio data from all clients together
|
||||
for ( int j = 0; j < iNumClients; j++ )
|
||||
if ( iCurNumAudChan == 1 )
|
||||
{
|
||||
// if channel gain is 1, avoid multiplication for speed optimization
|
||||
if ( vecdGains[j] == static_cast<double> ( 1.0 ) )
|
||||
// Mono target channel -------------------------------------------------
|
||||
for ( j = 0; j < iNumClients; j++ )
|
||||
{
|
||||
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ )
|
||||
// if channel gain is 1, avoid multiplication for speed optimization
|
||||
if ( vecdGains[j] == static_cast<double> ( 1.0 ) )
|
||||
{
|
||||
vecsOutData[i] =
|
||||
Double2Short ( vecsOutData[i] + vecvecsData[j][i] );
|
||||
if ( vecNumAudioChannels[j] == 1 )
|
||||
{
|
||||
// mono
|
||||
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ )
|
||||
{
|
||||
vecsOutData[i] =
|
||||
Double2Short ( vecsOutData[i] + vecvecsData[j][i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// stereo: apply stereo-to-mono attenuation
|
||||
for ( i = 0, k = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++, k += 2 )
|
||||
{
|
||||
vecsOutData[i] =
|
||||
Double2Short ( vecsOutData[i] +
|
||||
( vecvecsData[j][k] + vecvecsData[j][k + 1] ) / 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( vecNumAudioChannels[j] == 1 )
|
||||
{
|
||||
// mono
|
||||
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ )
|
||||
{
|
||||
vecsOutData[i] =
|
||||
Double2Short ( vecsOutData[i] +
|
||||
vecvecsData[j][i] * vecdGains[j] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// stereo: apply stereo-to-mono attenuation
|
||||
for ( i = 0, k = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++, k += 2 )
|
||||
{
|
||||
vecsOutData[i] =
|
||||
Double2Short ( vecsOutData[i] + vecdGains[j] *
|
||||
( vecvecsData[j][k] + vecvecsData[j][k + 1] ) / 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stereo target channel -----------------------------------------------
|
||||
for ( j = 0; j < iNumClients; j++ )
|
||||
{
|
||||
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ )
|
||||
// if channel gain is 1, avoid multiplication for speed optimization
|
||||
if ( vecdGains[j] == static_cast<double> ( 1.0 ) )
|
||||
{
|
||||
vecsOutData[i] =
|
||||
Double2Short ( vecsOutData[i] +
|
||||
vecvecsData[j][i] * vecdGains[j] );
|
||||
if ( vecNumAudioChannels[j] == 1 )
|
||||
{
|
||||
// mono: copy same mono data in both out stereo audio channels
|
||||
for ( i = 0, k = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++, k += 2 )
|
||||
{
|
||||
// left channel
|
||||
vecsOutData[k] =
|
||||
Double2Short ( vecsOutData[k] + vecvecsData[j][i] );
|
||||
|
||||
// right channel
|
||||
vecsOutData[k + 1] =
|
||||
Double2Short ( vecsOutData[k + 1] + vecvecsData[j][i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// stereo
|
||||
for ( i = 0; i < iNumOutSamples; i++ )
|
||||
{
|
||||
vecsOutData[i] =
|
||||
Double2Short ( vecsOutData[i] + vecvecsData[j][i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( vecNumAudioChannels[j] == 1 )
|
||||
{
|
||||
// mono: copy same mono data in both out stereo audio channels
|
||||
for ( i = 0, k = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++, k += 2 )
|
||||
{
|
||||
// left channel
|
||||
vecsOutData[k] = Double2Short (
|
||||
vecsOutData[k] + vecvecsData[j][i] * vecdGains[j] );
|
||||
|
||||
// right channel
|
||||
vecsOutData[k + 1] = Double2Short (
|
||||
vecsOutData[k + 1] + vecvecsData[j][i] * vecdGains[j] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// stereo
|
||||
for ( i = 0; i < iNumOutSamples; i++ )
|
||||
{
|
||||
vecsOutData[i] =
|
||||
Double2Short ( vecsOutData[i] +
|
||||
vecvecsData[j][i] * vecdGains[j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
15
src/server.h
15
src/server.h
|
@ -140,8 +140,10 @@ protected:
|
|||
const QString& strChatText );
|
||||
void WriteHTMLChannelList();
|
||||
|
||||
CVector<int16_t> ProcessData ( CVector<CVector<int16_t> >& vecvecsData,
|
||||
CVector<double>& vecdGains );
|
||||
CVector<int16_t> ProcessData ( const int iCurIndex,
|
||||
CVector<CVector<int16_t> >& vecvecsData,
|
||||
CVector<double>& vecdGains,
|
||||
CVector<int>& vecNumAudioChannels );
|
||||
|
||||
virtual void customEvent ( QEvent* Event );
|
||||
|
||||
|
@ -151,9 +153,12 @@ protected:
|
|||
QMutex Mutex;
|
||||
|
||||
// audio encoder/decoder
|
||||
CELTMode* CeltMode[MAX_NUM_CHANNELS];
|
||||
CELTEncoder* CeltEncoder[MAX_NUM_CHANNELS];
|
||||
CELTDecoder* CeltDecoder[MAX_NUM_CHANNELS];
|
||||
CELTMode* CeltModeMono[MAX_NUM_CHANNELS];
|
||||
CELTEncoder* CeltEncoderMono[MAX_NUM_CHANNELS];
|
||||
CELTDecoder* CeltDecoderMono[MAX_NUM_CHANNELS];
|
||||
CELTMode* CeltModeStereo[MAX_NUM_CHANNELS];
|
||||
CELTEncoder* CeltEncoderStereo[MAX_NUM_CHANNELS];
|
||||
CELTDecoder* CeltDecoderStereo[MAX_NUM_CHANNELS];
|
||||
|
||||
CVector<QString> vstrChatColors;
|
||||
|
||||
|
|
Loading…
Reference in a new issue