diff --git a/ChangeLog b/ChangeLog index 07893d9e..9f5a8eb0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -23,6 +23,7 @@ Fernando Lopez-Lezcano 2008-05-20 Stephane Letz * Package number bumped to 1.90 everywhere. + * Implementation of jack_get_max_delayed_usecs, jack_get_xrun_delayed_usecs and jack_reset_max_delayed_usecs. 2008-05-19 Stephane Letz diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 191e189c..c0c9e820 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -1493,17 +1493,29 @@ EXPORT float jack_get_max_delayed_usecs(jack_client_t* ext_client) #ifdef __CLIENTDEBUG__ JackLibGlobals::CheckContext(); #endif - jack_log("jack_get_max_delayed_usecs: not yet implemented"); - return 0.f; -} + JackClient* client = (JackClient*)ext_client; + if (client == NULL) { + jack_error("jack_get_max_delayed_usecs called with a NULL client"); + return 0.f; + } else { + JackEngineControl* control = GetEngineControl(); + return (control ? control->fMaxDelayedUsecs : 0.f); + } + } EXPORT float jack_get_xrun_delayed_usecs(jack_client_t* ext_client) { #ifdef __CLIENTDEBUG__ JackLibGlobals::CheckContext(); #endif - jack_log("jack_get_xrun_delayed_usecs: not yet implemented"); - return 0.f; + JackClient* client = (JackClient*)ext_client; + if (client == NULL) { + jack_error("jack_get_xrun_delayed_usecs called with a NULL client"); + return 0.f; + } else { + JackEngineControl* control = GetEngineControl(); + return (control ? control->fXrunDelayedUsecs : 0.f); + } } EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client) @@ -1511,7 +1523,13 @@ EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client) #ifdef __CLIENTDEBUG__ JackLibGlobals::CheckContext(); #endif - jack_log("jack_reset_max_delayed_usecs: not yet implemented"); + JackClient* client = (JackClient*)ext_client; + if (client == NULL) { + jack_error("jack_reset_max_delayed_usecs called with a NULL client"); + } else { + JackEngineControl* control = GetEngineControl(); + control->ResetXRun(); + } } // thread.h diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 90ffb668..ac7f248b 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -247,9 +247,9 @@ int JackAudioDriver::ProcessSync() return 0; } -void JackAudioDriver::NotifyXRun(jack_time_t callback_usecs) +void JackAudioDriver::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) { - fEngine->NotifyXRun(callback_usecs); + fEngine->NotifyXRun(callback_usecs, delayed_usecs); } jack_default_audio_sample_t* JackAudioDriver::GetInputBuffer(int port_index) diff --git a/common/JackAudioDriver.h b/common/JackAudioDriver.h index 83c54113..532d04e9 100644 --- a/common/JackAudioDriver.h +++ b/common/JackAudioDriver.h @@ -81,7 +81,7 @@ class EXPORT JackAudioDriver : public JackDriver virtual int SetBufferSize(jack_nframes_t buffer_size); virtual int SetSampleRate(jack_nframes_t sample_rate); - virtual void NotifyXRun(jack_time_t callback_usecs); // XRun notification sent by the driver + virtual void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); // XRun notification sent by the driver }; diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index 54aaeea6..8e4a83b2 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -47,6 +47,7 @@ JackDriver::JackDriver(const char* name, JackEngine* engine, JackSynchro** table fEngine = engine; fGraphManager = NULL; fLastWaitUst = 0; + fDelayedUsecs = 0.f; fIsMaster = true; } @@ -178,9 +179,9 @@ JackClientControl* JackDriver::GetClientControl() const return fClientControl; } -void JackDriver::NotifyXRun(jack_time_t callback_usecs) +void JackDriver::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) { - fEngine->NotifyXRun(callback_usecs); + fEngine->NotifyXRun(callback_usecs, delayed_usecs); } void JackDriverClient::SetMaster(bool onoff) diff --git a/common/JackDriver.h b/common/JackDriver.h index e5c1031f..ed0acdaf 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -148,6 +148,7 @@ class EXPORT JackDriver : public JackDriverClient jack_nframes_t fCaptureLatency; jack_nframes_t fPlaybackLatency; jack_time_t fLastWaitUst; + jack_time_t fDelayedUsecs; JackEngine* fEngine; JackGraphManager* fGraphManager; JackSynchro** fSynchroTable; @@ -220,7 +221,7 @@ class EXPORT JackDriver : public JackDriverClient return 0; } - void NotifyXRun(jack_time_t callback_usecs); // XRun notification sent by the driver + void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); // XRun notification sent by the driver virtual bool IsRealTime(); diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index 59f57e57..75cec372 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -269,10 +269,11 @@ void JackEngine::NotifyRemoveClient(const char* name, int refnum) } // Coming from the driver -void JackEngine::NotifyXRun(jack_time_t callback_usecs) +void JackEngine::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) { // Use the audio thread => request thread communication channel fEngineControl->ResetFrameTime(callback_usecs); + fEngineControl->NotifyXRun(delayed_usecs); fChannel->Notify(ALL_CLIENTS, kXRunCallback, 0); } diff --git a/common/JackEngine.h b/common/JackEngine.h index 83dca5b7..ceca07b6 100644 --- a/common/JackEngine.h +++ b/common/JackEngine.h @@ -108,7 +108,7 @@ class JackEngine virtual bool Process(jack_time_t callback_usecs); // Notifications - virtual void NotifyXRun(jack_time_t callback_usecs); + virtual void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs); virtual void NotifyXRun(int refnum); virtual void NotifyGraphReorder(); virtual void NotifyBufferSize(jack_nframes_t nframes); diff --git a/common/JackEngineControl.cpp b/common/JackEngineControl.cpp index 58055561..df0d414f 100644 --- a/common/JackEngineControl.cpp +++ b/common/JackEngineControl.cpp @@ -155,5 +155,17 @@ void JackEngineControl::ClearTimeMeasures() } fLastTime = fCurTime = 0; } + +void JackEngineControl::NotifyXRun(float delayed_usecs) +{ + fXrunDelayedUsecs = delayed_usecs; + if (delayed_usecs > fMaxDelayedUsecs) + fMaxDelayedUsecs = delayed_usecs; +} + +void JackEngineControl::ResetXRun() +{ + fMaxDelayedUsecs = 0.f; +} } // end of namespace diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index 291e8c30..6b453ecb 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -73,6 +73,8 @@ struct JackEngineControl : public JackShmMem bool fTemporary; jack_time_t fPeriodUsecs; jack_time_t fTimeOutUsecs; + float fMaxDelayedUsecs; + float fXrunDelayedUsecs; bool fTimeOut; bool fRealTime; int fPriority; @@ -128,6 +130,8 @@ struct JackEngineControl : public JackShmMem fPeriod = 0; fComputation = 0; fConstraint = 0; + fMaxDelayedUsecs = 0.f; + fXrunDelayedUsecs = 0.f; } ~JackEngineControl() {} @@ -140,6 +144,10 @@ struct JackEngineControl : public JackShmMem void InitFrameTime(); void ResetFrameTime(jack_time_t callback_usecs); void ReadFrameTime(JackTimer* timer); + + // XRun + void NotifyXRun(float delayed_usecs); + void ResetXRun(); // Private void CalcCPULoad(JackClientInterface** table, JackGraphManager* manager); diff --git a/common/JackLockedEngine.h b/common/JackLockedEngine.h index f76952f3..4c6c1806 100644 --- a/common/JackLockedEngine.h +++ b/common/JackLockedEngine.h @@ -154,10 +154,10 @@ class JackLockedEngine : public JackEngine, public JackLockAble } // Notifications - void NotifyXRun(jack_time_t callback_usecs) + void NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) { - // RT : no lock - fEngine->NotifyXRun(callback_usecs); + // RT : no lock + fEngine->NotifyXRun(callback_usecs, delayed_usecs); } void NotifyXRun(int refnum) diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 5adfe0a2..d92c3ac8 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -2268,52 +2268,33 @@ int JackAlsaDriver::Stop() int JackAlsaDriver::Read() { /* Taken from alsa_driver_run_cycle */ - - //jack_engine_t *engine = driver->engine; - int wait_status; - float delayed_usecs; + int wait_status; jack_nframes_t nframes; - //DEBUG ("alsa run cycle wait\n"); - nframes = alsa_driver_wait((alsa_driver_t *)fDriver, -1, &wait_status, &delayed_usecs); - //DEBUG ("alsaback from wait, nframes = %lu", nframes); - + nframes = alsa_driver_wait((alsa_driver_t *)fDriver, -1, &wait_status, &fDelayedUsecs); + if (wait_status < 0) return -1; /* driver failed */ if (nframes == 0) { - /* we detected an xrun and restarted: notify * clients about the delay. */ - //engine->delay (engine, delayed_usecs); jack_log("ALSA XRun"); - NotifyXRun(fLastWaitUst); + NotifyXRun(fLastWaitUst, fDelayedUsecs); return -1; } - //fLastWaitUst = GetMicroSeconds(); // Take callback date here if (nframes != fEngineControl->fBufferSize) jack_log("JackAlsaDriver::Read nframes = %ld", nframes); - //return engine->run_cycle (engine, nframes, delayed_usecs); fDelayedUst = (jack_time_t)delayed_usecs; return alsa_driver_read((alsa_driver_t *)fDriver, fEngineControl->fBufferSize); } int JackAlsaDriver::Write() { - //jack_log("write"); - int res = alsa_driver_write((alsa_driver_t *)fDriver, fEngineControl->fBufferSize); - jack_time_t write_time = GetMicroSeconds(); - - /* - if (write_time > (fLastWaitUst - fDelayedUst) + fEngineControl->fPeriodUsecs) { - jack_log("ALSA write XRun "); - NotifyXRun(write_time); - } - */ - return res; + return alsa_driver_write((alsa_driver_t *)fDriver, fEngineControl->fBufferSize); } void diff --git a/macosx/JackCoreAudioDriver.cpp b/macosx/JackCoreAudioDriver.cpp index 6a6a9048..bc1d01ea 100644 --- a/macosx/JackCoreAudioDriver.cpp +++ b/macosx/JackCoreAudioDriver.cpp @@ -250,7 +250,8 @@ OSStatus JackCoreAudioDriver::DeviceNotificationCallback(AudioDeviceID inDevice, case kAudioDeviceProcessorOverload: jack_log("JackCoreAudioDriver::DeviceNotificationCallback kAudioDeviceProcessorOverload"); - driver->NotifyXRun(GetMicroSeconds()); + jack_time_t cur_time = GetMicroSeconds(); + driver->NotifyXRun(cur_time, float(cur_time - driver->fLastWaitUst)); // Better this value than nothing... break; case kAudioDevicePropertyStreamConfiguration: