bug fix in socket buffer, fix in channel, ASIO buffer size setting should work now, some other small fixes
This commit is contained in:
parent
56c91ce201
commit
ee28e3bc8e
8 changed files with 132 additions and 96 deletions
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -622,11 +622,19 @@ CChannel::CChannel ( const bool bNIsServer ) : bIsServer ( bNIsServer ),
|
|||
MIN_SERVER_BLOCK_SIZE_SAMPLES * DEF_NET_BLOCK_SIZE_FACTOR,
|
||||
CT_MSADPCM );
|
||||
|
||||
SetNetwBufSizeFactOut ( DEF_NET_BLOCK_SIZE_FACTOR );
|
||||
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,11 +738,16 @@ void CChannel::SetNetwBufSizeOut ( const int iNewAudioBlockSizeOut )
|
|||
// this function is intended for the client (not the server)
|
||||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
// store new value
|
||||
iCurAudioBlockSizeOut = iNewAudioBlockSizeOut;
|
||||
// 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 );
|
||||
iAudComprSizeOut =
|
||||
AudioCompressionOut.Init ( iNewAudioBlockSizeOut, eAudComprTypeOut );
|
||||
}
|
||||
}
|
||||
|
||||
void CChannel::SetNetwBufSizeFactOut ( const int iNewNetwBlSiFactOut )
|
||||
|
|
|
@ -150,29 +150,40 @@ bool CClient::SetServerAddr ( QString strNAddr )
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CClient::SetSndCrdPreferredMonoBlSizeIndex ( const int iNewIdx )
|
||||
{
|
||||
// right now we simply set the internal value
|
||||
if ( ( iNewIdx >= 0 ) && ( CSndCrdBufferSizes::GetNumOfBufferSizes() ) )
|
||||
{
|
||||
iSndCrdPreferredMonoBlSizeIndex = iNewIdx;
|
||||
// right now we simply set the internal value
|
||||
if ( ( iNewIdx >= 0 ) && ( CSndCrdBufferSizes::GetNumOfBufferSizes() ) )
|
||||
{
|
||||
iSndCrdPreferredMonoBlSizeIndex = iNewIdx;
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// TODO take action on new parameter
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
// TODO possible BUG!!!!!!!!!!!!!!!!!!!!!
|
||||
// iBufferSizeMono must not be the same as iASIOBufferSizeMono
|
||||
iASIOBufferSizeStereo = 2 * iASIOBufferSizeMono;
|
||||
|
||||
// set the sample rate
|
||||
ASIOSetSampleRate ( SND_CRD_SAMPLE_RATE );
|
||||
|
||||
// create memory for intermediate audio buffer
|
||||
vecsTmpAudioSndCrdStereo.Init ( iBufferSizeStereo );
|
||||
|
||||
|
||||
|
||||
|
||||
int i;
|
||||
|
||||
// set the sample rate and check if sample rate is supported
|
||||
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 and activate ASIO buffers (buffer size in samples)
|
||||
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 );
|
||||
|
||||
vecsTmpAudioSndCrdStereo.Init ( iASIOBufferSizeStereo );
|
||||
|
||||
// create and activate ASIO buffers (buffer size in samples)
|
||||
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;
|
||||
|
|
|
@ -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(); }
|
||||
|
|
Loading…
Reference in a new issue