| @@ -1,6 +1,16 @@ | |||||
| ChangeLog | ChangeLog | ||||
| ######### | ######### | ||||
| * 1.9.19 (2021-07-15) | |||||
| * WIP (note to write asking CI help) | |||||
| * Add jack_position_t::tick_double, and flags around it | |||||
| * Add zalsa "-w" argument to wait for soundcard to be available | |||||
| * Bump internal protocol version to 9 (due to struct alignment) | |||||
| * Fix alignment of fields for atomic accesses | |||||
| * Fix build for platforms needing __STDC_FORMAT_MACROS | |||||
| * Fix compilation of documentation | |||||
| * 1.9.18 (2021-04-15) | * 1.9.18 (2021-04-15) | ||||
| * Add zalsa_in/out as internal client (based on zita-a2j/j2a and jack1 code) | * Add zalsa_in/out as internal client (based on zita-a2j/j2a and jack1 code) | ||||
| @@ -113,7 +113,7 @@ namespace Jack | |||||
| jack_set_process_callback(client, Process, this); | jack_set_process_callback(client, Process, this); | ||||
| jack_activate(client); | jack_activate(client); | ||||
| //conenct between sapaproxy and system ports | |||||
| //connect between sapaproxy and system ports | |||||
| for (unsigned int i = 0; i < ports_system_capture_cnt; i++) { | for (unsigned int i = 0; i < ports_system_capture_cnt; i++) { | ||||
| sprintf(port_name, "system:capture_%d", i + 1); | sprintf(port_name, "system:capture_%d", i + 1); | ||||
| jack_connect(client, port_name, jack_port_name(fInputPorts[i])); | jack_connect(client, port_name, jack_port_name(fInputPorts[i])); | ||||
| @@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
| */ | */ | ||||
| #define __STDC_FORMAT_MACROS 1 | |||||
| #include <inttypes.h> | |||||
| #include "JackClient.h" | #include "JackClient.h" | ||||
| #include "JackError.h" | #include "JackError.h" | ||||
| #include "JackGraphManager.h" | #include "JackGraphManager.h" | ||||
| @@ -27,8 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
| #include "JackTime.h" | #include "JackTime.h" | ||||
| #include "JackPortType.h" | #include "JackPortType.h" | ||||
| #include <math.h> | #include <math.h> | ||||
| #define __STDC_FORMAT_MACROS 1 | |||||
| #include <inttypes.h> | |||||
| using namespace Jack; | using namespace Jack; | ||||
| @@ -39,13 +39,16 @@ class JackActivationCount | |||||
| private: | private: | ||||
| SInt32 fValue; | |||||
| alignas(SInt32) SInt32 fValue; | |||||
| SInt32 fCount; | SInt32 fCount; | ||||
| public: | public: | ||||
| JackActivationCount(): fValue(0), fCount(0) | JackActivationCount(): fValue(0), fCount(0) | ||||
| {} | |||||
| { | |||||
| static_assert(offsetof(JackActivationCount, fValue) % sizeof(fValue) == 0, | |||||
| "fValue must be aligned within JackActivationCount"); | |||||
| } | |||||
| bool Signal(JackSynchro* synchro, JackClientControl* control); | bool Signal(JackSynchro* synchro, JackClientControl* control); | ||||
| @@ -23,6 +23,7 @@ | |||||
| #include "JackAtomic.h" | #include "JackAtomic.h" | ||||
| #include "JackCompilerDeps.h" | #include "JackCompilerDeps.h" | ||||
| #include <string.h> // for memcpy | #include <string.h> // for memcpy | ||||
| #include <cstddef> | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| @@ -121,7 +122,7 @@ class JackAtomicArrayState | |||||
| // fState[2] ==> request | // fState[2] ==> request | ||||
| T fState[3]; | T fState[3]; | ||||
| volatile AtomicArrayCounter fCounter; | |||||
| alignas(UInt32) volatile AtomicArrayCounter fCounter; | |||||
| UInt32 WriteNextStateStartAux(int state, bool* result) | UInt32 WriteNextStateStartAux(int state, bool* result) | ||||
| { | { | ||||
| @@ -159,6 +160,8 @@ class JackAtomicArrayState | |||||
| JackAtomicArrayState() | JackAtomicArrayState() | ||||
| { | { | ||||
| static_assert(offsetof(JackAtomicArrayState, fCounter) % sizeof(fCounter) == 0, | |||||
| "fCounter must be aligned within JackAtomicArrayState"); | |||||
| Counter1(fCounter) = 0; | Counter1(fCounter) = 0; | ||||
| } | } | ||||
| @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
| #include "JackAtomic.h" | #include "JackAtomic.h" | ||||
| #include "JackCompilerDeps.h" | #include "JackCompilerDeps.h" | ||||
| #include <string.h> // for memcpy | #include <string.h> // for memcpy | ||||
| #include <cstddef> | |||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| @@ -93,7 +94,7 @@ class JackAtomicState | |||||
| protected: | protected: | ||||
| T fState[2]; | T fState[2]; | ||||
| volatile AtomicCounter fCounter; | |||||
| alignas(UInt32) volatile AtomicCounter fCounter; | |||||
| SInt32 fCallWriteCounter; | SInt32 fCallWriteCounter; | ||||
| UInt32 WriteNextStateStartAux() | UInt32 WriteNextStateStartAux() | ||||
| @@ -131,6 +132,8 @@ class JackAtomicState | |||||
| JackAtomicState() | JackAtomicState() | ||||
| { | { | ||||
| static_assert(offsetof(JackAtomicState, fCounter) % sizeof(fCounter) == 0, | |||||
| "fCounter must be aligned within JackAtomicState"); | |||||
| Counter(fCounter) = 0; | Counter(fCounter) = 0; | ||||
| fCallWriteCounter = 0; | fCallWriteCounter = 0; | ||||
| } | } | ||||
| @@ -32,6 +32,9 @@ namespace Jack | |||||
| JackConnectionManager::JackConnectionManager() | JackConnectionManager::JackConnectionManager() | ||||
| { | { | ||||
| int i; | int i; | ||||
| static_assert(offsetof(JackConnectionManager, fInputCounter) % sizeof(UInt32) == 0, | |||||
| "fInputCounter must be aligned within JackConnectionManager"); | |||||
| jack_log("JackConnectionManager::InitConnections size = %ld ", sizeof(JackConnectionManager)); | jack_log("JackConnectionManager::InitConnections size = %ld ", sizeof(JackConnectionManager)); | ||||
| for (i = 0; i < PORT_NUM_MAX; i++) { | for (i = 0; i < PORT_NUM_MAX; i++) { | ||||
| @@ -417,7 +417,7 @@ class SERVER_EXPORT JackConnectionManager | |||||
| JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM]; /*! Table of input port per refnum : to find a refnum for a given port */ | JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM]; /*! Table of input port per refnum : to find a refnum for a given port */ | ||||
| JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM]; /*! Table of output port per refnum : to find a refnum for a given port */ | JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM]; /*! Table of output port per refnum : to find a refnum for a given port */ | ||||
| JackFixedMatrix<CLIENT_NUM> fConnectionRef; /*! Table of port connections by (refnum , refnum) */ | JackFixedMatrix<CLIENT_NUM> fConnectionRef; /*! Table of port connections by (refnum , refnum) */ | ||||
| JackActivationCount fInputCounter[CLIENT_NUM]; /*! Activation counter per refnum */ | |||||
| alignas(UInt32) JackActivationCount fInputCounter[CLIENT_NUM]; /*! Activation counter per refnum */ | |||||
| JackLoopFeedback<CONNECTION_NUM_FOR_PORT> fLoopFeedback; /*! Loop feedback connections */ | JackLoopFeedback<CONNECTION_NUM_FOR_PORT> fLoopFeedback; /*! Loop feedback connections */ | ||||
| bool IsLoopPathAux(int ref1, int ref2) const; | bool IsLoopPathAux(int ref1, int ref2) const; | ||||
| @@ -24,7 +24,7 @@ | |||||
| #include "config.h" | #include "config.h" | ||||
| #endif | #endif | ||||
| #define VERSION "1.9.18" | |||||
| #define VERSION "1.9.19" | |||||
| #define BUFFER_SIZE_MAX 8192 | #define BUFFER_SIZE_MAX 8192 | ||||
| @@ -72,7 +72,7 @@ | |||||
| #define ALL_CLIENTS -1 // for notification | #define ALL_CLIENTS -1 // for notification | ||||
| #define JACK_PROTOCOL_VERSION 8 | |||||
| #define JACK_PROTOCOL_VERSION 9 | |||||
| #define SOCKET_TIME_OUT 2 // in sec | #define SOCKET_TIME_OUT 2 // in sec | ||||
| #define DRIVER_OPEN_TIMEOUT 5 // in sec | #define DRIVER_OPEN_TIMEOUT 5 // in sec | ||||
| @@ -64,7 +64,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem | |||||
| int fClientPriority; | int fClientPriority; | ||||
| int fMaxClientPriority; | int fMaxClientPriority; | ||||
| char fServerName[JACK_SERVER_NAME_SIZE+1]; | char fServerName[JACK_SERVER_NAME_SIZE+1]; | ||||
| JackTransportEngine fTransport; | |||||
| alignas(UInt32) JackTransportEngine fTransport; | |||||
| jack_timer_type_t fClockSource; | jack_timer_type_t fClockSource; | ||||
| int fDriverNum; | int fDriverNum; | ||||
| bool fVerbose; | bool fVerbose; | ||||
| @@ -86,14 +86,18 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem | |||||
| UInt64 fConstraint; | UInt64 fConstraint; | ||||
| // Timer | // Timer | ||||
| JackFrameTimer fFrameTimer; | |||||
| alignas(UInt32) JackFrameTimer fFrameTimer; | |||||
| #ifdef JACK_MONITOR | #ifdef JACK_MONITOR | ||||
| JackEngineProfiling fProfiler; | JackEngineProfiling fProfiler; | ||||
| #endif | #endif | ||||
| JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name) | JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, jack_timer_type_t clock, const char* server_name) | ||||
| { | |||||
| { | |||||
| static_assert(offsetof(JackEngineControl, fTransport) % sizeof(UInt32) == 0, | |||||
| "fTransport must be aligned within JackEngineControl"); | |||||
| static_assert(offsetof(JackEngineControl, fFrameTimer) % sizeof(UInt32) == 0, | |||||
| "fFrameTimer must be aligned within JackEngineControl"); | |||||
| fBufferSize = 512; | fBufferSize = 512; | ||||
| fSampleRate = 48000; | fSampleRate = 48000; | ||||
| fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize); | fPeriodUsecs = jack_time_t(1000000.f / fSampleRate * fBufferSize); | ||||
| @@ -38,7 +38,10 @@ JackMessageBuffer::JackMessageBuffer() | |||||
| fOutBuffer(0), | fOutBuffer(0), | ||||
| fOverruns(0), | fOverruns(0), | ||||
| fRunning(false) | fRunning(false) | ||||
| {} | |||||
| { | |||||
| static_assert(offsetof(JackMessageBuffer, fOverruns) % sizeof(fOverruns) == 0, | |||||
| "fOverruns must be aligned within JackMessageBuffer"); | |||||
| } | |||||
| JackMessageBuffer::~JackMessageBuffer() | JackMessageBuffer::~JackMessageBuffer() | ||||
| {} | {} | ||||
| @@ -64,7 +64,7 @@ class JackMessageBuffer : public JackRunnableInterface | |||||
| JackProcessSync fGuard; | JackProcessSync fGuard; | ||||
| volatile unsigned int fInBuffer; | volatile unsigned int fInBuffer; | ||||
| volatile unsigned int fOutBuffer; | volatile unsigned int fOutBuffer; | ||||
| SInt32 fOverruns; | |||||
| alignas(SInt32) SInt32 fOverruns; | |||||
| bool fRunning; | bool fRunning; | ||||
| void Flush(); | void Flush(); | ||||
| @@ -36,6 +36,8 @@ namespace Jack | |||||
| JackTransportEngine::JackTransportEngine(): JackAtomicArrayState<jack_position_t>() | JackTransportEngine::JackTransportEngine(): JackAtomicArrayState<jack_position_t>() | ||||
| { | { | ||||
| static_assert(offsetof(JackTransportEngine, fWriteCounter) % sizeof(fWriteCounter) == 0, | |||||
| "fWriteCounter must be first member of JackTransportEngine to ensure its alignment"); | |||||
| fTransportState = JackTransportStopped; | fTransportState = JackTransportStopped; | ||||
| fTransportCmd = fPreviousCmd = TransportCommandStop; | fTransportCmd = fPreviousCmd = TransportCommandStop; | ||||
| fSyncTimeout = 10000000; /* 10 seconds default... | fSyncTimeout = 10000000; /* 10 seconds default... | ||||
| @@ -104,7 +104,7 @@ class SERVER_EXPORT JackTransportEngine : public JackAtomicArrayState<jack_posit | |||||
| bool fPendingPos; | bool fPendingPos; | ||||
| bool fNetworkSync; | bool fNetworkSync; | ||||
| bool fConditionnal; | bool fConditionnal; | ||||
| SInt32 fWriteCounter; | |||||
| alignas(SInt32) SInt32 fWriteCounter; | |||||
| bool CheckAllRolling(JackClientInterface** table); | bool CheckAllRolling(JackClientInterface** table); | ||||
| void MakeAllStartingLocating(JackClientInterface** table); | void MakeAllStartingLocating(JackClientInterface** table); | ||||
| @@ -606,10 +606,10 @@ int jack_set_xrun_callback (jack_client_t *client, | |||||
| * register a latency callback. | * register a latency callback. | ||||
| * | * | ||||
| * Another case is when a client wants to use | * Another case is when a client wants to use | ||||
| * @ref jack_port_get_latency_range(), which only returns meaninful | |||||
| * @ref jack_port_get_latency_range(), which only returns meaningful | |||||
| * values when ports get connected and latency values change. | * values when ports get connected and latency values change. | ||||
| * | * | ||||
| * See the documentation for @ref jack_port_set_latency_range() | |||||
| * See the documentation for @ref jack_port_set_latency_range() | |||||
| * on how the callback should operate. Remember that the @a mode | * on how the callback should operate. Remember that the @a mode | ||||
| * argument given to the latency callback will need to be | * argument given to the latency callback will need to be | ||||
| * passed into @ref jack_port_set_latency_range() | * passed into @ref jack_port_set_latency_range() | ||||
| @@ -538,11 +538,12 @@ typedef uint64_t jack_unique_t; /**< Unique ID (opaque) */ | |||||
| */ | */ | ||||
| typedef enum { | typedef enum { | ||||
| JackPositionBBT = 0x10, /**< Bar, Beat, Tick */ | |||||
| JackPositionTimecode = 0x20, /**< External timecode */ | |||||
| JackBBTFrameOffset = 0x40, /**< Frame offset of BBT information */ | |||||
| JackAudioVideoRatio = 0x80, /**< audio frames per video frame */ | |||||
| JackVideoFrameOffset = 0x100 /**< frame offset of first video frame */ | |||||
| JackPositionBBT = 0x10, /**< Bar, Beat, Tick */ | |||||
| JackPositionTimecode = 0x20, /**< External timecode */ | |||||
| JackBBTFrameOffset = 0x40, /**< Frame offset of BBT information */ | |||||
| JackAudioVideoRatio = 0x80, /**< audio frames per video frame */ | |||||
| JackVideoFrameOffset = 0x100, /**< frame offset of first video frame */ | |||||
| JackTickDouble = 0x200, /**< double-resolution tick */ | |||||
| } jack_position_bits_t; | } jack_position_bits_t; | ||||
| @@ -550,6 +551,9 @@ typedef enum { | |||||
| #define JACK_POSITION_MASK (JackPositionBBT|JackPositionTimecode) | #define JACK_POSITION_MASK (JackPositionBBT|JackPositionTimecode) | ||||
| #define EXTENDED_TIME_INFO | #define EXTENDED_TIME_INFO | ||||
| /** transport tick_double member is available for use */ | |||||
| #define JACK_TICK_DOUBLE | |||||
| PRE_PACKED_STRUCTURE | PRE_PACKED_STRUCTURE | ||||
| struct _jack_position { | struct _jack_position { | ||||
| @@ -609,10 +613,18 @@ struct _jack_position { | |||||
| set, but the value is zero, there is | set, but the value is zero, there is | ||||
| no video frame within this cycle. */ | no video frame within this cycle. */ | ||||
| /* JACK extra transport fields */ | |||||
| double tick_double; /**< current tick-within-beat in double resolution. | |||||
| Should be assumed zero if JackTickDouble is not set. | |||||
| Since older versions of JACK do not expose this variable, | |||||
| the macro JACK_TICK_DOUBLE is provided, | |||||
| which can be used as build-time detection. */ | |||||
| /* For binary compatibility, new fields should be allocated from | /* For binary compatibility, new fields should be allocated from | ||||
| * this padding area with new valid bits controlling access, so | * this padding area with new valid bits controlling access, so | ||||
| * the existing structure size and offsets are preserved. */ | * the existing structure size and offsets are preserved. */ | ||||
| int32_t padding[7]; | |||||
| int32_t padding[5]; | |||||
| /* When (unique_1 == unique_2) the contents are consistent. */ | /* When (unique_1 == unique_2) the contents are consistent. */ | ||||
| jack_unique_t unique_2; /**< unique ID */ | jack_unique_t unique_2; /**< unique ID */ | ||||
| @@ -792,7 +792,7 @@ HTML_HEADER = | |||||
| # each generated HTML page. If it is left blank doxygen will generate a | # each generated HTML page. If it is left blank doxygen will generate a | ||||
| # standard footer. | # standard footer. | ||||
| HTML_FOOTER = @SRCDIR@/no_date_footer.html | |||||
| HTML_FOOTER = | |||||
| # The HTML_STYLESHEET tag can be used to specify a user-defined cascading | # The HTML_STYLESHEET tag can be used to specify a user-defined cascading | ||||
| # style sheet that is used by each HTML page. It can be used to | # style sheet that is used by each HTML page. It can be used to | ||||
| @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
| #define __JackAtomic_APPLE__ | #define __JackAtomic_APPLE__ | ||||
| #include "JackTypes.h" | #include "JackTypes.h" | ||||
| #include <cassert> | |||||
| #if defined(__ppc__) || defined(__ppc64__) | #if defined(__ppc__) || defined(__ppc64__) | ||||
| @@ -67,8 +68,11 @@ static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* ad | |||||
| #else | #else | ||||
| #include <stdio.h> | |||||
| static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) | static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) | ||||
| { | { | ||||
| // Assert pointer is 32-bit aligned | |||||
| assert(((long)addr & (sizeof(int)-1)) == 0); | |||||
| return __sync_bool_compare_and_swap ((UInt32*)addr, value, newvalue); | return __sync_bool_compare_and_swap ((UInt32*)addr, value, newvalue); | ||||
| } | } | ||||
| @@ -53,7 +53,7 @@ | |||||
| typedef struct | typedef struct | ||||
| { | { | ||||
| jack_nframes_t ft; // running counter frame time | jack_nframes_t ft; // running counter frame time | ||||
| jack_nframes_t fcs; // from sycle start... | |||||
| jack_nframes_t fcs; // from cycle start... | |||||
| jack_nframes_t lft; // last frame time... | jack_nframes_t lft; // last frame time... | ||||
| } | } | ||||
| FrameTimeCollector; | FrameTimeCollector; | ||||
| @@ -193,7 +193,7 @@ void Jackclient::initsync (void) | |||||
| _resamp->out_count = 99999; | _resamp->out_count = 99999; | ||||
| _resamp->process (); | _resamp->process (); | ||||
| } | } | ||||
| // Initiliase state variables. | |||||
| // Initialise state variables. | |||||
| _t_a0 = _t_a1 = 0; | _t_a0 = _t_a1 = 0; | ||||
| _k_a0 = _k_a1 = 0; | _k_a0 = _k_a1 = 0; | ||||
| // Initialise loop filter state. | // Initialise loop filter state. | ||||
| @@ -520,7 +520,7 @@ class Context(ctx): | |||||
| """ | """ | ||||
| Prints a configuration message of the form ``msg: result``. | Prints a configuration message of the form ``msg: result``. | ||||
| The second part of the message will be in colors. The output | The second part of the message will be in colors. The output | ||||
| can be disabled easly by setting ``in_msg`` to a positive value:: | |||||
| can be disabled easily by setting ``in_msg`` to a positive value:: | |||||
| def configure(conf): | def configure(conf): | ||||
| self.in_msg = 1 | self.in_msg = 1 | ||||
| @@ -11,7 +11,7 @@ import sys | |||||
| from waflib import Logs, Options, Task, Utils | from waflib import Logs, Options, Task, Utils | ||||
| from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext | from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext | ||||
| VERSION='1.9.18' | |||||
| VERSION='1.9.19' | |||||
| APPNAME='jack' | APPNAME='jack' | ||||
| JACK_API_VERSION = '0.1.0' | JACK_API_VERSION = '0.1.0' | ||||
| @@ -228,7 +228,7 @@ def configure(conf): | |||||
| mandatory=False) | mandatory=False) | ||||
| conf.env.append_unique('CFLAGS', '-Wall') | conf.env.append_unique('CFLAGS', '-Wall') | ||||
| conf.env.append_unique('CXXFLAGS', '-Wall') | |||||
| conf.env.append_unique('CXXFLAGS', ['-Wall', '-Wno-invalid-offsetof']) | |||||
| conf.env.append_unique('CXXFLAGS', '-std=gnu++11') | conf.env.append_unique('CXXFLAGS', '-std=gnu++11') | ||||
| if not conf.env['IS_MACOSX']: | if not conf.env['IS_MACOSX']: | ||||