From 6a82de8a0be8700d6da15bc668f05066a1a2e917 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 3 May 2011 13:21:19 +0000 Subject: [PATCH 1/3] Use of MMCSS API. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4372 0c269be4-1314-0410-8aa9-9f06e86f4224 --- windows/JackMMCSS.cpp | 80 +++++++++++++++++++++++ windows/JackMMCSS.h | 72 ++++++++++++++++++++ windows/JackWinThread.cpp | 22 +++++-- windows/JackWinThread.h | 6 +- windows/jackd.workspace | 4 +- windows/libjack.cbp | 21 +++--- windows/libjacknet.cbp | 13 ++-- windows/libjackserver.cbp | 1 + windows/portaudio/JackPortAudioDriver.cpp | 2 + windows/portaudio/JackPortAudioDriver.h | 5 +- windows/winmme/JackWinMMEDriver.cpp | 3 +- windows/winmme/JackWinMMEOutputPort.cpp | 13 ++-- 12 files changed, 207 insertions(+), 35 deletions(-) create mode 100644 windows/JackMMCSS.cpp create mode 100644 windows/JackMMCSS.h diff --git a/windows/JackMMCSS.cpp b/windows/JackMMCSS.cpp new file mode 100644 index 00000000..9ddf0bf2 --- /dev/null +++ b/windows/JackMMCSS.cpp @@ -0,0 +1,80 @@ +/* + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +#include "JackMMCSS.h" +#include "JackError.h" +#include +#include + +namespace Jack +{ + +avSetMmThreadCharacteristics JackMMCSS::ffMMCSSFun1 = NULL; +avSetMmThreadPriority JackMMCSS::ffMMCSSFun2 = NULL; +avRevertMmThreadCharacteristics JackMMCSS::ffMMCSSFun3 = NULL; +JACK_HANDLE JackMMCSS::fAvrtDll; + +std::map JackMMCSS::fHandleTable; + +JackMMCSS::JackMMCSS() +{ + fAvrtDll = LoadJackModule("avrt.dll"); + + if (fAvrtDll != NULL) { + ffMMCSSFun1 = (avSetMmThreadCharacteristics)GetJackProc(fAvrtDll, "AvSetMmThreadCharacteristicsA"); + ffMMCSSFun2 = (avSetMmThreadPriority)GetJackProc(fAvrtDll, "AvSetMmThreadPriority"); + ffMMCSSFun3 = (avRevertMmThreadCharacteristics)GetJackProc(fAvrtDll, "AvRevertMmThreadCharacteristics"); + } +} + +JackMMCSS::~JackMMCSS() +{} + +int JackMMCSS::MMCSSAcquireRealTime(jack_native_thread_t thread) +{ + if (fHandleTable.find(thread) != fHandleTable.end()) { + return 0; + } + + if (ffMMCSSFun1) { + DWORD dummy = 0; + HANDLE task = ffMMCSSFun1("Pro Audio", &dummy); + if (task == NULL) { + jack_error("Cannot use MMCSS %d", GetLastError()); + } else if (ffMMCSSFun2(task, AVRT_PRIORITY_CRITICAL)) { + fHandleTable[thread] = task; + return 0; + } + } + + return -1; +} + +int JackMMCSS::MMCSSDropRealTime(jack_native_thread_t thread) +{ + if (fHandleTable.find(thread) != fHandleTable.end()) { + HANDLE task = fHandleTable[thread]; + ffMMCSSFun3(task); + return 0; + } else { + return -1; + } +} + +} diff --git a/windows/JackMMCSS.h b/windows/JackMMCSS.h new file mode 100644 index 00000000..39d89a6a --- /dev/null +++ b/windows/JackMMCSS.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + 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 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + + + +#ifndef __JackMMCSS__ +#define __JackMMCSS__ + +#include "JackSystemDeps.h" +#include "JackCompilerDeps.h" +#include +#include + +namespace Jack +{ + +typedef enum _AVRT_PRIORITY { + AVRT_PRIORITY_LOW = -1, + AVRT_PRIORITY_NORMAL, /* 0 */ + AVRT_PRIORITY_HIGH, /* 1 */ + AVRT_PRIORITY_CRITICAL /* 2 */ +} AVRT_PRIORITY, *PAVRT_PRIORITY; + +typedef HANDLE (WINAPI *avSetMmThreadCharacteristics)(LPCTSTR, LPDWORD); +typedef BOOL (WINAPI *avRevertMmThreadCharacteristics)(HANDLE); +typedef BOOL (WINAPI *avSetMmThreadPriority)(HANDLE, AVRT_PRIORITY); + +/*! +\brief MMCSS services. +*/ + +class SERVER_EXPORT JackMMCSS +{ + + private: + + static JACK_HANDLE fAvrtDll; + static avSetMmThreadCharacteristics ffMMCSSFun1; + static avSetMmThreadPriority ffMMCSSFun2; + static avRevertMmThreadCharacteristics ffMMCSSFun3; + static std::map fHandleTable; + + public: + + JackMMCSS(); + ~JackMMCSS(); + + static int MMCSSAcquireRealTime(jack_native_thread_t thread); + static int MMCSSDropRealTime(jack_native_thread_t thread); + +}; + +} // end of namespace + +#endif + diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index 042279ca..c31c9e57 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -17,11 +17,12 @@ */ - #include "JackWinThread.h" #include "JackError.h" #include "JackTime.h" +#include #include +#include namespace Jack { @@ -55,7 +56,7 @@ DWORD WINAPI JackWinThread::ThreadHandler(void* arg) } JackWinThread::JackWinThread(JackRunnableInterface* runnable) - : JackThreadInterface(runnable, 0, false, 0) + : JackMMCSS(), JackThreadInterface(runnable, 0, false, 0) { fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); fThread = (HANDLE)NULL; @@ -202,11 +203,17 @@ int JackWinThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority) { jack_log("JackWinThread::AcquireRealTimeImp priority = %d", THREAD_PRIORITY_TIME_CRITICAL); - if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) { + if (priority >= 90 && MMCSSAcquireRealTime(thread) == 0) { + jack_info("MMCSS API used to acquire RT for thread: %x", thread); return 0; } else { - jack_error("Cannot set thread priority = %d", GetLastError()); - return -1; + jack_info("MMCSS API not used..."); + if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) { + return 0; + } else { + jack_error("Cannot set thread priority = %d", GetLastError()); + return -1; + } } } @@ -222,7 +229,10 @@ int JackWinThread::DropSelfRealTime() int JackWinThread::DropRealTimeImp(jack_native_thread_t thread) { - if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) { + if (MMCSSDropRealTime(thread) == 0 ) { + jack_info("MMCSS API used to drop RT for thread: %x", thread); + return 0; + } else if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) { return 0; } else { jack_error("Cannot set thread priority = %d", GetLastError()); diff --git a/windows/JackWinThread.h b/windows/JackWinThread.h index 6861b6fc..51dc4d68 100644 --- a/windows/JackWinThread.h +++ b/windows/JackWinThread.h @@ -17,15 +17,15 @@ */ - - #ifndef __JackWinThread__ #define __JackWinThread__ #include "JackThread.h" +#include "JackMMCSS.h" #include "JackCompilerDeps.h" #include "JackSystemDeps.h" #include +#include namespace Jack { @@ -36,7 +36,7 @@ typedef DWORD (WINAPI *ThreadCallback)(void *arg); \brief Windows threads. */ -class SERVER_EXPORT JackWinThread : public detail::JackThreadInterface +class SERVER_EXPORT JackWinThread : public JackMMCSS, public detail::JackThreadInterface { private: diff --git a/windows/jackd.workspace b/windows/jackd.workspace index 57ed4640..ca5a45bd 100644 --- a/windows/jackd.workspace +++ b/windows/jackd.workspace @@ -1,7 +1,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/windows/libjack.cbp b/windows/libjack.cbp index ef61d312..636ab993 100644 --- a/windows/libjack.cbp +++ b/windows/libjack.cbp @@ -133,7 +133,7 @@ - + @@ -190,7 +190,7 @@ - + @@ -209,7 +209,7 @@ - + @@ -223,7 +223,7 @@ - + @@ -237,7 +237,7 @@ - + @@ -257,7 +257,7 @@ - + @@ -271,7 +271,7 @@ - + @@ -322,6 +322,7 @@ + diff --git a/windows/libjacknet.cbp b/windows/libjacknet.cbp index 1ea59e2d..7abb407c 100644 --- a/windows/libjacknet.cbp +++ b/windows/libjacknet.cbp @@ -32,8 +32,8 @@ - + @@ -62,8 +62,8 @@ - + @@ -93,8 +93,8 @@ - + @@ -125,8 +125,8 @@ - + @@ -160,8 +160,8 @@ - + @@ -196,8 +196,8 @@ - + @@ -235,6 +235,7 @@ + diff --git a/windows/libjackserver.cbp b/windows/libjackserver.cbp index 720aee33..d2f9b490 100644 --- a/windows/libjackserver.cbp +++ b/windows/libjackserver.cbp @@ -289,6 +289,7 @@ + diff --git a/windows/portaudio/JackPortAudioDriver.cpp b/windows/portaudio/JackPortAudioDriver.cpp index 489555c4..c671f19d 100644 --- a/windows/portaudio/JackPortAudioDriver.cpp +++ b/windows/portaudio/JackPortAudioDriver.cpp @@ -41,6 +41,8 @@ namespace Jack driver->fInputBuffer = (jack_default_audio_sample_t**)inputBuffer; driver->fOutputBuffer = (jack_default_audio_sample_t**)outputBuffer; + MMCSSAcquireRealTime(GetCurrentThread()); + if (statusFlags) { if (statusFlags & paOutputUnderflow) jack_error("JackPortAudioDriver::Render paOutputUnderflow"); diff --git a/windows/portaudio/JackPortAudioDriver.h b/windows/portaudio/JackPortAudioDriver.h index d4e15a55..894dbbbe 100644 --- a/windows/portaudio/JackPortAudioDriver.h +++ b/windows/portaudio/JackPortAudioDriver.h @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackAudioDriver.h" #include "JackPortAudioDevices.h" +#include "JackMMCSS.h" namespace Jack { @@ -30,7 +31,7 @@ namespace Jack \brief The PortAudio driver. */ -class JackPortAudioDriver : public JackAudioDriver +class JackPortAudioDriver : public JackMMCSS, public JackAudioDriver { private: @@ -54,7 +55,7 @@ class JackPortAudioDriver : public JackAudioDriver public: JackPortAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, PortAudioDevices* pa_devices) - : JackAudioDriver(name, alias, engine, table), fStream(NULL), fInputBuffer(NULL), fOutputBuffer(NULL), + : JackMMCSS(), JackAudioDriver(name, alias, engine, table), fStream(NULL), fInputBuffer(NULL), fOutputBuffer(NULL), fInputDevice(paNoDevice), fOutputDevice(paNoDevice) { fPaDevices = pa_devices; diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index 54d43c70..cbfe8fdb 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -60,7 +60,8 @@ JackWinMMEDriver::Attach() // Inputs for (int i = 0; i < fCaptureChannels; i++) { JackWinMMEInputPort *input_port = input_ports[i]; - name = input_port->GetName(); + name = input_port->GetName(); + printf("register port %d",buffer_size); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, buffer_size, &index) < 0) { diff --git a/windows/winmme/JackWinMMEOutputPort.cpp b/windows/winmme/JackWinMMEOutputPort.cpp index 7e96ef54..21200044 100644 --- a/windows/winmme/JackWinMMEOutputPort.cpp +++ b/windows/winmme/JackWinMMEOutputPort.cpp @@ -22,7 +22,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackMidiUtil.h" #include "JackTime.h" -#include "JackWinMMEOutputPort.h" +#include "JackWinMMEOutputPort.h" +#include "JackGlobals.h" +#include "JackEngineControl.h" using Jack::JackWinMMEOutputPort; @@ -44,7 +46,8 @@ JackWinMMEOutputPort::HandleMessageEvent(HMIDIOUT handle, UINT message, JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, const char *client_name, - const char *driver_name, UINT index, + const char *driver_name, + UINT index, size_t max_bytes, size_t max_messages) { @@ -86,7 +89,7 @@ JackWinMMEOutputPort::JackWinMMEOutputPort(const char *alias_name, snprintf(name, sizeof(name) - 1, "%s:playback_%d", client_name, index + 1); read_queue_ptr.release(); thread_queue_ptr.release(); - thread_ptr.release(); + thread_ptr.release(); return; destroy_thread_queue_semaphore: @@ -132,7 +135,7 @@ JackWinMMEOutputPort::Execute() for (;;) { if (! Wait(thread_queue_semaphore)) { jack_log("JackWinMMEOutputPort::Execute BREAK"); - + break; } jack_midi_event_t *event = thread_queue->DequeueEvent(); @@ -274,7 +277,7 @@ JackWinMMEOutputPort::Init() set_threaded_log_function(); // XX: Can more be done? Ideally, this thread should have the JACK server // thread priority + 1. - if (thread->AcquireSelfRealTime()) { + if (thread->AcquireSelfRealTime(GetEngineControl()->fServerPriority)) { jack_error("JackWinMMEOutputPort::Init - could not acquire realtime " "scheduling. Continuing anyway."); } From 2eb921de738cb014375a47a820246502ab822265 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 3 May 2011 13:26:09 +0000 Subject: [PATCH 2/3] Cleanup. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4373 0c269be4-1314-0410-8aa9-9f06e86f4224 --- windows/JackWinThread.cpp | 1 - windows/JackWinThread.h | 1 - windows/winmme/JackWinMMEDriver.cpp | 1 - 3 files changed, 3 deletions(-) diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index c31c9e57..afd8e443 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -20,7 +20,6 @@ #include "JackWinThread.h" #include "JackError.h" #include "JackTime.h" -#include #include #include diff --git a/windows/JackWinThread.h b/windows/JackWinThread.h index 51dc4d68..106e9963 100644 --- a/windows/JackWinThread.h +++ b/windows/JackWinThread.h @@ -25,7 +25,6 @@ #include "JackCompilerDeps.h" #include "JackSystemDeps.h" #include -#include namespace Jack { diff --git a/windows/winmme/JackWinMMEDriver.cpp b/windows/winmme/JackWinMMEDriver.cpp index cbfe8fdb..3263dc61 100644 --- a/windows/winmme/JackWinMMEDriver.cpp +++ b/windows/winmme/JackWinMMEDriver.cpp @@ -61,7 +61,6 @@ JackWinMMEDriver::Attach() for (int i = 0; i < fCaptureChannels; i++) { JackWinMMEInputPort *input_port = input_ports[i]; name = input_port->GetName(); - printf("register port %d",buffer_size); if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, buffer_size, &index) < 0) { From 2d12663fdabf8ef8e9a010a9c3f7f18746d64122 Mon Sep 17 00:00:00 2001 From: sletz Date: Tue, 3 May 2011 18:36:03 +0000 Subject: [PATCH 3/3] Format netjack1 C files. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4374 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackNetOneDriver.h | 1 + common/netjack.c | 574 +++++++++++++++++------------------- common/netjack.h | 184 ++++++------ common/netjack_packet.c | 466 ++++++++++++----------------- common/netjack_packet.h | 209 +++++++------ example-clients/netsource.c | 394 +++++++++++-------------- 6 files changed, 836 insertions(+), 992 deletions(-) diff --git a/common/JackNetOneDriver.h b/common/JackNetOneDriver.h index b97575ae..a38a612d 100644 --- a/common/JackNetOneDriver.h +++ b/common/JackNetOneDriver.h @@ -90,6 +90,7 @@ class JackNetOneDriver : public JackAudioDriver } }; + } #endif diff --git a/common/netjack.c b/common/netjack.c index 0f059482..075b97cd 100644 --- a/common/netjack.c +++ b/common/netjack.c @@ -86,26 +86,25 @@ int netjack_wait( netjack_driver_state_t *netj ) jacknet_packet_header *pkthdr; if( !netj->next_deadline_valid ) { - netj->next_deadline = jack_get_time() + netj->period_usecs; - netj->next_deadline_valid = 1; + netj->next_deadline = jack_get_time() + netj->period_usecs; + netj->next_deadline_valid = 1; } // Increment expected frame here. if( netj->expected_framecnt_valid ) { - netj->expected_framecnt += 1; + netj->expected_framecnt += 1; } else { - // starting up.... lets look into the packetcache, and fetch the highest packet. - packet_cache_drain_socket( netj->packcache, netj->sockfd ); - if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail ) ) { - netj->expected_framecnt = next_frame_avail; - netj->expected_framecnt_valid = 1; - } else { - // no packets there... start normally. - netj->expected_framecnt = 0; - netj->expected_framecnt_valid = 1; - } - + // starting up.... lets look into the packetcache, and fetch the highest packet. + packet_cache_drain_socket( netj->packcache, netj->sockfd ); + if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail ) ) { + netj->expected_framecnt = next_frame_avail; + netj->expected_framecnt_valid = 1; + } else { + // no packets there... start normally. + netj->expected_framecnt = 0; + netj->expected_framecnt_valid = 1; + } } //jack_log( "expect %d", netj->expected_framecnt ); @@ -113,26 +112,26 @@ int netjack_wait( netjack_driver_state_t *netj ) // then poll (have deadline calculated) // then drain socket, rinse and repeat. while(1) { - if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) { - if( next_frame_avail == netj->expected_framecnt ) { - we_have_the_expected_frame = 1; - if( !netj->always_deadline ) - break; - } - } - if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) { - break; - } - - packet_cache_drain_socket( netj->packcache, netj->sockfd ); + if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) { + if( next_frame_avail == netj->expected_framecnt ) { + we_have_the_expected_frame = 1; + if( !netj->always_deadline ) + break; + } + } + if( ! netjack_poll_deadline( netj->sockfd, netj->next_deadline ) ) { + break; + } + + packet_cache_drain_socket( netj->packcache, netj->sockfd ); } // check if we know who to send our packets too. if (!netj->srcaddress_valid) - if( netj->packcache->master_address_valid ) { - memcpy (&(netj->syncsource_address), &(netj->packcache->master_address), sizeof( struct sockaddr_in ) ); - netj->srcaddress_valid = 1; - } + if( netj->packcache->master_address_valid ) { + memcpy (&(netj->syncsource_address), &(netj->packcache->master_address), sizeof( struct sockaddr_in ) ); + netj->srcaddress_valid = 1; + } // XXX: switching mode unconditionally is stupid. // if we were running free perhaps we like to behave differently @@ -146,169 +145,168 @@ int netjack_wait( netjack_driver_state_t *netj ) if( we_have_the_expected_frame ) { - jack_time_t now = jack_get_time(); - if( now < netj->next_deadline ) - netj->time_to_deadline = netj->next_deadline - now; - else - netj->time_to_deadline = 0; - - packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp); - pkthdr = (jacknet_packet_header *) netj->rx_buf; - packet_header_ntoh(pkthdr); - netj->deadline_goodness = (int)pkthdr->sync_state; - netj->packet_data_valid = 1; - - int want_deadline; - if( netj->jitter_val != 0 ) - want_deadline = netj->jitter_val; - else if( netj->latency < 4 ) - want_deadline = -netj->period_usecs/2; - else - want_deadline = (netj->period_usecs/4+10*(int)netj->period_usecs*netj->latency/100); - - if( netj->deadline_goodness != MASTER_FREEWHEELS ) { - if( netj->deadline_goodness < want_deadline ) { - netj->next_deadline -= netj->period_usecs/100; - //jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); - } - if( netj->deadline_goodness > want_deadline ) { - netj->next_deadline += netj->period_usecs/100; - //jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); - } - } + jack_time_t now = jack_get_time(); + if( now < netj->next_deadline ) + netj->time_to_deadline = netj->next_deadline - now; + else + netj->time_to_deadline = 0; + + packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize , &packet_recv_time_stamp); + pkthdr = (jacknet_packet_header *) netj->rx_buf; + packet_header_ntoh(pkthdr); + netj->deadline_goodness = (int)pkthdr->sync_state; + netj->packet_data_valid = 1; + + int want_deadline; + if( netj->jitter_val != 0 ) + want_deadline = netj->jitter_val; + else if( netj->latency < 4 ) + want_deadline = -netj->period_usecs / 2; + else + want_deadline = (netj->period_usecs / 4 + 10 * (int)netj->period_usecs * netj->latency / 100); + + if( netj->deadline_goodness != MASTER_FREEWHEELS ) { + if( netj->deadline_goodness < want_deadline ) { + netj->next_deadline -= netj->period_usecs / 100; + //jack_log( "goodness: %d, Adjust deadline: --- %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); + } + if( netj->deadline_goodness > want_deadline ) { + netj->next_deadline += netj->period_usecs / 100; + //jack_log( "goodness: %d, Adjust deadline: +++ %d\n", netj->deadline_goodness, (int) netj->period_usecs*netj->latency/100 ); + } + } // if( netj->next_deadline < (netj->period_usecs*70/100) ) { // jack_error( "master is forcing deadline_offset to below 70%% of period_usecs... increase latency setting on master" ); // netj->deadline_offset = (netj->period_usecs*90/100); // } - netj->next_deadline += netj->period_usecs; + netj->next_deadline += netj->period_usecs; } else { - netj->time_to_deadline = 0; - netj->next_deadline += netj->period_usecs; - // bah... the packet is not there. - // either - // - it got lost. - // - its late - // - sync source is not sending anymore. - - // lets check if we have the next packets, we will just run a cycle without data. - // in that case. - - if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) - { - jack_nframes_t offset = next_frame_avail - netj->expected_framecnt; - - //XXX: hmm... i need to remember why resync_threshold wasnt right. - //if( offset < netj->resync_threshold ) - if( offset < 10 ) { - // ok. dont do nothing. we will run without data. - // this seems to be one or 2 lost packets. - // - // this can also be reordered packet jitter. - // (maybe this is not happening in real live) - // but it happens in netem. - - netj->packet_data_valid = 0; - - // I also found this happening, when the packet queue, is too full. - // but wtf ? use a smaller latency. this link can handle that ;S - if( packet_cache_get_fill( netj->packcache, netj->expected_framecnt ) > 80.0 ) - netj->next_deadline -= netj->period_usecs/2; - - - } else { - // the diff is too high. but we have a packet in the future. - // lets resync. - netj->expected_framecnt = next_frame_avail; - packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL ); - pkthdr = (jacknet_packet_header *) netj->rx_buf; - packet_header_ntoh(pkthdr); - //netj->deadline_goodness = 0; - netj->deadline_goodness = (int)pkthdr->sync_state - (int)netj->period_usecs * offset; - netj->next_deadline_valid = 0; - netj->packet_data_valid = 1; - } - - } else { - // no packets in buffer. - netj->packet_data_valid = 0; - - //printf( "frame %d No Packet in queue. num_lost_packets = %d \n", netj->expected_framecnt, netj->num_lost_packets ); - if( netj->num_lost_packets < 5 ) { - // ok. No Packet in queue. The packet was either lost, - // or we are running too fast. - // - // Adjusting the deadline unconditionally resulted in - // too many xruns on master. - // But we need to adjust for the case we are running too fast. - // So lets check if the last packet is there now. - // - // It would not be in the queue anymore, if it had been - // retrieved. This might break for redundancy, but - // i will make the packet cache drop redundant packets, - // that have already been retreived. - // - if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) { - if( next_frame_avail == (netj->expected_framecnt - 1) ) { - // Ok. the last packet is there now. - // and it had not been retrieved. - // - // TODO: We are still dropping 2 packets. - // perhaps we can adjust the deadline - // when (num_packets lost == 0) - - // This might still be too much. - netj->next_deadline += netj->period_usecs; - } - } - } else if( (netj->num_lost_packets <= 100) ) { - // lets try adjusting the deadline harder, for some packets, we might have just ran 2 fast. - netj->next_deadline += netj->period_usecs*netj->latency/8; - } else { - - // But now we can check for any new frame available. - // - if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) { - netj->expected_framecnt = next_frame_avail; - packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) &(netj->rx_buf), netj->rx_bufsize, NULL ); - pkthdr = (jacknet_packet_header *) netj->rx_buf; - packet_header_ntoh(pkthdr); - netj->deadline_goodness = pkthdr->sync_state; - netj->next_deadline_valid = 0; - netj->packet_data_valid = 1; - netj->running_free = 0; - jack_info( "resync after freerun... %d", netj->expected_framecnt ); - } else { - if( netj->num_lost_packets == 101 ) { - jack_info( "master seems gone... entering freerun mode", netj->expected_framecnt ); - } - - netj->running_free = 1; - - // when we really dont see packets. - // reset source address. and open possibility for new master. - // maybe dsl reconnect. Also restart of netsource without fix - // reply address changes port. - if (netj->num_lost_packets > 200 ) { - netj->srcaddress_valid = 0; - packet_cache_reset_master_address( netj->packcache ); - } - } - } - } + netj->time_to_deadline = 0; + netj->next_deadline += netj->period_usecs; + // bah... the packet is not there. + // either + // - it got lost. + // - its late + // - sync source is not sending anymore. + + // lets check if we have the next packets, we will just run a cycle without data. + // in that case. + + if( packet_cache_get_next_available_framecnt( netj->packcache, netj->expected_framecnt, &next_frame_avail) ) { + jack_nframes_t offset = next_frame_avail - netj->expected_framecnt; + + //XXX: hmm... i need to remember why resync_threshold wasnt right. + //if( offset < netj->resync_threshold ) + if( offset < 10 ) { + // ok. dont do nothing. we will run without data. + // this seems to be one or 2 lost packets. + // + // this can also be reordered packet jitter. + // (maybe this is not happening in real live) + // but it happens in netem. + + netj->packet_data_valid = 0; + + // I also found this happening, when the packet queue, is too full. + // but wtf ? use a smaller latency. this link can handle that ;S + if( packet_cache_get_fill( netj->packcache, netj->expected_framecnt ) > 80.0 ) + netj->next_deadline -= netj->period_usecs / 2; + + + } else { + // the diff is too high. but we have a packet in the future. + // lets resync. + netj->expected_framecnt = next_frame_avail; + packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize, NULL ); + pkthdr = (jacknet_packet_header *) netj->rx_buf; + packet_header_ntoh(pkthdr); + //netj->deadline_goodness = 0; + netj->deadline_goodness = (int)pkthdr->sync_state - (int)netj->period_usecs * offset; + netj->next_deadline_valid = 0; + netj->packet_data_valid = 1; + } + + } else { + // no packets in buffer. + netj->packet_data_valid = 0; + + //printf( "frame %d No Packet in queue. num_lost_packets = %d \n", netj->expected_framecnt, netj->num_lost_packets ); + if( netj->num_lost_packets < 5 ) { + // ok. No Packet in queue. The packet was either lost, + // or we are running too fast. + // + // Adjusting the deadline unconditionally resulted in + // too many xruns on master. + // But we need to adjust for the case we are running too fast. + // So lets check if the last packet is there now. + // + // It would not be in the queue anymore, if it had been + // retrieved. This might break for redundancy, but + // i will make the packet cache drop redundant packets, + // that have already been retreived. + // + if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) { + if( next_frame_avail == (netj->expected_framecnt - 1) ) { + // Ok. the last packet is there now. + // and it had not been retrieved. + // + // TODO: We are still dropping 2 packets. + // perhaps we can adjust the deadline + // when (num_packets lost == 0) + + // This might still be too much. + netj->next_deadline += netj->period_usecs; + } + } + } else if( (netj->num_lost_packets <= 100) ) { + // lets try adjusting the deadline harder, for some packets, we might have just ran 2 fast. + netj->next_deadline += netj->period_usecs * netj->latency / 8; + } else { + + // But now we can check for any new frame available. + // + if( packet_cache_get_highest_available_framecnt( netj->packcache, &next_frame_avail) ) { + netj->expected_framecnt = next_frame_avail; + packet_cache_retreive_packet_pointer( netj->packcache, netj->expected_framecnt, (char **) & (netj->rx_buf), netj->rx_bufsize, NULL ); + pkthdr = (jacknet_packet_header *) netj->rx_buf; + packet_header_ntoh(pkthdr); + netj->deadline_goodness = pkthdr->sync_state; + netj->next_deadline_valid = 0; + netj->packet_data_valid = 1; + netj->running_free = 0; + jack_info( "resync after freerun... %d", netj->expected_framecnt ); + } else { + if( netj->num_lost_packets == 101 ) { + jack_info( "master seems gone... entering freerun mode", netj->expected_framecnt ); + } + + netj->running_free = 1; + + // when we really dont see packets. + // reset source address. and open possibility for new master. + // maybe dsl reconnect. Also restart of netsource without fix + // reply address changes port. + if (netj->num_lost_packets > 200 ) { + netj->srcaddress_valid = 0; + packet_cache_reset_master_address( netj->packcache ); + } + } + } + } } int retval = 0; if( !netj->packet_data_valid ) { - netj->num_lost_packets += 1; - if( netj->num_lost_packets == 1 ) - retval = netj->period_usecs; + netj->num_lost_packets += 1; + if( netj->num_lost_packets == 1 ) + retval = netj->period_usecs; } else { - if( (netj->num_lost_packets>1) && !netj->running_free ) - retval = (netj->num_lost_packets-1) * netj->period_usecs; + if( (netj->num_lost_packets > 1) && !netj->running_free ) + retval = (netj->num_lost_packets - 1) * netj->period_usecs; - netj->num_lost_packets = 0; + netj->num_lost_packets = 0; } return retval; @@ -338,19 +336,17 @@ void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ) memset(packet_bufX, 0, payload_size); packet_header_hton(tx_pkthdr); - if (netj->srcaddress_valid) - { - int r; - if (netj->reply_port) - netj->syncsource_address.sin_port = htons(netj->reply_port); - - for( r=0; rredundancy; r++ ) - netjack_sendto(netj->outsockfd, (char *)packet_buf, tx_size, - 0, (struct sockaddr*)&(netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu); + if (netj->srcaddress_valid) { + int r; + if (netj->reply_port) + netj->syncsource_address.sin_port = htons(netj->reply_port); + + for( r = 0; r < netj->redundancy; r++ ) + netjack_sendto(netj->outsockfd, (char *)packet_buf, tx_size, + 0, (struct sockaddr*) & (netj->syncsource_address), sizeof(struct sockaddr_in), netj->mtu); } } - void netjack_attach( netjack_driver_state_t *netj ) { //puts ("net_driver_attach"); @@ -359,19 +355,17 @@ void netjack_attach( netjack_driver_state_t *netj ) unsigned int chn; int port_flags; - - if( netj->bitdepth == CELT_MODE ) - { + if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT #if HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 - celt_int32 lookahead; - netj->celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); + celt_int32 lookahead; + netj->celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); #else - celt_int32_t lookahead; - netj->celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); + celt_int32_t lookahead; + netj->celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); #endif - celt_mode_info( netj->celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); - netj->codec_latency = 2*lookahead; + celt_mode_info( netj->celt_mode, CELT_GET_LOOKAHEAD, &lookahead ); + netj->codec_latency = 2 * lookahead; #endif } @@ -394,21 +388,21 @@ void netjack_attach( netjack_driver_state_t *netj ) netj->capture_ports = jack_slist_append (netj->capture_ports, port); - if( netj->bitdepth == CELT_MODE ) { + if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT #if HAVE_CELT_API_0_11 - netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create_custom( netj->celt_mode, 1, NULL ) ); + netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create_custom( netj->celt_mode, 1, NULL ) ); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 - netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode, 1, NULL ) ); + netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode, 1, NULL ) ); #else - netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) ); + netj->capture_srcs = jack_slist_append(netj->capture_srcs, celt_decoder_create( netj->celt_mode ) ); #endif #endif - } else { + } else { #if HAVE_SAMPLERATE - netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL)); + netj->capture_srcs = jack_slist_append(netj->capture_srcs, src_new(SRC_LINEAR, 1, NULL)); #endif - } + } } for (chn = netj->capture_channels_audio; chn < netj->capture_channels; chn++) { @@ -442,24 +436,24 @@ void netjack_attach( netjack_driver_state_t *netj ) netj->playback_ports = jack_slist_append (netj->playback_ports, port); - if( netj->bitdepth == CELT_MODE ) { + if( netj->bitdepth == CELT_MODE ) { #if HAVE_CELT #if HAVE_CELT_API_0_11 - CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); - netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); + netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 - CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); - netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, netj->period_size, NULL ); + netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); #else - CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); - netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) ); + CELTMode *celt_mode = celt_mode_create( netj->sample_rate, 1, netj->period_size, NULL ); + netj->playback_srcs = jack_slist_append(netj->playback_srcs, celt_encoder_create( celt_mode ) ); #endif #endif - } else { + } else { #if HAVE_SAMPLERATE - netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL)); + netj->playback_srcs = jack_slist_append(netj->playback_srcs, src_new(SRC_LINEAR, 1, NULL)); #endif - } + } } for (chn = netj->playback_channels_audio; chn < netj->playback_channels; chn++) { snprintf (buf, sizeof(buf) - 1, "playback_%u", chn + 1); @@ -492,15 +486,12 @@ void netjack_detach( netjack_driver_state_t *netj ) jack_slist_free (netj->capture_ports); netj->capture_ports = NULL; - for (node = netj->capture_srcs; node; node = jack_slist_next (node)) - { + for (node = netj->capture_srcs; node; node = jack_slist_next (node)) { #if HAVE_CELT - if( netj->bitdepth == CELT_MODE ) - { + if( netj->bitdepth == CELT_MODE ) { CELTDecoder * decoder = node->data; celt_decoder_destroy(decoder); - } - else + } else #endif { #if HAVE_SAMPLERATE @@ -519,15 +510,12 @@ void netjack_detach( netjack_driver_state_t *netj ) jack_slist_free (netj->playback_ports); netj->playback_ports = NULL; - for (node = netj->playback_srcs; node; node = jack_slist_next (node)) - { + for (node = netj->playback_srcs; node; node = jack_slist_next (node)) { #if HAVE_CELT - if( netj->bitdepth == CELT_MODE ) - { + if( netj->bitdepth == CELT_MODE ) { CELTEncoder * encoder = node->data; celt_encoder_destroy(encoder); - } - else + } else #endif { #if HAVE_SAMPLERATE @@ -540,32 +528,32 @@ void netjack_detach( netjack_driver_state_t *netj ) netj->playback_srcs = NULL; #if HAVE_CELT - if( netj->bitdepth == CELT_MODE ) - celt_mode_destroy(netj->celt_mode); + if( netj->bitdepth == CELT_MODE ) + celt_mode_destroy(netj->celt_mode); #endif } netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, - jack_client_t * client, - const char *name, - unsigned int capture_ports, - unsigned int playback_ports, - unsigned int capture_ports_midi, - unsigned int playback_ports_midi, - jack_nframes_t sample_rate, - jack_nframes_t period_size, - unsigned int listen_port, - unsigned int transport_sync, - unsigned int resample_factor, - unsigned int resample_factor_up, - unsigned int bitdepth, - unsigned int use_autoconfig, - unsigned int latency, - unsigned int redundancy, - int dont_htonl_floats, - int always_deadline, - int jitter_val ) + jack_client_t * client, + const char *name, + unsigned int capture_ports, + unsigned int playback_ports, + unsigned int capture_ports_midi, + unsigned int playback_ports_midi, + jack_nframes_t sample_rate, + jack_nframes_t period_size, + unsigned int listen_port, + unsigned int transport_sync, + unsigned int resample_factor, + unsigned int resample_factor_up, + unsigned int bitdepth, + unsigned int use_autoconfig, + unsigned int latency, + unsigned int redundancy, + int dont_htonl_floats, + int always_deadline, + int jitter_val ) { // Fill in netj values. @@ -600,8 +588,7 @@ netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, netj->client = client; - if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE)) - { + if ((bitdepth != 0) && (bitdepth != 8) && (bitdepth != 16) && (bitdepth != CELT_MODE)) { jack_info ("Invalid bitdepth: %d (8, 16 or 0 for float) !!!", bitdepth); return NULL; } @@ -647,8 +634,7 @@ netjack_startup( netjack_driver_state_t *netj ) address.sin_family = AF_INET; address.sin_port = htons(netj->listen_port); address.sin_addr.s_addr = htonl(INADDR_ANY); - if (bind (netj->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0) - { + if (bind (netj->sockfd, (struct sockaddr *) &address, sizeof (address)) < 0) { jack_info("bind error"); return -1; } @@ -664,14 +650,13 @@ netjack_startup( netjack_driver_state_t *netj ) return -1; } netj->srcaddress_valid = 0; - if (netj->use_autoconfig) - { + if (netj->use_autoconfig) { jacknet_packet_header *first_packet = alloca (sizeof (jacknet_packet_header)); - #ifdef WIN32 +#ifdef WIN32 int address_size = sizeof( struct sockaddr_in ); - #else +#else socklen_t address_size = sizeof (struct sockaddr_in); - #endif +#endif //jack_info ("Waiting for an incoming packet !!!"); //jack_info ("*** IMPORTANT *** Dont connect a client to jackd until the driver is attached to a clock source !!!"); @@ -681,51 +666,44 @@ netjack_startup( netjack_driver_state_t *netj ) return -1; } first_pack_len = recvfrom (netj->sockfd, (char *)first_packet, sizeof (jacknet_packet_header), 0, (struct sockaddr*) & netj->syncsource_address, &address_size); - #ifdef WIN32 - if( first_pack_len == -1 ) { - first_pack_len = sizeof(jacknet_packet_header); - break; - } - #else - if (first_pack_len == sizeof (jacknet_packet_header)) - break; - #endif +#ifdef WIN32 + if( first_pack_len == -1 ) { + first_pack_len = sizeof(jacknet_packet_header); + break; + } +#else + if (first_pack_len == sizeof (jacknet_packet_header)) + break; +#endif } netj->srcaddress_valid = 1; - if (first_pack_len == sizeof (jacknet_packet_header)) - { + if (first_pack_len == sizeof (jacknet_packet_header)) { packet_header_ntoh (first_packet); jack_info ("AutoConfig Override !!!"); - if (netj->sample_rate != first_packet->sample_rate) - { + if (netj->sample_rate != first_packet->sample_rate) { jack_info ("AutoConfig Override: Master JACK sample rate = %d", first_packet->sample_rate); netj->sample_rate = first_packet->sample_rate; - } + } - if (netj->period_size != first_packet->period_size) - { + if (netj->period_size != first_packet->period_size) { jack_info ("AutoConfig Override: Master JACK period size is %d", first_packet->period_size); netj->period_size = first_packet->period_size; - } - if (netj->capture_channels_audio != first_packet->capture_channels_audio) - { + } + if (netj->capture_channels_audio != first_packet->capture_channels_audio) { jack_info ("AutoConfig Override: capture_channels_audio = %d", first_packet->capture_channels_audio); netj->capture_channels_audio = first_packet->capture_channels_audio; } - if (netj->capture_channels_midi != first_packet->capture_channels_midi) - { + if (netj->capture_channels_midi != first_packet->capture_channels_midi) { jack_info ("AutoConfig Override: capture_channels_midi = %d", first_packet->capture_channels_midi); netj->capture_channels_midi = first_packet->capture_channels_midi; } - if (netj->playback_channels_audio != first_packet->playback_channels_audio) - { + if (netj->playback_channels_audio != first_packet->playback_channels_audio) { jack_info ("AutoConfig Override: playback_channels_audio = %d", first_packet->playback_channels_audio); netj->playback_channels_audio = first_packet->playback_channels_audio; - } - if (netj->playback_channels_midi != first_packet->playback_channels_midi) - { + } + if (netj->playback_channels_midi != first_packet->playback_channels_midi) { jack_info ("AutoConfig Override: playback_channels_midi = %d", first_packet->playback_channels_midi); netj->playback_channels_midi = first_packet->playback_channels_midi; } @@ -739,24 +717,24 @@ netjack_startup( netjack_driver_state_t *netj ) netj->playback_channels = netj->playback_channels_audio + netj->playback_channels_midi; if( (netj->capture_channels * netj->period_size * netj->latency * 4) > 100000000 ) { - jack_error( "autoconfig requests more than 100MB packet cache... bailing out" ); - exit(1); + jack_error( "autoconfig requests more than 100MB packet cache... bailing out" ); + exit(1); } if( netj->playback_channels > 1000 ) { - jack_error( "autoconfig requests more than 1000 playback channels... bailing out" ); - exit(1); + jack_error( "autoconfig requests more than 1000 playback channels... bailing out" ); + exit(1); } - if( netj->mtu < (2*sizeof( jacknet_packet_header )) ) { - jack_error( "bullshit mtu requested by autoconfig" ); - exit(1); + if( netj->mtu < (2 * sizeof( jacknet_packet_header )) ) { + jack_error( "bullshit mtu requested by autoconfig" ); + exit(1); } if( netj->sample_rate == 0 ) { - jack_error( "sample_rate 0 requested by autoconfig" ); - exit(1); + jack_error( "sample_rate 0 requested by autoconfig" ); + exit(1); } // After possible Autoconfig: do all calculations... @@ -765,15 +743,15 @@ netjack_startup( netjack_driver_state_t *netj ) * 1000000.0f); if( netj->latency == 0 ) - netj->deadline_offset = 50*netj->period_usecs; + netj->deadline_offset = 50 * netj->period_usecs; else - netj->deadline_offset = netj->period_usecs + 10*netj->latency*netj->period_usecs/100; + netj->deadline_offset = netj->period_usecs + 10 * netj->latency * netj->period_usecs / 100; if( netj->bitdepth == CELT_MODE ) { // celt mode. // TODO: this is a hack. But i dont want to change the packet header. - netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); - netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8)&(~1); + netj->resample_factor = (netj->resample_factor * netj->period_size * 1024 / netj->sample_rate / 8) & (~1); + netj->resample_factor_up = (netj->resample_factor_up * netj->period_size * 1024 / netj->sample_rate / 8) & (~1); netj->net_period_down = netj->resample_factor; netj->net_period_up = netj->resample_factor_up; @@ -795,7 +773,7 @@ netjack_startup( netjack_driver_state_t *netj ) if( netj->latency == 0 ) netj->resync_threshold = 0; else - netj->resync_threshold = MIN( 15, netj->latency-1 ); + netj->resync_threshold = MIN( 15, netj->latency - 1 ); netj->running_free = 0; diff --git a/common/netjack.h b/common/netjack.h index 385da562..2ff3c299 100644 --- a/common/netjack.h +++ b/common/netjack.h @@ -37,113 +37,113 @@ extern "C" { #endif -struct _packet_cache; + struct _packet_cache; -typedef struct _netjack_driver_state netjack_driver_state_t; + typedef struct _netjack_driver_state netjack_driver_state_t; -struct _netjack_driver_state { - jack_nframes_t net_period_up; - jack_nframes_t net_period_down; + struct _netjack_driver_state { + jack_nframes_t net_period_up; + jack_nframes_t net_period_down; - jack_nframes_t sample_rate; - jack_nframes_t bitdepth; - jack_nframes_t period_size; - jack_time_t period_usecs; - int dont_htonl_floats; - int always_deadline; + jack_nframes_t sample_rate; + jack_nframes_t bitdepth; + jack_nframes_t period_size; + jack_time_t period_usecs; + int dont_htonl_floats; + int always_deadline; - jack_nframes_t codec_latency; + jack_nframes_t codec_latency; - unsigned int listen_port; + unsigned int listen_port; - unsigned int capture_channels; - unsigned int playback_channels; - unsigned int capture_channels_audio; - unsigned int playback_channels_audio; - unsigned int capture_channels_midi; - unsigned int playback_channels_midi; + unsigned int capture_channels; + unsigned int playback_channels; + unsigned int capture_channels_audio; + unsigned int playback_channels_audio; + unsigned int capture_channels_midi; + unsigned int playback_channels_midi; - JSList *capture_ports; - JSList *playback_ports; - JSList *playback_srcs; - JSList *capture_srcs; + JSList *capture_ports; + JSList *playback_ports; + JSList *playback_srcs; + JSList *capture_srcs; - jack_client_t *client; + jack_client_t *client; #ifdef WIN32 - SOCKET sockfd; - SOCKET outsockfd; + SOCKET sockfd; + SOCKET outsockfd; #else - int sockfd; - int outsockfd; + int sockfd; + int outsockfd; #endif - struct sockaddr_in syncsource_address; - - int reply_port; - int srcaddress_valid; - - int sync_state; - unsigned int handle_transport_sync; - - unsigned int *rx_buf; - unsigned int rx_bufsize; - //unsigned int tx_bufsize; - unsigned int mtu; - unsigned int latency; - unsigned int redundancy; - - jack_nframes_t expected_framecnt; - int expected_framecnt_valid; - unsigned int num_lost_packets; - jack_time_t next_deadline; - jack_time_t deadline_offset; - int next_deadline_valid; - int packet_data_valid; - int resync_threshold; - int running_free; - int deadline_goodness; - jack_time_t time_to_deadline; - unsigned int use_autoconfig; - unsigned int resample_factor; - unsigned int resample_factor_up; - int jitter_val; - struct _packet_cache * packcache; + struct sockaddr_in syncsource_address; + + int reply_port; + int srcaddress_valid; + + int sync_state; + unsigned int handle_transport_sync; + + unsigned int *rx_buf; + unsigned int rx_bufsize; + //unsigned int tx_bufsize; + unsigned int mtu; + unsigned int latency; + unsigned int redundancy; + + jack_nframes_t expected_framecnt; + int expected_framecnt_valid; + unsigned int num_lost_packets; + jack_time_t next_deadline; + jack_time_t deadline_offset; + int next_deadline_valid; + int packet_data_valid; + int resync_threshold; + int running_free; + int deadline_goodness; + jack_time_t time_to_deadline; + unsigned int use_autoconfig; + unsigned int resample_factor; + unsigned int resample_factor_up; + int jitter_val; + struct _packet_cache * packcache; #if HAVE_CELT - CELTMode *celt_mode; + CELTMode *celt_mode; #endif -}; - -int netjack_wait( netjack_driver_state_t *netj ); -void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ); -void netjack_read( netjack_driver_state_t *netj, jack_nframes_t nframes ) ; -void netjack_write( netjack_driver_state_t *netj, jack_nframes_t nframes, int syncstate ); -void netjack_attach( netjack_driver_state_t *netj ); -void netjack_detach( netjack_driver_state_t *netj ); - -netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, - jack_client_t * client, - const char *name, - unsigned int capture_ports, - unsigned int playback_ports, - unsigned int capture_ports_midi, - unsigned int playback_ports_midi, - jack_nframes_t sample_rate, - jack_nframes_t period_size, - unsigned int listen_port, - unsigned int transport_sync, - unsigned int resample_factor, - unsigned int resample_factor_up, - unsigned int bitdepth, - unsigned int use_autoconfig, - unsigned int latency, - unsigned int redundancy, - int dont_htonl_floats, - int always_deadline, - int jitter_val ); - -void netjack_release( netjack_driver_state_t *netj ); -int netjack_startup( netjack_driver_state_t *netj ); + }; + + int netjack_wait( netjack_driver_state_t *netj ); + void netjack_send_silence( netjack_driver_state_t *netj, int syncstate ); + void netjack_read( netjack_driver_state_t *netj, jack_nframes_t nframes ) ; + void netjack_write( netjack_driver_state_t *netj, jack_nframes_t nframes, int syncstate ); + void netjack_attach( netjack_driver_state_t *netj ); + void netjack_detach( netjack_driver_state_t *netj ); + + netjack_driver_state_t *netjack_init (netjack_driver_state_t *netj, + jack_client_t * client, + const char *name, + unsigned int capture_ports, + unsigned int playback_ports, + unsigned int capture_ports_midi, + unsigned int playback_ports_midi, + jack_nframes_t sample_rate, + jack_nframes_t period_size, + unsigned int listen_port, + unsigned int transport_sync, + unsigned int resample_factor, + unsigned int resample_factor_up, + unsigned int bitdepth, + unsigned int use_autoconfig, + unsigned int latency, + unsigned int redundancy, + int dont_htonl_floats, + int always_deadline, + int jitter_val ); + + void netjack_release( netjack_driver_state_t *netj ); + int netjack_startup( netjack_driver_state_t *netj ); #ifdef __cplusplus } diff --git a/common/netjack_packet.c b/common/netjack_packet.c index 9919a85b..9434985c 100644 --- a/common/netjack_packet.c +++ b/common/netjack_packet.c @@ -152,13 +152,12 @@ packet_cache int i, fragment_number; if( pkt_size == sizeof(jacknet_packet_header) ) - fragment_number = 1; + fragment_number = 1; else - fragment_number = (pkt_size - sizeof (jacknet_packet_header) - 1) / fragment_payload_size + 1; + fragment_number = (pkt_size - sizeof (jacknet_packet_header) - 1) / fragment_payload_size + 1; packet_cache *pcache = malloc (sizeof (packet_cache)); - if (pcache == NULL) - { + if (pcache == NULL) { jack_error ("could not allocate packet cache (1)"); return NULL; } @@ -169,14 +168,12 @@ packet_cache pcache->last_framecnt_retreived = 0; pcache->last_framecnt_retreived_valid = 0; - if (pcache->packets == NULL) - { + if (pcache->packets == NULL) { jack_error ("could not allocate packet cache (2)"); return NULL; } - for (i = 0; i < num_packets; i++) - { + for (i = 0; i < num_packets; i++) { pcache->packets[i].valid = 0; pcache->packets[i].num_fragments = fragment_number; pcache->packets[i].packet_size = pkt_size; @@ -184,8 +181,7 @@ packet_cache pcache->packets[i].framecnt = 0; pcache->packets[i].fragment_array = malloc (sizeof (char) * fragment_number); pcache->packets[i].packet_buf = malloc (pkt_size); - if ((pcache->packets[i].fragment_array == NULL) || (pcache->packets[i].packet_buf == NULL)) - { + if ((pcache->packets[i].fragment_array == NULL) || (pcache->packets[i].packet_buf == NULL)) { jack_error ("could not allocate packet cache (3)"); return NULL; } @@ -200,10 +196,9 @@ packet_cache_free (packet_cache *pcache) { int i; if( pcache == NULL ) - return; + return; - for (i = 0; i < pcache->size; i++) - { + for (i = 0; i < pcache->size; i++) { free (pcache->packets[i].fragment_array); free (pcache->packets[i].packet_buf); } @@ -218,8 +213,7 @@ cache_packet int i; cache_packet *retval; - for (i = 0; i < pcache->size; i++) - { + for (i = 0; i < pcache->size; i++) { if (pcache->packets[i].valid && (pcache->packets[i].framecnt == framecnt)) return &(pcache->packets[i]); } @@ -228,8 +222,7 @@ cache_packet // find a free packet. retval = packet_cache_get_free_packet (pcache); - if (retval != NULL) - { + if (retval != NULL) { cache_packet_set_framecnt (retval, framecnt); return retval; } @@ -257,10 +250,8 @@ cache_packet cache_packet *retval = &(pcache->packets[0]); int i; - for (i = 0; i < pcache->size; i++) - { - if (pcache->packets[i].valid && (pcache->packets[i].framecnt < minimal_frame)) - { + for (i = 0; i < pcache->size; i++) { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt < minimal_frame)) { minimal_frame = pcache->packets[i].framecnt; retval = &(pcache->packets[i]); } @@ -274,8 +265,7 @@ cache_packet { int i; - for (i = 0; i < pcache->size; i++) - { + for (i = 0; i < pcache->size; i++) { if (pcache->packets[i].valid == 0) return &(pcache->packets[i]); } @@ -320,28 +310,23 @@ cache_packet_add_fragment (cache_packet *pack, char *packet_buf, int rcv_len) jack_nframes_t fragment_nr = ntohl (pkthdr->fragment_nr); jack_nframes_t framecnt = ntohl (pkthdr->framecnt); - if (framecnt != pack->framecnt) - { + if (framecnt != pack->framecnt) { jack_error ("errror. framecnts dont match"); return; } - if (fragment_nr == 0) - { + if (fragment_nr == 0) { memcpy (pack->packet_buf, packet_buf, rcv_len); pack->fragment_array[0] = 1; return; } - if ((fragment_nr < pack->num_fragments) && (fragment_nr > 0)) - { - if ((fragment_nr * fragment_payload_size + rcv_len - sizeof (jacknet_packet_header)) <= (pack->packet_size - sizeof (jacknet_packet_header))) - { + if ((fragment_nr < pack->num_fragments) && (fragment_nr > 0)) { + if ((fragment_nr * fragment_payload_size + rcv_len - sizeof (jacknet_packet_header)) <= (pack->packet_size - sizeof (jacknet_packet_header))) { memcpy (packet_bufX + fragment_nr * fragment_payload_size, dataX, rcv_len - sizeof (jacknet_packet_header)); pack->fragment_array[fragment_nr] = 1; - } - else + } else jack_error ("too long packet received..."); } } @@ -373,11 +358,11 @@ netjack_poll_deadline (int sockfd, jack_time_t deadline) jack_time_t now = jack_get_time(); if( now >= deadline ) - return 0; + return 0; - if( (deadline-now) >= 1000000 ) { - jack_error( "deadline more than 1 second in the future, trimming it." ); - deadline = now+500000; + if( (deadline - now) >= 1000000 ) { + jack_error( "deadline more than 1 second in the future, trimming it." ); + deadline = now + 500000; } #if HAVE_PPOLL timeout_spec.tv_nsec = (deadline - now) * 1000; @@ -394,25 +379,23 @@ netjack_poll_deadline (int sockfd, jack_time_t deadline) poll_err = poll (&fds, 1, timeout); #endif - if (poll_err == -1) - { - switch (errno) - { + if (poll_err == -1) { + switch (errno) { case EBADF: - jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno); - break; + jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno); + break; case EFAULT: - jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno); - break; + jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno); + break; case EINTR: - jack_error ("Error %d: A signal occurred before any requested event", errno); - break; + jack_error ("Error %d: A signal occurred before any requested event", errno); + break; case EINVAL: - jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno); - break; + jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno); + break; case ENOMEM: - jack_error ("Error %d: There was no space to allocate file descriptor tables", errno); - break; + jack_error ("Error %d: There was no space to allocate file descriptor tables", errno); + break; } } return poll_err; @@ -427,17 +410,17 @@ netjack_poll (int sockfd, int timeout) struct sigaction action; sigemptyset(&sigmask); - sigaddset(&sigmask, SIGHUP); - sigaddset(&sigmask, SIGINT); - sigaddset(&sigmask, SIGQUIT); - sigaddset(&sigmask, SIGPIPE); - sigaddset(&sigmask, SIGTERM); - sigaddset(&sigmask, SIGUSR1); - sigaddset(&sigmask, SIGUSR2); - - action.sa_handler = SIG_DFL; - action.sa_mask = sigmask; - action.sa_flags = SA_RESTART; + sigaddset(&sigmask, SIGHUP); + sigaddset(&sigmask, SIGINT); + sigaddset(&sigmask, SIGQUIT); + sigaddset(&sigmask, SIGPIPE); + sigaddset(&sigmask, SIGTERM); + sigaddset(&sigmask, SIGUSR1); + sigaddset(&sigmask, SIGUSR2); + + action.sa_handler = SIG_DFL; + action.sa_mask = sigmask; + action.sa_flags = SA_RESTART; for (i = 1; i < NSIG; i++) if (sigismember (&sigmask, i)) @@ -447,31 +430,28 @@ netjack_poll (int sockfd, int timeout) fds.events = POLLIN; sigprocmask(SIG_UNBLOCK, &sigmask, &rsigmask); - while (poll_err == 0) - { + while (poll_err == 0) { poll_err = poll (&fds, 1, timeout); } sigprocmask(SIG_SETMASK, &rsigmask, NULL); - if (poll_err == -1) - { - switch (errno) - { + if (poll_err == -1) { + switch (errno) { case EBADF: - jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno); - break; + jack_error ("Error %d: An invalid file descriptor was given in one of the sets", errno); + break; case EFAULT: - jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno); - break; + jack_error ("Error %d: The array given as argument was not contained in the calling program's address space", errno); + break; case EINTR: - jack_error ("Error %d: A signal occurred before any requested event", errno); - break; + jack_error ("Error %d: A signal occurred before any requested event", errno); + break; case EINVAL: - jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno); - break; + jack_error ("Error %d: The nfds value exceeds the RLIMIT_NOFILE value", errno); + break; case ENOMEM: - jack_error ("Error %d: There was no space to allocate file descriptor tables", errno); - break; + jack_error ("Error %d: There was no space to allocate file descriptor tables", errno); + break; } return 0; } @@ -496,10 +476,10 @@ netjack_poll_deadline (int sockfd, jack_time_t deadline) while( 1 ) { jack_time_t now = jack_get_time(); if( now >= deadline ) - return 0; + return 0; int timeout_usecs = (deadline - now); - //jack_error( "timeout = %d", timeout_usecs ); + //jack_error( "timeout = %d", timeout_usecs ); timeout.tv_sec = 0; timeout.tv_usec = (timeout_usecs < 500) ? 500 : timeout_usecs; timeout.tv_usec = (timeout_usecs > 1000000) ? 500000 : timeout_usecs; @@ -531,36 +511,35 @@ packet_cache_drain_socket( packet_cache *pcache, int sockfd ) #else socklen_t senderlen = sizeof( struct sockaddr_in ); #endif - while (1) - { + while (1) { #ifdef WIN32 rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, 0, - (struct sockaddr*) &sender_address, &senderlen); + (struct sockaddr*) &sender_address, &senderlen); #else rcv_len = recvfrom (sockfd, rx_packet, pcache->mtu, MSG_DONTWAIT, - (struct sockaddr*) &sender_address, &senderlen); + (struct sockaddr*) &sender_address, &senderlen); #endif if (rcv_len < 0) return; - if (pcache->master_address_valid) { - // Verify its from our master. - if (memcmp (&sender_address, &(pcache->master_address), senderlen) != 0) - continue; - } else { - // Setup this one as master - //printf( "setup master...\n" ); - memcpy ( &(pcache->master_address), &sender_address, senderlen ); - pcache->master_address_valid = 1; - } + if (pcache->master_address_valid) { + // Verify its from our master. + if (memcmp (&sender_address, &(pcache->master_address), senderlen) != 0) + continue; + } else { + // Setup this one as master + //printf( "setup master...\n" ); + memcpy ( &(pcache->master_address), &sender_address, senderlen ); + pcache->master_address_valid = 1; + } framecnt = ntohl (pkthdr->framecnt); - if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived )) - continue; + if( pcache->last_framecnt_retreived_valid && (framecnt <= pcache->last_framecnt_retreived )) + continue; cpack = packet_cache_get_packet (pcache, framecnt); cache_packet_add_fragment (cpack, rx_packet, rcv_len); - cpack->recv_timestamp = jack_get_time(); + cpack->recv_timestamp = jack_get_time(); } } @@ -577,10 +556,8 @@ packet_cache_clear_old_packets (packet_cache *pcache, jack_nframes_t framecnt ) { int i; - for (i = 0; i < pcache->size; i++) - { - if (pcache->packets[i].valid && (pcache->packets[i].framecnt < framecnt)) - { + for (i = 0; i < pcache->size; i++) { + if (pcache->packets[i].valid && (pcache->packets[i].framecnt < framecnt)) { cache_packet_reset (&(pcache->packets[i])); } } @@ -654,8 +631,7 @@ packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ) int num_packets_before_us = 0; int i; - for (i = 0; i < pcache->size; i++) - { + for (i = 0; i < pcache->size; i++) { cache_packet *cpack = &(pcache->packets[i]); if (cpack->valid && cache_packet_is_complete( cpack )) if( cpack->framecnt >= expected_framecnt ) @@ -670,11 +646,10 @@ int packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ) { int i; - jack_nframes_t best_offset = JACK_MAX_FRAMES/2-1; + jack_nframes_t best_offset = JACK_MAX_FRAMES / 2 - 1; int retval = 0; - for (i = 0; i < pcache->size; i++) - { + for (i = 0; i < pcache->size; i++) { cache_packet *cpack = &(pcache->packets[i]); //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); @@ -688,13 +663,13 @@ packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t e if( (cpack->framecnt - expected_framecnt) > best_offset ) { continue; - } + } - best_offset = cpack->framecnt - expected_framecnt; - retval = 1; + best_offset = cpack->framecnt - expected_framecnt; + retval = 1; - if (best_offset == 0) - break; + if (best_offset == 0) + break; } if (retval && framecnt) *framecnt = expected_framecnt + best_offset; @@ -709,22 +684,21 @@ packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_ jack_nframes_t best_value = 0; int retval = 0; - for (i = 0; i < pcache->size; i++) - { + for (i = 0; i < pcache->size; i++) { cache_packet *cpack = &(pcache->packets[i]); //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); if (!cpack->valid || !cache_packet_is_complete( cpack )) { //printf( "invalid\n" ); continue; - } + } - if (cpack->framecnt < best_value) { - continue; - } + if (cpack->framecnt < best_value) { + continue; + } - best_value = cpack->framecnt; - retval = 1; + best_value = cpack->framecnt; + retval = 1; } if (retval && framecnt) @@ -741,25 +715,24 @@ packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecn jack_nframes_t best_offset = 0; int retval = 0; - for (i = 0; i < pcache->size; i++) - { + for (i = 0; i < pcache->size; i++) { cache_packet *cpack = &(pcache->packets[i]); //printf( "p%d: valid=%d, frame %d\n", i, cpack->valid, cpack->framecnt ); if (!cpack->valid || !cache_packet_is_complete( cpack )) { //printf( "invalid\n" ); continue; - } + } - if ((cpack->framecnt - expected_framecnt) < best_offset) { - continue; - } + if ((cpack->framecnt - expected_framecnt) < best_offset) { + continue; + } - best_offset = cpack->framecnt - expected_framecnt; - retval = 1; + best_offset = cpack->framecnt - expected_framecnt; + retval = 1; - if( best_offset == 0 ) - break; + if( best_offset == 0 ) + break; } if (retval && framecnt) *framecnt = JACK_MAX_FRAMES - best_offset; @@ -785,13 +758,11 @@ netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct so pkthdr = (jacknet_packet_header *) packet_buf; pkthdr->fragment_nr = htonl (0); err = sendto(sockfd, packet_buf, pkt_size, flags, addr, addr_size); - if( err<0 ) { + if( err < 0 ) { //printf( "error in send\n" ); perror( "send" ); } - } - else - { + } else { int err; // Copy the packet header to the tx pack first. memcpy(tx_packet, packet_buf, sizeof (jacknet_packet_header)); @@ -799,8 +770,7 @@ netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct so // Now loop and send all char *packet_bufX = packet_buf + sizeof (jacknet_packet_header); - while (packet_bufX < (packet_buf + pkt_size - fragment_payload_size)) - { + while (packet_bufX < (packet_buf + pkt_size - fragment_payload_size)) { pkthdr->fragment_nr = htonl (frag_cnt++); memcpy (dataX, packet_bufX, fragment_payload_size); sendto (sockfd, tx_packet, mtu, flags, addr, addr_size); @@ -814,7 +784,7 @@ netjack_sendto (int sockfd, char *packet_buf, int pkt_size, int flags, struct so // sendto(last_pack_size); err = sendto(sockfd, tx_packet, last_payload_size + sizeof(jacknet_packet_header), flags, addr, addr_size); - if( err<0 ) { + if( err < 0 ) { //printf( "error in send\n" ); perror( "send" ); } @@ -826,24 +796,21 @@ decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, ja { int i; jack_midi_clear_buffer (buf); - for (i = 0; i < buffer_size_uint32 - 3;) - { + for (i = 0; i < buffer_size_uint32 - 3;) { uint32_t payload_size; payload_size = buffer_uint32[i]; payload_size = ntohl (payload_size); - if (payload_size) - { + if (payload_size) { jack_midi_event_t event; - event.time = ntohl (buffer_uint32[i+1]); - event.size = ntohl (buffer_uint32[i+2]); - event.buffer = (jack_midi_data_t*) (&(buffer_uint32[i+3])); + event.time = ntohl (buffer_uint32[i + 1]); + event.size = ntohl (buffer_uint32[i + 2]); + event.buffer = (jack_midi_data_t*) (&(buffer_uint32[i + 3])); jack_midi_event_write (buf, event.time, event.buffer, event.size); // skip to the next event - unsigned int nb_data_quads = (((event.size-1) & ~0x3) >> 2)+1; - i += 3+nb_data_quads; - } - else + unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1; + i += 3 + nb_data_quads; + } else break; // no events can follow an empty event, we're done } } @@ -855,38 +822,34 @@ encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, ja unsigned int written = 0; // midi port, encode midi events unsigned int nevents = jack_midi_get_event_count (buf); - for (i = 0; i < nevents; ++i) - { + for (i = 0; i < nevents; ++i) { jack_midi_event_t event; jack_midi_event_get (&event, buf, i); unsigned int nb_data_quads = (((event.size - 1) & ~0x3) >> 2) + 1; unsigned int payload_size = 3 + nb_data_quads; // only write if we have sufficient space for the event // otherwise drop it - if (written + payload_size < buffer_size_uint32 - 1) - { + if (written + payload_size < buffer_size_uint32 - 1) { // write header - buffer_uint32[written]=htonl (payload_size); + buffer_uint32[written] = htonl (payload_size); written++; - buffer_uint32[written]=htonl (event.time); + buffer_uint32[written] = htonl (event.time); written++; - buffer_uint32[written]=htonl (event.size); + buffer_uint32[written] = htonl (event.size); written++; // write data jack_midi_data_t* tmpbuff = (jack_midi_data_t*)(&(buffer_uint32[written])); memcpy (tmpbuff, event.buffer, event.size); written += nb_data_quads; - } - else - { + } else { // buffer overflow jack_error ("midi buffer overflow"); break; } } // now put a netjack_midi 'no-payload' event, signaling EOF - buffer_uint32[written]=0; + buffer_uint32[written] = 0; } // render functions for float @@ -904,8 +867,7 @@ render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_pe if (!packet_payload) return; - while (node != NULL) - { + while (node != NULL) { int i; int_float_t val; #if HAVE_SAMPLERATE @@ -917,15 +879,12 @@ render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_pe const char *porttype = jack_port_type (port); - if (jack_port_is_audio (porttype)) - { + if (jack_port_is_audio (porttype)) { #if HAVE_SAMPLERATE // audio port, resample if necessary - if (net_period_down != nframes) - { + if (net_period_down != nframes) { SRC_STATE *src_state = src_node->data; - for (i = 0; i < net_period_down; i++) - { + for (i = 0; i < net_period_down; i++) { packet_bufX[i] = ntohl (packet_bufX[i]); } @@ -941,27 +900,20 @@ render_payload_to_jack_ports_float ( void *packet_payload, jack_nframes_t net_pe src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); src_node = jack_slist_next (src_node); - } - else + } else #endif { - if( dont_htonl_floats ) - { - memcpy( buf, packet_bufX, net_period_down*sizeof(jack_default_audio_sample_t)); - } - else - { - for (i = 0; i < net_period_down; i++) - { - val.i = packet_bufX[i]; - val.i = ntohl (val.i); - buf[i] = val.f; + if( dont_htonl_floats ) { + memcpy( buf, packet_bufX, net_period_down * sizeof(jack_default_audio_sample_t)); + } else { + for (i = 0; i < net_period_down; i++) { + val.i = packet_bufX[i]; + val.i = ntohl (val.i); + buf[i] = val.f; } } } - } - else if (jack_port_is_midi (porttype)) - { + } else if (jack_port_is_midi (porttype)) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down; @@ -985,8 +937,7 @@ render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_src uint32_t *packet_bufX = (uint32_t *) packet_payload; - while (node != NULL) - { + while (node != NULL) { #if HAVE_SAMPLERATE SRC_DATA src; #endif @@ -997,8 +948,7 @@ render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_src const char *porttype = jack_port_type (port); - if (jack_port_is_audio (porttype)) - { + if (jack_port_is_audio (porttype)) { // audio port, resample if necessary #if HAVE_SAMPLERATE @@ -1016,32 +966,24 @@ render_jack_ports_to_payload_float (JSList *playback_ports, JSList *playback_src src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); - for (i = 0; i < net_period_up; i++) - { + for (i = 0; i < net_period_up; i++) { packet_bufX[i] = htonl (packet_bufX[i]); } src_node = jack_slist_next (src_node); - } - else + } else #endif { - if( dont_htonl_floats ) - { - memcpy( packet_bufX, buf, net_period_up*sizeof(jack_default_audio_sample_t) ); - } - else - { - for (i = 0; i < net_period_up; i++) - { - val.f = buf[i]; - val.i = htonl (val.i); - packet_bufX[i] = val.i; + if( dont_htonl_floats ) { + memcpy( packet_bufX, buf, net_period_up * sizeof(jack_default_audio_sample_t) ); + } else { + for (i = 0; i < net_period_up; i++) { + val.f = buf[i]; + val.i = htonl (val.i); + packet_bufX[i] = val.i; } } } - } - else if (jack_port_is_midi (porttype)) - { + } else if (jack_port_is_midi (porttype)) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up; @@ -1067,10 +1009,9 @@ render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_per uint16_t *packet_bufX = (uint16_t *)packet_payload; if( !packet_payload ) - return; + return; - while (node != NULL) - { + while (node != NULL) { int i; //uint32_t val; #if HAVE_SAMPLERATE @@ -1085,16 +1026,13 @@ render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_per #endif const char *porttype = jack_port_type (port); - if (jack_port_is_audio (porttype)) - { + if (jack_port_is_audio (porttype)) { // audio port, resample if necessary #if HAVE_SAMPLERATE - if (net_period_down != nframes) - { + if (net_period_down != nframes) { SRC_STATE *src_state = src_node->data; - for (i = 0; i < net_period_down; i++) - { + for (i = 0; i < net_period_down; i++) { floatbuf[i] = ((float) ntohs(packet_bufX[i])) / 32767.0 - 1.0; } @@ -1110,14 +1048,11 @@ render_payload_to_jack_ports_16bit (void *packet_payload, jack_nframes_t net_per src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); src_node = jack_slist_next (src_node); - } - else + } else #endif for (i = 0; i < net_period_down; i++) buf[i] = ((float) ntohs (packet_bufX[i])) / 32768.0 - 1.0; - } - else if (jack_port_is_midi (porttype)) - { + } else if (jack_port_is_midi (porttype)) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; @@ -1141,8 +1076,7 @@ render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_src uint16_t *packet_bufX = (uint16_t *)packet_payload; - while (node != NULL) - { + while (node != NULL) { #if HAVE_SAMPLERATE SRC_DATA src; #endif @@ -1151,13 +1085,11 @@ render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_src jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); - if (jack_port_is_audio (porttype)) - { + if (jack_port_is_audio (porttype)) { // audio port, resample if necessary #if HAVE_SAMPLERATE - if (net_period_up != nframes) - { + if (net_period_up != nframes) { SRC_STATE *src_state = src_node->data; float *floatbuf = alloca (sizeof(float) * net_period_up); @@ -1174,19 +1106,15 @@ render_jack_ports_to_payload_16bit (JSList *playback_ports, JSList *playback_src src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); - for (i = 0; i < net_period_up; i++) - { + for (i = 0; i < net_period_up; i++) { packet_bufX[i] = htons (((uint16_t)((floatbuf[i] + 1.0) * 32767.0))); } src_node = jack_slist_next (src_node); - } - else + } else #endif for (i = 0; i < net_period_up; i++) packet_bufX[i] = htons(((uint16_t)((buf[i] + 1.0) * 32767.0))); - } - else if (jack_port_is_midi (porttype)) - { + } else if (jack_port_is_midi (porttype)) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up / 2; @@ -1215,8 +1143,7 @@ render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_peri if (!packet_payload) return; - while (node != NULL) - { + while (node != NULL) { int i; //uint32_t val; #if HAVE_SAMPLERATE @@ -1231,12 +1158,10 @@ render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_peri #endif const char *porttype = jack_port_type (port); - if (jack_port_is_audio(porttype)) - { + if (jack_port_is_audio(porttype)) { #if HAVE_SAMPLERATE // audio port, resample if necessary - if (net_period_down != nframes) - { + if (net_period_down != nframes) { SRC_STATE *src_state = src_node->data; for (i = 0; i < net_period_down; i++) floatbuf[i] = ((float) packet_bufX[i]) / 127.0; @@ -1253,14 +1178,11 @@ render_payload_to_jack_ports_8bit (void *packet_payload, jack_nframes_t net_peri src_set_ratio (src_state, src.src_ratio); src_process (src_state, &src); src_node = jack_slist_next (src_node); - } - else + } else #endif for (i = 0; i < net_period_down; i++) buf[i] = ((float) packet_bufX[i]) / 127.0; - } - else if (jack_port_is_midi (porttype)) - { + } else if (jack_port_is_midi (porttype)) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; @@ -1284,8 +1206,7 @@ render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs int8_t *packet_bufX = (int8_t *)packet_payload; - while (node != NULL) - { + while (node != NULL) { #if HAVE_SAMPLERATE SRC_DATA src; #endif @@ -1295,12 +1216,10 @@ render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); - if (jack_port_is_audio (porttype)) - { + if (jack_port_is_audio (porttype)) { #if HAVE_SAMPLERATE // audio port, resample if necessary - if (net_period_up != nframes) - { + if (net_period_up != nframes) { SRC_STATE *src_state = src_node->data; @@ -1321,14 +1240,11 @@ render_jack_ports_to_payload_8bit (JSList *playback_ports, JSList *playback_srcs for (i = 0; i < net_period_up; i++) packet_bufX[i] = floatbuf[i] * 127.0; src_node = jack_slist_next (src_node); - } - else + } else #endif for (i = 0; i < net_period_up; i++) packet_bufX[i] = buf[i] * 127.0; - } - else if (jack_port_is_midi (porttype)) - { + } else if (jack_port_is_midi (porttype)) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up / 4; @@ -1352,33 +1268,29 @@ render_payload_to_jack_ports_celt (void *packet_payload, jack_nframes_t net_peri unsigned char *packet_bufX = (unsigned char *)packet_payload; - while (node != NULL) - { + while (node != NULL) { jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); - if (jack_port_is_audio (porttype)) - { + if (jack_port_is_audio (porttype)) { // audio port, decode celt data. CELTDecoder *decoder = src_node->data; - #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 +#if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 if( !packet_payload ) celt_decode_float( decoder, NULL, net_period_down, buf, nframes ); else celt_decode_float( decoder, packet_bufX, net_period_down, buf, nframes ); - #else +#else if( !packet_payload ) celt_decode_float( decoder, NULL, net_period_down, buf ); else celt_decode_float( decoder, packet_bufX, net_period_down, buf ); - #endif +#endif src_node = jack_slist_next (src_node); - } - else if (jack_port_is_midi (porttype)) - { + } else if (jack_port_is_midi (porttype)) { // midi port, decode midi events // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_down / 2; @@ -1401,31 +1313,27 @@ render_jack_ports_to_payload_celt (JSList *playback_ports, JSList *playback_srcs unsigned char *packet_bufX = (unsigned char *)packet_payload; - while (node != NULL) - { + while (node != NULL) { jack_port_t *port = (jack_port_t *) node->data; jack_default_audio_sample_t* buf = jack_port_get_buffer (port, nframes); const char *porttype = jack_port_type (port); - if (jack_port_is_audio (porttype)) - { + if (jack_port_is_audio (porttype)) { // audio port, encode celt data. - int encoded_bytes; - float *floatbuf = alloca (sizeof(float) * nframes ); - memcpy( floatbuf, buf, nframes*sizeof(float) ); - CELTEncoder *encoder = src_node->data; + int encoded_bytes; + float *floatbuf = alloca (sizeof(float) * nframes ); + memcpy( floatbuf, buf, nframes * sizeof(float) ); + CELTEncoder *encoder = src_node->data; #if HAVE_CELT_API_0_8 || HAVE_CELT_API_0_11 - encoded_bytes = celt_encode_float( encoder, floatbuf, nframes, packet_bufX, net_period_up ); + encoded_bytes = celt_encode_float( encoder, floatbuf, nframes, packet_bufX, net_period_up ); #else - encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); + encoded_bytes = celt_encode_float( encoder, floatbuf, NULL, packet_bufX, net_period_up ); #endif - if( encoded_bytes != net_period_up ) - printf( "something in celt changed. netjack needs to be changed to handle this.\n" ); - src_node = jack_slist_next( src_node ); - } - else if (jack_port_is_midi (porttype)) - { + if( encoded_bytes != net_period_up ) + printf( "something in celt changed. netjack needs to be changed to handle this.\n" ); + src_node = jack_slist_next( src_node ); + } else if (jack_port_is_midi (porttype)) { // encode midi events from port to packet // convert the data buffer to a standard format (uint32_t based) unsigned int buffer_size_uint32 = net_period_up / 2; diff --git a/common/netjack_packet.h b/common/netjack_packet.h index a31f5d44..1f88ae32 100644 --- a/common/netjack_packet.h +++ b/common/netjack_packet.h @@ -28,8 +28,8 @@ #define __JACK_NET_PACKET_H__ #ifdef __cplusplus - extern "C" - { +extern "C" +{ #endif #include @@ -42,115 +42,106 @@ #define CELT_MODE 1000 // Magic bitdepth value that indicates CELT compression #define MASTER_FREEWHEELS 0x80000000 -typedef struct _jacknet_packet_header jacknet_packet_header; - -struct _jacknet_packet_header -{ - // General AutoConf Data - jack_nframes_t capture_channels_audio; - jack_nframes_t playback_channels_audio; - jack_nframes_t capture_channels_midi; - jack_nframes_t playback_channels_midi; - jack_nframes_t period_size; - jack_nframes_t sample_rate; - - // Transport Sync - jack_nframes_t sync_state; - jack_nframes_t transport_frame; - jack_nframes_t transport_state; - - // Packet loss Detection, and latency reduction - jack_nframes_t framecnt; - jack_nframes_t latency; - - jack_nframes_t reply_port; - jack_nframes_t mtu; - jack_nframes_t fragment_nr; -}; - -typedef union _int_float int_float_t; - -union _int_float -{ - uint32_t i; - float f; -}; - -// fragment reorder cache. -typedef struct _cache_packet cache_packet; - -struct _cache_packet -{ - int valid; - int num_fragments; - int packet_size; - int mtu; - jack_time_t recv_timestamp; - jack_nframes_t framecnt; - char * fragment_array; - char * packet_buf; -}; - -typedef struct _packet_cache packet_cache; - -struct _packet_cache -{ - int size; - cache_packet *packets; - int mtu; - struct sockaddr_in master_address; - int master_address_valid; - jack_nframes_t last_framecnt_retreived; - int last_framecnt_retreived_valid; -}; - -// fragment cache function prototypes -// XXX: Some of these are private. -packet_cache *packet_cache_new(int num_packets, int pkt_size, int mtu); -void packet_cache_free(packet_cache *pkt_cache); - -cache_packet *packet_cache_get_packet(packet_cache *pkt_cache, jack_nframes_t framecnt); -cache_packet *packet_cache_get_oldest_packet(packet_cache *pkt_cache); -cache_packet *packet_cache_get_free_packet(packet_cache *pkt_cache); - -void cache_packet_reset(cache_packet *pack); -void cache_packet_set_framecnt(cache_packet *pack, jack_nframes_t framecnt); -void cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len); -int cache_packet_is_complete(cache_packet *pack); - -void packet_cache_drain_socket( packet_cache *pcache, int sockfd ); -void packet_cache_reset_master_address( packet_cache *pcache ); -float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ); -int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp ); -int packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt ); -int packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); -int packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt ); -int packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); -// Function Prototypes - -int netjack_poll_deadline (int sockfd, jack_time_t deadline); - -void netjack_sendto(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu); - - -int get_sample_size(int bitdepth); -void packet_header_hton(jacknet_packet_header *pkthdr); - -void packet_header_ntoh(jacknet_packet_header *pkthdr); - -void render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats ); - -void render_jack_ports_to_payload(int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); - - -// XXX: This is sort of deprecated: -// This one waits forever. an is not using ppoll -int netjack_poll(int sockfd, int timeout); + typedef struct _jacknet_packet_header jacknet_packet_header; + + struct _jacknet_packet_header { + // General AutoConf Data + jack_nframes_t capture_channels_audio; + jack_nframes_t playback_channels_audio; + jack_nframes_t capture_channels_midi; + jack_nframes_t playback_channels_midi; + jack_nframes_t period_size; + jack_nframes_t sample_rate; + + // Transport Sync + jack_nframes_t sync_state; + jack_nframes_t transport_frame; + jack_nframes_t transport_state; + + // Packet loss Detection, and latency reduction + jack_nframes_t framecnt; + jack_nframes_t latency; + + jack_nframes_t reply_port; + jack_nframes_t mtu; + jack_nframes_t fragment_nr; + }; + + typedef union _int_float int_float_t; + + union _int_float { + uint32_t i; + float f; + }; + + // fragment reorder cache. + typedef struct _cache_packet cache_packet; + + struct _cache_packet { + int valid; + int num_fragments; + int packet_size; + int mtu; + jack_time_t recv_timestamp; + jack_nframes_t framecnt; + char * fragment_array; + char * packet_buf; + }; + + typedef struct _packet_cache packet_cache; + + struct _packet_cache { + int size; + cache_packet *packets; + int mtu; + struct sockaddr_in master_address; + int master_address_valid; + jack_nframes_t last_framecnt_retreived; + int last_framecnt_retreived_valid; + }; + + // fragment cache function prototypes + // XXX: Some of these are private. + packet_cache *packet_cache_new(int num_packets, int pkt_size, int mtu); + void packet_cache_free(packet_cache *pkt_cache); + + cache_packet *packet_cache_get_packet(packet_cache *pkt_cache, jack_nframes_t framecnt); + cache_packet *packet_cache_get_oldest_packet(packet_cache *pkt_cache); + cache_packet *packet_cache_get_free_packet(packet_cache *pkt_cache); + + void cache_packet_reset(cache_packet *pack); + void cache_packet_set_framecnt(cache_packet *pack, jack_nframes_t framecnt); + void cache_packet_add_fragment(cache_packet *pack, char *packet_buf, int rcv_len); + int cache_packet_is_complete(cache_packet *pack); + + void packet_cache_drain_socket( packet_cache *pcache, int sockfd ); + void packet_cache_reset_master_address( packet_cache *pcache ); + float packet_cache_get_fill( packet_cache *pcache, jack_nframes_t expected_framecnt ); + int packet_cache_retreive_packet_pointer( packet_cache *pcache, jack_nframes_t framecnt, char **packet_buf, int pkt_size, jack_time_t *timestamp ); + int packet_cache_release_packet( packet_cache *pcache, jack_nframes_t framecnt ); + int packet_cache_get_next_available_framecnt( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); + int packet_cache_get_highest_available_framecnt( packet_cache *pcache, jack_nframes_t *framecnt ); + int packet_cache_find_latency( packet_cache *pcache, jack_nframes_t expected_framecnt, jack_nframes_t *framecnt ); + + // Function Prototypes + + int netjack_poll_deadline (int sockfd, jack_time_t deadline); + void netjack_sendto(int sockfd, char *packet_buf, int pkt_size, int flags, struct sockaddr *addr, int addr_size, int mtu); + int get_sample_size(int bitdepth); + void packet_header_hton(jacknet_packet_header *pkthdr); + void packet_header_ntoh(jacknet_packet_header *pkthdr); + void render_payload_to_jack_ports(int bitdepth, void *packet_payload, jack_nframes_t net_period_down, JSList *capture_ports, JSList *capture_srcs, jack_nframes_t nframes, int dont_htonl_floats ); + void render_jack_ports_to_payload(int bitdepth, JSList *playback_ports, JSList *playback_srcs, jack_nframes_t nframes, void *packet_payload, jack_nframes_t net_period_up, int dont_htonl_floats ); + + // XXX: This is sort of deprecated: + // This one waits forever. an is not using ppoll + int netjack_poll(int sockfd, int timeout); + + void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); + void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); -void decode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); -void encode_midi_buffer (uint32_t *buffer_uint32, unsigned int buffer_size_uint32, jack_default_audio_sample_t* buf); #ifdef __cplusplus - } +} #endif #endif diff --git a/example-clients/netsource.c b/example-clients/netsource.c index 4c53792c..c5cc926f 100644 --- a/example-clients/netsource.c +++ b/example-clients/netsource.c @@ -92,7 +92,7 @@ int state_netxruns = 0; int state_currentframe = 0; int state_recv_packet_queue_time = 0; -int quit=0; +int quit = 0; int outsockfd; @@ -128,43 +128,39 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int capture_ports = NULL; /* Allocate audio capture channels */ - for (chn = 0; chn < n_capture_audio; chn++) - { + for (chn = 0; chn < n_capture_audio; chn++) { snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); - if (!port) - { + if (!port) { printf( "jack_netsource: cannot register %s port\n", buf); break; } - if (bitdepth == 1000) { - #if HAVE_CELT - #if HAVE_CELT_API_0_11 + if (bitdepth == 1000) { +#if HAVE_CELT +#if HAVE_CELT_API_0_11 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) ); - #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 +#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) ); - #else +#else CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL ); capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) ); - #endif - #endif +#endif +#endif } else { - #if HAVE_SAMPLERATE - capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL)); - #endif +#if HAVE_SAMPLERATE + capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL)); +#endif } capture_ports = jack_slist_append (capture_ports, port); } /* Allocate midi capture channels */ - for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++) - { + for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++) { snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1); port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); - if (!port) - { + if (!port) { printf ("jack_netsource: cannot register %s port\n", buf); break; } @@ -174,43 +170,39 @@ alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int /* Allocate audio playback channels */ port_flags = JackPortIsInput; playback_ports = NULL; - for (chn = 0; chn < n_playback_audio; chn++) - { + for (chn = 0; chn < n_playback_audio; chn++) { snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0); - if (!port) - { + if (!port) { printf ("jack_netsource: cannot register %s port\n", buf); break; } if( bitdepth == 1000 ) { - #if HAVE_CELT - #if HAVE_CELT_API_0_11 +#if HAVE_CELT +#if HAVE_CELT_API_0_11 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) ); - #elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 +#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8 CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) ); - #else +#else CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL ); playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) ); - #endif - #endif +#endif +#endif } else { - #if HAVE_SAMPLERATE +#if HAVE_SAMPLERATE playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL)); - #endif +#endif } playback_ports = jack_slist_append (playback_ports, port); } /* Allocate midi playback channels */ - for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++) - { + for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++) { snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1); port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0); - if (!port) - { + if (!port) { printf ("jack_netsource: cannot register %s port\n", buf); break; } @@ -237,8 +229,7 @@ sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg) retval = 0; } - else if (state == JackTransportStarting && last_transport_state != JackTransportStarting) - { + else if (state == JackTransportStarting && last_transport_state != JackTransportStarting) { retval = 0; latency_count = latency - 1; } @@ -250,10 +241,10 @@ sync_cb (jack_transport_state_t state, jack_position_t *pos, void *arg) void freewheel_cb (int starting, void *arg) { - freewheeling = starting; + freewheeling = starting; } - int deadline_goodness=0; +int deadline_goodness = 0; /** * The process callback for this JACK application. * It is called by JACK at the appropriate times. @@ -279,7 +270,7 @@ process (jack_nframes_t nframes, void *arg) jack_time_t packet_recv_timestamp; if( bitdepth == 1000 ) - net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ; + net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ; else net_period = (float) nframes / (float) factor; @@ -299,47 +290,45 @@ process (jack_nframes_t nframes, void *arg) */ if( latency == 0 ) { - /* reset packet_bufX... */ - packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); - - /* ---------- Send ---------- */ - render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, - packet_bufX, net_period, dont_htonl_floats); - - /* fill in packet hdr */ - pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos); - pkthdr_tx->transport_frame = local_trans_pos.frame; - pkthdr_tx->framecnt = framecnt; - pkthdr_tx->latency = latency; - pkthdr_tx->reply_port = reply_port; - pkthdr_tx->sample_rate = jack_get_sample_rate (client); - pkthdr_tx->period_size = nframes; - - /* playback for us is capture on the other side */ - pkthdr_tx->capture_channels_audio = playback_channels_audio; - pkthdr_tx->playback_channels_audio = capture_channels_audio; - pkthdr_tx->capture_channels_midi = playback_channels_midi; - pkthdr_tx->playback_channels_midi = capture_channels_midi; - pkthdr_tx->mtu = mtu; - if( freewheeling!= 0 ) - pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; - else - pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness; - //printf("goodness=%d\n", deadline_goodness ); - - packet_header_hton (pkthdr_tx); - if (cont_miss < 3*latency+5) { - int r; - for( r=0; r 50+5*latency) - { - state_connected = 0; - packet_cache_reset_master_address( packcache ); - //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); - cont_miss = 0; - } + /* reset packet_bufX... */ + packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + + /* ---------- Send ---------- */ + render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, + packet_bufX, net_period, dont_htonl_floats); + + /* fill in packet hdr */ + pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos); + pkthdr_tx->transport_frame = local_trans_pos.frame; + pkthdr_tx->framecnt = framecnt; + pkthdr_tx->latency = latency; + pkthdr_tx->reply_port = reply_port; + pkthdr_tx->sample_rate = jack_get_sample_rate (client); + pkthdr_tx->period_size = nframes; + + /* playback for us is capture on the other side */ + pkthdr_tx->capture_channels_audio = playback_channels_audio; + pkthdr_tx->playback_channels_audio = capture_channels_audio; + pkthdr_tx->capture_channels_midi = playback_channels_midi; + pkthdr_tx->playback_channels_midi = capture_channels_midi; + pkthdr_tx->mtu = mtu; + if( freewheeling != 0 ) + pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; + else + pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness; + //printf("goodness=%d\n", deadline_goodness ); + + packet_header_hton (pkthdr_tx); + if (cont_miss < 3 * latency + 5) { + int r; + for( r = 0; r < redundancy; r++ ) + netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu); + } else if (cont_miss > 50 + 5 * latency) { + state_connected = 0; + packet_cache_reset_master_address( packcache ); + //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); + cont_miss = 0; + } } /* @@ -354,19 +343,19 @@ process (jack_nframes_t nframes, void *arg) input_fd = outsockfd; // for latency == 0 we can poll. - if( (latency == 0) || (freewheeling!=0) ) { - jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client)/jack_get_sample_rate(client); + if( (latency == 0) || (freewheeling != 0) ) { + jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client) / jack_get_sample_rate(client); // Now loop until we get the right packet. while(1) { jack_nframes_t got_frame; if ( ! netjack_poll_deadline( input_fd, deadline ) ) - break; + break; packet_cache_drain_socket(packcache, input_fd); if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame )) - if( got_frame == (framecnt - latency) ) - break; + if( got_frame == (framecnt - latency) ) + break; } } else { // normally: @@ -377,8 +366,7 @@ process (jack_nframes_t nframes, void *arg) size = packet_cache_retreive_packet_pointer( packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp ); /* First alternative : we received what we expected. Render the data * to the JACK ports so it can be played. */ - if (size == rx_bufsize) - { + if (size == rx_bufsize) { uint32_t *packet_buf_rx = rx_packet_ptr; jacknet_packet_header *pkthdr_rx = (jacknet_packet_header *) packet_buf_rx; packet_bufX = packet_buf_rx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); @@ -389,13 +377,12 @@ process (jack_nframes_t nframes, void *arg) deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency; //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset ); - if (cont_miss) - { + if (cont_miss) { //printf("Frame %d \tRecovered from dropouts\n", framecnt); cont_miss = 0; } render_payload_to_jack_ports (bitdepth, packet_bufX, net_period, - capture_ports, capture_srcs, nframes, dont_htonl_floats); + capture_ports, capture_srcs, nframes, dont_htonl_floats); state_currentframe = framecnt; state_recv_packet_queue_time = recv_time_offset; @@ -406,8 +393,7 @@ process (jack_nframes_t nframes, void *arg) /* Second alternative : we've received something that's not * as big as expected or we missed a packet. We render silence * to the ouput ports */ - else - { + else { jack_nframes_t latency_estimate; if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) ) //if( (state_latency == 0) || (latency_estimate < state_latency) ) @@ -423,8 +409,7 @@ process (jack_nframes_t nframes, void *arg) cont_miss += 1; chn = 0; node = capture_ports; - while (node != NULL) - { + while (node != NULL) { port = (jack_port_t *) node->data; buf = jack_port_get_buffer (port, nframes); porttype = jack_port_type (port); @@ -438,47 +423,45 @@ process (jack_nframes_t nframes, void *arg) } } if (latency != 0) { - /* reset packet_bufX... */ - packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); - - /* ---------- Send ---------- */ - render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, - packet_bufX, net_period, dont_htonl_floats); - - /* fill in packet hdr */ - pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos); - pkthdr_tx->transport_frame = local_trans_pos.frame; - pkthdr_tx->framecnt = framecnt; - pkthdr_tx->latency = latency; - pkthdr_tx->reply_port = reply_port; - pkthdr_tx->sample_rate = jack_get_sample_rate (client); - pkthdr_tx->period_size = nframes; - - /* playback for us is capture on the other side */ - pkthdr_tx->capture_channels_audio = playback_channels_audio; - pkthdr_tx->playback_channels_audio = capture_channels_audio; - pkthdr_tx->capture_channels_midi = playback_channels_midi; - pkthdr_tx->playback_channels_midi = capture_channels_midi; - pkthdr_tx->mtu = mtu; - if( freewheeling!= 0 ) - pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; - else - pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness; - //printf("goodness=%d\n", deadline_goodness ); - - packet_header_hton (pkthdr_tx); - if (cont_miss < 3*latency+5) { - int r; - for( r=0; r 50+5*latency) - { - state_connected = 0; - packet_cache_reset_master_address( packcache ); - //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); - cont_miss = 0; - } + /* reset packet_bufX... */ + packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t); + + /* ---------- Send ---------- */ + render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes, + packet_bufX, net_period, dont_htonl_floats); + + /* fill in packet hdr */ + pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos); + pkthdr_tx->transport_frame = local_trans_pos.frame; + pkthdr_tx->framecnt = framecnt; + pkthdr_tx->latency = latency; + pkthdr_tx->reply_port = reply_port; + pkthdr_tx->sample_rate = jack_get_sample_rate (client); + pkthdr_tx->period_size = nframes; + + /* playback for us is capture on the other side */ + pkthdr_tx->capture_channels_audio = playback_channels_audio; + pkthdr_tx->playback_channels_audio = capture_channels_audio; + pkthdr_tx->capture_channels_midi = playback_channels_midi; + pkthdr_tx->playback_channels_midi = capture_channels_midi; + pkthdr_tx->mtu = mtu; + if( freewheeling != 0 ) + pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS; + else + pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness; + //printf("goodness=%d\n", deadline_goodness ); + + packet_header_hton (pkthdr_tx); + if (cont_miss < 3 * latency + 5) { + int r; + for( r = 0; r < redundancy; r++ ) + netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu); + } else if (cont_miss > 50 + 5 * latency) { + state_connected = 0; + packet_cache_reset_master_address( packcache ); + //printf ("Frame %d \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss); + cont_miss = 0; + } } framecnt++; @@ -502,20 +485,18 @@ init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t por { name->sin_family = AF_INET ; name->sin_port = htons (port); - if (hostname) - { + if (hostname) { struct hostent *hostinfo = gethostbyname (hostname); if (hostinfo == NULL) { fprintf (stderr, "init_sockaddr_in: unknown host: %s.\n", hostname); - fflush( stderr ); - } + fflush( stderr ); + } #ifdef WIN32 name->sin_addr.s_addr = inet_addr( hostname ); #else name->sin_addr = *(struct in_addr *) hostinfo->h_addr ; #endif - } - else + } else name->sin_addr.s_addr = htonl (INADDR_ANY) ; } @@ -523,32 +504,32 @@ init_sockaddr_in (struct sockaddr_in *name , const char *hostname , uint16_t por void printUsage () { -fprintf (stderr, "usage: jack_netsource [options]\n" - "\n" - " -h this help text\n" - " -H - Host name of the slave JACK\n" - " -o - Number of audio playback channels\n" - " -i - Number of audio capture channels\n" - " -O - Number of midi playback channels\n" - " -I - Number of midi capture channels\n" - " -n - Network latency in JACK periods\n" - " -p - UDP port that the slave is listening on\n" - " -r - UDP port that we are listening on\n" - " -B - reply port, for use in NAT environments\n" - " -b - Set transport to use 16bit or 8bit\n" - " -c - Use CELT encoding with kbits per channel\n" - " -m - Assume this mtu for the link\n" - " -R - Redundancy: send out packets N times.\n" - " -e - skip host-to-network endianness conversion\n" - " -N - Reports a different name to jack\n" - " -s - The name of the local jack server\n" - "\n"); + fprintf (stderr, "usage: jack_netsource [options]\n" + "\n" + " -h this help text\n" + " -H - Host name of the slave JACK\n" + " -o - Number of audio playback channels\n" + " -i - Number of audio capture channels\n" + " -O - Number of midi playback channels\n" + " -I - Number of midi capture channels\n" + " -n - Network latency in JACK periods\n" + " -p - UDP port that the slave is listening on\n" + " -r - UDP port that we are listening on\n" + " -B - reply port, for use in NAT environments\n" + " -b - Set transport to use 16bit or 8bit\n" + " -c - Use CELT encoding with kbits per channel\n" + " -m - Assume this mtu for the link\n" + " -R - Redundancy: send out packets N times.\n" + " -e - skip host-to-network endianness conversion\n" + " -N - Reports a different name to jack\n" + " -s - The name of the local jack server\n" + "\n"); } void sigterm_handler( int signal ) { - quit = 1; + quit = 1; } int @@ -561,7 +542,7 @@ main (int argc, char *argv[]) jack_status_t status; #ifdef WIN32 WSADATA wsa; - int rc = WSAStartup(MAKEWORD(2,0),&wsa); + int rc = WSAStartup(MAKEWORD(2, 0), &wsa); #endif /* Torben's famous state variables, aka "the reporting API" ! */ /* heh ? these are only the copies of them ;) */ @@ -570,10 +551,9 @@ main (int argc, char *argv[]) /* Argument parsing stuff */ extern char *optarg; extern int optind, optopt; - int errflg=0, c; + int errflg = 0, c; - if (argc < 3) - { + if (argc < 3) { printUsage (); return 1; } @@ -583,17 +563,15 @@ main (int argc, char *argv[]) sprintf(client_name, "netjack"); sprintf(peer_ip, "localhost"); - while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:")) != -1) - { - switch (c) - { + while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:")) != -1) { + switch (c) { case 'h': printUsage(); exit (0); break; case 'H': free(peer_ip); - peer_ip = (char *) malloc (sizeof (char) * strlen (optarg)+1); + peer_ip = (char *) malloc (sizeof (char) * strlen (optarg) + 1); strcpy (peer_ip, optarg); break; case 'o': @@ -647,11 +625,11 @@ main (int argc, char *argv[]) break; case 'N': free(client_name); - client_name = (char *) malloc (sizeof (char) * strlen (optarg)+1); + client_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1); strcpy (client_name, optarg); break; case 's': - server_name = (char *) malloc (sizeof (char) * strlen (optarg)+1); + server_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1); strcpy (server_name, optarg); options |= JackServerName; break; @@ -664,8 +642,7 @@ main (int argc, char *argv[]) errflg++; } } - if (errflg) - { + if (errflg) { printUsage (); exit (2); } @@ -688,8 +665,7 @@ main (int argc, char *argv[]) fprintf (stderr, "bind failure\n" ); } } - if (reply_port) - { + if (reply_port) { init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port); if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) { fprintf (stderr, "bind failure\n" ); @@ -698,10 +674,9 @@ main (int argc, char *argv[]) /* try to become a client of the JACK server */ client = jack_client_open (client_name, options, &status, server_name); - if (client == NULL) - { + if (client == NULL) { fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n" - "Is the JACK server running ?\n", status); + "Is the JACK server running ?\n", status); return 1; } @@ -714,7 +689,7 @@ main (int argc, char *argv[]) alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi); if( bitdepth == 1000 ) - net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8)&(~1) ; + net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ; else net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); @@ -722,8 +697,7 @@ main (int argc, char *argv[]) packcache = packet_cache_new (latency + 50, rx_bufsize, mtu); /* tell the JACK server that we are ready to roll */ - if (jack_activate (client)) - { + if (jack_activate (client)) { fprintf (stderr, "Cannot activate client"); return 1; } @@ -737,49 +711,41 @@ main (int argc, char *argv[]) statecopy_latency = state_latency; statecopy_netxruns = state_netxruns; - while ( !quit ) - { + while ( !quit ) { #ifdef WIN32 Sleep (1000); #else sleep(1); #endif - if (statecopy_connected != state_connected) - { + if (statecopy_connected != state_connected) { statecopy_connected = state_connected; - if (statecopy_connected) - { + if (statecopy_connected) { state_netxruns = 1; // We want to reset the netxrun count on each new connection printf ("Connected :-)\n"); - } - else + } else printf ("Not Connected\n"); - fflush(stdout); + fflush(stdout); } - if (statecopy_connected) - { - if (statecopy_netxruns != state_netxruns) { - statecopy_netxruns = state_netxruns; - printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n", - client_name, - state_currentframe, - statecopy_netxruns, - 100*statecopy_netxruns/state_currentframe, - state_recv_packet_queue_time); - - fflush(stdout); + if (statecopy_connected) { + if (statecopy_netxruns != state_netxruns) { + statecopy_netxruns = state_netxruns; + printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n", + client_name, + state_currentframe, + statecopy_netxruns, + 100 * statecopy_netxruns / state_currentframe, + state_recv_packet_queue_time); + + fflush(stdout); } - } - else - { - if (statecopy_latency != state_latency) - { - statecopy_latency = state_latency; - if (statecopy_latency > 1) - printf ("current latency %d\n", statecopy_latency); - fflush(stdout); + } else { + if (statecopy_latency != state_latency) { + statecopy_latency = state_latency; + if (statecopy_latency > 1) + printf ("current latency %d\n", statecopy_latency); + fflush(stdout); } } }