From 51fbf0cf719645d0d0f532f25072d949958c359f Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 19 Mar 2009 10:38:23 +0000 Subject: [PATCH] rebase from trunk 3420:3447 git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3448 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 43 ++++--- common/JackAPI.cpp | 17 ++- common/JackAudioAdapter.cpp | 29 ++--- common/JackAudioAdapterInterface.cpp | 109 +++++++++++------- common/JackAudioAdapterInterface.h | 26 +++-- common/JackClient.cpp | 2 - common/JackConnectionManager.cpp | 5 - common/JackConnectionManager.h | 7 +- common/JackEngineControl.cpp | 43 ------- common/JackEngineControl.h | 44 +++++-- common/JackEngineProfiling.h | 2 +- common/JackFilters.h | 24 +++- common/JackFrameTimer.h | 2 +- common/JackGlobals.cpp | 6 +- common/JackGlobals.h | 7 +- common/JackGraphManager.cpp | 5 - common/JackGraphManager.h | 6 +- common/JackLibSampleRateResampler.cpp | 8 +- common/JackLibSampleRateResampler.h | 4 +- common/JackNetAPI.cpp | 4 +- common/JackNetAdapter.cpp | 34 +++--- common/JackNetDriver.cpp | 5 +- common/JackNetManager.cpp | 9 +- common/JackResampler.cpp | 14 +-- common/JackResampler.h | 8 +- common/JackThreadedDriver.cpp | 1 + common/JackTransportEngine.cpp | 6 - common/JackTransportEngine.h | 6 +- common/JackWaitThreadedDriver.cpp | 3 +- common/jack/ringbuffer.h | 10 ++ common/jack/thread.h | 35 +++++- common/ringbuffer.c | 14 +++ common/wscript | 1 + linux/alsa/JackAlsaAdapter.cpp | 12 +- linux/wscript | 1 + macosx/coreaudio/JackCoreAudioAdapter.cpp | 9 +- .../iPhoneNet.xcodeproj/project.pbxproj | 10 ++ posix/JackFifo.cpp | 6 +- posix/JackPosixThread.cpp | 3 +- posix/JackSocket.cpp | 100 ++-------------- posix/JackSocket.h | 7 +- posix/JackTypes_os.h | 2 + solaris/oss/JackOSSAdapter.cpp | 22 ++-- windows/portaudio/JackPortAudioAdapter.cpp | 11 +- 44 files changed, 390 insertions(+), 332 deletions(-) diff --git a/ChangeLog b/ChangeLog index f650afa5..e29fb0e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -17,38 +17,55 @@ Nedko Arnaudov Fernando Lopez-Lezcano Romain Moret Florian Faber -Michael Voigt +Michael Voigt Torben Hohn --------------------------- Jackdmp changes log ---------------------------- +--------------------------- -2009-03-10 Stephane Letz +2009-03-19 Stephane Letz + + * Tim Blechmann optimization patch (inlining some heavy used methods). + +2009-03-12 Stephane Letz - * Add -g (ring-buffer) parameter to netadapter. + * Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1). +2009-03-12 Stephane Letz + + * Try automatic adaptative mode in adapters. + +2009-03-11 Stephane Letz + + * Client incorrect re-naming fixed : now done at socket level also. + +2009-03-10 Stephane Letz + + * Add -g (ring-buffer) parameter to netadapter. + * Automatic adaptative ringbuffer size mode when -g = 0. + 2009-03-09 Stephane Letz - * Use Torben Hohn PI controler code for adapters (in progress). - + * Use Torben Hohn PI controler code for adapters (in progress). + 2009-03-05 Stephane Letz - * Support for BIG_ENDIAN machines in NetJack2 for transport data. + * Support for BIG_ENDIAN machines in NetJack2 for transport data. * Add auto_connect parameter in netmanager and netadapter. - + 2009-03-03 Stephane Letz * More robust profiling tools when clients come and go. - + 2009-03-01 Stephane Letz * Raise default port number to 1024. - + 2009-02-27 Stephane Letz * Improve generated gnuplot files for adapting code. - + 2009-02-25 Stephane Letz * Major cleanup in adapter code. @@ -57,8 +74,8 @@ Torben Hohn * Fix JackNetDriver::Close method. * For audio device reservation, add card_to_num function. - * Fix buffer size and sample rate handling in JackAlsaAdapter. - * Add control for adapter ringbuffer size. + * Fix buffer size and sample rate handling in JackAlsaAdapter. + * Add control for adapter ringbuffer size. * Fix JackAlsaAdapter.h for 64 bits compilation. 2009-02-24 Stephane Letz diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 02b8ff8d..fa7b4f22 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -219,10 +219,12 @@ extern "C" thread_routine routine, void *arg); EXPORT int jack_drop_real_time_scheduling (pthread_t thread); - + EXPORT int jack_client_stop_thread (jack_client_t* client, pthread_t thread); EXPORT int jack_client_kill_thread (jack_client_t* client, pthread_t thread); - +#ifndef WIN32 + EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc); +#endif EXPORT char * jack_get_internal_client_name (jack_client_t *client, jack_intclient_t intclient); EXPORT jack_intclient_t jack_internal_client_handle (jack_client_t *client, @@ -1759,8 +1761,8 @@ EXPORT int jack_client_max_real_time_priority(jack_client_t* ext_client) JackEngineControl* control = GetEngineControl(); return (control->fRealTime) ? control->fMaxClientPriority : -1; } -} - +} + EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority) { JackEngineControl* control = GetEngineControl(); @@ -1792,6 +1794,13 @@ EXPORT int jack_client_kill_thread(jack_client_t* client, pthread_t thread) return JackThread::KillImp(thread); } +#ifndef WIN32 +EXPORT void jack_set_thread_creator (jack_thread_creator_t jtc) +{ + JackGlobals::fJackThreadCreator = jtc; +} +#endif + // intclient.h EXPORT int jack_internal_client_new (const char *client_name, const char *load_name, diff --git a/common/JackAudioAdapter.cpp b/common/JackAudioAdapter.cpp index 6961a06f..03f4605f 100644 --- a/common/JackAudioAdapter.cpp +++ b/common/JackAudioAdapter.cpp @@ -36,20 +36,21 @@ namespace Jack int JackAudioAdapter::Process (jack_nframes_t frames, void* arg) { JackAudioAdapter* adapter = static_cast(arg); - if (!adapter->fAudioAdapter->IsRunning()) - return 0; - float* inputBuffer[adapter->fAudioAdapter->GetInputs()]; float* outputBuffer[adapter->fAudioAdapter->GetOutputs()]; + + // Always clear output for (int i = 0; i < adapter->fAudioAdapter->GetInputs(); i++) { inputBuffer[i] = (float*)jack_port_get_buffer(adapter->fCapturePortList[i], frames); + memset(inputBuffer[i], 0, frames * sizeof(float)); } + for (int i = 0; i < adapter->fAudioAdapter->GetOutputs(); i++) { outputBuffer[i] = (float*)jack_port_get_buffer(adapter->fPlaybackPortList[i], frames); } - + adapter->fAudioAdapter->PullAndPush(inputBuffer, outputBuffer, frames); - return 0; + return 0; } int JackAudioAdapter::BufferSize ( jack_nframes_t buffer_size, void* arg ) @@ -70,23 +71,23 @@ namespace Jack //JackAudioAdapter ********************************************************* - JackAudioAdapter::JackAudioAdapter (jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params, bool system) + JackAudioAdapter::JackAudioAdapter (jack_client_t* jack_client, JackAudioAdapterInterface* audio_io, const JSList* params, bool system) :fJackClient(jack_client), fAudioAdapter(audio_io) { const JSList* node; const jack_driver_param_t* param; fAutoConnect = false; - + for (node = params; node; node = jack_slist_next(node)) { param = (const jack_driver_param_t*) node->data; switch (param->character) { case 'c': - fAutoConnect = param->value.i; + fAutoConnect = true; break; } } } - + JackAudioAdapter::~JackAudioAdapter() { // When called, Close has already been used for the client, thus ports are already unregistered. @@ -105,11 +106,11 @@ namespace Jack delete[] fCapturePortList; delete[] fPlaybackPortList; } - + void JackAudioAdapter::ConnectPorts() { const char **ports; - + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsInput); if (ports != NULL) { for (int i = 0; i < fAudioAdapter->GetInputs() && ports[i]; i++) { @@ -117,7 +118,7 @@ namespace Jack } free(ports); } - + ports = jack_get_ports(fJackClient, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); if (ports != NULL) { for (int i = 0; i < fAudioAdapter->GetOutputs() && ports[i]; i++) { @@ -137,7 +138,7 @@ namespace Jack char name[32]; jack_log("JackAudioAdapter::Open fCaptureChannels %d fPlaybackChannels %d", fAudioAdapter->GetInputs(), fAudioAdapter->GetOutputs()); fAudioAdapter->Create(); - + //jack ports fCapturePortList = new jack_port_t*[fAudioAdapter->GetInputs()]; fPlaybackPortList = new jack_port_t*[fAudioAdapter->GetOutputs()]; @@ -165,7 +166,7 @@ namespace Jack goto fail; if ( jack_activate ( fJackClient ) < 0 ) goto fail; - + if (fAutoConnect) ConnectPorts(); diff --git a/common/JackAudioAdapterInterface.cpp b/common/JackAudioAdapterInterface.cpp index 364e70f5..47425d40 100644 --- a/common/JackAudioAdapterInterface.cpp +++ b/common/JackAudioAdapterInterface.cpp @@ -52,13 +52,12 @@ namespace Jack for (int i = 1; i < max; i++) { fprintf(file, "%d \t %d \t %d \t %f \t %f \t %d \t %d \n", - fTable[i].delta, fTable[i+1].time1 - fTable[i].time1, - fTable[i+1].time2 - fTable[i].time2, + fTable[i].delta, fTable[i].time1, fTable[i].time2, fTable[i].r1, fTable[i].r2, fTable[i].pos1, fTable[i].pos2); } fclose(file); - /* No used for now + // No used for now // Adapter timing 1 file = fopen("AdapterTiming1.plot", "w"); fprintf(file, "set multiplot\n"); @@ -68,9 +67,9 @@ namespace Jack fprintf(file, "set xlabel \"audio cycles\"\n"); fprintf(file, "set ylabel \"frames\"\n"); fprintf(file, "plot "); - sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Consumer interrupt period\" with lines,"); + sprintf(buffer, "\"JackAudioAdapter.log\" using 2 title \"Ringbuffer error\" with lines,"); fprintf(file, buffer); - sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Producer interrupt period\" with lines"); + sprintf(buffer, "\"JackAudioAdapter.log\" using 3 title \"Ringbuffer error with timing correction\" with lines"); fprintf(file, buffer); fprintf(file, "\n unset multiplot\n"); @@ -89,8 +88,7 @@ namespace Jack fprintf(file, buffer); fclose(file); - */ - + // Adapter timing 2 file = fopen("AdapterTiming2.plot", "w"); fprintf(file, "set multiplot\n"); @@ -155,16 +153,32 @@ namespace Jack } #endif + + void JackAudioAdapterInterface::GrowRingBufferSize() + { + fRingbufferCurSize *= 2; + } + + void JackAudioAdapterInterface::AdaptRingBufferSize() + { + if (fHostBufferSize > fAdaptedBufferSize) + fRingbufferCurSize = 4 * fHostBufferSize; + else + fRingbufferCurSize = 4 * fAdaptedBufferSize; + } void JackAudioAdapterInterface::ResetRingBuffers() { + if (fRingbufferCurSize > DEFAULT_RB_SIZE) + fRingbufferCurSize = DEFAULT_RB_SIZE; + for (int i = 0; i < fCaptureChannels; i++) - fCaptureRingBuffer[i]->Reset(); + fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); for (int i = 0; i < fPlaybackChannels; i++) - fPlaybackRingBuffer[i]->Reset(); + fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); } - - void JackAudioAdapterInterface::Reset() + + void JackAudioAdapterInterface::Reset() { ResetRingBuffers(); fRunning = false; @@ -179,11 +193,25 @@ namespace Jack //ringbuffers fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; - for (int i = 0; i < fCaptureChannels; i++ ) - fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize); - for (int i = 0; i < fPlaybackChannels; i++ ) - fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality, fRingbufferSize); - + + if (fAdaptative) { + AdaptRingBufferSize(); + jack_info("Ringbuffer automatic adaptative mode size = %d frames", fRingbufferCurSize); + } else { + if (fRingbufferCurSize > DEFAULT_RB_SIZE) + fRingbufferCurSize = DEFAULT_RB_SIZE; + jack_info("Fixed ringbuffer size = %d frames", fRingbufferCurSize); + } + + for (int i = 0; i < fCaptureChannels; i++ ) { + fCaptureRingBuffer[i] = new JackLibSampleRateResampler(fQuality); + fCaptureRingBuffer[i]->Reset(fRingbufferCurSize); + } + for (int i = 0; i < fPlaybackChannels; i++ ) { + fPlaybackRingBuffer[i] = new JackLibSampleRateResampler(fQuality); + fPlaybackRingBuffer[i]->Reset(fRingbufferCurSize); + } + if (fCaptureChannels > 0) jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); if (fPlaybackChannels > 0) @@ -206,14 +234,14 @@ namespace Jack { bool failure = false; fRunning = true; + + // Finer estimation of the position in the ringbuffer + int delta_frames = (fPullAndPushTime > 0) ? (int)((float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f) : 0; + double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetError() - delta_frames); - /* - Finer estimation of the position in the ringbuffer ?? - int delta_frames = (int)(float(long(GetMicroSeconds() - fPullAndPushTime)) * float(fAdaptedSampleRate)) / 1000000.f; - double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetOffset() - delta_frames); - */ - - double ratio = fPIControler.GetRatio(fCaptureRingBuffer[0]->GetOffset()); + #ifdef JACK_MONITOR + fTable.Write(fCaptureRingBuffer[0]->GetError(), fCaptureRingBuffer[0]->GetError() - delta_frames, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fCaptureRingBuffer[0]->ReadSpace()); + #endif // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { @@ -223,18 +251,17 @@ namespace Jack } for (int i = 0; i < fPlaybackChannels; i++) { - fPlaybackRingBuffer[i]->SetRatio(1 / ratio); + fPlaybackRingBuffer[i]->SetRatio(1/ratio); if (fPlaybackRingBuffer[i]->ReadResample(outputBuffer[i], frames) < frames) failure = true; } - - #ifdef JACK_MONITOR - fTable.Write(0, 0, ratio, 1/ratio, fCaptureRingBuffer[0]->ReadSpace(), fPlaybackRingBuffer[0]->WriteSpace()); - #endif - // Reset all ringbuffers in case of failure if (failure) { jack_error("JackAudioAdapterInterface::PushAndPull ringbuffer failure... reset"); + if (fAdaptative) { + GrowRingBufferSize(); + jack_info("Ringbuffer size = %d frames", fRingbufferCurSize); + } ResetRingBuffers(); return -1; } else { @@ -244,28 +271,24 @@ namespace Jack int JackAudioAdapterInterface::PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames) { - bool failure = false; fPullAndPushTime = GetMicroSeconds(); - + if (!fRunning) + return 0; + + int res = 0; + // Push/pull from ringbuffer for (int i = 0; i < fCaptureChannels; i++) { if (fCaptureRingBuffer[i]->Read(inputBuffer[i], frames) < frames) - failure = true; + res = -1; } for (int i = 0; i < fPlaybackChannels; i++) { if (fPlaybackRingBuffer[i]->Write(outputBuffer[i], frames) < frames) - failure = true; - } - - // Reset all ringbuffers in case of failure - if (failure) { - jack_error("JackCallbackAudioAdapter::PullAndPush ringbuffer failure... reset"); - Reset(); - return -1; - } else { - return 0; + res = -1; } + + return res; } - + } // namespace diff --git a/common/JackAudioAdapterInterface.h b/common/JackAudioAdapterInterface.h index e843a453..acf2b400 100644 --- a/common/JackAudioAdapterInterface.h +++ b/common/JackAudioAdapterInterface.h @@ -23,6 +23,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackResampler.h" #include "JackFilters.h" #include "JackConstants.h" +#include namespace Jack { @@ -89,12 +90,15 @@ namespace Jack JackResampler** fPlaybackRingBuffer; unsigned int fQuality; - unsigned int fRingbufferSize; + unsigned int fRingbufferCurSize; jack_time_t fPullAndPushTime; - + bool fRunning; + bool fAdaptative; void ResetRingBuffers(); + void AdaptRingBufferSize(); + void GrowRingBufferSize(); public: @@ -107,9 +111,11 @@ namespace Jack fAdaptedSampleRate ( sample_rate ), fPIControler(sample_rate / sample_rate, 256), fCaptureRingBuffer(NULL), fPlaybackRingBuffer(NULL), - fQuality(0), fRingbufferSize(DEFAULT_RB_SIZE), + fQuality(0), + fRingbufferCurSize(DEFAULT_ADAPTATIVE_SIZE), fPullAndPushTime(0), - fRunning(false) + fRunning(false), + fAdaptative(true) {} JackAudioAdapterInterface ( jack_nframes_t host_buffer_size, jack_nframes_t host_sample_rate, @@ -123,7 +129,6 @@ namespace Jack fAdaptedSampleRate ( adapted_sample_rate ), fPIControler(host_sample_rate / host_sample_rate, 256), fQuality(0), - fRingbufferSize(DEFAULT_RB_SIZE), fPullAndPushTime(0), fRunning ( false ) {} @@ -131,11 +136,6 @@ namespace Jack virtual ~JackAudioAdapterInterface() {} - bool IsRunning() - { - return fRunning; - } - virtual void Reset(); virtual void Create(); @@ -154,12 +154,16 @@ namespace Jack virtual int SetHostBufferSize ( jack_nframes_t buffer_size ) { fHostBufferSize = buffer_size; + if (fAdaptative) + AdaptRingBufferSize(); return 0; } virtual int SetAdaptedBufferSize ( jack_nframes_t buffer_size ) { fAdaptedBufferSize = buffer_size; + if (fAdaptative) + AdaptRingBufferSize(); return 0; } @@ -217,7 +221,7 @@ namespace Jack int PushAndPull(float** inputBuffer, float** outputBuffer, unsigned int frames); int PullAndPush(float** inputBuffer, float** outputBuffer, unsigned int frames); - + }; } diff --git a/common/JackClient.cpp b/common/JackClient.cpp index 88d363e3..3599547e 100644 --- a/common/JackClient.cpp +++ b/common/JackClient.cpp @@ -674,13 +674,11 @@ int JackClient::TransportReposition(jack_position_t* pos) jack_transport_state_t JackClient::TransportQuery(jack_position_t* pos) { - jack_log("TransportQuery"); return GetEngineControl()->fTransport.Query(pos); } jack_nframes_t JackClient::GetCurrentTransportFrame() { - jack_log("GetCurrentTransportFrame"); return GetEngineControl()->fTransport.GetCurrentFrame(); } diff --git a/common/JackConnectionManager.cpp b/common/JackConnectionManager.cpp index c84f535e..5108ddcd 100644 --- a/common/JackConnectionManager.cpp +++ b/common/JackConnectionManager.cpp @@ -83,11 +83,6 @@ bool JackConnectionManager::IsLoopPathAux(int ref1, int ref2) const // External API //-------------- -int JackConnectionManager::GetActivation(int refnum) const -{ - return fInputCounter[refnum].GetValue(); -} - /*! \brief Connect port_src to port_dst. */ diff --git a/common/JackConnectionManager.h b/common/JackConnectionManager.h index 94af4c0d..b95261d6 100644 --- a/common/JackConnectionManager.h +++ b/common/JackConnectionManager.h @@ -440,7 +440,12 @@ class SERVER_EXPORT JackConnectionManager void DirectConnect(int ref1, int ref2); void DirectDisconnect(int ref1, int ref2); - int GetActivation(int refnum) const; + int GetActivation(int refnum) const + { + return fInputCounter[refnum].GetValue(); + } + + // Graph void ResetGraph(JackClientTiming* timing); diff --git a/common/JackEngineControl.cpp b/common/JackEngineControl.cpp index b75dcf25..41cf71ef 100644 --- a/common/JackEngineControl.cpp +++ b/common/JackEngineControl.cpp @@ -33,44 +33,6 @@ static inline jack_time_t JACK_MAX(jack_time_t a, jack_time_t b) return (a < b) ? b : a; } -void JackEngineControl::CycleIncTime(jack_time_t callback_usecs) -{ - // Timer - fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs); -} - -void JackEngineControl::CycleBegin(JackClientInterface** table, - JackGraphManager* manager, - jack_time_t cur_cycle_begin, - jack_time_t prev_cycle_end) -{ - fTransport.CycleBegin(fSampleRate, cur_cycle_begin); - CalcCPULoad(table, manager, cur_cycle_begin, prev_cycle_end); -#ifdef JACK_MONITOR - fProfiler.Profile(table, manager, fPeriodUsecs, cur_cycle_begin, prev_cycle_end); -#endif -} - -void JackEngineControl::CycleEnd(JackClientInterface** table) -{ - fTransport.CycleEnd(table, fSampleRate, fBufferSize); -} - -void JackEngineControl::InitFrameTime() -{ - fFrameTimer.InitFrameTime(); -} - -void JackEngineControl::ResetFrameTime(jack_time_t cur_cycle_begin) -{ - fFrameTimer.ResetFrameTime(fSampleRate, cur_cycle_begin, fPeriodUsecs); -} - -void JackEngineControl::ReadFrameTime(JackTimer* timer) -{ - fFrameTimer.ReadFrameTime(timer); -} - void JackEngineControl::CalcCPULoad(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, @@ -126,9 +88,4 @@ void JackEngineControl::NotifyXRun(float delayed_usecs) fMaxDelayedUsecs = delayed_usecs; } -void JackEngineControl::ResetXRun() -{ - fMaxDelayedUsecs = 0.f; -} - } // end of namespace diff --git a/common/JackEngineControl.h b/common/JackEngineControl.h index e8d6c8e5..a4e2adcd 100644 --- a/common/JackEngineControl.h +++ b/common/JackEngineControl.h @@ -119,18 +119,48 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem {} // Cycle - void CycleIncTime(jack_time_t callback_usecs); - void CycleBegin(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); - void CycleEnd(JackClientInterface** table); + void CycleIncTime(jack_time_t callback_usecs) + { + // Timer + fFrameTimer.IncFrameTime(fBufferSize, callback_usecs, fPeriodUsecs); + } + + void CycleBegin(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) + { + fTransport.CycleBegin(fSampleRate, cur_cycle_begin); + CalcCPULoad(table, manager, cur_cycle_begin, prev_cycle_end); +#ifdef JACK_MONITOR + fProfiler.Profile(table, manager, fPeriodUsecs, cur_cycle_begin, prev_cycle_end); +#endif + } + + void CycleEnd(JackClientInterface** table) + { + fTransport.CycleEnd(table, fSampleRate, fBufferSize); + } // Timer - void InitFrameTime(); - void ResetFrameTime(jack_time_t callback_usecs); - void ReadFrameTime(JackTimer* timer); + void InitFrameTime() + { + fFrameTimer.InitFrameTime(); + } + + void ResetFrameTime(jack_time_t callback_usecs) + { + fFrameTimer.ResetFrameTime(fSampleRate, callback_usecs, fPeriodUsecs); + } + + void ReadFrameTime(JackTimer* timer) + { + fFrameTimer.ReadFrameTime(timer); + } // XRun void NotifyXRun(float delayed_usecs); - void ResetXRun(); + void ResetXRun() + { + fMaxDelayedUsecs = 0.f; + } // Private void CalcCPULoad(JackClientInterface** table, JackGraphManager* manager, jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end); diff --git a/common/JackEngineProfiling.h b/common/JackEngineProfiling.h index bc82627f..62c4b86e 100644 --- a/common/JackEngineProfiling.h +++ b/common/JackEngineProfiling.h @@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -#define TIME_POINTS 125000 +#define TIME_POINTS 100000 #define FAILURE_TIME_POINTS 10000 #define FAILURE_WINDOW 10 #define MEASURED_CLIENTS 32 diff --git a/common/JackFilters.h b/common/JackFilters.h index dada7204..2af946d2 100644 --- a/common/JackFilters.h +++ b/common/JackFilters.h @@ -263,20 +263,21 @@ namespace Jack static_resample_factor = resample_factor; } + /* double GetRatio(int fill_level) { double offset = fill_level; // Save offset. offset_array[(offset_differential_index++) % smooth_size] = offset; - + // Build the mean of the windowed offset array basically fir lowpassing. double smooth_offset = 0.0; for (int i = 0; i < smooth_size; i++) { smooth_offset += offset_array[(i + offset_differential_index - 1) % smooth_size] * window_array[i]; } smooth_offset /= double(smooth_size); - + // This is the integral of the smoothed_offset offset_integral += smooth_offset; @@ -284,13 +285,13 @@ namespace Jack // It only used in the P component and the I component is used for the fine tuning anyways. if (fabs(smooth_offset) < pclamp) smooth_offset = 0.0; - + // Ok, now this is the PI controller. // u(t) = K * (e(t) + 1/T \int e(t') dt') // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T double current_resample_factor = static_resample_factor - smooth_offset / catch_factor - offset_integral / catch_factor / catch_factor2; - + // Now quantize this value around resample_mean, so that the noise which is in the integral component doesnt hurt. current_resample_factor = floor((current_resample_factor - resample_mean) * controlquant + 0.5) / controlquant + resample_mean; @@ -298,6 +299,21 @@ namespace Jack resample_mean = 0.9999 * resample_mean + 0.0001 * current_resample_factor; return current_resample_factor; } + */ + + + double GetRatio(int error) + { + double smooth_offset = error; + + // This is the integral of the smoothed_offset + offset_integral += smooth_offset; + + // Ok, now this is the PI controller. + // u(t) = K * (e(t) + 1/T \int e(t') dt') + // Kp = 1/catch_factor and T = catch_factor2 Ki = Kp/T + return static_resample_factor - smooth_offset/catch_factor - offset_integral/catch_factor/catch_factor2; + } void OurOfBounds() { diff --git a/common/JackFrameTimer.h b/common/JackFrameTimer.h index fb5ee934..703a90be 100644 --- a/common/JackFrameTimer.h +++ b/common/JackFrameTimer.h @@ -73,7 +73,7 @@ class SERVER_EXPORT JackTimer \brief A class using the JackAtomicState to manage jack time. */ -class JackFrameTimer : public JackAtomicState +class SERVER_EXPORT JackFrameTimer : public JackAtomicState { private: diff --git a/common/JackGlobals.cpp b/common/JackGlobals.cpp index ef005b9e..599523db 100644 --- a/common/JackGlobals.cpp +++ b/common/JackGlobals.cpp @@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software +along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -32,4 +32,8 @@ JackMutex* JackGlobals::fOpenMutex = new JackMutex(); bool JackGlobals::fServerRunning = false; JackClient* JackGlobals::fClientTable[CLIENT_NUM] = {}; +#ifndef WIN32 +jack_thread_creator_t JackGlobals::fJackThreadCreator = pthread_create; +#endif + } // end of namespace diff --git a/common/JackGlobals.h b/common/JackGlobals.h index 5b109ed9..8495c062 100644 --- a/common/JackGlobals.h +++ b/common/JackGlobals.h @@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License -along with this program; if not, write to the Free Software +along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -36,7 +36,10 @@ struct JackGlobals { static JackMutex* fOpenMutex; static bool fServerRunning; static JackClient* fClientTable[]; - +#ifndef WIN32 + static jack_thread_creator_t fJackThreadCreator; +#endif + }; } // end of namespace diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index c34ea5d4..ae5f3351 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -101,11 +101,6 @@ int JackGraphManager::SuspendRefNum(JackClientControl* control, JackSynchro* tab return manager->SuspendRefNum(control, table, fClientTiming, usec); } -JackClientTiming* JackGraphManager::GetClientTiming(int ref) -{ - return &fClientTiming[ref]; -} - // Server void JackGraphManager::DirectConnect(int ref1, int ref2) { diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index ed32041a..67d482e7 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -120,7 +120,11 @@ class SERVER_EXPORT JackGraphManager : public JackShmMem, public JackAtomicState int ResumeRefNum(JackClientControl* control, JackSynchro* table); int SuspendRefNum(JackClientControl* control, JackSynchro* table, long usecs); - JackClientTiming* GetClientTiming(int refnum); + JackClientTiming* GetClientTiming(int refnum) + { + return &fClientTiming[refnum]; + } + void Save(JackConnectionManager* dst); void Restore(JackConnectionManager* src); diff --git a/common/JackLibSampleRateResampler.cpp b/common/JackLibSampleRateResampler.cpp index e2486749..7475282a 100644 --- a/common/JackLibSampleRateResampler.cpp +++ b/common/JackLibSampleRateResampler.cpp @@ -31,8 +31,8 @@ JackLibSampleRateResampler::JackLibSampleRateResampler() jack_error("JackLibSampleRateResampler::JackLibSampleRateResampler err = %s", src_strerror(error)); } -JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size) - :JackResampler(ringbuffer_size) +JackLibSampleRateResampler::JackLibSampleRateResampler(unsigned int quality) + :JackResampler() { switch (quality) { case 0: @@ -67,9 +67,9 @@ JackLibSampleRateResampler::~JackLibSampleRateResampler() src_delete(fResampler); } -void JackLibSampleRateResampler::Reset() +void JackLibSampleRateResampler::Reset(unsigned int new_size) { - JackResampler::Reset(); + JackResampler::Reset(new_size); src_reset(fResampler); } diff --git a/common/JackLibSampleRateResampler.h b/common/JackLibSampleRateResampler.h index 3abc1619..e51a7442 100644 --- a/common/JackLibSampleRateResampler.h +++ b/common/JackLibSampleRateResampler.h @@ -40,13 +40,13 @@ class JackLibSampleRateResampler : public JackResampler public: JackLibSampleRateResampler(); - JackLibSampleRateResampler(unsigned int quality, unsigned int ringbuffer_size); + JackLibSampleRateResampler(unsigned int quality); virtual ~JackLibSampleRateResampler(); unsigned int ReadResample(float* buffer, unsigned int frames); unsigned int WriteResample(float* buffer, unsigned int frames); - void Reset(); + void Reset(unsigned int new_size); }; } diff --git a/common/JackNetAPI.cpp b/common/JackNetAPI.cpp index 6d9b1c1b..dd19f904 100644 --- a/common/JackNetAPI.cpp +++ b/common/JackNetAPI.cpp @@ -738,9 +738,9 @@ struct JackNetAdapter : public JackAudioAdapterInterface { fCaptureRingBuffer = new JackResampler*[fCaptureChannels]; fPlaybackRingBuffer = new JackResampler*[fPlaybackChannels]; for (int i = 0; i < fCaptureChannels; i++ ) - fCaptureRingBuffer[i] = new JackResampler(fRingbufferSize); + fCaptureRingBuffer[i] = new JackResampler(); for (int i = 0; i < fPlaybackChannels; i++ ) - fPlaybackRingBuffer[i] = new JackResampler(fRingbufferSize); + fPlaybackRingBuffer[i] = new JackResampler(); if (fCaptureChannels > 0) jack_log("ReadSpace = %ld", fCaptureRingBuffer[0]->ReadSpace()); diff --git a/common/JackNetAdapter.cpp b/common/JackNetAdapter.cpp index f5512eb5..7164e637 100644 --- a/common/JackNetAdapter.cpp +++ b/common/JackNetAdapter.cpp @@ -96,7 +96,8 @@ namespace Jack fQuality = param->value.ui; break; case 'g': - fRingbufferSize = param->value.ui; + fRingbufferCurSize = param->value.ui; + fAdaptative = false; break; } } @@ -242,27 +243,24 @@ namespace Jack bool JackNetAdapter::Execute() { - try - { + try { // Keep running even in case of error - while ( fThread.GetStatus() == JackThread::kRunning ) - if ( Process() == SOCKET_ERROR ) + while (fThread.GetStatus() == JackThread::kRunning) + if (Process() == SOCKET_ERROR) return false; return false; - } - catch ( JackNetException& e ) - { + } catch (JackNetException& e) { e.PrintMessage(); - jack_log ( "NetAdapter is restarted." ); + jack_info("NetAdapter is restarted."); + Reset(); fThread.DropRealTime(); - fThread.SetStatus ( JackThread::kIniting ); - if ( Init() ) - { - fThread.SetStatus ( JackThread::kRunning ); + fThread.SetStatus(JackThread::kIniting); + if (Init()) { + fThread.SetStatus(JackThread::kRunning); return true; - } - else + } else { return false; + } } } @@ -472,9 +470,9 @@ extern "C" strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + desc->params[i].value.ui = 32768; + strcpy(desc->params[i].short_desc, "Fixed ringbuffer size"); + strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)"); i++; strcpy ( desc->params[i].name, "auto-connect" ); diff --git a/common/JackNetDriver.cpp b/common/JackNetDriver.cpp index d34c7db5..c949001d 100644 --- a/common/JackNetDriver.cpp +++ b/common/JackNetDriver.cpp @@ -45,6 +45,9 @@ namespace Jack fSocket.GetName ( fParams.fSlaveNetName ); fParams.fTransportSync = transport_sync; fParams.fNetworkMode = network_mode; + fSendTransportData.fState = -1; + fReturnTransportData.fState = -1; + fLastTransportState = -1; fLastTimebaseMaster = -1; fMidiCapturePortList = NULL; fMidiPlaybackPortList = NULL; @@ -411,7 +414,7 @@ namespace Jack case JackTransportStarting : fEngineControl->fTransport.RequestNewPos ( &fSendTransportData.fPosition ); fEngineControl->fTransport.SetCommand ( TransportCommandStart ); - jack_info ( "Master starts transport." ); + jack_info ( "Master starts transport frame = %d", fSendTransportData.fPosition.frame); break; case JackTransportRolling : diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 5f723b99..1b8b9c72 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -34,6 +34,9 @@ namespace Jack //settings fClientName = const_cast ( fParams.fName ); fJackClient = NULL; + fSendTransportData.fState = -1; + fReturnTransportData.fState = -1; + fLastTransportState = -1; uint port_index; //jack audio ports @@ -279,7 +282,7 @@ namespace Jack fSendTransportData.fNewState = ( ( fSendTransportData.fState != fLastTransportState ) && ( fSendTransportData.fState != fReturnTransportData.fState ) ); if ( fSendTransportData.fNewState ) - jack_info ( "Sending '%s' to '%s'.", GetTransportState ( fSendTransportData.fState ), fParams.fName ); + jack_info ( "Sending '%s' to '%s' frame = %ld", GetTransportState ( fSendTransportData.fState ), fParams.fName, fSendTransportData.fPosition.frame ); fLastTransportState = fSendTransportData.fState; } @@ -328,10 +331,10 @@ namespace Jack jack_info ( "'%s' stops transport.", fParams.fName ); break; case JackTransportStarting : - if ( jack_transport_reposition ( fJackClient, &fReturnTransportData.fPosition ) < 0 ) + if ( jack_transport_reposition ( fJackClient, &fReturnTransportData.fPosition ) == EINVAL ) jack_error ( "Can't set new position." ); jack_transport_start ( fJackClient ); - jack_info ( "'%s' starts transport.", fParams.fName ); + jack_info ( "'%s' starts transport frame = %d", fParams.fName, fReturnTransportData.fPosition.frame); break; case JackTransportNetStarting : jack_info ( "'%s' is ready to roll..", fParams.fName ); diff --git a/common/JackResampler.cpp b/common/JackResampler.cpp index 86798d9e..fb1793d4 100644 --- a/common/JackResampler.cpp +++ b/common/JackResampler.cpp @@ -30,23 +30,17 @@ JackResampler::JackResampler() jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); } -JackResampler::JackResampler(unsigned int ringbuffer_size) - :fRatio(1),fRingBufferSize(ringbuffer_size) -{ - fRingBuffer = jack_ringbuffer_create(sizeof(float) * fRingBufferSize); - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); -} - JackResampler::~JackResampler() { if (fRingBuffer) jack_ringbuffer_free(fRingBuffer); } -void JackResampler::Reset() +void JackResampler::Reset(unsigned int new_size) { - jack_ringbuffer_reset(fRingBuffer); - jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize) / 2); + fRingBufferSize = new_size; + jack_ringbuffer_reset_size(fRingBuffer, sizeof(float) * fRingBufferSize); + jack_ringbuffer_read_advance(fRingBuffer, (sizeof(float) * fRingBufferSize / 2)); } unsigned int JackResampler::ReadSpace() diff --git a/common/JackResampler.h b/common/JackResampler.h index d8d2e42c..521f5139 100644 --- a/common/JackResampler.h +++ b/common/JackResampler.h @@ -26,7 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. namespace Jack { -#define DEFAULT_RB_SIZE 16384 +#define DEFAULT_RB_SIZE 32768 +#define DEFAULT_ADAPTATIVE_SIZE 2048 inline float Range(float min, float max, float val) { @@ -49,10 +50,9 @@ class JackResampler public: JackResampler(); - JackResampler(unsigned int ringbuffer_size); virtual ~JackResampler(); - virtual void Reset(); + virtual void Reset(unsigned int new_size); virtual unsigned int ReadResample(float* buffer, unsigned int frames); virtual unsigned int WriteResample(float* buffer, unsigned int frames); @@ -63,7 +63,7 @@ class JackResampler virtual unsigned int ReadSpace(); virtual unsigned int WriteSpace(); - unsigned int GetOffset() + unsigned int GetError() { return (jack_ringbuffer_read_space(fRingBuffer) / sizeof(float)) - (fRingBufferSize / 2); } diff --git a/common/JackThreadedDriver.cpp b/common/JackThreadedDriver.cpp index ca8dde69..590d9575 100644 --- a/common/JackThreadedDriver.cpp +++ b/common/JackThreadedDriver.cpp @@ -209,6 +209,7 @@ bool JackThreadedDriver::Init() if (fDriver->IsRealTime()) { jack_log("JackThreadedDriver::Init IsRealTime"); // Will do "something" on OSX only... + GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); if (fThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireRealTime error"); diff --git a/common/JackTransportEngine.cpp b/common/JackTransportEngine.cpp index 861b123e..66f96cf2 100644 --- a/common/JackTransportEngine.cpp +++ b/common/JackTransportEngine.cpp @@ -86,12 +86,6 @@ int JackTransportEngine::SetTimebaseMaster(int refnum, bool conditionnal) } } -void JackTransportEngine::GetTimebaseMaster(int& refnum, bool& conditionnal) -{ - refnum = fTimeBaseMaster; - conditionnal = fConditionnal; -} - // RT bool JackTransportEngine::CheckAllRolling(JackClientInterface** table) { diff --git a/common/JackTransportEngine.h b/common/JackTransportEngine.h index 1d201f66..9602516d 100644 --- a/common/JackTransportEngine.h +++ b/common/JackTransportEngine.h @@ -144,7 +144,11 @@ class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayStateIsRealTime()) { jack_log("JackWaitThreadedDriver::Init IsRealTime"); // Will do "something" on OSX only... + GetEngineControl()->fPeriod = GetEngineControl()->fConstraint = GetEngineControl()->fPeriodUsecs * 1000; fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint); if (fThread.AcquireRealTime(GetEngineControl()->fServerPriority) < 0) { jack_error("AcquireRealTime error"); @@ -61,7 +62,7 @@ bool JackWaitThreadedDriver::Execute() return false; } catch (JackNetException& e) { e.PrintMessage(); - jack_log("Driver is restarted"); + jack_info("Driver is restarted"); fThread.DropRealTime(); // Thread in kIniting status again... fThread.SetStatus(JackThread::kIniting); diff --git a/common/jack/ringbuffer.h b/common/jack/ringbuffer.h index a4bd824f..cb0ca942 100644 --- a/common/jack/ringbuffer.h +++ b/common/jack/ringbuffer.h @@ -192,6 +192,16 @@ int jack_ringbuffer_mlock(jack_ringbuffer_t *rb); */ void jack_ringbuffer_reset(jack_ringbuffer_t *rb); +/** + * Reset the internal "available" size, and read and write pointers, making an empty buffer. + * + * This is not thread safe. + * + * @param rb a pointer to the ringbuffer structure. + * @param sz the new size, that must be less than allocated size. + */ +void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz); + /** * Write data into the ringbuffer. * diff --git a/common/jack/thread.h b/common/jack/thread.h index 9ff84b98..c09c6ca2 100644 --- a/common/jack/thread.h +++ b/common/jack/thread.h @@ -33,15 +33,15 @@ extern "C" * clients. These interfaces hide some system variations in the * handling of realtime scheduling and associated privileges. */ - + /** * @defgroup ClientThreads Creating and managing client threads * @{ */ - + /** * @returns if JACK is running with realtime scheduling, this returns - * the priority that any JACK-created client threads will run at. + * the priority that any JACK-created client threads will run at. * Otherwise returns -1. */ @@ -114,8 +114,35 @@ int jack_client_stop_thread(jack_client_t* client, pthread_t thread); * @param thread POSIX thread ID. * * @returns 0, if successful; otherwise an error number. - */ + */ int jack_client_kill_thread(jack_client_t* client, pthread_t thread); + +#ifndef WIN32 + + typedef int (*jack_thread_creator_t)(pthread_t*, + const pthread_attr_t*, + void* (*function)(void*), + void* arg); +/** + * This function can be used in very very specialized cases + * where it is necessary that client threads created by JACK + * are created by something other than pthread_create(). After + * it is used, any threads that JACK needs for the client will + * will be created by calling the function passed to this + * function. + * + * No normal application/client should consider calling this. + * The specific case for which it was created involves running + * win32/x86 plugins under Wine on Linux, where it is necessary + * that all threads that might call win32 functions are known + * to Wine. + * + * @param creator a function that creates a new thread + * + */ +void jack_set_thread_creator (jack_thread_creator_t creator); + +#endif /* @} */ diff --git a/common/ringbuffer.c b/common/ringbuffer.c index 72559594..a7209a2b 100644 --- a/common/ringbuffer.c +++ b/common/ringbuffer.c @@ -55,6 +55,7 @@ EXPORT void jack_ringbuffer_read_advance(jack_ringbuffer_t *rb, size_t cnt); EXPORT size_t jack_ringbuffer_read_space(const jack_ringbuffer_t *rb); EXPORT int jack_ringbuffer_mlock(jack_ringbuffer_t *rb); EXPORT void jack_ringbuffer_reset(jack_ringbuffer_t *rb); +EXPORT void jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz); EXPORT size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src, size_t cnt); void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt); @@ -123,6 +124,19 @@ jack_ringbuffer_reset (jack_ringbuffer_t * rb) rb->write_ptr = 0; } +/* Reset the read and write pointers to zero. This is not thread + safe. */ + +EXPORT void +jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz) +{ + rb->size = sz; + rb->size_mask = rb->size; + rb->size_mask -= 1; + rb->read_ptr = 0; + rb->write_ptr = 0; +} + /* Return the number of bytes available for reading. This is the number of bytes in front of the read pointer and behind the write pointer. */ diff --git a/common/wscript b/common/wscript index adddc27a..2bd56828 100644 --- a/common/wscript +++ b/common/wscript @@ -190,6 +190,7 @@ def build(bld): 'JackAudioAdapterInterface.cpp', 'JackLibSampleRateResampler.cpp', 'JackResampler.cpp', + 'JackGlobals.cpp', 'ringbuffer.c'] if bld.env['IS_LINUX']: diff --git a/linux/alsa/JackAlsaAdapter.cpp b/linux/alsa/JackAlsaAdapter.cpp index 0e9fb4ce..a046e1f2 100644 --- a/linux/alsa/JackAlsaAdapter.cpp +++ b/linux/alsa/JackAlsaAdapter.cpp @@ -77,7 +77,8 @@ namespace Jack fQuality = param->value.ui; break; case 'g': - fRingbufferSize = param->value.ui; + fRingbufferCurSize = param->value.ui; + fAdaptative = false; break; } } @@ -104,7 +105,6 @@ namespace Jack //turn the thread realtime fThread.AcquireRealTime ( JackServerGlobals::fInstance->GetEngineControl()->fClientPriority ); - return 0; } @@ -251,7 +251,7 @@ extern "C" strcpy ( desc->params[i].name, "duplex" ); desc->params[i].character = 'D'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = 1; + desc->params[i].value.i = true; strcpy ( desc->params[i].short_desc, "Provide both capture and playback ports" ); strcpy ( desc->params[i].long_desc, desc->params[i].short_desc ); @@ -286,9 +286,9 @@ extern "C" strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + desc->params[i].value.ui = 32768; + strcpy(desc->params[i].short_desc, "Fixed ringbuffer size"); + strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)"); return desc; } diff --git a/linux/wscript b/linux/wscript index 5751bf60..46af1bc9 100644 --- a/linux/wscript +++ b/linux/wscript @@ -22,6 +22,7 @@ def create_jack_driver_obj(bld, target, sources, uselib = None): driver.install_path = '${ADDON_DIR}/' if uselib: driver.uselib = uselib + driver.uselib_local = 'serverlib' return driver def build(bld): diff --git a/macosx/coreaudio/JackCoreAudioAdapter.cpp b/macosx/coreaudio/JackCoreAudioAdapter.cpp index dd238b7b..a0222cab 100644 --- a/macosx/coreaudio/JackCoreAudioAdapter.cpp +++ b/macosx/coreaudio/JackCoreAudioAdapter.cpp @@ -378,7 +378,8 @@ JackCoreAudioAdapter::JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nfra break; case 'g': - fRingbufferSize = param->value.ui; + fRingbufferCurSize = param->value.ui; + fAdaptative = false; break; } } @@ -1080,9 +1081,9 @@ extern "C" strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + desc->params[i].value.ui = 32768; + strcpy(desc->params[i].short_desc, "Fixed ringbuffer size"); + strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)"); return desc; } diff --git a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj index d137323b..8ce87173 100755 --- a/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj +++ b/macosx/iphone/iPhoneNet.xcodeproj/project.pbxproj @@ -52,6 +52,10 @@ 4B1A945A0F49C03600D3626B /* JackPosixThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A933B0F49AC4500D3626B /* JackPosixThread.cpp */; }; 4B1A947F0F49C42300D3626B /* JackAudioQueueAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */; }; 4B1A95760F49CEAB00D3626B /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */; }; + 4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4B2791890F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; + 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2791870F72570C000536B7 /* JackGlobals.cpp */; }; 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDC8F90F5420C000465F9C /* freeverb.mm */; }; 4BF1360F0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */; }; @@ -104,6 +108,7 @@ 4B1A947D0F49C42300D3626B /* JackAudioQueueAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioQueueAdapter.cpp; path = ../coreaudio/JackAudioQueueAdapter.cpp; sourceTree = SOURCE_ROOT; }; 4B1A947E0F49C42300D3626B /* JackAudioQueueAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioQueueAdapter.h; path = ../coreaudio/JackAudioQueueAdapter.h; sourceTree = SOURCE_ROOT; }; 4B1A95750F49CEAB00D3626B /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.2.1.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; + 4B2791870F72570C000536B7 /* JackGlobals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackGlobals.cpp; path = ../../common/JackGlobals.cpp; sourceTree = SOURCE_ROOT; }; 4BBDC8F90F5420C000465F9C /* freeverb.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = freeverb.mm; sourceTree = SOURCE_ROOT; }; 4BF1360E0F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JackAudioAdapterInterface.cpp; path = ../../common/JackAudioAdapterInterface.cpp; sourceTree = SOURCE_ROOT; }; 4BF136120F4B0B5E00218A3F /* JackAudioAdapterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JackAudioAdapterInterface.h; path = ../../common/JackAudioAdapterInterface.h; sourceTree = SOURCE_ROOT; }; @@ -204,6 +209,7 @@ 4B1A93110F49AB3400D3626B /* JackNetTool.cpp */, 4B1A930F0F49AB2F00D3626B /* JackNetInterface.cpp */, 4B1A930D0F49AB2A00D3626B /* JackNetAPI.cpp */, + 4B2791870F72570C000536B7 /* JackGlobals.cpp */, 32CA4F630368D1EE00C91783 /* iPhoneNet_Prefix.pch */, 4B0772490F54021B000DC657 /* main_slave.mm */, 4B0772500F54022D000DC657 /* main_master.mm */, @@ -383,6 +389,7 @@ 4BF136550F4B0F9F00218A3F /* ringbuffer.c in Sources */, 4B07724A0F54021B000DC657 /* main_slave.mm in Sources */, 4B0773870F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, + 4B27918A0F72570C000536B7 /* JackGlobals.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -403,6 +410,7 @@ 4B07722E0F54018C000DC657 /* ringbuffer.c in Sources */, 4B0772510F54022D000DC657 /* main_master.mm in Sources */, 4B0773860F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, + 4B27918B0F72570C000536B7 /* JackGlobals.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -420,6 +428,7 @@ 4BF136100F4B0B4C00218A3F /* JackAudioAdapterInterface.cpp in Sources */, 4BF1364E0F4B0F7700218A3F /* JackResampler.cpp in Sources */, 4BF136560F4B0F9F00218A3F /* ringbuffer.c in Sources */, + 4B2791890F72570C000536B7 /* JackGlobals.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -440,6 +449,7 @@ 4BFF456D0F4D5D9700106083 /* ringbuffer.c in Sources */, 4B0773880F541EE2000DC657 /* iPhoneNetAppDelegate.m in Sources */, 4BBDC8FA0F5420C000465F9C /* freeverb.mm in Sources */, + 4B2791880F72570C000536B7 /* JackGlobals.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/posix/JackFifo.cpp b/posix/JackFifo.cpp index 94d76fcf..8f927dea 100644 --- a/posix/JackFifo.cpp +++ b/posix/JackFifo.cpp @@ -30,9 +30,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -void JackFifo::BuildName(const char* name, const char* server_name, char* res) +void JackFifo::BuildName(const char* client_name, const char* server_name, char* res) { - sprintf(res, "%s/jack_fifo.%d_%s_%s", jack_client_dir, JackTools::GetUID(), server_name, name); + char ext_client_name[JACK_CLIENT_NAME_SIZE + 1]; + JackTools::RewriteName(client_name, ext_client_name); + sprintf(res, "%s/jack_fifo.%d_%s_%s", jack_client_dir, JackTools::GetUID(), server_name, ext_client_name); } bool JackFifo::Signal() diff --git a/posix/JackPosixThread.cpp b/posix/JackPosixThread.cpp index a1ac219e..aa1d0fbd 100644 --- a/posix/JackPosixThread.cpp +++ b/posix/JackPosixThread.cpp @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "JackPosixThread.h" #include "JackError.h" #include "JackTime.h" +#include "JackGlobals.h" #include // for memset #include // for _POSIX_PRIORITY_SCHEDULING check @@ -139,7 +140,7 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi return -1; } - if ((res = pthread_create(thread, &attributes, start_routine, arg))) { + if ((res = JackGlobals::fJackThreadCreator(thread, &attributes, start_routine, arg))) { jack_error("Cannot create thread res = %d err = %s", res, strerror(errno)); return -1; } diff --git a/posix/JackSocket.cpp b/posix/JackSocket.cpp index 989d6b55..ec891acb 100644 --- a/posix/JackSocket.cpp +++ b/posix/JackSocket.cpp @@ -29,6 +29,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { +static void BuildName(const char* client_name, char* res, const char* dir, int which) +{ + char ext_client_name[JACK_CLIENT_NAME_SIZE + 1]; + JackTools::RewriteName(client_name, ext_client_name); + sprintf(res, "%s/jack_%s_%d_%d", dir, ext_client_name, JackTools::GetUID(), which); +} + JackClientSocket::JackClientSocket(int socket): fSocket(socket),fTimeOut(0) {} @@ -112,36 +119,7 @@ int JackClientSocket::Connect(const char* dir, const char* name, int which) // A } addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%s_%d_%d", dir, name, JackTools::GetUID(), which); - jack_log("Connect: addr.sun_path %s", addr.sun_path); - - if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - jack_error("Cannot connect to server socket err = %s", strerror(errno)); - close(fSocket); - return -1; - } - -#ifdef __APPLE__ - int on = 1 ; - if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) { - jack_log("setsockopt SO_NOSIGPIPE fd = %ld err = %s", fSocket, strerror(errno)); - } -#endif - - return 0; -} - -int JackClientSocket::Connect(const char* dir, int which) -{ - struct sockaddr_un addr; - - if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - jack_error("Cannot create socket err = %s", strerror(errno)); - return -1; - } - - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%d_%d", dir, JackTools::GetUID(), which); + BuildName(name, addr.sun_path, dir, which); jack_log("Connect: addr.sun_path %s", addr.sun_path); if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { @@ -271,67 +249,9 @@ int JackServerSocket::Bind(const char* dir, const char* name, int which) // A re } addr.sun_family = AF_UNIX; - - // TO CORRECT: always reuse the same name for now... - snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%s_%d_%d", dir, name, JackTools::GetUID(), which); + BuildName(name, fName, dir, which); strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1); - /* - if (access(addr.sun_path, F_OK) == 0) { - goto error; - } - */ - - jack_log("Bind: addr.sun_path %s", addr.sun_path); - unlink(fName); // Security... - - if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - jack_error("Cannot bind server to socket err = %s", strerror(errno)); - goto error; - } - - if (listen(fSocket, 1) < 0) { - jack_error("Cannot enable listen on server socket err = %s", strerror(errno)); - goto error; - } - - return 0; - -error: - unlink(fName); - close(fSocket); - return -1; -} - -int JackServerSocket::Bind(const char* dir, int which) // A revoir : utilisation de "which" -{ - struct sockaddr_un addr; - - if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - jack_error("Cannot create server socket err = %s", strerror(errno)); - return -1; - } - - addr.sun_family = AF_UNIX; - - /* - for (int i = 0; i < 999; i++) { - snprintf(addr.sun_path, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i); - snprintf(fName, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i); - if (access(addr.sun_path, F_OK) != 0) { - break; - } - } - */ - - // TO CORRECT: always reuse the same name for now... - snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%d_%d", dir, JackTools::GetUID(), which); - strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1); - /* - if (access(addr.sun_path, F_OK) == 0) { - goto error; - } - */ - + jack_log("Bind: addr.sun_path %s", addr.sun_path); unlink(fName); // Security... diff --git a/posix/JackSocket.h b/posix/JackSocket.h index 2ccaf06d..0382bd84 100644 --- a/posix/JackSocket.h +++ b/posix/JackSocket.h @@ -50,7 +50,6 @@ class JackClientSocket {} JackClientSocket(int socket); - int Connect(const char* dir, int which); int Connect(const char* dir, const char* name, int which); int Close(); int Read(void* data, int len); @@ -69,13 +68,16 @@ class JackClientSocket \brief Server socket. */ +#define SOCKET_MAX_NAME_SIZE 256 + + class JackServerSocket { private: int fSocket; - char fName[256]; + char fName[SOCKET_MAX_NAME_SIZE]; public: @@ -84,7 +86,6 @@ class JackServerSocket ~JackServerSocket() {} - int Bind(const char* dir, int which); int Bind(const char* dir, const char* name, int which); JackClientSocket* Accept(); int Close(); diff --git a/posix/JackTypes_os.h b/posix/JackTypes_os.h index 84307c15..01e6c9b9 100644 --- a/posix/JackTypes_os.h +++ b/posix/JackTypes_os.h @@ -26,4 +26,6 @@ typedef unsigned long long UInt64; typedef pthread_key_t jack_tls_key; +typedef int (*jack_thread_creator_t)(pthread_t*, const pthread_attr_t*, void* (*function)(void*), void* arg); + #endif diff --git a/solaris/oss/JackOSSAdapter.cpp b/solaris/oss/JackOSSAdapter.cpp index cbb3e549..7bdfec96 100644 --- a/solaris/oss/JackOSSAdapter.cpp +++ b/solaris/oss/JackOSSAdapter.cpp @@ -183,7 +183,8 @@ JackOSSAdapter::JackOSSAdapter(jack_nframes_t buffer_size, jack_nframes_t sample break; case 'g': - fRingbufferSize = param->value.ui; + fRingbufferCurSize = param->value.ui; + fAdaptative = false; break; } @@ -494,9 +495,16 @@ int JackOSSAdapter::Open() } DisplayDeviceInfo(); - + + //start adapter thread + if (fThread.StartSync() < 0) { + jack_error ( "Cannot start audioadapter thread" ); + return -1; + } + + //turn the thread realtime fThread.AcquireRealTime(JackServerGlobals::fInstance->GetEngineControl()->fClientPriority); - return fThread.StartSync(); + return 0; error: CloseAux(); @@ -742,10 +750,10 @@ extern "C" strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); - + desc->params[i].value.ui = 32768; + strcpy(desc->params[i].short_desc, "Fixed ringbuffer size"); + strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)"); + return desc; } diff --git a/windows/portaudio/JackPortAudioAdapter.cpp b/windows/portaudio/JackPortAudioAdapter.cpp index 17972e6b..0f5e161b 100644 --- a/windows/portaudio/JackPortAudioAdapter.cpp +++ b/windows/portaudio/JackPortAudioAdapter.cpp @@ -97,7 +97,8 @@ namespace Jack fQuality = param->value.ui; break; case 'g': - fRingbufferSize = param->value.ui; + fRingbufferCurSize = param->value.ui; + fAdaptative = false; break; } } @@ -282,7 +283,7 @@ extern "C" strcpy(desc->params[i].name, "list-devices"); desc->params[i].character = 'l'; desc->params[i].type = JackDriverParamBool; - desc->params[i].value.i = TRUE; + desc->params[i].value.i = true; strcpy(desc->params[i].short_desc, "Display available PortAudio devices"); strcpy(desc->params[i].long_desc, desc->params[i].short_desc); @@ -298,9 +299,9 @@ extern "C" strcpy(desc->params[i].name, "ring-buffer"); desc->params[i].character = 'g'; desc->params[i].type = JackDriverParamInt; - desc->params[i].value.ui = 0; - strcpy(desc->params[i].short_desc, "Resampling ringbuffer size in frames (default = 16384)"); - strcpy(desc->params[i].long_desc, desc->params[i].short_desc); + desc->params[i].value.ui = 32768; + strcpy(desc->params[i].short_desc, "Fixed ringbuffer size"); + strcpy(desc->params[i].long_desc, "Fixed ringbuffer size (if not set => automatic adaptative)"); return desc; }