preparations for "mono in/stereo out" mode

This commit is contained in:
Volker Fischer 2014-02-23 20:01:17 +00:00
parent 4dca2d1c93
commit 5811b1f9d4
3 changed files with 158 additions and 139 deletions

View file

@ -43,7 +43,7 @@ CClient::CClient ( const quint16 iPortNumber ) :
eAudioCompressionType ( CT_OPUS ), eAudioCompressionType ( CT_OPUS ),
iCeltNumCodedBytes ( CELT_NUM_BYTES_MONO_LOW_QUALITY ), iCeltNumCodedBytes ( CELT_NUM_BYTES_MONO_LOW_QUALITY ),
eAudioQuality ( AQ_LOW ), eAudioQuality ( AQ_LOW ),
bUseStereo ( false ), eAudioChannelConf ( CC_MONO ),
bIsInitializationPhase ( true ), bIsInitializationPhase ( true ),
Socket ( &Channel, iPortNumber ), Socket ( &Channel, iPortNumber ),
Sound ( AudioCallback, this ), Sound ( AudioCallback, this ),
@ -483,7 +483,14 @@ void CClient::SetUseStereo ( const bool bNUseStereo )
} }
// set new parameter // set new parameter
bUseStereo = bNUseStereo; if ( bNUseStereo )
{
eAudioChannelConf = CC_STEREO;
}
else
{
eAudioChannelConf = CC_MONO;
}
Init(); Init();
if ( bWasRunning ) if ( bWasRunning )
@ -774,18 +781,7 @@ void CClient::Init()
// inits for audio coding // inits for audio coding
if ( eAudioCompressionType == CT_CELT ) if ( eAudioCompressionType == CT_CELT )
{ {
if ( bUseStereo ) if ( eAudioChannelConf == CC_MONO )
{
if ( eAudioQuality == AQ_LOW )
{
iCeltNumCodedBytes = CELT_NUM_BYTES_STEREO_LOW_QUALITY;
}
else
{
iCeltNumCodedBytes = CELT_NUM_BYTES_STEREO_NORMAL_QUALITY;
}
}
else
{ {
if ( eAudioQuality == AQ_LOW ) if ( eAudioQuality == AQ_LOW )
{ {
@ -796,27 +792,21 @@ void CClient::Init()
iCeltNumCodedBytes = CELT_NUM_BYTES_MONO_NORMAL_QUALITY; iCeltNumCodedBytes = CELT_NUM_BYTES_MONO_NORMAL_QUALITY;
} }
} }
else
{
if ( eAudioQuality == AQ_LOW )
{
iCeltNumCodedBytes = CELT_NUM_BYTES_STEREO_LOW_QUALITY;
}
else
{
iCeltNumCodedBytes = CELT_NUM_BYTES_STEREO_NORMAL_QUALITY;
}
}
} }
else else
{ {
if ( bUseStereo ) if ( eAudioChannelConf == CC_MONO )
{
switch ( eAudioQuality )
{
case AQ_LOW:
iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_LOW_QUALITY;
break;
case AQ_NORMAL:
iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_NORMAL_QUALITY;
break;
case AQ_HIGH:
iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_HIGH_QUALITY;
break;
}
}
else
{ {
switch ( eAudioQuality ) switch ( eAudioQuality )
{ {
@ -833,19 +823,36 @@ void CClient::Init()
break; break;
} }
} }
else
{
switch ( eAudioQuality )
{
case AQ_LOW:
iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_LOW_QUALITY;
break;
case AQ_NORMAL:
iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_NORMAL_QUALITY;
break;
case AQ_HIGH:
iCeltNumCodedBytes = OPUS_NUM_BYTES_STEREO_HIGH_QUALITY;
break;
}
}
} }
vecCeltData.Init ( iCeltNumCodedBytes ); vecCeltData.Init ( iCeltNumCodedBytes );
if ( bUseStereo ) if ( eAudioChannelConf == CC_MONO )
{ {
opus_custom_encoder_ctl ( OpusEncoderStereo, opus_custom_encoder_ctl ( OpusEncoderMono,
OPUS_SET_BITRATE ( OPUS_SET_BITRATE (
CalcBitRateBitsPerSecFromCodedBytes ( CalcBitRateBitsPerSecFromCodedBytes (
iCeltNumCodedBytes ) ) ); iCeltNumCodedBytes ) ) );
} }
else else
{ {
opus_custom_encoder_ctl ( OpusEncoderMono, opus_custom_encoder_ctl ( OpusEncoderStereo,
OPUS_SET_BITRATE ( OPUS_SET_BITRATE (
CalcBitRateBitsPerSecFromCodedBytes ( CalcBitRateBitsPerSecFromCodedBytes (
iCeltNumCodedBytes ) ) ); iCeltNumCodedBytes ) ) );
@ -853,13 +860,14 @@ void CClient::Init()
// inits for network and channel // inits for network and channel
vecbyNetwData.Init ( iCeltNumCodedBytes ); vecbyNetwData.Init ( iCeltNumCodedBytes );
if ( bUseStereo )
if ( eAudioChannelConf == CC_MONO )
{ {
// set the channel network properties // set the channel network properties
Channel.SetAudioStreamProperties ( eAudioCompressionType, Channel.SetAudioStreamProperties ( eAudioCompressionType,
iCeltNumCodedBytes, iCeltNumCodedBytes,
iSndCrdFrameSizeFactor, iSndCrdFrameSizeFactor,
2 ); 1 );
} }
else else
{ {
@ -867,7 +875,7 @@ void CClient::Init()
Channel.SetAudioStreamProperties ( eAudioCompressionType, Channel.SetAudioStreamProperties ( eAudioCompressionType,
iCeltNumCodedBytes, iCeltNumCodedBytes,
iSndCrdFrameSizeFactor, iSndCrdFrameSizeFactor,
1 ); 2 );
} }
// reset initialization phase flag // reset initialization phase flag
@ -929,16 +937,7 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
const double dRevLev = const double dRevLev =
static_cast<double> ( iReverbLevel ) / AUD_REVERB_MAX / 2; static_cast<double> ( iReverbLevel ) / AUD_REVERB_MAX / 2;
if ( bUseStereo ) if ( eAudioChannelConf == CC_MONO )
{
// for stereo always apply reverberation effect on both channels
for ( i = 0; i < iStereoBlockSizeSam; i += 2 )
{
// both channels (stereo)
AudioReverbL.ProcessSample ( vecsStereoSndCrd[i], vecsStereoSndCrd[i + 1], dRevLev );
}
}
else
{ {
if ( bReverbOnLeftChan ) if ( bReverbOnLeftChan )
{ {
@ -959,6 +958,15 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
} }
} }
} }
else
{
// for stereo always apply reverberation effect on both channels
for ( i = 0; i < iStereoBlockSizeSam; i += 2 )
{
// both channels (stereo)
AudioReverbL.ProcessSample ( vecsStereoSndCrd[i], vecsStereoSndCrd[i + 1], dRevLev );
}
}
} }
// mix both signals depending on the fading setting, convert // mix both signals depending on the fading setting, convert
@ -966,7 +974,7 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
if ( iAudioInFader == AUD_FADER_IN_MIDDLE ) if ( iAudioInFader == AUD_FADER_IN_MIDDLE )
{ {
// no action require if fader is in the middle and stereo is used // no action require if fader is in the middle and stereo is used
if ( !bUseStereo ) if ( eAudioChannelConf == CC_MONO )
{ {
// mix channels together (store result in first half of the vector) // mix channels together (store result in first half of the vector)
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )
@ -982,33 +990,7 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
} }
else else
{ {
if ( bUseStereo ) if ( eAudioChannelConf == CC_MONO )
{
// stereo
const double dAttFactStereo = static_cast<double> (
AUD_FADER_IN_MIDDLE - abs ( AUD_FADER_IN_MIDDLE - iAudioInFader ) ) /
AUD_FADER_IN_MIDDLE;
if ( iAudioInFader > AUD_FADER_IN_MIDDLE )
{
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )
{
// attenuation on right channel
vecsStereoSndCrd[j + 1] = Double2Short (
dAttFactStereo * vecsStereoSndCrd[j + 1] );
}
}
else
{
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )
{
// attenuation on left channel
vecsStereoSndCrd[j] = Double2Short (
dAttFactStereo * vecsStereoSndCrd[j] );
}
}
}
else
{ {
// mono // mono
// make sure that in the middle position the two channels are // make sure that in the middle position the two channels are
@ -1045,31 +1027,37 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
} }
} }
} }
else
{
// stereo
const double dAttFactStereo = static_cast<double> (
AUD_FADER_IN_MIDDLE - abs ( AUD_FADER_IN_MIDDLE - iAudioInFader ) ) /
AUD_FADER_IN_MIDDLE;
if ( iAudioInFader > AUD_FADER_IN_MIDDLE )
{
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )
{
// attenuation on right channel
vecsStereoSndCrd[j + 1] = Double2Short (
dAttFactStereo * vecsStereoSndCrd[j + 1] );
}
}
else
{
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )
{
// attenuation on left channel
vecsStereoSndCrd[j] = Double2Short (
dAttFactStereo * vecsStereoSndCrd[j] );
}
}
}
} }
for ( i = 0; i < iSndCrdFrameSizeFactor; i++ ) for ( i = 0; i < iSndCrdFrameSizeFactor; i++ )
{ {
if ( bUseStereo ) if ( eAudioChannelConf == CC_MONO )
{
// encode current audio frame
if ( eAudioCompressionType == CT_CELT )
{
cc6_celt_encode ( CeltEncoderStereo,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES],
NULL,
&vecCeltData[0],
iCeltNumCodedBytes );
}
else
{
opus_custom_encode ( OpusEncoderStereo,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES],
SYSTEM_FRAME_SIZE_SAMPLES,
&vecCeltData[0],
iCeltNumCodedBytes );
}
}
else
{ {
// encode current audio frame // encode current audio frame
if ( eAudioCompressionType == CT_CELT ) if ( eAudioCompressionType == CT_CELT )
@ -1089,6 +1077,26 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
iCeltNumCodedBytes ); iCeltNumCodedBytes );
} }
} }
else
{
// encode current audio frame
if ( eAudioCompressionType == CT_CELT )
{
cc6_celt_encode ( CeltEncoderStereo,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES],
NULL,
&vecCeltData[0],
iCeltNumCodedBytes );
}
else
{
opus_custom_encode ( OpusEncoderStereo,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES],
SYSTEM_FRAME_SIZE_SAMPLES,
&vecCeltData[0],
iCeltNumCodedBytes );
}
}
// send coded audio through the network // send coded audio through the network
Channel.PrepAndSendPacket ( &Socket, Channel.PrepAndSendPacket ( &Socket,
@ -1117,25 +1125,7 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
// flag // flag
bIsInitializationPhase = false; bIsInitializationPhase = false;
if ( bUseStereo ) if ( eAudioChannelConf == CC_MONO )
{
if ( eAudioCompressionType == CT_CELT )
{
cc6_celt_decode ( CeltDecoderStereo,
&vecbyNetwData[0],
iCeltNumCodedBytes,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES] );
}
else
{
opus_custom_decode ( OpusDecoderStereo,
&vecbyNetwData[0],
iCeltNumCodedBytes,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES],
SYSTEM_FRAME_SIZE_SAMPLES );
}
}
else
{ {
if ( eAudioCompressionType == CT_CELT ) if ( eAudioCompressionType == CT_CELT )
{ {
@ -1153,29 +1143,29 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
SYSTEM_FRAME_SIZE_SAMPLES ); SYSTEM_FRAME_SIZE_SAMPLES );
} }
} }
else
{
if ( eAudioCompressionType == CT_CELT )
{
cc6_celt_decode ( CeltDecoderStereo,
&vecbyNetwData[0],
iCeltNumCodedBytes,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES] );
}
else
{
opus_custom_decode ( OpusDecoderStereo,
&vecbyNetwData[0],
iCeltNumCodedBytes,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES],
SYSTEM_FRAME_SIZE_SAMPLES );
}
}
} }
else else
{ {
// lost packet // lost packet
if ( bUseStereo ) if ( eAudioChannelConf == CC_MONO )
{
if ( eAudioCompressionType == CT_CELT )
{
cc6_celt_decode ( CeltDecoderStereo,
NULL,
0,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES] );
}
else
{
opus_custom_decode ( OpusDecoderStereo,
NULL,
iCeltNumCodedBytes,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES],
SYSTEM_FRAME_SIZE_SAMPLES );
}
}
else
{ {
if ( eAudioCompressionType == CT_CELT ) if ( eAudioCompressionType == CT_CELT )
{ {
@ -1193,6 +1183,24 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
SYSTEM_FRAME_SIZE_SAMPLES ); SYSTEM_FRAME_SIZE_SAMPLES );
} }
} }
else
{
if ( eAudioCompressionType == CT_CELT )
{
cc6_celt_decode ( CeltDecoderStereo,
NULL,
0,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES] );
}
else
{
opus_custom_decode ( OpusDecoderStereo,
NULL,
iCeltNumCodedBytes,
&vecsStereoSndCrd[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES],
SYSTEM_FRAME_SIZE_SAMPLES );
}
}
} }
} }
@ -1215,7 +1223,7 @@ fflush(pFileDelay);
// phase // phase
if ( Channel.IsConnected() && ( !bIsInitializationPhase ) ) if ( Channel.IsConnected() && ( !bIsInitializationPhase ) )
{ {
if ( !bUseStereo ) if ( eAudioChannelConf == CC_MONO )
{ {
// copy mono data in stereo sound card buffer // copy mono data in stereo sound card buffer
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )

View file

@ -129,7 +129,7 @@ public:
EAudioQuality GetAudioQuality() const { return eAudioQuality; } EAudioQuality GetAudioQuality() const { return eAudioQuality; }
void SetAudioQuality ( const EAudioQuality eNAudioQuality ); void SetAudioQuality ( const EAudioQuality eNAudioQuality );
bool GetUseStereo() const { return bUseStereo; } bool GetUseStereo() const { return ( eAudioChannelConf == CC_STEREO ); }
void SetUseStereo ( const bool bNUseStereo ); void SetUseStereo ( const bool bNUseStereo );
void SetServerListCentralServerAddress ( const QString& sNCentServAddr ) void SetServerListCentralServerAddress ( const QString& sNCentServAddr )
@ -328,7 +328,7 @@ void SetAudoCompressiontype ( const EAudComprType eNAudCompressionType );
EAudComprType eAudioCompressionType; EAudComprType eAudioCompressionType;
int iCeltNumCodedBytes; int iCeltNumCodedBytes;
EAudioQuality eAudioQuality; EAudioQuality eAudioQuality;
bool bUseStereo; EAudChanConf eAudioChannelConf;
bool bIsInitializationPhase; bool bIsInitializationPhase;
CVector<unsigned char> vecCeltData; CVector<unsigned char> vecCeltData;

View file

@ -427,6 +427,17 @@ public slots:
* Other Classes/Enums * * Other Classes/Enums *
\******************************************************************************/ \******************************************************************************/
// Audio channel configuration -------------------------------------------------
enum EAudChanConf
{
// used for settings -> enum values must be fixed!
CC_MONO = 0,
CC_MONO_IN_STEREO_OUT = 1,
CC_STEREO = 2
};
// Audio compression type enum ------------------------------------------------- // Audio compression type enum -------------------------------------------------
enum EAudComprType enum EAudComprType
{ {