better handling of sound card reinits
This commit is contained in:
parent
e2c98e2384
commit
3f75913dca
6 changed files with 1962 additions and 1975 deletions
|
@ -256,7 +256,7 @@ int CSound::bufferSizeCallback ( jack_nframes_t, void *arg )
|
||||||
{
|
{
|
||||||
CSound* pSound = reinterpret_cast<CSound*> ( arg );
|
CSound* pSound = reinterpret_cast<CSound*> ( arg );
|
||||||
|
|
||||||
pSound->EmitReinitRequestSignal();
|
pSound->EmitReinitRequestSignal ( RS_ONLY_RESTART_AND_INIT );
|
||||||
|
|
||||||
return 0; // zero on success, non-zero on error
|
return 0; // zero on success, non-zero on error
|
||||||
}
|
}
|
||||||
|
|
|
@ -498,11 +498,7 @@ OSStatus CSound::deviceNotification ( AudioDeviceID,
|
||||||
// xrun handling (it is important to act on xruns under CoreAudio
|
// xrun handling (it is important to act on xruns under CoreAudio
|
||||||
// since it seems that the xrun situation stays stable for a
|
// since it seems that the xrun situation stays stable for a
|
||||||
// while and would give you a long time bad audio
|
// while and would give you a long time bad audio
|
||||||
|
pSound->EmitReinitRequestSignal ( RS_ONLY_RESTART );
|
||||||
// TEST we reuse the signal which was intended only for Windows OS but
|
|
||||||
// with a modification in the client (see client.cpp)
|
|
||||||
pSound->EmitReinitRequestSignal();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return noErr;
|
return noErr;
|
||||||
|
|
|
@ -128,8 +128,8 @@ CClient::CClient ( const quint16 iPortNumber ) :
|
||||||
SIGNAL ( CLPingWithNumClientsReceived ( CHostAddress, int, int ) ),
|
SIGNAL ( CLPingWithNumClientsReceived ( CHostAddress, int, int ) ),
|
||||||
this, SLOT ( OnCLPingWithNumClientsReceived ( CHostAddress, int, int ) ) );
|
this, SLOT ( OnCLPingWithNumClientsReceived ( CHostAddress, int, int ) ) );
|
||||||
|
|
||||||
QObject::connect ( &Sound, SIGNAL ( ReinitRequest() ),
|
QObject::connect ( &Sound, SIGNAL ( ReinitRequest ( ESndCrdResetType ) ),
|
||||||
this, SLOT ( OnSndCrdReinitRequest() ) );
|
this, SLOT ( OnSndCrdReinitRequest ( ESndCrdResetType ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::OnSendProtMessage ( CVector<uint8_t> vecMessage )
|
void CClient::OnSendProtMessage ( CVector<uint8_t> vecMessage )
|
||||||
|
@ -443,7 +443,7 @@ void CClient::SetSndCrdRightOutputChannel ( const int iNewChan )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::OnSndCrdReinitRequest()
|
void CClient::OnSndCrdReinitRequest ( ESndCrdResetType eSndCrdResetType )
|
||||||
{
|
{
|
||||||
// if client was running then first
|
// if client was running then first
|
||||||
// stop it and restart again after new initialization
|
// stop it and restart again after new initialization
|
||||||
|
@ -453,31 +453,20 @@ void CClient::OnSndCrdReinitRequest()
|
||||||
Sound.Stop();
|
Sound.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// reinit the driver (we use the currently selected driver) and
|
// perform reinit request as indicated by the request type parameter
|
||||||
// init client object, too
|
if ( eSndCrdResetType != RS_ONLY_RESTART )
|
||||||
|
{
|
||||||
// TODO possible bug: In ASIO driver if set dev is called, the driver is
|
if ( eSndCrdResetType != RS_ONLY_RESTART_AND_INIT )
|
||||||
// unloaded. See ASIO manual: "Note: A host application has to defer
|
{
|
||||||
// processing of these notification to a later "secure" time as the
|
// reinit the driver if requested
|
||||||
// driver has finish its processing of the notification. Especially on
|
// (we use the currently selected driver)
|
||||||
// the kAsioResetRequest it is a bad idea to unload the driver during
|
|
||||||
// the asioMessage callback since the callback has to return back into
|
|
||||||
// the driver, which is no longer present."
|
|
||||||
|
|
||||||
// TODO write separate driver reset function in sound base instead
|
|
||||||
// of doing setdev with the old driver ID -> avoid unloading driver
|
|
||||||
|
|
||||||
Sound.SetDev ( Sound.GetDev() );
|
Sound.SetDev ( Sound.GetDev() );
|
||||||
|
}
|
||||||
|
|
||||||
// This is a test. We reuse the SndCrdReinitRequest which was
|
// init client object (must always be performed if the driver
|
||||||
// initially only intended for the Windows OS. But for Mac we
|
// was changed)
|
||||||
// must not call the client Init function to work properly, therefore
|
|
||||||
// we add the preprocesser check here
|
|
||||||
// TODO better solution was to introduce a new signal in the sound base
|
|
||||||
// and a new signal handler in the client
|
|
||||||
#if !defined ( __APPLE__ ) && !defined ( __MACOSX )
|
|
||||||
Init();
|
Init();
|
||||||
#endif
|
}
|
||||||
|
|
||||||
if ( bWasRunning )
|
if ( bWasRunning )
|
||||||
{
|
{
|
||||||
|
|
|
@ -335,7 +335,7 @@ public slots:
|
||||||
int iMs,
|
int iMs,
|
||||||
int iNumClients );
|
int iNumClients );
|
||||||
|
|
||||||
void OnSndCrdReinitRequest();
|
void OnSndCrdReinitRequest ( ESndCrdResetType eSndCrdResetType );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ConClientListMesReceived ( CVector<CChannelShortInfo> vecChanInfo );
|
void ConClientListMesReceived ( CVector<CChannelShortInfo> vecChanInfo );
|
||||||
|
|
|
@ -32,6 +32,16 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
// TODO better solution with enum definition
|
||||||
|
// problem: in signals it seems not to work to use CSoundBase::ESndCrdResetType
|
||||||
|
enum ESndCrdResetType
|
||||||
|
{
|
||||||
|
RS_ONLY_RESTART,
|
||||||
|
RS_ONLY_RESTART_AND_INIT,
|
||||||
|
RS_RELOAD_RESTART_AND_INIT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Classes ********************************************************************/
|
/* Classes ********************************************************************/
|
||||||
class CSoundBase : public QThread
|
class CSoundBase : public QThread
|
||||||
{
|
{
|
||||||
|
@ -73,7 +83,8 @@ public:
|
||||||
|
|
||||||
// TODO this should be protected but since it is used
|
// TODO this should be protected but since it is used
|
||||||
// in a callback function it has to be public -> better solution
|
// in a callback function it has to be public -> better solution
|
||||||
void EmitReinitRequestSignal() { emit ReinitRequest(); }
|
void EmitReinitRequestSignal ( const ESndCrdResetType eSndCrdResetType )
|
||||||
|
{ emit ReinitRequest ( eSndCrdResetType ); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// driver handling
|
// driver handling
|
||||||
|
@ -109,7 +120,7 @@ protected:
|
||||||
QString strDriverNames[MAX_NUMBER_SOUND_CARDS];
|
QString strDriverNames[MAX_NUMBER_SOUND_CARDS];
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void ReinitRequest();
|
void ReinitRequest ( ESndCrdResetType eSndCrdResetType );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* !defined ( SOUNDBASE_HOIHGEH8_3_4344456456345634565KJIUHF1912__INCLUDED_ ) */
|
#endif /* !defined ( SOUNDBASE_HOIHGEH8_3_4344456456345634565KJIUHF1912__INCLUDED_ ) */
|
||||||
|
|
|
@ -959,6 +959,7 @@ long CSound::asioMessages ( long selector,
|
||||||
double* )
|
double* )
|
||||||
{
|
{
|
||||||
long ret = 0;
|
long ret = 0;
|
||||||
|
|
||||||
switch ( selector )
|
switch ( selector )
|
||||||
{
|
{
|
||||||
case kAsioEngineVersion:
|
case kAsioEngineVersion:
|
||||||
|
@ -968,26 +969,16 @@ long CSound::asioMessages ( long selector,
|
||||||
|
|
||||||
// both messages might be send if the buffer size changes
|
// both messages might be send if the buffer size changes
|
||||||
case kAsioBufferSizeChange:
|
case kAsioBufferSizeChange:
|
||||||
|
pSound->EmitReinitRequestSignal ( RS_ONLY_RESTART_AND_INIT );
|
||||||
|
ret = 1L; // 1L if request is accepted or 0 otherwise
|
||||||
|
break;
|
||||||
|
|
||||||
case kAsioResetRequest:
|
case kAsioResetRequest:
|
||||||
|
pSound->EmitReinitRequestSignal ( RS_RELOAD_RESTART_AND_INIT );
|
||||||
|
|
||||||
// TODO implement separate ASIO reset function in base class!
|
|
||||||
|
|
||||||
// kAsioBufferSizeChange:
|
|
||||||
// Informs the application that the driver has a new preferred buffer size.
|
|
||||||
//
|
|
||||||
// kAsioResetRequest:
|
|
||||||
// Requests a driver reset. If accepted, this will close the driver
|
|
||||||
// (ASIOExit() ) and re-open it again (ASIOInit() etc.) at the next
|
|
||||||
// "safe" time (usually during the application IDLE time). Some
|
|
||||||
// drivers need to reconfigure for instance when the sample rate
|
|
||||||
// changes, or some basic changes have been made in ASIOControlPanel().
|
|
||||||
|
|
||||||
|
|
||||||
pSound->EmitReinitRequestSignal();
|
|
||||||
ret = 1L; // 1L if request is accepted or 0 otherwise
|
ret = 1L; // 1L if request is accepted or 0 otherwise
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue