bug fix in socket buffer, fix in channel, ASIO buffer size setting should work now, some other small fixes

This commit is contained in:
Volker Fischer 2009-03-05 20:07:41 +00:00
parent 56c91ce201
commit ee28e3bc8e
8 changed files with 132 additions and 96 deletions

View file

@ -380,10 +380,13 @@ void CNetBuf::Clear ( const EClearType eClearType )
void CNetBuf::FadeInAudioDataBlock ( CVector<double>& vecdData )
{
// correct fading length if necessary
const int iCurFadingLen = min ( vecdData.Size(), iNumSamFading );
// apply linear fading
for ( int i = 0; i < iNumSamFading; i++ )
for ( int i = 0; i < iCurFadingLen; i++ )
{
vecdData[i] *= ( (double) i / iNumSamFading );
vecdData[i] *= ( (double) i / iCurFadingLen );
}
// reset flag
@ -394,14 +397,17 @@ void CNetBuf::FadeOutExtrapolateAudioDataBlock ( CVector<double>& vecdData,
const double dExPDiff,
const double dExPLastV )
{
// correct fading length if necessary
const int iCurFadingLenExtra = min ( vecdData.Size(), iNumSamFadingExtra );
// apply linear extrapolation and linear fading
for ( int i = 0; i < iNumSamFadingExtra; i++ )
for ( int i = 0; i < iCurFadingLenExtra; i++ )
{
// calculate extrapolated value
vecdData[i] = ( ( i + 1 ) * dExPDiff + dExPLastV );
// linear fading
vecdData[i] *= ( (double) ( iNumSamFadingExtra - i ) / iNumSamFadingExtra );
vecdData[i] *= ( (double) ( iCurFadingLenExtra - i ) / iCurFadingLenExtra );
}
}

View file

@ -622,11 +622,19 @@ CChannel::CChannel ( const bool bNIsServer ) : bIsServer ( bNIsServer ),
MIN_SERVER_BLOCK_SIZE_SAMPLES * DEF_NET_BLOCK_SIZE_FACTOR,
CT_MSADPCM );
if ( bIsServer )
{
SetNetwBufSizeFactOut ( DEF_NET_BLOCK_SIZE_FACTOR );
}
else
{
SetNetwBufSizeOut ( MIN_SERVER_BLOCK_SIZE_SAMPLES );
}
// set initial audio compression format for output
SetAudioCompressionOut ( CT_MSADPCM );
// connections -------------------------------------------------------------
QObject::connect ( &Protocol,
SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ),
@ -730,12 +738,17 @@ void CChannel::SetNetwBufSizeOut ( const int iNewAudioBlockSizeOut )
// this function is intended for the client (not the server)
QMutexLocker locker ( &Mutex );
// direct setting of audio buffer (without buffer size factor) is
// right now only intendet for the client, not the server
if ( !bIsServer )
{
// store new value
iCurAudioBlockSizeOut = iNewAudioBlockSizeOut;
iAudComprSizeOut =
AudioCompressionOut.Init ( iNewAudioBlockSizeOut, eAudComprTypeOut );
}
}
void CChannel::SetNetwBufSizeFactOut ( const int iNewNetwBlSiFactOut )
{

View file

@ -150,9 +150,6 @@ bool CClient::SetServerAddr ( QString strNAddr )
return true;
}
void CClient::SetSndCrdPreferredMonoBlSizeIndex ( const int iNewIdx )
{
// right now we simply set the internal value
@ -161,18 +158,32 @@ if ( ( iNewIdx >= 0 ) && ( CSndCrdBufferSizes::GetNumOfBufferSizes() ) )
iSndCrdPreferredMonoBlSizeIndex = iNewIdx;
}
// TODO take action on new parameter
// init with new parameter, if client was running then first
// stop it and restart again after new initialization
const bool bWasRunning = Sound.IsRunning();
if ( bWasRunning )
{
Sound.Stop();
}
// init with new block size index parameter
Init ( iSndCrdPreferredMonoBlSizeIndex );
if ( bWasRunning )
{
Sound.Start();
}
// tell the server that audio coding has changed (it
// is important to call this function AFTER we have applied
// the new setting to the channel!)
Channel.CreateNetTranspPropsMessFromCurrentSettings();
}
void CClient::Start()
{
// init object
// TEST
Init ( 192 );
Init ( iSndCrdPreferredMonoBlSizeIndex );
// enable channel
Channel.SetEnable ( true );
@ -203,8 +214,12 @@ void CClient::AudioCallback ( CVector<short>& psData, void* arg )
pMyClientObj->ProcessAudioData ( psData );
}
void CClient::Init ( const int iPrefMonoBlockSizeSamAtSndCrdSamRate )
void CClient::Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate )
{
// translate block size index in actual block size
const int iPrefMonoBlockSizeSamAtSndCrdSamRate = CSndCrdBufferSizes::
GetBufferSizeFromIndex ( iPrefMonoBlockSizeSamIndexAtSndCrdSamRate );
// get actual sound card buffer size using preferred size
iSndCrdMonoBlockSizeSam = Sound.Init ( iPrefMonoBlockSizeSamAtSndCrdSamRate );
iSndCrdStereoBlockSizeSam = 2 * iSndCrdMonoBlockSizeSam;

View file

@ -156,7 +156,7 @@ protected:
// callback function must be static, otherwise it does not work
static void AudioCallback ( CVector<short>& psData, void* arg );
void Init ( const int iPrefMonoBlockSizeSamAtSndCrdSamRate );
void Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate );
void ProcessAudioData ( CVector<short>& vecsStereoSndCrd );
void UpdateTimeResponseMeasurement();
void UpdateSocketBufferSize();

