first working stereo version (algorithm part)

This commit is contained in:
Volker Fischer 2010-03-22 16:38:15 +00:00
parent 7173108c77
commit 2a77dbda58
3 changed files with 137 additions and 40 deletions

View file

@ -51,10 +51,11 @@ CClient::CClient ( const quint16 iPortNumber ) :
bFraSiFactSafeSupported ( false ), bFraSiFactSafeSupported ( false ),
iCeltNumCodedBytes ( CELT_NUM_BYTES_MONO_NORMAL_QUALITY ), iCeltNumCodedBytes ( CELT_NUM_BYTES_MONO_NORMAL_QUALITY ),
bCeltDoHighQuality ( false ), bCeltDoHighQuality ( false ),
bStereo ( false ),
bSndCrdConversionBufferRequired ( false ), bSndCrdConversionBufferRequired ( false ),
iSndCardMonoBlockSizeSamConvBuff ( 0 ) iSndCardMonoBlockSizeSamConvBuff ( 0 )
{ {
// init audio endocder/decoder (mono) // init audio encoder/decoder (mono)
CeltModeMono = celt_mode_create ( CeltModeMono = celt_mode_create (
SYSTEM_SAMPLE_RATE, 1, SYSTEM_FRAME_SIZE_SAMPLES, NULL ); SYSTEM_SAMPLE_RATE, 1, SYSTEM_FRAME_SIZE_SAMPLES, NULL );
@ -67,7 +68,7 @@ CClient::CClient ( const quint16 iPortNumber ) :
CELT_SET_COMPLEXITY_REQUEST, celt_int32_t ( 1 ) ); CELT_SET_COMPLEXITY_REQUEST, celt_int32_t ( 1 ) );
#endif #endif
// init audio endocder/decoder (stereo) // init audio encoder/decoder (stereo)
CeltModeStereo = celt_mode_create ( CeltModeStereo = celt_mode_create (
SYSTEM_SAMPLE_RATE, 2, SYSTEM_FRAME_SIZE_SAMPLES, NULL ); SYSTEM_SAMPLE_RATE, 2, SYSTEM_FRAME_SIZE_SAMPLES, NULL );
@ -510,23 +511,49 @@ void CClient::Init()
// inits for CELT coding // inits for CELT coding
if ( bCeltDoHighQuality ) if ( bCeltDoHighQuality )
{
if ( bStereo )
{
iCeltNumCodedBytes = CELT_NUM_BYTES_STEREO_HIGH_QUALITY;
}
else
{ {
iCeltNumCodedBytes = CELT_NUM_BYTES_MONO_HIGH_QUALITY; iCeltNumCodedBytes = CELT_NUM_BYTES_MONO_HIGH_QUALITY;
} }
}
else
{
if ( bStereo )
{
iCeltNumCodedBytes = CELT_NUM_BYTES_STEREO_NORMAL_QUALITY;
}
else else
{ {
iCeltNumCodedBytes = CELT_NUM_BYTES_MONO_NORMAL_QUALITY; iCeltNumCodedBytes = CELT_NUM_BYTES_MONO_NORMAL_QUALITY;
} }
}
vecCeltData.Init ( iCeltNumCodedBytes ); vecCeltData.Init ( iCeltNumCodedBytes );
// init network buffers // inits for network and channel
vecsNetwork.Init ( iMonoBlockSizeSam );
vecbyNetwData.Init ( iCeltNumCodedBytes ); vecbyNetwData.Init ( iCeltNumCodedBytes );
if ( bStereo )
{
vecsNetwork.Init ( iStereoBlockSizeSam );
// set the channel network properties // set the channel network properties
Channel.SetAudioStreamProperties ( iCeltNumCodedBytes, Channel.SetAudioStreamProperties ( iCeltNumCodedBytes,
iSndCrdFrameSizeFactor, iSndCrdFrameSizeFactor,
1 /* only mono right now */ ); 2 );
}
else
{
vecsNetwork.Init ( iMonoBlockSizeSam );
// set the channel network properties
Channel.SetAudioStreamProperties ( iCeltNumCodedBytes,
iSndCrdFrameSizeFactor,
1 );
}
} }
void CClient::AudioCallback ( CVector<int16_t>& psData, void* arg ) void CClient::AudioCallback ( CVector<int16_t>& psData, void* arg )
@ -614,7 +641,17 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
// from double to short // from double to short
if ( iAudioInFader == AUD_FADER_IN_MIDDLE ) if ( iAudioInFader == AUD_FADER_IN_MIDDLE )
{ {
// just mix channels together if ( bStereo )
{
// perform type conversion
for ( i = 0; i < iStereoBlockSizeSam; i++ )
{
vecsNetwork[i] = Double2Short ( vecdAudioStereo[i] );
}
}
else
{
// mix channels together
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 ) for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )
{ {
vecsNetwork[i] = vecsNetwork[i] =
@ -622,8 +659,19 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
vecdAudioStereo[j + 1] ) / 2 ); vecdAudioStereo[j + 1] ) / 2 );
} }
} }
}
else else
{ {
// TODO for stereo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// TODO for stereo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// TODO for stereo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// TODO for stereo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// TODO for stereo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// TODO for stereo!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// make sure that in the middle position the two channels are // make sure that in the middle position the two channels are
// amplified by 1/2, if the pan is set to one channel, this // amplified by 1/2, if the pan is set to one channel, this
// channel should have an amplification of 1 // channel should have an amplification of 1
@ -658,6 +706,17 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
} }
for ( i = 0; i < iSndCrdFrameSizeFactor; i++ ) for ( i = 0; i < iSndCrdFrameSizeFactor; i++ )
{
if ( bStereo )
{
// encode current audio frame with CELT encoder
celt_encode ( CeltEncoderStereo,
&vecsNetwork[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES],
NULL,
&vecCeltData[0],
iCeltNumCodedBytes );
}
else
{ {
// encode current audio frame with CELT encoder // encode current audio frame with CELT encoder
celt_encode ( CeltEncoderMono, celt_encode ( CeltEncoderMono,
@ -665,6 +724,7 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
NULL, NULL,
&vecCeltData[0], &vecCeltData[0],
iCeltNumCodedBytes ); iCeltNumCodedBytes );
}
// send coded audio through the network // send coded audio through the network
Socket.SendPacket ( Channel.PrepSendPacket ( vecCeltData ), Socket.SendPacket ( Channel.PrepSendPacket ( vecCeltData ),
@ -690,24 +750,54 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
// CELT decoding // CELT decoding
if ( bReceiveDataOk ) if ( bReceiveDataOk )
{
if ( bStereo )
{
celt_decode ( CeltDecoderStereo,
&vecbyNetwData[0],
iCeltNumCodedBytes,
&vecsAudioSndCrdStereo[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES] );
}
else
{ {
celt_decode ( CeltDecoderMono, celt_decode ( CeltDecoderMono,
&vecbyNetwData[0], &vecbyNetwData[0],
iCeltNumCodedBytes, iCeltNumCodedBytes,
&vecsAudioSndCrdMono[i * SYSTEM_FRAME_SIZE_SAMPLES] ); &vecsAudioSndCrdMono[i * SYSTEM_FRAME_SIZE_SAMPLES] );
} }
}
else else
{ {
// lost packet // lost packet
if ( bStereo )
{
celt_decode ( CeltDecoderStereo,
NULL,
0,
&vecsAudioSndCrdStereo[i * 2 * SYSTEM_FRAME_SIZE_SAMPLES] );
}
else
{
celt_decode ( CeltDecoderMono, celt_decode ( CeltDecoderMono,
NULL, NULL,
0, 0,
&vecsAudioSndCrdMono[i * SYSTEM_FRAME_SIZE_SAMPLES] ); &vecsAudioSndCrdMono[i * SYSTEM_FRAME_SIZE_SAMPLES] );
} }
} }
}
// check if channel is connected // check if channel is connected
if ( Channel.IsConnected() ) if ( Channel.IsConnected() )
{
if ( bStereo )
{
// copy data
for ( i = 0; i < iStereoBlockSizeSam; i++ )
{
vecsStereoSndCrd[i] = vecsAudioSndCrdStereo[i];
}
}
else
{ {
// 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 )
@ -716,6 +806,7 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
vecsAudioSndCrdMono[i]; vecsAudioSndCrdMono[i];
} }
} }
}
else else
{ {
// if not connected, clear data // if not connected, clear data

View file

@ -70,6 +70,11 @@
#define CELT_NUM_BYTES_MONO_NORMAL_QUALITY 24 #define CELT_NUM_BYTES_MONO_NORMAL_QUALITY 24
#define CELT_NUM_BYTES_MONO_HIGH_QUALITY 44 #define CELT_NUM_BYTES_MONO_HIGH_QUALITY 44
// 46: stereo low/normal quality 222 kbsp (128) / 180 kbps (256)
// 70: stereo high quality 294 kbps (128) / 252 kbps (256)
#define CELT_NUM_BYTES_STEREO_NORMAL_QUALITY 46
#define CELT_NUM_BYTES_STEREO_HIGH_QUALITY 70
/* Classes ********************************************************************/ /* Classes ********************************************************************/
class CClient : public QObject class CClient : public QObject
@ -231,6 +236,7 @@ protected:
CELTDecoder* CeltDecoderStereo; CELTDecoder* CeltDecoderStereo;
int iCeltNumCodedBytes; int iCeltNumCodedBytes;
bool bCeltDoHighQuality; bool bCeltDoHighQuality;
bool bStereo;
CVector<unsigned char> vecCeltData; CVector<unsigned char> vecCeltData;
CSocket Socket; CSocket Socket;

View file

@ -6,7 +6,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>535</width> <width>535</width>
<height>382</height> <height>374</height>
</rect> </rect>
</property> </property>
<property name="windowTitle" > <property name="windowTitle" >