git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1324 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.61
@@ -50,6 +50,11 @@ struct JackEngineControl : public JackShmMem | |||||
bool fSyncMode; | bool fSyncMode; | ||||
bool fVerbose; | bool fVerbose; | ||||
void InitFrameTime() | |||||
{ | |||||
fFrameTimer.InitFrameTime(); | |||||
} | |||||
void IncFrameTime(jack_time_t callback_usecs) | void IncFrameTime(jack_time_t callback_usecs) | ||||
{ | { | ||||
fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs); | fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs); | ||||
@@ -36,7 +36,7 @@ JackTimer::JackTimer() | |||||
fSecondOrderIntegrator = 0.0f; | fSecondOrderIntegrator = 0.0f; | ||||
} | } | ||||
void JackFrameTimer::Init() | |||||
void JackFrameTimer::InitFrameTime() | |||||
{ | { | ||||
fFirstWakeUp = true; | fFirstWakeUp = true; | ||||
} | } | ||||
@@ -44,23 +44,13 @@ void JackFrameTimer::Init() | |||||
void JackFrameTimer::IncFrameTime(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs) | void JackFrameTimer::IncFrameTime(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs) | ||||
{ | { | ||||
if (fFirstWakeUp) { | if (fFirstWakeUp) { | ||||
InitFrameTime(callback_usecs, period_usecs); | |||||
InitFrameTimeAux(callback_usecs, period_usecs); | |||||
fFirstWakeUp = false; | fFirstWakeUp = false; | ||||
} else { | } else { | ||||
IncFrameTimeAux(nframes, callback_usecs, period_usecs); | IncFrameTimeAux(nframes, callback_usecs, period_usecs); | ||||
} | } | ||||
} | } | ||||
void JackFrameTimer::InitFrameTime(jack_time_t callback_usecs, jack_time_t period_usecs) | |||||
{ | |||||
JackTimer* timer = WriteNextStateStart(); | |||||
timer->fSecondOrderIntegrator = 0.0f; | |||||
timer->fCurrentCallback = callback_usecs; | |||||
timer->fNextWakeUp = callback_usecs + period_usecs; | |||||
WriteNextStateStop(); | |||||
TrySwitchState(); | |||||
} | |||||
void JackFrameTimer::ResetFrameTime(jack_nframes_t frames_rate, jack_time_t callback_usecs, jack_time_t period_usecs) | void JackFrameTimer::ResetFrameTime(jack_nframes_t frames_rate, jack_time_t callback_usecs, jack_time_t period_usecs) | ||||
{ | { | ||||
if (!fFirstWakeUp) { // ResetFrameTime may be called by a xrun/delayed wakeup on the first cycle | if (!fFirstWakeUp) { // ResetFrameTime may be called by a xrun/delayed wakeup on the first cycle | ||||
@@ -75,20 +65,6 @@ void JackFrameTimer::ResetFrameTime(jack_nframes_t frames_rate, jack_time_t call | |||||
} | } | ||||
} | } | ||||
void JackFrameTimer::IncFrameTimeAux(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs) | |||||
{ | |||||
JackTimer* timer = WriteNextStateStart(); | |||||
float delta = (int64_t)callback_usecs - (int64_t)timer->fNextWakeUp; | |||||
timer->fCurrentWakeup = timer->fNextWakeUp; | |||||
timer->fCurrentCallback = callback_usecs; | |||||
timer->fFrames += nframes; | |||||
timer->fSecondOrderIntegrator += 0.5f * timer->fFilterCoefficient * delta; | |||||
timer->fNextWakeUp = timer->fCurrentWakeup + period_usecs + (int64_t) floorf((timer->fFilterCoefficient * (delta + timer->fSecondOrderIntegrator))); | |||||
timer->fInitialized = true; | |||||
WriteNextStateStop(); | |||||
TrySwitchState(); | |||||
} | |||||
/* | /* | ||||
Use the state returned by ReadCurrentState and check that the state was not changed during the read operation. | Use the state returned by ReadCurrentState and check that the state was not changed during the read operation. | ||||
The operation is lock-free since there is no intermediate state in the write operation that could cause the | The operation is lock-free since there is no intermediate state in the write operation that could cause the | ||||
@@ -105,5 +81,31 @@ void JackFrameTimer::ReadFrameTime(JackTimer* timer) | |||||
} while (cur_index != next_index); // Until a coherent state has been read | } while (cur_index != next_index); // Until a coherent state has been read | ||||
} | } | ||||
// Internal | |||||
void JackFrameTimer::InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t period_usecs) | |||||
{ | |||||
JackTimer* timer = WriteNextStateStart(); | |||||
timer->fSecondOrderIntegrator = 0.0f; | |||||
timer->fCurrentCallback = callback_usecs; | |||||
timer->fNextWakeUp = callback_usecs + period_usecs; | |||||
WriteNextStateStop(); | |||||
TrySwitchState(); | |||||
} | |||||
void JackFrameTimer::IncFrameTimeAux(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs) | |||||
{ | |||||
JackTimer* timer = WriteNextStateStart(); | |||||
float delta = (int64_t)callback_usecs - (int64_t)timer->fNextWakeUp; | |||||
timer->fCurrentWakeup = timer->fNextWakeUp; | |||||
timer->fCurrentCallback = callback_usecs; | |||||
timer->fFrames += nframes; | |||||
timer->fSecondOrderIntegrator += 0.5f * timer->fFilterCoefficient * delta; | |||||
timer->fNextWakeUp = timer->fCurrentWakeup + period_usecs + (int64_t) floorf((timer->fFilterCoefficient * (delta + timer->fSecondOrderIntegrator))); | |||||
timer->fInitialized = true; | |||||
WriteNextStateStop(); | |||||
TrySwitchState(); | |||||
} | |||||
} // end of namespace | } // end of namespace | ||||
@@ -60,6 +60,7 @@ class JackFrameTimer : public JackAtomicState<JackTimer> | |||||
bool fFirstWakeUp; | bool fFirstWakeUp; | ||||
void IncFrameTimeAux(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs); | void IncFrameTimeAux(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs); | ||||
void InitFrameTimeAux(jack_time_t callback_usecs, jack_time_t period_usecs); | |||||
public: | public: | ||||
@@ -68,8 +69,7 @@ class JackFrameTimer : public JackAtomicState<JackTimer> | |||||
~JackFrameTimer() | ~JackFrameTimer() | ||||
{} | {} | ||||
void Init(); | |||||
void InitFrameTime(jack_time_t callback_usecs, jack_time_t period_usecs); | |||||
void InitFrameTime(); | |||||
void ResetFrameTime(jack_nframes_t frames_rate, jack_time_t callback_usecs, jack_time_t period_usecs); | void ResetFrameTime(jack_nframes_t frames_rate, jack_time_t callback_usecs, jack_time_t period_usecs); | ||||
void IncFrameTime(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs); | void IncFrameTime(jack_nframes_t nframes, jack_time_t callback_usecs, jack_time_t period_usecs); | ||||
void ReadFrameTime(JackTimer* timer); | void ReadFrameTime(JackTimer* timer); | ||||
@@ -17,10 +17,10 @@ along with this program; if not, write to the Free Software | |||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
*/ | */ | ||||
#ifdef WIN32 | |||||
#pragma warning (disable : 4786) | |||||
#endif | |||||
#ifdef WIN32 | |||||
#pragma warning (disable : 4786) | |||||
#endif | |||||
#include "JackServer.h" | #include "JackServer.h" | ||||
#include "JackTime.h" | #include "JackTime.h" | ||||
@@ -178,7 +178,7 @@ int JackServer::Close() | |||||
int JackServer::Start() | int JackServer::Start() | ||||
{ | { | ||||
JackLog("JackServer::Start\n"); | JackLog("JackServer::Start\n"); | ||||
fEngineControl->fFrameTimer.Init(); | |||||
fEngineControl->InitFrameTime(); | |||||
return fAudioDriver->Start(); | return fAudioDriver->Start(); | ||||
} | } | ||||
@@ -189,7 +189,7 @@ int JackServer::Stop() | |||||
} | } | ||||
int JackServer::Activate(int refnum) | int JackServer::Activate(int refnum) | ||||
{ | |||||
{ | |||||
int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum; | int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum; | ||||
fGraphManager->DirectConnect(fw_refnum, refnum); | fGraphManager->DirectConnect(fw_refnum, refnum); | ||||
fGraphManager->DirectConnect(refnum, fw_refnum); | fGraphManager->DirectConnect(refnum, fw_refnum); | ||||
@@ -197,27 +197,27 @@ int JackServer::Activate(int refnum) | |||||
} | } | ||||
// Disconnection from the FW must be done in last otherwise an intermediate "unconnected" | // Disconnection from the FW must be done in last otherwise an intermediate "unconnected" | ||||
// (thus unactivated) state may happen where the client is still checked for its end. | |||||
int JackServer::Deactivate(int refnum) | |||||
{ | |||||
int res = fEngine->ClientDeactivate(refnum); | |||||
int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum; | |||||
// Disconnect only when needed | |||||
if (fGraphManager->IsDirectConnection(refnum, fw_refnum)) { | |||||
fGraphManager->DirectDisconnect(refnum, fw_refnum); | |||||
} else { | |||||
JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | |||||
} | |||||
// Disconnect only when needed | |||||
if (fGraphManager->IsDirectConnection(fw_refnum, refnum)) { | |||||
fGraphManager->DirectDisconnect(fw_refnum, refnum); | |||||
} else { | |||||
JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | |||||
} | |||||
return res; | |||||
// (thus unactivated) state may happen where the client is still checked for its end. | |||||
int JackServer::Deactivate(int refnum) | |||||
{ | |||||
int res = fEngine->ClientDeactivate(refnum); | |||||
int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum; | |||||
// Disconnect only when needed | |||||
if (fGraphManager->IsDirectConnection(refnum, fw_refnum)) { | |||||
fGraphManager->DirectDisconnect(refnum, fw_refnum); | |||||
} else { | |||||
JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | |||||
} | |||||
// Disconnect only when needed | |||||
if (fGraphManager->IsDirectConnection(fw_refnum, refnum)) { | |||||
fGraphManager->DirectDisconnect(fw_refnum, refnum); | |||||
} else { | |||||
JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | |||||
} | |||||
return res; | |||||
} | } | ||||
int JackServer::SetBufferSize(jack_nframes_t buffer_size) | int JackServer::SetBufferSize(jack_nframes_t buffer_size) | ||||
@@ -233,12 +233,12 @@ int JackServer::SetBufferSize(jack_nframes_t buffer_size) | |||||
if (fAudioDriver->SetBufferSize(buffer_size) == 0) { | if (fAudioDriver->SetBufferSize(buffer_size) == 0) { | ||||
fFreewheelDriver->SetBufferSize(buffer_size); | fFreewheelDriver->SetBufferSize(buffer_size); | ||||
fEngine->NotifyBufferSize(buffer_size); | fEngine->NotifyBufferSize(buffer_size); | ||||
fEngineControl->fFrameTimer.Init(); | |||||
fEngineControl->InitFrameTime(); | |||||
return fAudioDriver->Start(); | return fAudioDriver->Start(); | ||||
} else { // Failure: restore current value | } else { // Failure: restore current value | ||||
jack_error("Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size); | jack_error("Cannot SetBufferSize for audio driver, restore current value %ld", current_buffer_size); | ||||
fFreewheelDriver->SetBufferSize(current_buffer_size); | fFreewheelDriver->SetBufferSize(current_buffer_size); | ||||
fEngineControl->fFrameTimer.Init(); | |||||
fEngineControl->InitFrameTime(); | |||||
return fAudioDriver->Start(); | return fAudioDriver->Start(); | ||||
} | } | ||||
} | } | ||||
@@ -268,7 +268,7 @@ int JackServer::SetFreewheel(bool onoff) | |||||
fGraphManager->Restore(fState); // Restore previous connection state | fGraphManager->Restore(fState); // Restore previous connection state | ||||
fEngine->NotifyFreewheel(onoff); | fEngine->NotifyFreewheel(onoff); | ||||
fFreewheelDriver->SetMaster(false); | fFreewheelDriver->SetMaster(false); | ||||
fEngineControl->fFrameTimer.Init(); | |||||
fEngineControl->InitFrameTime(); | |||||
return fAudioDriver->Start(); | return fAudioDriver->Start(); | ||||
} | } | ||||
} else { | } else { | ||||