View file

@ -251,7 +251,7 @@
<property name="minimumSize" >
<size>
<width>110</width>
<height>0</height>
<height>20</height>
</size>
</property>
<property name="frameShape" >
@ -281,7 +281,7 @@
<property name="minimumSize" >
<size>
<width>110</width>
<height>0</height>
<height>20</height>
</size>
</property>
<property name="frameShape" >
@ -386,7 +386,7 @@
<property name="minimumSize" >
<size>
<width>50</width>
<height>0</height>
<height>20</height>
</size>
</property>
<property name="frameShape" >
@ -427,7 +427,7 @@
<property name="minimumSize" >
<size>
<width>50</width>
<height>0</height>
<height>20</height>
</size>
</property>
<property name="font" >
@ -484,6 +484,12 @@
</item>
<item>
<widget class="QLabel" name="TextUpstreamValue" >
<property name="minimumSize" >
<size>
<width>0</width>
<height>20</height>
</size>
</property>
<property name="font" >
<font>
<weight>75</weight>

View file

@ -61,11 +61,6 @@ void CSoundBase::Stop()
{
wait ( 5000 );
}
// TODO stop audio interface (previously done in Close function, we
// better should implement a stop function in derived sound classes
Close();
}
void CSoundBase::run()

View file

@ -43,9 +43,8 @@ ASIOBufferInfo bufferInfos[2 * NUM_IN_OUT_CHANNELS]; // for input and output b
ASIOChannelInfo channelInfos[2 * NUM_IN_OUT_CHANNELS];
bool bASIOPostOutput;
ASIOCallbacks asioCallbacks;
int iBufferSizeMono;
int iBufferSizeStereo;
int iASIOBufferSizeMono;
int iASIOBufferSizeStereo;
CVector<short> vecsTmpAudioSndCrdStereo;
@ -88,12 +87,12 @@ void CSound::SetDev ( const int iNewDev )
// loading and initializing the new driver failed, go back to original
// driver and display error message
LoadAndInitializeDriver ( lCurDev );
Init ( iBufferSizeStereo );
Init ( iASIOBufferSizeStereo );
throw CGenErr ( strErrorMessage.c_str() );
}
Init ( iBufferSizeStereo );
Init ( iASIOBufferSizeStereo );
}
else
{
@ -319,92 +318,75 @@ int CSound::GetActualBufferSize ( const int iDesiredBufferSizeMono )
int CSound::Init ( const int iNewPrefMonoBufferSize )
{
// first, stop audio and dispose ASIO buffers
ASIOStop();
ASIOMutex.lock(); // get mutex lock
{
// get the actual sound card buffer size which is supported
// by the audio hardware
iASIOBufferSizeMono =
GetActualBufferSize ( iNewPrefMonoBufferSize );
// init base clasee
CSoundBase::Init ( iNewPrefMonoBufferSize );
CSoundBase::Init ( iASIOBufferSizeMono );
// set internal buffer size value and calculate stereo buffer size
iBufferSizeMono = iNewPrefMonoBufferSize;
iBufferSizeStereo = 2 * iBufferSizeMono;
iASIOBufferSizeStereo = 2 * iASIOBufferSizeMono;
// TODO possible BUG!!!!!!!!!!!!!!!!!!!!!
// iBufferSizeMono must not be the same as iASIOBufferSizeMono
// create memory for intermediate audio buffer
vecsTmpAudioSndCrdStereo.Init ( iBufferSizeStereo );
int i;
// set the sample rate and check if sample rate is supported
// set the sample rate
ASIOSetSampleRate ( SND_CRD_SAMPLE_RATE );
// TEST
iASIOBufferSizeMono = GetActualBufferSize ( iBufferSizeMono );
for ( i = 0; i < NUM_IN_OUT_CHANNELS; i++ )
{
// prepare input channels
bufferInfos[i].isInput = ASIOTrue;
bufferInfos[i].channelNum = i;
bufferInfos[i].buffers[0] = 0;
bufferInfos[i].buffers[1] = 0;
// prepare output channels
bufferInfos[NUM_IN_OUT_CHANNELS + i].isInput = ASIOFalse;
bufferInfos[NUM_IN_OUT_CHANNELS + i].channelNum = i;
bufferInfos[NUM_IN_OUT_CHANNELS + i].buffers[0] = 0;
bufferInfos[NUM_IN_OUT_CHANNELS + i].buffers[1] = 0;
}
// create memory for intermediate audio buffer
vecsTmpAudioSndCrdStereo.Init ( iASIOBufferSizeStereo );
// create and activate ASIO buffers (buffer size in samples)
ASIOCreateBuffers ( bufferInfos, 2 /* in/out */ * NUM_IN_OUT_CHANNELS /* stereo */,
ASIOCreateBuffers ( bufferInfos,
2 /* in/out */ * NUM_IN_OUT_CHANNELS /* stereo */,
iASIOBufferSizeMono, &asioCallbacks );
// check wether the driver requires the ASIOOutputReady() optimization
// (can be used by the driver to reduce output latency by one block)
bASIOPostOutput = ( ASIOOutputReady() == ASE_OK );
}
ASIOMutex.unlock();
// initialization is done, (re)start audio
return iASIOBufferSizeMono;
}
void CSound::Start()
{
// start audio
ASIOStart();
// TEST
return iNewPrefMonoBufferSize;
// call base class
CSoundBase::Start();
}
void CSound::Stop()
{
// stop audio
ASIOStop();
// call base class
CSoundBase::Stop();
}
void CSound::Close()
{
// stop driver
ASIOStop();
// TODO
}
CSound::CSound ( void (*fpNewCallback) ( CVector<short>& psData, void* arg ), void* arg ) :
CSoundBase ( true, fpNewCallback, arg )
{
int i;
// TEST
pSound = this;
// get available ASIO driver names in system
for ( int i = 0; i < MAX_NUMBER_SOUND_CARDS; i++ )
for ( i = 0; i < MAX_NUMBER_SOUND_CARDS; i++ )
{
cDriverNames[i] = new char[32];
}
@ -422,6 +404,23 @@ pSound = this;
// init device index with illegal value to show that driver is not initialized
lCurDev = -1;
// init buffer infos, we always want to have two input and
// two output channels
for ( i = 0; i < NUM_IN_OUT_CHANNELS; i++ )
{
// prepare input channels
bufferInfos[i].isInput = ASIOTrue;
bufferInfos[i].channelNum = i;
bufferInfos[i].buffers[0] = 0;
bufferInfos[i].buffers[1] = 0;
// prepare output channels
bufferInfos[NUM_IN_OUT_CHANNELS + i].isInput = ASIOFalse;
bufferInfos[NUM_IN_OUT_CHANNELS + i].channelNum = i;
bufferInfos[NUM_IN_OUT_CHANNELS + i].buffers[0] = 0;
bufferInfos[NUM_IN_OUT_CHANNELS + i].buffers[1] = 0;
}
// set up the asioCallback structure
asioCallbacks.bufferSwitch = &bufferSwitch;
asioCallbacks.sampleRateDidChange = &sampleRateChanged;

View file

@ -60,6 +60,8 @@ public:
virtual ~CSound();
virtual int Init ( const int iNewPrefMonoBufferSize );
virtual void Start();
virtual void Stop();
virtual void Close();
virtual void OpenDriverSetup() { ASIOControlPanel(); }