| @@ -0,0 +1,42 @@ | |||
| MAINTAINERCLEANFILES = Makefile.in version.h | |||
| libjackincludedir = $(includedir)/jack | |||
| libjackinclude_HEADERS = \ | |||
| intclient.h \ | |||
| jack.h \ | |||
| ringbuffer.h \ | |||
| statistics.h \ | |||
| session.h \ | |||
| thread.h \ | |||
| timestamps.h \ | |||
| transport.h \ | |||
| types.h \ | |||
| midiport.h \ | |||
| weakmacros.h \ | |||
| weakjack.h \ | |||
| control.h \ | |||
| jslist.h | |||
| noinst_HEADERS = \ | |||
| atomicity.h \ | |||
| bitset.h \ | |||
| driver.h \ | |||
| driver_interface.h \ | |||
| driver_parse.h \ | |||
| engine.h \ | |||
| hardware.h \ | |||
| internal.h \ | |||
| intsimd.h \ | |||
| memops.h \ | |||
| messagebuffer.h \ | |||
| pool.h \ | |||
| port.h \ | |||
| ringbuffer.h \ | |||
| sanitycheck.h \ | |||
| shm.h \ | |||
| start.h \ | |||
| systemtest.h \ | |||
| unlock.h \ | |||
| varargs.h \ | |||
| version.h | |||
| @@ -0,0 +1,38 @@ | |||
| /* | |||
| Copyright (C) 2004 Jack O'Quin | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __jack_atomicity_h__ | |||
| #define __jack_atomicity_h__ | |||
| /* | |||
| * Interface with various machine-dependent headers derived from the | |||
| * gcc/libstdc++.v3 sources. We try to modify the GCC sources as | |||
| * little as possible. The following include is resolved using the | |||
| * config/configure.hosts mechanism. It will use an OS-dependent | |||
| * version if available, otherwise the one for this CPU. Some of | |||
| * these files might not work with older GCC compilers. | |||
| */ | |||
| #include <sysdeps/atomicity.h> | |||
| /* These functions are defined for each platform. The C++ library | |||
| * function names start with "__" to avoid namespace pollution. */ | |||
| #define exchange_and_add __exchange_and_add | |||
| #define atomic_add __atomic_add | |||
| #endif /* __jack_atomicity_h__ */ | |||
| @@ -0,0 +1,111 @@ | |||
| /* | |||
| * bitset.h -- some simple bit vector set operations. | |||
| * | |||
| * This is useful for sets of small non-negative integers. There are | |||
| * some obvious set operations that are not implemented because I | |||
| * don't need them right now. | |||
| * | |||
| * These functions represent sets as arrays of unsigned 32-bit | |||
| * integers allocated on the heap. The first entry contains the set | |||
| * cardinality (number of elements allowed), followed by one or more | |||
| * words containing bit vectors. | |||
| * | |||
| */ | |||
| /* | |||
| * Copyright (C) 2005 Jack O'Quin | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 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 | |||
| * General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU General Public License | |||
| * along with this program; if not, write to the Free Software | |||
| * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __bitset_h__ | |||
| #define __bitset_h__ | |||
| #include <inttypes.h> /* POSIX standard fixed-size types */ | |||
| #include <assert.h> /* `#define NDEBUG' to disable */ | |||
| /* On some 64-bit machines, this implementation may be slightly | |||
| * inefficient, depending on how compilers allocate space for | |||
| * uint32_t. For the set sizes I currently need, this is acceptable. | |||
| * It should not be hard to pack the bits better, if that becomes | |||
| * worthwhile. | |||
| */ | |||
| typedef uint32_t _bitset_word_t; | |||
| typedef _bitset_word_t *bitset_t; | |||
| #define WORD_SIZE(cardinality) (1+((cardinality)+31)/32) | |||
| #define BYTE_SIZE(cardinality) (WORD_SIZE(cardinality)*sizeof(_bitset_word_t)) | |||
| #define WORD_INDEX(element) (1+(element)/32) | |||
| #define BIT_INDEX(element) ((element)&037) | |||
| static inline void | |||
| bitset_add(bitset_t set, unsigned int element) | |||
| { | |||
| assert(element < set[0]); | |||
| set[WORD_INDEX(element)] |= (1 << BIT_INDEX(element)); | |||
| } | |||
| static inline void | |||
| bitset_copy(bitset_t to_set, bitset_t from_set) | |||
| { | |||
| assert(to_set[0] == from_set[0]); | |||
| memcpy(to_set, from_set, BYTE_SIZE(to_set[0])); | |||
| } | |||
| static inline void | |||
| bitset_create(bitset_t *set, unsigned int cardinality) | |||
| { | |||
| *set = (bitset_t) calloc(WORD_SIZE(cardinality), | |||
| sizeof(_bitset_word_t)); | |||
| assert(*set); | |||
| *set[0] = cardinality; | |||
| } | |||
| static inline void | |||
| bitset_destroy(bitset_t *set) | |||
| { | |||
| if (*set) { | |||
| free(*set); | |||
| *set = (bitset_t) 0; | |||
| } | |||
| } | |||
| static inline int | |||
| bitset_empty(bitset_t set) | |||
| { | |||
| int i; | |||
| _bitset_word_t result = 0; | |||
| int nwords = WORD_SIZE(set[0]); | |||
| for (i = 1; i < nwords; i++) { | |||
| result |= set[i]; | |||
| } | |||
| return (result == 0); | |||
| } | |||
| static inline int | |||
| bitset_contains(bitset_t set, unsigned int element) | |||
| { | |||
| assert(element < set[0]); | |||
| return (0 != (set[WORD_INDEX(element)] & (1<<BIT_INDEX(element)))); | |||
| } | |||
| static inline void | |||
| bitset_remove(bitset_t set, unsigned int element) | |||
| { | |||
| assert(element < set[0]); | |||
| set[WORD_INDEX(element)] &= ~(1<<BIT_INDEX(element)); | |||
| } | |||
| #endif /* __bitset_h__ */ | |||
| @@ -0,0 +1,565 @@ | |||
| /* -*- Mode: C ; c-basic-offset: 4 -*- */ | |||
| /* | |||
| JACK control API | |||
| Copyright (C) 2008 Nedko Arnaudov | |||
| Copyright (C) 2008 GRAME | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; version 2 of the License. | |||
| 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| /** | |||
| * @file jack/control.h | |||
| * @ingroup publicheader | |||
| * @brief JACK control API | |||
| * | |||
| */ | |||
| #ifndef JACKCTL_H__2EEDAD78_DF4C_4B26_83B7_4FF1A446A47E__INCLUDED | |||
| #define JACKCTL_H__2EEDAD78_DF4C_4B26_83B7_4FF1A446A47E__INCLUDED | |||
| #include <jack/jslist.h> | |||
| #if !defined (__sun__) | |||
| #include <stdbool.h> | |||
| #endif | |||
| /** Parameter types, intentionally similar to jack_driver_param_type_t */ | |||
| typedef enum | |||
| { | |||
| JackParamInt = 1, /**< @brief value type is a signed integer */ | |||
| JackParamUInt, /**< @brief value type is an unsigned integer */ | |||
| JackParamChar, /**< @brief value type is a char */ | |||
| JackParamString, /**< @brief value type is a string with max size of ::JACK_PARAM_STRING_MAX+1 chars */ | |||
| JackParamBool, /**< @brief value type is a boolean */ | |||
| } jackctl_param_type_t; | |||
| /** @brief Max value that jackctl_param_type_t type can have */ | |||
| #define JACK_PARAM_MAX (JackParamBool + 1) | |||
| /** @brief Max length of string parameter value, excluding terminating null char */ | |||
| #define JACK_PARAM_STRING_MAX 127 | |||
| /** @brief Type for parameter value */ | |||
| /* intentionally similar to jack_driver_param_value_t */ | |||
| union jackctl_parameter_value | |||
| { | |||
| uint32_t ui; /**< @brief member used for ::JackParamUInt */ | |||
| int32_t i; /**< @brief member used for ::JackParamInt */ | |||
| char c; /**< @brief member used for ::JackParamChar */ | |||
| char str[JACK_PARAM_STRING_MAX + 1]; /**< @brief member used for ::JackParamString */ | |||
| bool b; /**< @brief member used for ::JackParamBool */ | |||
| }; | |||
| /** opaque type for server object */ | |||
| typedef struct jackctl_server jackctl_server_t; | |||
| /** opaque type for driver object */ | |||
| typedef struct jackctl_driver jackctl_driver_t; | |||
| /** opaque type for internal client object */ | |||
| typedef struct jackctl_internal jackctl_internal_t; | |||
| /** opaque type for parameter object */ | |||
| typedef struct jackctl_parameter jackctl_parameter_t; | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| #if 0 | |||
| } /* Adjust editor indent */ | |||
| #endif | |||
| /** | |||
| * @defgroup ControlAPI the API for starting and controlling a JACK server | |||
| * @{ | |||
| */ | |||
| /** | |||
| * Call this function to setup process signal handling. As a general | |||
| * rule, it is required for proper operation for the server object. | |||
| * | |||
| * @param flags signals setup flags, use 0 for none. Currently no | |||
| * flags are defined | |||
| * | |||
| * @return the configurated signal set. | |||
| */ | |||
| sigset_t | |||
| jackctl_setup_signals( | |||
| unsigned int flags); | |||
| /** | |||
| * Call this function to wait on a signal set. | |||
| * | |||
| * @param signals signals set to wait on | |||
| */ | |||
| void | |||
| jackctl_wait_signals( | |||
| sigset_t signals); | |||
| /** | |||
| * Call this function to create server object. | |||
| * | |||
| * @param on_device_acquire - Optional callback to be called before device is acquired. If false is returned, device usage will fail | |||
| * @param on_device_release - Optional callback to be called after device is released. | |||
| * | |||
| * @return server object handle, NULL if creation of server object | |||
| * failed. Successfully created server object must be destroyed with | |||
| * paired call to ::jackctl_server_destroy | |||
| */ | |||
| jackctl_server_t * | |||
| jackctl_server_create( | |||
| bool (* on_device_acquire)(const char * device_name), | |||
| void (* on_device_release)(const char * device_name)); | |||
| /** | |||
| * Call this function to destroy server object. | |||
| * | |||
| * @param server server object handle to destroy | |||
| */ | |||
| void | |||
| jackctl_server_destroy( | |||
| jackctl_server_t * server); | |||
| /** | |||
| * Call this function to start JACK server | |||
| * | |||
| * @param server server object handle | |||
| * @param driver driver to use | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| jackctl_server_start( | |||
| jackctl_server_t * server, | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| * Call this function to stop JACK server | |||
| * | |||
| * @param server server object handle | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| jackctl_server_stop( | |||
| jackctl_server_t * server); | |||
| /** | |||
| * Call this function to get list of available drivers. List node data | |||
| * pointers is a driver object handle (::jackctl_driver_t). | |||
| * | |||
| * @param server server object handle to get drivers for | |||
| * | |||
| * @return Single linked list of driver object handles. Must not be | |||
| * modified. Always same for same server object. | |||
| */ | |||
| const JSList * | |||
| jackctl_server_get_drivers_list( | |||
| jackctl_server_t * server); | |||
| /** | |||
| * Call this function to get list of server parameters. List node data | |||
| * pointers is a parameter object handle (::jackctl_parameter_t). | |||
| * | |||
| * @param server server object handle to get parameters for | |||
| * | |||
| * @return Single linked list of parameter object handles. Must not be | |||
| * modified. Always same for same server object. | |||
| */ | |||
| const JSList * | |||
| jackctl_server_get_parameters( | |||
| jackctl_server_t * server); | |||
| /** | |||
| * Call this function to get list of available internal clients. List node data | |||
| * pointers is a internal client object handle (::jackctl_internal_t). | |||
| * | |||
| * @param server server object handle to get internal clients for | |||
| * | |||
| * @return Single linked list of internal client object handles. Must not be | |||
| * modified. Always same for same server object. | |||
| */ | |||
| const JSList * | |||
| jackctl_server_get_internals_list( | |||
| jackctl_server_t * server); | |||
| /** | |||
| * Call this function to load one internal client. | |||
| * | |||
| * @param server server object handle | |||
| * @param internal internal to use | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| jackctl_server_load_internal( | |||
| jackctl_server_t * server, | |||
| jackctl_internal_t * internal); | |||
| /** | |||
| * Call this function to unload one internal client. | |||
| * | |||
| * @param server server object handle | |||
| * @param internal internal to unload | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| jackctl_server_unload_internal( | |||
| jackctl_server_t * server, | |||
| jackctl_internal_t * internal); | |||
| /** | |||
| * Call this function to add a slave in the driver slave list. | |||
| * | |||
| * @param server server object handle | |||
| * @param driver driver to add in the driver slave list. | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| jackctl_server_add_slave(jackctl_server_t * server, | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| * Call this function to remove a slave from the driver slave list. | |||
| * | |||
| * @param server server object handle | |||
| * @param driver driver to remove from the driver slave list. | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| jackctl_server_remove_slave(jackctl_server_t * server, | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| * Call this function to switch master driver. | |||
| * | |||
| * @param server server object handle | |||
| * @param driver driver to switch to | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| jackctl_server_switch_master(jackctl_server_t * server, | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| * Call this function to get name of driver. | |||
| * | |||
| * @param driver driver object handle to get name of | |||
| * | |||
| * @return driver name. Must not be modified. Always same for same | |||
| * driver object. | |||
| */ | |||
| const char * | |||
| jackctl_driver_get_name( | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| * Call this function to get list of driver parameters. List node data | |||
| * pointers is a parameter object handle (::jackctl_parameter_t). | |||
| * | |||
| * @param driver driver object handle to get parameters for | |||
| * | |||
| * @return Single linked list of parameter object handles. Must not be | |||
| * modified. Always same for same driver object. | |||
| */ | |||
| const JSList * | |||
| jackctl_driver_get_parameters( | |||
| jackctl_driver_t * driver); | |||
| /** | |||
| * Call this function to get name of internal client. | |||
| * | |||
| * @param internal internal object handle to get name of | |||
| * | |||
| * @return internal name. Must not be modified. Always same for same | |||
| * internal object. | |||
| */ | |||
| const char * | |||
| jackctl_internal_get_name( | |||
| jackctl_internal_t * internal); | |||
| /** | |||
| * Call this function to get list of internal parameters. List node data | |||
| * pointers is a parameter object handle (::jackctl_parameter_t). | |||
| * | |||
| * @param internal internal object handle to get parameters for | |||
| * | |||
| * @return Single linked list of parameter object handles. Must not be | |||
| * modified. Always same for same internal object. | |||
| */ | |||
| const JSList * | |||
| jackctl_internal_get_parameters( | |||
| jackctl_internal_t * internal); | |||
| /** | |||
| * Call this function to get parameter name. | |||
| * | |||
| * @param parameter parameter object handle to get name of | |||
| * | |||
| * @return parameter name. Must not be modified. Always same for same | |||
| * parameter object. | |||
| */ | |||
| const char * | |||
| jackctl_parameter_get_name( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to get parameter short description. | |||
| * | |||
| * @param parameter parameter object handle to get short description of | |||
| * | |||
| * @return parameter short description. Must not be modified. Always | |||
| * same for same parameter object. | |||
| */ | |||
| const char * | |||
| jackctl_parameter_get_short_description( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to get parameter long description. | |||
| * | |||
| * @param parameter parameter object handle to get long description of | |||
| * | |||
| * @return parameter long description. Must not be modified. Always | |||
| * same for same parameter object. | |||
| */ | |||
| const char * | |||
| jackctl_parameter_get_long_description( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to get parameter type. | |||
| * | |||
| * @param parameter parameter object handle to get type of | |||
| * | |||
| * @return parameter type. Always same for same parameter object. | |||
| */ | |||
| jackctl_param_type_t | |||
| jackctl_parameter_get_type( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to get parameter character. | |||
| * | |||
| * @param parameter parameter object handle to get character of | |||
| * | |||
| * @return character. | |||
| */ | |||
| char | |||
| jackctl_parameter_get_id( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to check whether parameter has been set, or its | |||
| * default value is being used. | |||
| * | |||
| * @param parameter parameter object handle to check | |||
| * | |||
| * @return true - parameter is set, false - parameter is using default | |||
| * value. | |||
| */ | |||
| bool | |||
| jackctl_parameter_is_set( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to reset parameter to its default value. | |||
| * | |||
| * @param parameter parameter object handle to reset value of | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| jackctl_parameter_reset( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to get parameter value. | |||
| * | |||
| * @param parameter parameter object handle to get value of | |||
| * | |||
| * @return parameter value. | |||
| */ | |||
| union jackctl_parameter_value | |||
| jackctl_parameter_get_value( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to set parameter value. | |||
| * | |||
| * @param parameter parameter object handle to get value of | |||
| * @param value_ptr pointer to variable containing parameter value | |||
| * | |||
| * @return success status: true - success, false - fail | |||
| */ | |||
| bool | |||
| jackctl_parameter_set_value( | |||
| jackctl_parameter_t * parameter, | |||
| const union jackctl_parameter_value * value_ptr); | |||
| /** | |||
| * Call this function to get parameter default value. | |||
| * | |||
| * @param parameter parameter object handle to get default value of | |||
| * | |||
| * @return parameter default value. | |||
| */ | |||
| union jackctl_parameter_value | |||
| jackctl_parameter_get_default_value( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function check whether parameter has range constraint. | |||
| * | |||
| * @param parameter object handle of parameter to check | |||
| * | |||
| * @return whether parameter has range constraint. | |||
| */ | |||
| bool | |||
| jackctl_parameter_has_range_constraint( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function check whether parameter has enumeration constraint. | |||
| * | |||
| * @param parameter object handle of parameter to check | |||
| * | |||
| * @return whether parameter has enumeration constraint. | |||
| */ | |||
| bool | |||
| jackctl_parameter_has_enum_constraint( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function get how many enumeration values parameter has. | |||
| * | |||
| * @param parameter object handle of parameter | |||
| * | |||
| * @return number of enumeration values | |||
| */ | |||
| uint32_t | |||
| jackctl_parameter_get_enum_constraints_count( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to get parameter enumeration value. | |||
| * | |||
| * @param parameter object handle of parameter | |||
| * @param index index of parameter enumeration value | |||
| * | |||
| * @return enumeration value. | |||
| */ | |||
| union jackctl_parameter_value | |||
| jackctl_parameter_get_enum_constraint_value( | |||
| jackctl_parameter_t * parameter, | |||
| uint32_t index); | |||
| /** | |||
| * Call this function to get parameter enumeration value description. | |||
| * | |||
| * @param parameter object handle of parameter | |||
| * @param index index of parameter enumeration value | |||
| * | |||
| * @return enumeration value description. | |||
| */ | |||
| const char * | |||
| jackctl_parameter_get_enum_constraint_description( | |||
| jackctl_parameter_t * parameter, | |||
| uint32_t index); | |||
| /** | |||
| * Call this function to get parameter range. | |||
| * | |||
| * @param parameter object handle of parameter | |||
| * @param min_ptr pointer to variable receiving parameter minimum value | |||
| * @param max_ptr pointer to variable receiving parameter maximum value | |||
| */ | |||
| void | |||
| jackctl_parameter_get_range_constraint( | |||
| jackctl_parameter_t * parameter, | |||
| union jackctl_parameter_value * min_ptr, | |||
| union jackctl_parameter_value * max_ptr); | |||
| /** | |||
| * Call this function to check whether parameter constraint is strict, | |||
| * i.e. whether supplying non-matching value will not work for sure. | |||
| * | |||
| * @param parameter parameter object handle to check | |||
| * | |||
| * @return whether parameter constraint is strict. | |||
| */ | |||
| bool | |||
| jackctl_parameter_constraint_is_strict( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to check whether parameter has fake values, | |||
| * i.e. values have no user meaningful meaning and only value | |||
| * description is meaningful to user. | |||
| * | |||
| * @param parameter parameter object handle to check | |||
| * | |||
| * @return whether parameter constraint is strict. | |||
| */ | |||
| bool | |||
| jackctl_parameter_constraint_is_fake_value( | |||
| jackctl_parameter_t * parameter); | |||
| /** | |||
| * Call this function to log an error message. | |||
| * | |||
| * @param format string | |||
| */ | |||
| void | |||
| jack_error( | |||
| const char *format, | |||
| ...); | |||
| /** | |||
| * Call this function to log an information message. | |||
| * | |||
| * @param format string | |||
| */ | |||
| void | |||
| jack_info( | |||
| const char *format, | |||
| ...); | |||
| /** | |||
| * Call this function to log an information message but only when | |||
| * verbose mode is enabled. | |||
| * | |||
| * @param format string | |||
| */ | |||
| void | |||
| jack_log( | |||
| const char *format, | |||
| ...); | |||
| /* @} */ | |||
| #if 0 | |||
| { /* Adjust editor indent */ | |||
| #endif | |||
| #ifdef __cplusplus | |||
| } /* extern "C" */ | |||
| #endif | |||
| #endif /* #ifndef JACKCTL_H__2EEDAD78_DF4C_4B26_83B7_4FF1A446A47E__INCLUDED */ | |||
| @@ -0,0 +1,304 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __jack_driver_h__ | |||
| #define __jack_driver_h__ | |||
| #include <pthread.h> | |||
| #include <jack/types.h> | |||
| #include <jack/port.h> | |||
| #include <jack/driver_interface.h> | |||
| typedef float gain_t; | |||
| typedef unsigned long channel_t; | |||
| typedef enum { | |||
| Lock = 0x1, | |||
| NoLock = 0x2, | |||
| Sync = 0x4, | |||
| NoSync = 0x8 | |||
| } ClockSyncStatus; | |||
| typedef void (*ClockSyncListenerFunction)(channel_t,ClockSyncStatus,void*); | |||
| typedef struct { | |||
| unsigned long id; | |||
| ClockSyncListenerFunction function; | |||
| void *arg; | |||
| } ClockSyncListener; | |||
| struct _jack_engine; | |||
| struct _jack_driver; | |||
| typedef int (*JackDriverAttachFunction)(struct _jack_driver *, | |||
| struct _jack_engine *); | |||
| typedef int (*JackDriverDetachFunction)(struct _jack_driver *, | |||
| struct _jack_engine *); | |||
| typedef int (*JackDriverReadFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverWriteFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverNullCycleFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverStopFunction)(struct _jack_driver *); | |||
| typedef int (*JackDriverStartFunction)(struct _jack_driver *); | |||
| typedef int (*JackDriverBufSizeFunction)(struct _jack_driver *, | |||
| jack_nframes_t nframes); | |||
| /* | |||
| Call sequence summary: | |||
| 1) engine loads driver via runtime dynamic linking | |||
| - calls jack_driver_load | |||
| - we call dlsym for "driver_initialize" and execute it | |||
| 2) engine attaches to driver | |||
| 3) engine starts driver | |||
| 4) driver runs its own thread, calling | |||
| while () { | |||
| driver->wait (); | |||
| driver->engine->run_cycle () | |||
| } | |||
| 5) engine stops driver | |||
| 6) engine detaches from driver | |||
| 7) engine calls driver `finish' routine | |||
| Note that stop/start may be called multiple times in the event of an | |||
| error return from the `wait' function. | |||
| */ | |||
| typedef struct _jack_driver { | |||
| /* The _jack_driver structure fields are included at the beginning of | |||
| each driver-specific structure using the JACK_DRIVER_DECL macro, | |||
| which is defined below. The comments that follow describe each | |||
| common field. | |||
| The driver should set this to be the interval it expects to elapse | |||
| between returning from the `wait' function. if set to zero, it | |||
| implies that the driver does not expect regular periodic wakeups. | |||
| jack_time_t period_usecs; | |||
| The driver should set this within its "wait" function to indicate | |||
| the UST of the most recent determination that the engine cycle | |||
| should run. it should not be set if the "extra_fd" argument of | |||
| the wait function is set to a non-zero value. | |||
| jack_time_t last_wait_ust; | |||
| These are not used by the driver. They should not be written to or | |||
| modified in any way | |||
| void *handle; | |||
| struct _jack_internal_client *internal_client; | |||
| This should perform any cleanup associated with the driver. it will | |||
| be called when jack server process decides to get rid of the | |||
| driver. in some systems, it may not be called at all, so the driver | |||
| should never rely on a call to this. it can set it to NULL if | |||
| it has nothing do do. | |||
| void (*finish)(struct _jack_driver *); | |||
| The JACK engine will call this when it wishes to attach itself to | |||
| the driver. the engine will pass a pointer to itself, which the driver | |||
| may use in anyway it wishes to. the driver may assume that this | |||
| is the same engine object that will make `wait' calls until a | |||
| `detach' call is made. | |||
| JackDriverAttachFunction attach; | |||
| The JACK engine will call this when it is finished using a driver. | |||
| JackDriverDetachFunction detach; | |||
| The JACK engine will call this when it wants to wait until the | |||
| driver decides that its time to process some data. the driver returns | |||
| a count of the number of audioframes that can be processed. | |||
| it should set the variable pointed to by `status' as follows: | |||
| zero: the wait completed normally, processing may begin | |||
| negative: the wait failed, and recovery is not possible | |||
| positive: the wait failed, and the driver stopped itself. | |||
| a call to `start' will return the driver to | |||
| a correct and known state. | |||
| the driver should also fill out the `delayed_usecs' variable to | |||
| indicate any delay in its expected periodic execution. for example, | |||
| if it discovers that its return from poll(2) is later than it | |||
| expects it to be, it would place an estimate of the delay | |||
| in this variable. the engine will use this to decide if it | |||
| plans to continue execution. | |||
| JackDriverWaitFunction wait; | |||
| The JACK engine will call this to ask the driver to move | |||
| data from its inputs to its output port buffers. it should | |||
| return 0 to indicate successful completion, negative otherwise. | |||
| This function will always be called after the wait function (above). | |||
| JackDriverReadFunction read; | |||
| The JACK engine will call this to ask the driver to move | |||
| data from its input port buffers to its outputs. it should | |||
| return 0 to indicate successful completion, negative otherwise. | |||
| this function will always be called after the read function (above). | |||
| JackDriverWriteFunction write; | |||
| The JACK engine will call this after the wait function (above) has | |||
| been called, but for some reason the engine is unable to execute | |||
| a full "cycle". the driver should do whatever is necessary to | |||
| keep itself running correctly, but cannot reference ports | |||
| or other JACK data structures in any way. | |||
| JackDriverNullCycleFunction null_cycle; | |||
| The engine will call this when it plans to stop calling the `wait' | |||
| function for some period of time. the driver should take | |||
| appropriate steps to handle this (possibly no steps at all). | |||
| NOTE: the driver must silence its capture buffers (if any) | |||
| from within this function or the function that actually | |||
| implements the change in state. | |||
| JackDriverStopFunction stop; | |||
| The engine will call this to let the driver know that it plans | |||
| to start calling the `wait' function on a regular basis. the driver | |||
| should take any appropriate steps to handle this (possibly no steps | |||
| at all). NOTE: The driver may wish to silence its playback buffers | |||
| (if any) from within this function or the function that actually | |||
| implements the change in state. | |||
| JackDriverStartFunction start; | |||
| The engine will call this to let the driver know that some client | |||
| has requested a new buffer size. The stop function will be called | |||
| prior to this, and the start function after this one has returned. | |||
| JackDriverBufSizeFunction bufsize; | |||
| */ | |||
| /* define the fields here... */ | |||
| #define JACK_DRIVER_DECL \ | |||
| jack_time_t period_usecs; \ | |||
| jack_time_t last_wait_ust; \ | |||
| void *handle; \ | |||
| struct _jack_client_internal * internal_client; \ | |||
| void (*finish)(struct _jack_driver *);\ | |||
| JackDriverAttachFunction attach; \ | |||
| JackDriverDetachFunction detach; \ | |||
| JackDriverReadFunction read; \ | |||
| JackDriverWriteFunction write; \ | |||
| JackDriverNullCycleFunction null_cycle; \ | |||
| JackDriverStopFunction stop; \ | |||
| JackDriverStartFunction start; \ | |||
| JackDriverBufSizeFunction bufsize; | |||
| JACK_DRIVER_DECL /* expand the macro */ | |||
| } jack_driver_t; | |||
| typedef jack_driver_desc_t * (*JackDriverDescFunction) (); | |||
| void jack_driver_init (jack_driver_t *); | |||
| void jack_driver_release (jack_driver_t *); | |||
| jack_driver_t *jack_driver_load (int argc, char **argv); | |||
| void jack_driver_unload (jack_driver_t *); | |||
| /**************************** | |||
| *** Non-Threaded Drivers *** | |||
| ****************************/ | |||
| /* | |||
| Call sequence summary: | |||
| 1) engine loads driver via runtime dynamic linking | |||
| - calls jack_driver_load | |||
| - we call dlsym for "driver_initialize" and execute it | |||
| - driver_initialize calls jack_driver_nt_init | |||
| 2) nt layer attaches to driver | |||
| 3) nt layer starts driver | |||
| 4) nt layer runs a thread, calling | |||
| while () { | |||
| driver->nt_run_ctcle(); | |||
| } | |||
| 5) nt layer stops driver | |||
| 6) nt layer detaches driver | |||
| 7) engine calls driver `finish' routine which calls jack_driver_nt_finish | |||
| Note that stop/start may be called multiple times in the event of an | |||
| error return from the `wait' function. | |||
| */ | |||
| struct _jack_driver_nt; | |||
| typedef int (*JackDriverNTAttachFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTDetachFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTStopFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTStartFunction)(struct _jack_driver_nt *); | |||
| typedef int (*JackDriverNTBufSizeFunction)(struct _jack_driver_nt *, | |||
| jack_nframes_t nframes); | |||
| typedef int (*JackDriverNTRunCycleFunction)(struct _jack_driver_nt *); | |||
| typedef struct _jack_driver_nt { | |||
| #define JACK_DRIVER_NT_DECL \ | |||
| JACK_DRIVER_DECL \ | |||
| struct _jack_engine * engine; \ | |||
| volatile int nt_run; \ | |||
| pthread_t nt_thread; \ | |||
| pthread_mutex_t nt_run_lock; \ | |||
| JackDriverNTAttachFunction nt_attach; \ | |||
| JackDriverNTDetachFunction nt_detach; \ | |||
| JackDriverNTStopFunction nt_stop; \ | |||
| JackDriverNTStartFunction nt_start; \ | |||
| JackDriverNTBufSizeFunction nt_bufsize; \ | |||
| JackDriverNTRunCycleFunction nt_run_cycle; | |||
| #define nt_read read | |||
| #define nt_write write | |||
| #define nt_null_cycle null_cycle | |||
| JACK_DRIVER_NT_DECL | |||
| } jack_driver_nt_t; | |||
| void jack_driver_nt_init (jack_driver_nt_t * driver); | |||
| void jack_driver_nt_finish (jack_driver_nt_t * driver); | |||
| #endif /* __jack_driver_h__ */ | |||
| @@ -0,0 +1,123 @@ | |||
| /* | |||
| Copyright (C) 2003 Bob Ham <rah@bash.sh> | |||
| 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 __jack_driver_interface_h__ | |||
| #define __jack_driver_interface_h__ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| #include <limits.h> | |||
| #include <jack/jack.h> | |||
| #include <jack/internal.h> | |||
| #define JACK_DRIVER_NAME_MAX 15 | |||
| #define JACK_DRIVER_PARAM_NAME_MAX 15 | |||
| #define JACK_DRIVER_PARAM_STRING_MAX 63 | |||
| #define JACK_CONSTRAINT_FLAG_RANGE ((uint32_t)1) /**< if set, constraint is a range (min-max) */ | |||
| #define JACK_CONSTRAINT_FLAG_STRICT ((uint32_t)2) /**< if set, constraint is strict, i.e. supplying non-matching value will not work */ | |||
| #define JACK_CONSTRAINT_FLAG_FAKE_VALUE ((uint32_t)4) /**< if set, values have no user meaningful meaning */ | |||
| /** Driver parameter types */ | |||
| typedef enum | |||
| { | |||
| JackDriverParamInt = 1, | |||
| JackDriverParamUInt, | |||
| JackDriverParamChar, | |||
| JackDriverParamString, | |||
| JackDriverParamBool | |||
| } jack_driver_param_type_t; | |||
| /** Driver parameter value */ | |||
| typedef union | |||
| { | |||
| uint32_t ui; | |||
| int32_t i; | |||
| char c; | |||
| char str[JACK_DRIVER_PARAM_STRING_MAX+1]; | |||
| } jack_driver_param_value_t; | |||
| typedef struct { | |||
| jack_driver_param_value_t value; | |||
| char short_desc[64]; /**< A short (~30 chars) description for the user */ | |||
| } jack_driver_param_value_enum_t; | |||
| typedef struct { | |||
| uint32_t flags; /**< JACK_CONSTRAINT_FLAG_XXX */ | |||
| union { | |||
| struct { | |||
| jack_driver_param_value_t min; | |||
| jack_driver_param_value_t max; | |||
| } range; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is set */ | |||
| struct { | |||
| uint32_t count; | |||
| jack_driver_param_value_enum_t * possible_values_array; | |||
| } enumeration; /**< valid when JACK_CONSTRAINT_FLAG_RANGE flag is not set */ | |||
| } constraint; | |||
| } jack_driver_param_constraint_desc_t; | |||
| /** A driver parameter descriptor */ | |||
| typedef struct | |||
| { | |||
| char name[JACK_DRIVER_NAME_MAX+1]; /**< The parameter's name */ | |||
| char character; /**< The parameter's character (for getopt, etc) */ | |||
| jack_driver_param_type_t type; /**< The parameter's type */ | |||
| jack_driver_param_value_t value; /**< The parameter's (default) value */ | |||
| jack_driver_param_constraint_desc_t * constraint; /**< Pointer to parameter constraint descriptor. NULL if there is no constraint */ | |||
| char short_desc[64]; /**< A short (~30 chars) description for the user */ | |||
| char long_desc[1024]; /**< A longer description for the user */ | |||
| } jack_driver_param_desc_t; | |||
| /** A driver parameter */ | |||
| typedef struct | |||
| { | |||
| char character; | |||
| jack_driver_param_value_t value; | |||
| } jack_driver_param_t; | |||
| /** A struct for describing a jack driver */ | |||
| typedef struct | |||
| { | |||
| char name[JACK_DRIVER_NAME_MAX+1]; /**< The driver's canonical name */ | |||
| char file[PATH_MAX+1]; /**< The filename of the driver's shared object file */ | |||
| uint32_t nparams; /**< The number of parameters the driver has */ | |||
| jack_driver_param_desc_t * params; /**< An array of parameter descriptors */ | |||
| } jack_driver_desc_t; | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __jack_driver_interface_h__ */ | |||
| @@ -0,0 +1,212 @@ | |||
| /* -*- mode: c; c-file-style: "linux"; -*- */ | |||
| /* | |||
| Copyright (C) 2003 Bob Ham <rah@bash.sh | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __jack_driver_parse_h__ | |||
| #define __jack_driver_parse_h__ | |||
| #include <jack/jslist.h> | |||
| #include <jack/driver_interface.h> | |||
| static void | |||
| jack_print_driver_options (jack_driver_desc_t * desc, FILE *file) | |||
| { | |||
| unsigned long i; | |||
| char arg_default[JACK_DRIVER_PARAM_STRING_MAX + 1]; | |||
| for (i = 0; i < desc->nparams; i++) { | |||
| switch (desc->params[i].type) { | |||
| case JackDriverParamInt: | |||
| sprintf (arg_default, "%" PRId32, desc->params[i].value.i); | |||
| break; | |||
| case JackDriverParamUInt: | |||
| sprintf (arg_default, "%" PRIu32, desc->params[i].value.ui); | |||
| break; | |||
| case JackDriverParamChar: | |||
| sprintf (arg_default, "%c", desc->params[i].value.c); | |||
| break; | |||
| case JackDriverParamString: | |||
| if (desc->params[i].value.str && | |||
| strcmp (desc->params[i].value.str, "") != 0) | |||
| sprintf (arg_default, "%s", desc->params[i].value.str); | |||
| else | |||
| sprintf (arg_default, "none"); | |||
| break; | |||
| case JackDriverParamBool: | |||
| sprintf (arg_default, "%s", desc->params[i].value.i ? "true" : "false"); | |||
| break; | |||
| } | |||
| fprintf (file, "\t-%c, --%s \t%s (default: %s)\n", | |||
| desc->params[i].character, | |||
| desc->params[i].name, | |||
| desc->params[i].short_desc, | |||
| arg_default); | |||
| } | |||
| } | |||
| static void | |||
| jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, FILE *file) | |||
| { | |||
| fprintf (file, "Usage information for the '%s' parameter for driver '%s':\n", | |||
| desc->params[param].name, desc->name); | |||
| fprintf (file, "%s\n", desc->params[param].long_desc); | |||
| } | |||
| static int | |||
| jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char **argv, JSList ** param_ptr) | |||
| { | |||
| struct option * long_options; | |||
| char * options, * options_ptr; | |||
| unsigned long i; | |||
| int opt, param_index; | |||
| JSList * params = NULL; | |||
| jack_driver_param_t * driver_param; | |||
| if (argc <= 1) { | |||
| *param_ptr = NULL; | |||
| return 0; | |||
| } | |||
| /* check for help */ | |||
| if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) { | |||
| if (argc > 2) { | |||
| for (i = 0; i < desc->nparams; i++) { | |||
| if (strcmp (desc->params[i].name, argv[2]) == 0) { | |||
| jack_print_driver_param_usage (desc, i, stdout); | |||
| return 1; | |||
| } | |||
| } | |||
| fprintf (stderr, "jackd: unknown option '%s' " | |||
| "for driver '%s'\n", argv[2], | |||
| desc->name); | |||
| } | |||
| printf ("Parameters for driver '%s' (all parameters are optional):\n", desc->name); | |||
| jack_print_driver_options (desc, stdout); | |||
| return 1; | |||
| } | |||
| /* set up the stuff for getopt */ | |||
| options = calloc (desc->nparams*3 + 1, sizeof (char)); | |||
| long_options = calloc (desc->nparams + 1, sizeof (struct option)); | |||
| options_ptr = options; | |||
| for (i = 0; i < desc->nparams; i++) { | |||
| sprintf (options_ptr, "%c::", desc->params[i].character); | |||
| options_ptr += 3; | |||
| long_options[i].name = desc->params[i].name; | |||
| long_options[i].flag = NULL; | |||
| long_options[i].val = desc->params[i].character; | |||
| long_options[i].has_arg = optional_argument; | |||
| } | |||
| /* create the params */ | |||
| optind = 0; | |||
| opterr = 0; | |||
| while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { | |||
| if (opt == ':' || opt == '?') { | |||
| if (opt == ':') { | |||
| fprintf (stderr, "Missing option to argument '%c'\n", optopt); | |||
| } else { | |||
| fprintf (stderr, "Unknownage with option '%c'\n", optopt); | |||
| } | |||
| fprintf (stderr, "Options for driver '%s':\n", desc->name); | |||
| jack_print_driver_options (desc, stderr); | |||
| exit (1); | |||
| } | |||
| for (param_index = 0; param_index < desc->nparams; param_index++) { | |||
| if (opt == desc->params[param_index].character) { | |||
| break; | |||
| } | |||
| } | |||
| driver_param = calloc (1, sizeof (jack_driver_param_t)); | |||
| driver_param->character = desc->params[param_index].character; | |||
| if (!optarg && optind < argc && | |||
| strlen(argv[optind]) && | |||
| argv[optind][0] != '-') { | |||
| optarg = argv[optind]; | |||
| } | |||
| if (optarg) { | |||
| switch (desc->params[param_index].type) { | |||
| case JackDriverParamInt: | |||
| driver_param->value.i = atoi (optarg); | |||
| break; | |||
| case JackDriverParamUInt: | |||
| driver_param->value.ui = strtoul (optarg, NULL, 10); | |||
| break; | |||
| case JackDriverParamChar: | |||
| driver_param->value.c = optarg[0]; | |||
| break; | |||
| case JackDriverParamString: | |||
| strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX); | |||
| break; | |||
| case JackDriverParamBool: | |||
| if (strcasecmp ("false", optarg) == 0 || | |||
| strcasecmp ("off", optarg) == 0 || | |||
| strcasecmp ("no", optarg) == 0 || | |||
| strcasecmp ("0", optarg) == 0 || | |||
| strcasecmp ("(null)", optarg) == 0 ) { | |||
| driver_param->value.i = FALSE; | |||
| } else { | |||
| driver_param->value.i = TRUE; | |||
| } | |||
| break; | |||
| } | |||
| } else { | |||
| if (desc->params[param_index].type == JackDriverParamBool) { | |||
| driver_param->value.i = TRUE; | |||
| } else { | |||
| driver_param->value = desc->params[param_index].value; | |||
| } | |||
| } | |||
| params = jack_slist_append (params, driver_param); | |||
| } | |||
| free (options); | |||
| free (long_options); | |||
| if (param_ptr) | |||
| *param_ptr = params; | |||
| return 0; | |||
| } | |||
| #endif /* __jack_driver_parse_h__ */ | |||
| @@ -0,0 +1,272 @@ | |||
| /* -*- mode: c; c-file-style: "bsd"; -*- */ | |||
| /* | |||
| Copyright (C) 2001-2003 Paul Davis | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __jack_engine_h__ | |||
| #define __jack_engine_h__ | |||
| #include <jack/jack.h> | |||
| #include <jack/internal.h> | |||
| #include <jack/driver_interface.h> | |||
| struct _jack_driver; | |||
| struct _jack_client_internal; | |||
| struct _jack_port_internal; | |||
| /* Structures is allocated by the engine in local memory to keep track | |||
| * of port buffers and connections. | |||
| */ | |||
| typedef struct { | |||
| jack_shm_info_t* shm_info; | |||
| jack_shmsize_t offset; | |||
| } jack_port_buffer_info_t; | |||
| /* The engine keeps an array of these in its local memory. */ | |||
| typedef struct _jack_port_internal { | |||
| struct _jack_port_shared *shared; | |||
| JSList *connections; | |||
| jack_port_buffer_info_t *buffer_info; | |||
| } jack_port_internal_t; | |||
| /* The engine's internal port type structure. */ | |||
| typedef struct _jack_port_buffer_list { | |||
| pthread_mutex_t lock; /* only lock within server */ | |||
| JSList *freelist; /* list of free buffers */ | |||
| jack_port_buffer_info_t *info; /* jack_buffer_info_t array */ | |||
| } jack_port_buffer_list_t; | |||
| typedef struct _jack_reserved_name { | |||
| jack_client_id_t uuid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| } jack_reserved_name_t; | |||
| #define JACKD_WATCHDOG_TIMEOUT 10000 | |||
| #define JACKD_CLIENT_EVENT_TIMEOUT 2000 | |||
| /* The main engine structure in local memory. */ | |||
| struct _jack_engine { | |||
| jack_control_t *control; | |||
| JSList *drivers; | |||
| struct _jack_driver *driver; | |||
| jack_driver_desc_t *driver_desc; | |||
| JSList *driver_params; | |||
| JSList *slave_drivers; | |||
| /* these are "callbacks" made by the driver backend */ | |||
| int (*set_buffer_size) (struct _jack_engine *, jack_nframes_t frames); | |||
| int (*set_sample_rate) (struct _jack_engine *, jack_nframes_t frames); | |||
| int (*run_cycle) (struct _jack_engine *, jack_nframes_t nframes, | |||
| float delayed_usecs); | |||
| void (*delay) (struct _jack_engine *, float delayed_usecs); | |||
| void (*transport_cycle_start) (struct _jack_engine *, jack_time_t time); | |||
| void (*driver_exit) (struct _jack_engine *); | |||
| jack_time_t (*get_microseconds)(void); | |||
| /* "private" sections starts here */ | |||
| /* engine serialization -- use precedence for deadlock avoidance */ | |||
| pthread_mutex_t request_lock; /* precedes client_lock */ | |||
| pthread_rwlock_t client_lock; | |||
| pthread_mutex_t port_lock; | |||
| pthread_mutex_t problem_lock; /* must hold write lock on client_lock */ | |||
| int process_errors; | |||
| int period_msecs; | |||
| /* Time to wait for clients in msecs. Used when jackd is run | |||
| * without realtime priority enabled. */ | |||
| int client_timeout_msecs; | |||
| /* info on the shm segment containing this->control */ | |||
| jack_shm_info_t control_shm; | |||
| /* address-space local port buffer and segment info, | |||
| indexed by the port type_id | |||
| */ | |||
| jack_port_buffer_list_t port_buffers[JACK_MAX_PORT_TYPES]; | |||
| jack_shm_info_t port_segment[JACK_MAX_PORT_TYPES]; | |||
| unsigned int port_max; | |||
| pthread_t server_thread; | |||
| pthread_t watchdog_thread; | |||
| int fds[2]; | |||
| int cleanup_fifo[2]; | |||
| jack_client_id_t next_client_id; | |||
| size_t pfd_size; | |||
| size_t pfd_max; | |||
| struct pollfd *pfd; | |||
| char fifo_prefix[PATH_MAX+1]; | |||
| int *fifo; | |||
| unsigned long fifo_size; | |||
| /* session handling */ | |||
| int session_reply_fd; | |||
| int session_pending_replies; | |||
| unsigned long external_client_cnt; | |||
| int rtpriority; | |||
| volatile char freewheeling; | |||
| volatile char stop_freewheeling; | |||
| jack_client_id_t fwclient; | |||
| pthread_t freewheel_thread; | |||
| char verbose; | |||
| char do_munlock; | |||
| const char *server_name; | |||
| char temporary; | |||
| int reordered; | |||
| int watchdog_check; | |||
| int feedbackcount; | |||
| int removing_clients; | |||
| pid_t wait_pid; | |||
| int nozombies; | |||
| int timeout_count_threshold; | |||
| volatile int problems; | |||
| volatile int timeout_count; | |||
| volatile int new_clients_allowed; | |||
| /* these lists are protected by `client_lock' */ | |||
| JSList *clients; | |||
| JSList *clients_waiting; | |||
| JSList *reserved_client_names; | |||
| jack_port_internal_t *internal_ports; | |||
| jack_client_internal_t *timebase_client; | |||
| jack_port_buffer_info_t *silent_buffer; | |||
| jack_client_internal_t *current_client; | |||
| #define JACK_ENGINE_ROLLING_COUNT 32 | |||
| #define JACK_ENGINE_ROLLING_INTERVAL 1024 | |||
| jack_time_t rolling_client_usecs[JACK_ENGINE_ROLLING_COUNT]; | |||
| int rolling_client_usecs_cnt; | |||
| int rolling_client_usecs_index; | |||
| int rolling_interval; | |||
| float max_usecs; | |||
| float spare_usecs; | |||
| int first_wakeup; | |||
| #ifdef JACK_USE_MACH_THREADS | |||
| /* specific resources for server/client real-time thread communication */ | |||
| mach_port_t servertask, bp; | |||
| int portnum; | |||
| #endif | |||
| /* used for port names munging */ | |||
| int audio_out_cnt; | |||
| int audio_in_cnt; | |||
| int midi_out_cnt; | |||
| int midi_in_cnt; | |||
| }; | |||
| /* public functions */ | |||
| jack_engine_t *jack_engine_new (int real_time, int real_time_priority, | |||
| int do_mlock, int do_unlock, | |||
| const char *server_name, int temporary, | |||
| int verbose, int client_timeout, | |||
| unsigned int port_max, | |||
| pid_t waitpid, jack_nframes_t frame_time_offset, int nozombies, | |||
| int timeout_count_threshold, | |||
| JSList *drivers); | |||
| void jack_engine_delete (jack_engine_t *); | |||
| int jack_run (jack_engine_t *engine); | |||
| int jack_wait (jack_engine_t *engine); | |||
| int jack_engine_load_driver (jack_engine_t *engine, | |||
| jack_driver_desc_t * driver_desc, | |||
| JSList * driver_params); | |||
| int jack_engine_load_slave_driver (jack_engine_t *engine, | |||
| jack_driver_desc_t * driver_desc, | |||
| JSList * driver_params); | |||
| void jack_dump_configuration(jack_engine_t *engine, int take_lock); | |||
| /* private engine functions */ | |||
| void jack_engine_reset_rolling_usecs (jack_engine_t *engine); | |||
| int internal_client_request (void* ptr, jack_request_t *request); | |||
| int jack_get_fifo_fd (jack_engine_t *engine, | |||
| unsigned int which_fifo); | |||
| extern jack_timer_type_t clock_source; | |||
| extern jack_client_internal_t * | |||
| jack_client_internal_by_id (jack_engine_t *engine, jack_client_id_t id); | |||
| #define jack_rdlock_graph(e) { DEBUG ("acquiring graph read lock"); if (pthread_rwlock_rdlock (&e->client_lock)) abort(); } | |||
| #define jack_lock_graph(e) { DEBUG ("acquiring graph write lock"); if (pthread_rwlock_wrlock (&e->client_lock)) abort(); } | |||
| #define jack_try_rdlock_graph(e) pthread_rwlock_tryrdlock (&e->client_lock) | |||
| #define jack_unlock_graph(e) { DEBUG ("release graph lock"); if (pthread_rwlock_unlock (&e->client_lock)) abort(); } | |||
| #define jack_trylock_problems(e) pthread_mutex_trylock (&e->problem_lock) | |||
| #define jack_lock_problems(e) { DEBUG ("acquiring problem lock"); if (pthread_mutex_lock (&e->problem_lock)) abort(); } | |||
| #define jack_unlock_problems(e) { DEBUG ("release problem lock"); if (pthread_mutex_unlock (&e->problem_lock)) abort(); } | |||
| #if 0 | |||
| static inline void jack_rdlock_graph (jack_engine_t* engine) { | |||
| DEBUG ("acquiring graph read lock"); | |||
| pthread_rwlock_rdlock (&engine->client_lock); | |||
| } | |||
| static inline void jack_lock_graph (jack_engine_t* engine) { | |||
| DEBUG ("acquiring graph lock"); | |||
| pthread_rwlock_wrlock (&engine->client_lock); | |||
| } | |||
| static inline int jack_try_rdlock_graph (jack_engine_t *engine) | |||
| { | |||
| DEBUG ("TRYING to acquiring graph read lock"); | |||
| return pthread_rwlock_tryrdlock (&engine->client_lock); | |||
| } | |||
| static inline void jack_unlock_graph (jack_engine_t* engine) | |||
| { | |||
| DEBUG ("releasing graph lock"); | |||
| pthread_rwlock_unlock (&engine->client_lock); | |||
| } | |||
| #endif | |||
| static inline unsigned int jack_power_of_two (unsigned int n) | |||
| { | |||
| return !(n & (n - 1)); | |||
| } | |||
| /* Internal port handling interfaces for JACK engine. */ | |||
| void jack_port_clear_connections (jack_engine_t *engine, | |||
| jack_port_internal_t *port); | |||
| void jack_port_registration_notify (jack_engine_t *, jack_port_id_t, int); | |||
| void jack_port_release (jack_engine_t *engine, jack_port_internal_t *); | |||
| void jack_sort_graph (jack_engine_t *engine); | |||
| int jack_stop_freewheeling (jack_engine_t* engine, int engine_exiting); | |||
| jack_client_internal_t * | |||
| jack_client_by_name (jack_engine_t *engine, const char *name); | |||
| int jack_deliver_event (jack_engine_t *, jack_client_internal_t *, jack_event_t *); | |||
| void jack_stop_watchdog (jack_engine_t * ); | |||
| void | |||
| jack_engine_signal_problems (jack_engine_t* engine); | |||
| int | |||
| jack_use_driver (jack_engine_t *engine, struct _jack_driver *driver); | |||
| int | |||
| jack_drivers_start (jack_engine_t *engine); | |||
| int | |||
| jack_add_slave_driver (jack_engine_t *engine, struct _jack_driver *driver); | |||
| #endif /* __jack_engine_h__ */ | |||
| @@ -0,0 +1,65 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __jack_hardware_h__ | |||
| #define __jack_hardware_h__ | |||
| #include <jack/types.h> | |||
| typedef enum { | |||
| AutoSync, | |||
| WordClock, | |||
| ClockMaster | |||
| } SampleClockMode; | |||
| typedef enum { | |||
| Cap_HardwareMonitoring = 0x1, | |||
| Cap_AutoSync = 0x2, | |||
| Cap_WordClock = 0x4, | |||
| Cap_ClockMaster = 0x8, | |||
| Cap_ClockLockReporting = 0x10, | |||
| Cap_HardwareMetering = 0x20 | |||
| } Capabilities; | |||
| struct _jack_hardware; | |||
| typedef void (*JackHardwareReleaseFunction)(struct _jack_hardware *); | |||
| typedef int (*JackHardwareSetInputMonitorMaskFunction)(struct _jack_hardware *, unsigned long); | |||
| typedef int (*JackHardwareChangeSampleClockFunction)(struct _jack_hardware *, SampleClockMode); | |||
| typedef double (*JackHardwareGetHardwarePeak)(jack_port_t *port, jack_nframes_t frames); | |||
| typedef double (*JackHardwareGetHardwarePower)(jack_port_t *port, jack_nframes_t frames); | |||
| typedef struct _jack_hardware { | |||
| unsigned long capabilities; | |||
| unsigned long input_monitor_mask; | |||
| JackHardwareChangeSampleClockFunction change_sample_clock; | |||
| JackHardwareSetInputMonitorMaskFunction set_input_monitor_mask; | |||
| JackHardwareReleaseFunction release; | |||
| JackHardwareGetHardwarePeak get_hardware_peak; | |||
| JackHardwareGetHardwarePower get_hardware_power; | |||
| void *private; | |||
| } jack_hardware_t; | |||
| jack_hardware_t * jack_hardware_new (); | |||
| #endif /* __jack_hardware_h__ */ | |||
| @@ -0,0 +1,129 @@ | |||
| /* | |||
| * Copyright (C) 2004 Jack O'Quin | |||
| * | |||
| * 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 __jack_intclient_h__ | |||
| #define __jack_intclient_h__ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| #include <jack/types.h> | |||
| /** | |||
| * Get an internal client's name. This is useful when @ref | |||
| * JackUseExactName was not specified on jack_internal_client_load() | |||
| * and @ref JackNameNotUnique status was returned. In that case, the | |||
| * actual name will differ from the @a client_name requested. | |||
| * | |||
| * @param client requesting JACK client's handle. | |||
| * | |||
| * @param intclient handle returned from jack_internal_client_load() | |||
| * or jack_internal_client_handle(). | |||
| * | |||
| * @return NULL if unsuccessful, otherwise pointer to the internal | |||
| * client name obtained from the heap via malloc(). The caller should | |||
| * free() this storage when no longer needed. | |||
| */ | |||
| char *jack_get_internal_client_name (jack_client_t *client, | |||
| jack_intclient_t intclient); | |||
| /** | |||
| * Return the @ref jack_intclient_t handle for an internal client | |||
| * running in the JACK server. | |||
| * | |||
| * @param client requesting JACK client's handle. | |||
| * | |||
| * @param client_name for the internal client of no more than | |||
| * jack_client_name_size() characters. The name scope is local to the | |||
| * current server. | |||
| * | |||
| * @param status (if non-NULL) an address for JACK to return | |||
| * information from this operation. This status word is formed by | |||
| * OR-ing together the relevant @ref JackStatus bits. | |||
| * | |||
| * @return Opaque internal client handle if successful. If 0, the | |||
| * internal client was not found, and @a *status includes the @ref | |||
| * JackNoSuchClient and @ref JackFailure bits. | |||
| */ | |||
| jack_intclient_t jack_internal_client_handle (jack_client_t *client, | |||
| const char *client_name, | |||
| jack_status_t *status); | |||
| /** | |||
| * Load an internal client into the JACK server. | |||
| * | |||
| * Internal clients run inside the JACK server process. They can use | |||
| * most of the same functions as external clients. Each internal | |||
| * client is built as a shared object module, which must declare | |||
| * jack_initialize() and jack_finish() entry points called at load and | |||
| * unload times. See @ref inprocess.c for an example. | |||
| * | |||
| * @param client loading JACK client's handle. | |||
| * | |||
| * @param client_name of at most jack_client_name_size() characters | |||
| * for the internal client to load. The name scope is local to the | |||
| * current server. | |||
| * | |||
| * @param options formed by OR-ing together @ref JackOptions bits. | |||
| * Only the @ref JackLoadOptions bits are valid. | |||
| * | |||
| * @param status (if non-NULL) an address for JACK to return | |||
| * information from the load operation. This status word is formed by | |||
| * OR-ing together the relevant @ref JackStatus bits. | |||
| * | |||
| * <b>Optional parameters:</b> depending on corresponding [@a options | |||
| * bits] additional parameters may follow @a status (in this order). | |||
| * | |||
| * @arg [@ref JackLoadName] <em>(char *) load_name</em> is the shared | |||
| * object file from which to load the new internal client (otherwise | |||
| * use the @a client_name). | |||
| * | |||
| * @arg [@ref JackLoadInit] <em>(char *) load_init</em> an arbitary | |||
| * string passed to the internal client's jack_initialize() routine | |||
| * (otherwise NULL), of no more than @ref JACK_LOAD_INIT_LIMIT bytes. | |||
| * | |||
| * @return Opaque internal client handle if successful. If this is 0, | |||
| * the load operation failed, the internal client was not loaded, and | |||
| * @a *status includes the @ref JackFailure bit. | |||
| */ | |||
| jack_intclient_t jack_internal_client_load (jack_client_t *client, | |||
| const char *client_name, | |||
| jack_options_t options, | |||
| jack_status_t *status, ...); | |||
| /** | |||
| * Unload an internal client from a JACK server. This calls the | |||
| * intclient's jack_finish() entry point then removes it. See @ref | |||
| * inprocess.c for an example. | |||
| * | |||
| * @param client unloading JACK client's handle. | |||
| * | |||
| * @param intclient handle returned from jack_internal_client_load() or | |||
| * jack_internal_client_handle(). | |||
| * | |||
| * @return 0 if successful, otherwise @ref JackStatus bits. | |||
| */ | |||
| jack_status_t jack_internal_client_unload (jack_client_t *client, | |||
| jack_intclient_t intclient); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __jack_intclient_h__ */ | |||
| @@ -0,0 +1,561 @@ | |||
| /* -*- mode: c; c-file-style: "bsd"; -*- */ | |||
| /* | |||
| Internal shared data and functions. | |||
| If you edit this file, you should carefully consider changing the | |||
| JACK_PROTOCOL_VERSION in configure.in. | |||
| Copyright (C) 2001-2003 Paul Davis | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __jack_internal_h__ | |||
| #define __jack_internal_h__ | |||
| #include <stdlib.h> | |||
| #include <unistd.h> | |||
| #include <limits.h> | |||
| #include <dlfcn.h> | |||
| #include <pthread.h> | |||
| #include <sys/types.h> | |||
| #include <sys/time.h> | |||
| #ifndef POST_PACKED_STRUCTURE | |||
| #ifdef __GNUC__ | |||
| /* POST_PACKED_STRUCTURE needs to be a macro which | |||
| expands into a compiler directive. The directive must | |||
| tell the compiler to arrange the preceding structure | |||
| declaration so that it is packed on byte-boundaries rather | |||
| than use the natural alignment of the processor and/or | |||
| compiler. | |||
| */ | |||
| #define POST_PACKED_STRUCTURE __attribute__((__packed__)) | |||
| #else | |||
| /* Add other things here for non-gcc platforms */ | |||
| #endif | |||
| #endif | |||
| /* Needed by <sysdeps/time.h> */ | |||
| extern void jack_error (const char *fmt, ...); | |||
| extern void jack_info (const char *fmt, ...); | |||
| #include <jack/jack.h> | |||
| #include <jack/types.h> | |||
| #include <jack/port.h> | |||
| #include <jack/transport.h> | |||
| #include <jack/session.h> | |||
| #include <jack/thread.h> | |||
| extern jack_thread_creator_t jack_thread_creator; | |||
| typedef enum { | |||
| JACK_TIMER_SYSTEM_CLOCK, | |||
| JACK_TIMER_CYCLE_COUNTER, | |||
| JACK_TIMER_HPET, | |||
| } jack_timer_type_t; | |||
| void jack_init_time (); | |||
| void jack_set_clock_source (jack_timer_type_t); | |||
| const char* jack_clock_source_name (jack_timer_type_t); | |||
| #include <sysdeps/time.h> | |||
| #include <sysdeps/atomicity.h> | |||
| #ifdef JACK_USE_MACH_THREADS | |||
| #include <sysdeps/mach_port.h> | |||
| #endif | |||
| #include <jack/messagebuffer.h> | |||
| #ifndef PATH_MAX | |||
| #ifdef MAXPATHLEN | |||
| #define PATH_MAX MAXPATHLEN | |||
| #else | |||
| #define PATH_MAX 1024 | |||
| #endif /* MAXPATHLEN */ | |||
| #endif /* !PATH_MAX */ | |||
| #ifdef DEBUG_ENABLED | |||
| /* grab thread id instead of PID on linux */ | |||
| #if defined(__gnu_linux__) | |||
| #ifdef gettid /* glibc has a version */ | |||
| #define GETTID() gettid() | |||
| #else /* use our own version */ | |||
| #include <sys/syscall.h> | |||
| #define GETTID() syscall(__NR_gettid) | |||
| #endif | |||
| #else | |||
| #define GETTID() getpid() | |||
| #endif | |||
| #define DEBUG(format,args...) \ | |||
| MESSAGE("jack:%5d:%" PRIu64 " %s:%s:%d: " format "", GETTID(), jack_get_microseconds(), __FILE__, __FUNCTION__, __LINE__ , ## args) | |||
| #else | |||
| #if JACK_CPP_VARARGS_BROKEN | |||
| #define DEBUG(format...) | |||
| #else | |||
| #define DEBUG(format,args...) | |||
| #endif | |||
| #endif | |||
| /* Enable preemption checking for Linux Realtime Preemption kernels. | |||
| * | |||
| * This checks if any RT-safe code section does anything to cause CPU | |||
| * preemption. Examples are sleep() or other system calls that block. | |||
| * If a problem is detected, the kernel writes a syslog entry, and | |||
| * sends SIGUSR2 to the client. | |||
| */ | |||
| #ifdef DO_PREEMPTION_CHECKING | |||
| #define CHECK_PREEMPTION(engine, onoff) \ | |||
| if ((engine)->real_time) gettimeofday (1, (onoff)) | |||
| #else | |||
| #define CHECK_PREEMPTION(engine, onoff) | |||
| #endif | |||
| #ifndef FALSE | |||
| #define FALSE (0) | |||
| #endif | |||
| #ifndef TRUE | |||
| #define TRUE (1) | |||
| #endif | |||
| typedef struct _jack_engine jack_engine_t; | |||
| typedef struct _jack_request jack_request_t; | |||
| typedef void * dlhandle; | |||
| typedef enum { | |||
| TransportCommandNone = 0, | |||
| TransportCommandStart = 1, | |||
| TransportCommandStop = 2, | |||
| } transport_command_t; | |||
| typedef struct { | |||
| volatile uint32_t guard1; | |||
| volatile jack_nframes_t frames; | |||
| volatile jack_time_t current_wakeup; | |||
| volatile jack_time_t next_wakeup; | |||
| volatile float second_order_integrator; | |||
| volatile int32_t initialized; | |||
| volatile uint32_t guard2; | |||
| /* not accessed by clients */ | |||
| int32_t reset_pending; /* xrun happened, deal with it */ | |||
| float filter_coefficient; /* set once, never altered */ | |||
| } POST_PACKED_STRUCTURE jack_frame_timer_t; | |||
| /* JACK engine shared memory data structure. */ | |||
| typedef struct { | |||
| jack_transport_state_t transport_state; | |||
| volatile transport_command_t transport_cmd; | |||
| transport_command_t previous_cmd; /* previous transport_cmd */ | |||
| jack_position_t current_time; /* position for current cycle */ | |||
| jack_position_t pending_time; /* position for next cycle */ | |||
| jack_position_t request_time; /* latest requested position */ | |||
| jack_unique_t prev_request; /* previous request unique ID */ | |||
| volatile _Atomic_word seq_number; /* unique ID sequence number */ | |||
| int8_t new_pos; /* new position this cycle */ | |||
| int8_t pending_pos; /* new position request pending */ | |||
| jack_nframes_t pending_frame; /* pending frame number */ | |||
| int32_t sync_clients; /* number of active_slowsync clients */ | |||
| int32_t sync_remain; /* number of them with sync_poll */ | |||
| jack_time_t sync_timeout; | |||
| jack_time_t sync_time_left; | |||
| jack_frame_timer_t frame_timer; | |||
| int32_t internal; | |||
| jack_timer_type_t clock_source; | |||
| pid_t engine_pid; | |||
| jack_nframes_t buffer_size; | |||
| int8_t real_time; | |||
| int8_t do_mlock; | |||
| int8_t do_munlock; | |||
| int32_t client_priority; | |||
| int32_t max_client_priority; | |||
| int32_t has_capabilities; | |||
| float cpu_load; | |||
| float xrun_delayed_usecs; | |||
| float max_delayed_usecs; | |||
| uint32_t port_max; | |||
| int32_t engine_ok; | |||
| jack_port_type_id_t n_port_types; | |||
| jack_port_type_info_t port_types[JACK_MAX_PORT_TYPES]; | |||
| jack_port_shared_t ports[0]; | |||
| } POST_PACKED_STRUCTURE jack_control_t; | |||
| typedef enum { | |||
| BufferSizeChange, | |||
| SampleRateChange, | |||
| AttachPortSegment, | |||
| PortConnected, | |||
| PortDisconnected, | |||
| GraphReordered, | |||
| PortRegistered, | |||
| PortUnregistered, | |||
| XRun, | |||
| StartFreewheel, | |||
| StopFreewheel, | |||
| ClientRegistered, | |||
| ClientUnregistered, | |||
| SaveSession, | |||
| LatencyCallback | |||
| } JackEventType; | |||
| typedef struct { | |||
| JackEventType type; | |||
| union { | |||
| uint32_t n; | |||
| char name[JACK_PORT_NAME_SIZE]; | |||
| jack_port_id_t port_id; | |||
| jack_port_id_t self_id; | |||
| } x; | |||
| union { | |||
| uint32_t n; | |||
| jack_port_type_id_t ptid; | |||
| jack_port_id_t other_id; | |||
| } y; | |||
| } POST_PACKED_STRUCTURE jack_event_t; | |||
| typedef enum { | |||
| ClientInternal, /* connect request just names .so */ | |||
| ClientDriver, /* code is loaded along with driver */ | |||
| ClientExternal /* client is in another process */ | |||
| } ClientType; | |||
| typedef enum { | |||
| NotTriggered, | |||
| Triggered, | |||
| Running, | |||
| Finished | |||
| } jack_client_state_t; | |||
| /* JACK client shared memory data structure. */ | |||
| typedef volatile struct { | |||
| volatile jack_client_id_t id; /* w: engine r: engine and client */ | |||
| volatile jack_client_id_t uid; /* w: engine r: engine and client */ | |||
| volatile jack_client_state_t state; /* w: engine and client r: engine */ | |||
| volatile char name[JACK_CLIENT_NAME_SIZE]; | |||
| volatile char session_command[JACK_PORT_NAME_SIZE]; | |||
| volatile jack_session_flags_t session_flags; | |||
| volatile ClientType type; /* w: engine r: engine and client */ | |||
| volatile int8_t active; /* w: engine r: engine and client */ | |||
| volatile int8_t dead; /* r/w: engine */ | |||
| volatile int8_t timed_out; /* r/w: engine */ | |||
| volatile int8_t is_timebase; /* w: engine, r: engine and client */ | |||
| volatile int8_t timebase_new; /* w: engine and client, r: engine */ | |||
| volatile int8_t is_slowsync; /* w: engine, r: engine and client */ | |||
| volatile int8_t active_slowsync; /* w: engine, r: engine and client */ | |||
| volatile int8_t sync_poll; /* w: engine and client, r: engine */ | |||
| volatile int8_t sync_new; /* w: engine and client, r: engine */ | |||
| volatile pid_t pid; /* w: client r: engine; client pid */ | |||
| volatile pid_t pgrp; /* w: client r: engine; client pgrp */ | |||
| volatile uint64_t signalled_at; | |||
| volatile uint64_t awake_at; | |||
| volatile uint64_t finished_at; | |||
| volatile int32_t last_status; /* w: client, r: engine and client */ | |||
| /* indicators for whether callbacks have been set for this client. | |||
| We do not include ptrs to the callbacks here (or their arguments) | |||
| so that we can avoid 32/64 bit pointer size mismatches between | |||
| the jack server and a client. The pointers are in the client- | |||
| local structure which is part of the libjack compiled for | |||
| either 32 bit or 64 bit clients. | |||
| */ | |||
| volatile uint8_t process_cbset; | |||
| volatile uint8_t thread_init_cbset; | |||
| volatile uint8_t bufsize_cbset; | |||
| volatile uint8_t srate_cbset; | |||
| volatile uint8_t port_register_cbset; | |||
| volatile uint8_t port_connect_cbset; | |||
| volatile uint8_t graph_order_cbset; | |||
| volatile uint8_t xrun_cbset; | |||
| volatile uint8_t sync_cb_cbset; | |||
| volatile uint8_t timebase_cb_cbset; | |||
| volatile uint8_t freewheel_cb_cbset; | |||
| volatile uint8_t client_register_cbset; | |||
| volatile uint8_t thread_cb_cbset; | |||
| volatile uint8_t session_cbset; | |||
| volatile uint8_t latency_cbset; | |||
| } POST_PACKED_STRUCTURE jack_client_control_t; | |||
| typedef struct { | |||
| uint32_t protocol_v; /* protocol version, must go first */ | |||
| int32_t load; | |||
| ClientType type; | |||
| jack_options_t options; | |||
| jack_client_id_t uuid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| char object_path[PATH_MAX+1]; | |||
| char object_data[1024]; | |||
| } POST_PACKED_STRUCTURE jack_client_connect_request_t; | |||
| typedef struct { | |||
| jack_status_t status; | |||
| jack_shm_registry_index_t client_shm_index; | |||
| jack_shm_registry_index_t engine_shm_index; | |||
| char fifo_prefix[PATH_MAX+1]; | |||
| int32_t realtime; | |||
| int32_t realtime_priority; | |||
| char name[JACK_CLIENT_NAME_SIZE]; /* unique name, if assigned */ | |||
| /* these are actually pointers, but they must | |||
| be the same size regardless of whether the | |||
| server and/or client are 64 bit or 32 bit. | |||
| force them to be 64 bit. | |||
| */ | |||
| uint64_t client_control; | |||
| uint64_t engine_control; | |||
| #ifdef JACK_USE_MACH_THREADS | |||
| /* specific resources for server/client real-time thread communication */ | |||
| int32_t portnum; | |||
| #endif | |||
| } POST_PACKED_STRUCTURE jack_client_connect_result_t; | |||
| typedef struct { | |||
| jack_client_id_t client_id; | |||
| } POST_PACKED_STRUCTURE jack_client_connect_ack_request_t; | |||
| typedef struct { | |||
| int8_t status; | |||
| } POST_PACKED_STRUCTURE jack_client_connect_ack_result_t; | |||
| typedef enum { | |||
| RegisterPort = 1, | |||
| UnRegisterPort = 2, | |||
| ConnectPorts = 3, | |||
| DisconnectPorts = 4, | |||
| SetTimeBaseClient = 5, | |||
| ActivateClient = 6, | |||
| DeactivateClient = 7, | |||
| DisconnectPort = 8, | |||
| SetClientCapabilities = 9, | |||
| GetPortConnections = 10, | |||
| GetPortNConnections = 11, | |||
| ResetTimeBaseClient = 12, | |||
| SetSyncClient = 13, | |||
| ResetSyncClient = 14, | |||
| SetSyncTimeout = 15, | |||
| SetBufferSize = 16, | |||
| FreeWheel = 17, | |||
| StopFreeWheel = 18, | |||
| IntClientHandle = 19, | |||
| IntClientLoad = 20, | |||
| IntClientName = 21, | |||
| IntClientUnload = 22, | |||
| RecomputeTotalLatencies = 23, | |||
| RecomputeTotalLatency = 24, | |||
| SessionNotify = 25, | |||
| GetClientByUUID = 26, | |||
| ReserveName = 30, | |||
| SessionReply = 31, | |||
| SessionHasCallback = 32 | |||
| } RequestType; | |||
| struct _jack_request { | |||
| //RequestType type; | |||
| uint32_t type; | |||
| union { | |||
| struct { | |||
| char name[JACK_PORT_NAME_SIZE]; | |||
| char type[JACK_PORT_TYPE_SIZE]; | |||
| uint32_t flags; | |||
| jack_shmsize_t buffer_size; | |||
| jack_port_id_t port_id; | |||
| jack_client_id_t client_id; | |||
| } POST_PACKED_STRUCTURE port_info; | |||
| struct { | |||
| char source_port[JACK_PORT_NAME_SIZE]; | |||
| char destination_port[JACK_PORT_NAME_SIZE]; | |||
| } POST_PACKED_STRUCTURE connect; | |||
| struct { | |||
| char path[JACK_PORT_NAME_SIZE]; | |||
| jack_session_event_type_t type; | |||
| char target[JACK_CLIENT_NAME_SIZE]; | |||
| } POST_PACKED_STRUCTURE session; | |||
| struct { | |||
| int32_t nports; | |||
| const char **ports; /* this is only exposed to internal clients, so there | |||
| is no 64/32 issue. external clients read the ports | |||
| one by one from the server, and allocate their | |||
| own "ports" array in their own address space. | |||
| we are lucky, because this is part of a union | |||
| whose other components are bigger than this one. | |||
| otherwise it would change structure size when | |||
| comparing the 64 and 32 bit versions. | |||
| */ | |||
| } POST_PACKED_STRUCTURE port_connections; | |||
| struct { | |||
| jack_client_id_t client_id; | |||
| int32_t conditional; | |||
| } POST_PACKED_STRUCTURE timebase; | |||
| struct { | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| jack_client_id_t uuid; | |||
| } POST_PACKED_STRUCTURE reservename; | |||
| struct { | |||
| //jack_options_t options; | |||
| uint32_t options; | |||
| jack_client_id_t id; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| char path[PATH_MAX+1]; | |||
| char init[JACK_LOAD_INIT_LIMIT]; | |||
| } POST_PACKED_STRUCTURE intclient; | |||
| jack_client_id_t client_id; | |||
| jack_nframes_t nframes; | |||
| jack_time_t timeout; | |||
| pid_t cap_pid; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| } POST_PACKED_STRUCTURE x; | |||
| int32_t status; | |||
| } POST_PACKED_STRUCTURE; | |||
| /* Per-client structure allocated in the server's address space. | |||
| * It's here because its not part of the engine structure. | |||
| */ | |||
| typedef struct _jack_client_internal { | |||
| jack_client_control_t *control; | |||
| int request_fd; | |||
| int event_fd; | |||
| int subgraph_start_fd; | |||
| int subgraph_wait_fd; | |||
| JSList *ports; /* protected by engine->client_lock */ | |||
| JSList *truefeeds; /* protected by engine->client_lock */ | |||
| JSList *sortfeeds; /* protected by engine->client_lock */ | |||
| int fedcount; | |||
| int tfedcount; | |||
| jack_shm_info_t control_shm; | |||
| unsigned long execution_order; | |||
| struct _jack_client_internal *next_client; /* not a linked list! */ | |||
| dlhandle handle; | |||
| int (*initialize)(jack_client_t*, const char*); /* int. clients only */ | |||
| void (*finish)(void *); /* internal clients only */ | |||
| int error; | |||
| int session_reply_pending; | |||
| #ifdef JACK_USE_MACH_THREADS | |||
| /* specific resources for server/client real-time thread communication */ | |||
| mach_port_t serverport; | |||
| trivial_message message; | |||
| int running; | |||
| int portnum; | |||
| #endif /* JACK_USE_MACH_THREADS */ | |||
| jack_client_t *private_client; | |||
| } jack_client_internal_t; | |||
| typedef struct _jack_thread_arg { | |||
| jack_client_t* client; | |||
| void* (*work_function)(void*); | |||
| int priority; | |||
| int realtime; | |||
| void* arg; | |||
| pid_t cap_pid; | |||
| } jack_thread_arg_t; | |||
| extern int jack_client_handle_port_connection (jack_client_t *client, | |||
| jack_event_t *event); | |||
| extern jack_client_t *jack_driver_client_new (jack_engine_t *, | |||
| const char *client_name); | |||
| extern jack_client_t *jack_client_alloc_internal (jack_client_control_t*, | |||
| jack_engine_t*); | |||
| /* internal clients call this. it's defined in jack/engine.c */ | |||
| void handle_internal_client_request (jack_control_t*, jack_request_t*); | |||
| extern char *jack_tmpdir; | |||
| extern char *jack_user_dir (void); | |||
| extern char *jack_server_dir (const char *server_name, char *server_dir); | |||
| extern void *jack_zero_filled_buffer; | |||
| extern jack_port_functions_t jack_builtin_audio_functions; | |||
| extern jack_port_type_info_t jack_builtin_port_types[]; | |||
| extern void jack_client_fix_port_buffers (jack_client_t *client); | |||
| extern void jack_transport_copy_position (jack_position_t *from, | |||
| jack_position_t *to); | |||
| extern void jack_call_sync_client (jack_client_t *client); | |||
| extern void jack_call_timebase_master (jack_client_t *client); | |||
| extern char *jack_default_server_name (void); | |||
| void silent_jack_error_callback (const char *desc); | |||
| /* needed for port management */ | |||
| extern jack_port_t *jack_port_by_id_int (const jack_client_t *client, | |||
| jack_port_id_t id, int* free); | |||
| extern jack_port_t *jack_port_by_name_int (jack_client_t *client, | |||
| const char *port_name); | |||
| extern int jack_port_name_equals (jack_port_shared_t* port, const char* target); | |||
| /** Get the size (in bytes) of the data structure used to store | |||
| * MIDI events internally. | |||
| */ | |||
| extern size_t jack_midi_internal_event_size (); | |||
| extern int jack_client_handle_latency_callback (jack_client_t *client, jack_event_t *event, int is_driver); | |||
| #ifdef __GNUC__ | |||
| # define likely(x) __builtin_expect((x),1) | |||
| # define unlikely(x) __builtin_expect((x),0) | |||
| #else | |||
| # define likely(x) (x) | |||
| # define unlikely(x) (x) | |||
| #endif | |||
| #ifdef VALGRIND_CLEAN | |||
| #include <string.h> | |||
| #define VALGRIND_MEMSET(ptr,val,size) memset ((ptr),(val),(size)) | |||
| #else | |||
| #define VALGRIND_MEMSET(ptr,val,size) | |||
| #endif | |||
| #endif /* __jack_internal_h__ */ | |||
| @@ -0,0 +1,56 @@ | |||
| /* | |||
| Copyright (C) 2005-2007 Jussi Laako | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __jack_intsimd_h__ | |||
| #define __jack_intsimd_h__ | |||
| #ifdef USE_DYNSIMD | |||
| #if (defined(__i386__) || defined(__x86_64__)) | |||
| #define ARCH_X86 | |||
| #endif /* __i386__ || __x86_64__ */ | |||
| #endif /* USE_DYNSIMD */ | |||
| #ifdef ARCH_X86 | |||
| #define ARCH_X86_SSE(x) ((x) & 0xff) | |||
| #define ARCH_X86_HAVE_SSE2(x) (ARCH_X86_SSE(x) >= 2) | |||
| #define ARCH_X86_3DNOW(x) ((x) >> 8) | |||
| #define ARCH_X86_HAVE_3DNOW(x) (ARCH_X86_3DNOW(x)) | |||
| typedef float v2sf __attribute__((vector_size(8))); | |||
| typedef float v4sf __attribute__((vector_size(16))); | |||
| typedef v2sf * pv2sf; | |||
| typedef v4sf * pv4sf; | |||
| extern int cpu_type; | |||
| int have_3dnow (void); | |||
| int have_sse (void); | |||
| void x86_3dnow_copyf (float *, const float *, int); | |||
| void x86_3dnow_add2f (float *, const float *, int); | |||
| void x86_sse_copyf (float *, const float *, int); | |||
| void x86_sse_add2f (float *, const float *, int); | |||
| void x86_sse_f2i (int *, const float *, int, float); | |||
| void x86_sse_i2f (float *, const int *, int, float); | |||
| #endif /* ARCH_X86 */ | |||
| void jack_port_set_funcs (void); | |||
| #endif /* __jack_intsimd_h__ */ | |||
| @@ -0,0 +1,303 @@ | |||
| /* | |||
| Based on gslist.c from glib-1.2.9 (LGPL). | |||
| Adaption to JACK, Copyright (C) 2002 Kai Vehmanen. | |||
| - replaced use of gtypes with normal ANSI C types | |||
| - glib's memery allocation routines replaced with | |||
| malloc/free calls | |||
| 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 __jack_jslist_h__ | |||
| #define __jack_jslist_h__ | |||
| #include <stdlib.h> | |||
| typedef struct _JSList JSList; | |||
| typedef int (*JCompareFunc) (void* a, | |||
| void* b); | |||
| struct _JSList | |||
| { | |||
| void *data; | |||
| JSList *next; | |||
| }; | |||
| static __inline__ | |||
| JSList* | |||
| jack_slist_alloc (void) | |||
| { | |||
| JSList *new_list; | |||
| new_list = malloc(sizeof(JSList)); | |||
| new_list->data = NULL; | |||
| new_list->next = NULL; | |||
| return new_list; | |||
| } | |||
| static __inline__ | |||
| JSList* | |||
| jack_slist_prepend (JSList *list, | |||
| void *data) | |||
| { | |||
| JSList *new_list; | |||
| new_list = malloc(sizeof(JSList)); | |||
| new_list->data = data; | |||
| new_list->next = list; | |||
| return new_list; | |||
| } | |||
| #define jack_slist_next(slist) ((slist) ? (((JSList *)(slist))->next) : NULL) | |||
| static __inline__ | |||
| JSList* | |||
| jack_slist_last (JSList *list) | |||
| { | |||
| if (list) | |||
| { | |||
| while (list->next) | |||
| list = list->next; | |||
| } | |||
| return list; | |||
| } | |||
| static __inline__ | |||
| JSList* | |||
| jack_slist_remove_link (JSList *list, | |||
| JSList *link) | |||
| { | |||
| JSList *tmp; | |||
| JSList *prev; | |||
| prev = NULL; | |||
| tmp = list; | |||
| while (tmp) | |||
| { | |||
| if (tmp == link) | |||
| { | |||
| if (prev) | |||
| prev->next = tmp->next; | |||
| if (list == tmp) | |||
| list = list->next; | |||
| tmp->next = NULL; | |||
| break; | |||
| } | |||
| prev = tmp; | |||
| tmp = tmp->next; | |||
| } | |||
| return list; | |||
| } | |||
| static __inline__ | |||
| void | |||
| jack_slist_free (JSList *list) | |||
| { | |||
| while (list) | |||
| { | |||
| JSList *next = list->next; | |||
| free(list); | |||
| list = next; | |||
| } | |||
| } | |||
| static __inline__ | |||
| void | |||
| jack_slist_free_1 (JSList *list) | |||
| { | |||
| if (list) | |||
| { | |||
| free(list); | |||
| } | |||
| } | |||
| static __inline__ | |||
| JSList* | |||
| jack_slist_remove (JSList *list, | |||
| void *data) | |||
| { | |||
| JSList *tmp; | |||
| JSList *prev; | |||
| prev = NULL; | |||
| tmp = list; | |||
| while (tmp) | |||
| { | |||
| if (tmp->data == data) | |||
| { | |||
| if (prev) | |||
| prev->next = tmp->next; | |||
| if (list == tmp) | |||
| list = list->next; | |||
| tmp->next = NULL; | |||
| jack_slist_free (tmp); | |||
| break; | |||
| } | |||
| prev = tmp; | |||
| tmp = tmp->next; | |||
| } | |||
| return list; | |||
| } | |||
| static __inline__ | |||
| unsigned int | |||
| jack_slist_length (JSList *list) | |||
| { | |||
| unsigned int length; | |||
| length = 0; | |||
| while (list) | |||
| { | |||
| length++; | |||
| list = list->next; | |||
| } | |||
| return length; | |||
| } | |||
| static __inline__ | |||
| JSList* | |||
| jack_slist_find (JSList *list, | |||
| void *data) | |||
| { | |||
| while (list) | |||
| { | |||
| if (list->data == data) | |||
| break; | |||
| list = list->next; | |||
| } | |||
| return list; | |||
| } | |||
| static __inline__ | |||
| JSList* | |||
| jack_slist_copy (JSList *list) | |||
| { | |||
| JSList *new_list = NULL; | |||
| if (list) | |||
| { | |||
| JSList *last; | |||
| new_list = jack_slist_alloc (); | |||
| new_list->data = list->data; | |||
| last = new_list; | |||
| list = list->next; | |||
| while (list) | |||
| { | |||
| last->next = jack_slist_alloc (); | |||
| last = last->next; | |||
| last->data = list->data; | |||
| list = list->next; | |||
| } | |||
| } | |||
| return new_list; | |||
| } | |||
| static __inline__ | |||
| JSList* | |||
| jack_slist_append (JSList *list, | |||
| void *data) | |||
| { | |||
| JSList *new_list; | |||
| JSList *last; | |||
| new_list = jack_slist_alloc (); | |||
| new_list->data = data; | |||
| if (list) | |||
| { | |||
| last = jack_slist_last (list); | |||
| last->next = new_list; | |||
| return list; | |||
| } | |||
| else | |||
| return new_list; | |||
| } | |||
| static __inline__ | |||
| JSList* | |||
| jack_slist_sort_merge (JSList *l1, | |||
| JSList *l2, | |||
| JCompareFunc compare_func) | |||
| { | |||
| JSList list, *l; | |||
| l=&list; | |||
| while (l1 && l2) | |||
| { | |||
| if (compare_func(l1->data,l2->data) < 0) | |||
| { | |||
| l=l->next=l1; | |||
| l1=l1->next; | |||
| } | |||
| else | |||
| { | |||
| l=l->next=l2; | |||
| l2=l2->next; | |||
| } | |||
| } | |||
| l->next= l1 ? l1 : l2; | |||
| return list.next; | |||
| } | |||
| static __inline__ | |||
| JSList* | |||
| jack_slist_sort (JSList *list, | |||
| JCompareFunc compare_func) | |||
| { | |||
| JSList *l1, *l2; | |||
| if (!list) | |||
| return NULL; | |||
| if (!list->next) | |||
| return list; | |||
| l1 = list; | |||
| l2 = list->next; | |||
| while ((l2 = l2->next) != NULL) | |||
| { | |||
| if ((l2 = l2->next) == NULL) | |||
| break; | |||
| l1=l1->next; | |||
| } | |||
| l2 = l1->next; | |||
| l1->next = NULL; | |||
| return jack_slist_sort_merge (jack_slist_sort (list, compare_func), | |||
| jack_slist_sort (l2, compare_func), | |||
| compare_func); | |||
| } | |||
| #endif /* __jack_jslist_h__ */ | |||
| @@ -0,0 +1,115 @@ | |||
| /* | |||
| Copyright (C) 1999-2000 Paul Davis | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #ifndef __jack_memops_h__ | |||
| #define __jack_memops_h__ | |||
| #include <jack/types.h> | |||
| typedef enum { | |||
| None, | |||
| Rectangular, | |||
| Triangular, | |||
| Shaped | |||
| } DitherAlgorithm; | |||
| #define DITHER_BUF_SIZE 8 | |||
| #define DITHER_BUF_MASK 7 | |||
| typedef struct { | |||
| unsigned int depth; | |||
| float rm1; | |||
| unsigned int idx; | |||
| float e[DITHER_BUF_SIZE]; | |||
| } dither_state_t; | |||
| /* float functions */ | |||
| void sample_move_floatLE_sSs (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long dst_skip); | |||
| void sample_move_dS_floatLE (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| /* integer functions */ | |||
| void sample_move_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d32u24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d24_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d16_sSs (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_move_dS_s32u24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s24s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s16s (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip); | |||
| void sample_merge_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| void sample_merge_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state); | |||
| static __inline__ void | |||
| sample_merge (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt) | |||
| { | |||
| while (cnt--) { | |||
| *dst += *src; | |||
| dst++; | |||
| src++; | |||
| } | |||
| } | |||
| static __inline__ void | |||
| sample_memcpy (jack_default_audio_sample_t *dst, jack_default_audio_sample_t *src, unsigned long cnt) | |||
| { | |||
| memcpy (dst, src, cnt * sizeof (jack_default_audio_sample_t)); | |||
| } | |||
| void memset_interleave (char *dst, char val, unsigned long bytes, unsigned long unit_bytes, unsigned long skip_bytes); | |||
| void memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); | |||
| void memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long dst_skip_bytes, unsigned long src_skip_bytes); | |||
| void merge_memcpy_d16_s16 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); | |||
| void merge_memcpy_d32_s32 (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar); | |||
| #endif /* __jack_memops_h__ */ | |||
| @@ -0,0 +1,44 @@ | |||
| /* | |||
| * messagebuffer.h -- realtime-safe message interface for jackd. | |||
| * | |||
| * This function is included in libjack so backend drivers can use | |||
| * it, *not* for external client processes. The VERBOSE() and | |||
| * MESSAGE() macros are realtime-safe. | |||
| */ | |||
| /* | |||
| * Copyright (C) 2004 Rui Nuno Capela, Steve Harris | |||
| * | |||
| * 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 __jack_messagebuffer_h__ | |||
| #define __jack_messagebuffer_h__ | |||
| #define MESSAGE(fmt,args...) jack_messagebuffer_add(fmt , ##args) | |||
| #define VERBOSE(engine,fmt,args...) \ | |||
| if ((engine)->verbose) \ | |||
| jack_messagebuffer_add(fmt , ##args) | |||
| void jack_messagebuffer_init(); | |||
| void jack_messagebuffer_exit(); | |||
| void jack_message_buffer_thread_init (void (*cb)(void*), void*); | |||
| void jack_messagebuffer_add(const char *fmt, ...); | |||
| void jack_messagebuffer_thread_init (void (*cb)(void*), void* arg); | |||
| #endif /* __jack_messagebuffer_h__ */ | |||
| @@ -0,0 +1,174 @@ | |||
| /* | |||
| Copyright (C) 2004 Ian Esten | |||
| 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 __JACK_MIDIPORT_H | |||
| #define __JACK_MIDIPORT_H | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| #include <jack/weakmacros.h> | |||
| #include <jack/types.h> | |||
| #include <stdlib.h> | |||
| /** Type for raw event data contained in @ref jack_midi_event_t. */ | |||
| typedef unsigned char jack_midi_data_t; | |||
| /** A Jack MIDI event. */ | |||
| typedef struct _jack_midi_event | |||
| { | |||
| jack_nframes_t time; /**< Sample index at which event is valid */ | |||
| size_t size; /**< Number of bytes of data in \a buffer */ | |||
| jack_midi_data_t *buffer; /**< Raw MIDI data */ | |||
| } jack_midi_event_t; | |||
| /** | |||
| * @defgroup MIDIAPI Reading and writing MIDI data | |||
| * @{ | |||
| */ | |||
| /* Get number of events in a port buffer. | |||
| * | |||
| * @param port_buffer Port buffer from which to retrieve event. | |||
| * @return number of events inside @a port_buffer | |||
| */ | |||
| jack_nframes_t | |||
| jack_midi_get_event_count(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** Get a MIDI event from an event port buffer. | |||
| * | |||
| * Jack MIDI is normalised, the MIDI event returned by this function is | |||
| * guaranteed to be a complete MIDI event (the status byte will always be | |||
| * present, and no realtime events will interspered with the event). | |||
| * | |||
| * @param event Event structure to store retrieved event in. | |||
| * @param port_buffer Port buffer from which to retrieve event. | |||
| * @param event_index Index of event to retrieve. | |||
| * @return 0 on success, ENODATA if buffer is empty. | |||
| */ | |||
| int | |||
| jack_midi_event_get(jack_midi_event_t *event, | |||
| void *port_buffer, | |||
| uint32_t event_index) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** Clear an event buffer. | |||
| * | |||
| * This should be called at the beginning of each process cycle before calling | |||
| * @ref jack_midi_event_reserve or @ref jack_midi_event_write. This | |||
| * function may not be called on an input port's buffer. | |||
| * | |||
| * @param port_buffer Port buffer to clear (must be an output port buffer). | |||
| */ | |||
| void | |||
| jack_midi_clear_buffer(void *port_buffer) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** Get the size of the largest event that can be stored by the port. | |||
| * | |||
| * This function returns the current space available, taking into account | |||
| * events already stored in the port. | |||
| * | |||
| * @param port_buffer Port buffer to check size of. | |||
| */ | |||
| size_t | |||
| jack_midi_max_event_size(void* port_buffer) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** Allocate space for an event to be written to an event port buffer. | |||
| * | |||
| * Clients are to write the actual event data to be written starting at the | |||
| * pointer returned by this function. Clients must not write more than | |||
| * @a data_size bytes into this buffer. Clients must write normalised | |||
| * MIDI data to the port - no running status and no (1-byte) realtime | |||
| * messages interspersed with other messages (realtime messages are fine | |||
| * when they occur on their own, like other messages). | |||
| * | |||
| * Events must be written in order, sorted by their sample offsets. | |||
| * JACK will not sort the events for you, and will refuse to store | |||
| * out-of-order events. | |||
| * | |||
| * @param port_buffer Buffer to write event to. | |||
| * @param time Sample offset of event. | |||
| * @param data_size Length of event's raw data in bytes. | |||
| * @return Pointer to the beginning of the reserved event's data buffer, or | |||
| * NULL on error (ie not enough space). | |||
| */ | |||
| jack_midi_data_t* | |||
| jack_midi_event_reserve(void *port_buffer, | |||
| jack_nframes_t time, | |||
| size_t data_size) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** Write an event into an event port buffer. | |||
| * | |||
| * This function is simply a wrapper for @ref jack_midi_event_reserve | |||
| * which writes the event data into the space reserved in the buffer. | |||
| * | |||
| * Clients must not write more than | |||
| * @a data_size bytes into this buffer. Clients must write normalised | |||
| * MIDI data to the port - no running status and no (1-byte) realtime | |||
| * messages interspersed with other messages (realtime messages are fine | |||
| * when they occur on their own, like other messages). | |||
| * | |||
| * Events must be written in order, sorted by their sample offsets. | |||
| * JACK will not sort the events for you, and will refuse to store | |||
| * out-of-order events. | |||
| * | |||
| * @param port_buffer Buffer to write event to. | |||
| * @param time Sample offset of event. | |||
| * @param data Message data to be written. | |||
| * @param data_size Length of @a data in bytes. | |||
| * @return 0 on success, ENOBUFS if there's not enough space in buffer for event. | |||
| */ | |||
| int | |||
| jack_midi_event_write(void *port_buffer, | |||
| jack_nframes_t time, | |||
| const jack_midi_data_t *data, | |||
| size_t data_size) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** Get the number of events that could not be written to @a port_buffer. | |||
| * | |||
| * This function returning a non-zero value implies @a port_buffer is full. | |||
| * Currently the only way this can happen is if events are lost on port mixdown. | |||
| * | |||
| * @param port_buffer Port to receive count for. | |||
| * @returns Number of events that could not be written to @a port_buffer. | |||
| */ | |||
| uint32_t | |||
| jack_midi_get_lost_event_count(void *port_buffer) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /*@}*/ | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __JACK_MIDIPORT_H */ | |||
| @@ -0,0 +1,28 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| 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 __jack_pool_h__ | |||
| #define __jack_pool_h__ | |||
| #include <sys/types.h> | |||
| void * jack_pool_alloc (size_t bytes); | |||
| void jack_pool_release (void *); | |||
| #endif /* __jack_pool_h__ */ | |||
| @@ -0,0 +1,188 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| 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 __jack_port_h__ | |||
| #define __jack_port_h__ | |||
| #include <pthread.h> | |||
| #include <jack/types.h> | |||
| #include <jack/jslist.h> | |||
| #include <jack/shm.h> | |||
| #define JACK_PORT_NAME_SIZE 256 | |||
| #define JACK_PORT_TYPE_SIZE 32 | |||
| /* The relatively low value of this constant reflects the fact that | |||
| * JACK currently only knows about *2* port types. (May 2006) | |||
| * | |||
| * Further, the 4 covers: | |||
| * - a single non-negotiated audio format | |||
| * - music data (ie. MIDI) | |||
| * - video | |||
| * - one other | |||
| * | |||
| * which is probably enough for more than just the foreseeable future. | |||
| */ | |||
| #define JACK_MAX_PORT_TYPES 4 | |||
| #define JACK_AUDIO_PORT_TYPE 0 | |||
| #define JACK_MIDI_PORT_TYPE 1 | |||
| /* these should probably go somewhere else, but not in <jack/types.h> */ | |||
| #define JACK_CLIENT_NAME_SIZE 33 | |||
| typedef uint32_t jack_client_id_t; | |||
| /* JACK shared memory segments are limited to MAX_INT32, they can be | |||
| * shared between 32-bit and 64-bit clients. | |||
| */ | |||
| #define JACK_SHM_MAX (MAX_INT32) | |||
| typedef int32_t jack_port_type_id_t; | |||
| #define JACK_BACKEND_ALIAS "system" | |||
| #ifndef POST_PACKED_STRUCTURE | |||
| #ifdef __GNUC__ | |||
| /* POST_PACKED_STRUCTURE needs to be a macro which | |||
| expands into a compiler directive. The directive must | |||
| tell the compiler to arrange the preceding structure | |||
| declaration so that it is packed on byte-boundaries rather | |||
| than use the natural alignment of the processor and/or | |||
| compiler. | |||
| */ | |||
| #define POST_PACKED_STRUCTURE __attribute__((__packed__)) | |||
| #else | |||
| /* Add other things here for non-gcc platforms */ | |||
| #endif | |||
| #endif | |||
| /* Port type structure. | |||
| * | |||
| * (1) One for each port type is part of the engine's jack_control_t | |||
| * shared memory structure. | |||
| * | |||
| * (2) One for each port type is appended to the engine's | |||
| * jack_client_connect_result_t response. The client reads them into | |||
| * its local memory, using them to attach the corresponding shared | |||
| * memory segments. | |||
| */ | |||
| typedef struct _jack_port_type_info { | |||
| jack_port_type_id_t ptype_id; | |||
| const char type_name[JACK_PORT_TYPE_SIZE]; | |||
| /* If == 1, then a buffer to handle nframes worth of data has | |||
| * sizeof(jack_default_audio_sample_t) * nframes bytes. | |||
| * | |||
| * If > 1, the buffer allocated for input mixing will be | |||
| * this value times sizeof(jack_default_audio_sample_t) | |||
| * * nframes bytes in size. For non-audio data types, | |||
| * it may have a different value. | |||
| * | |||
| * If < 0, the value should be ignored, and buffer_size | |||
| * should be used. | |||
| */ | |||
| int32_t buffer_scale_factor; | |||
| /* ignored unless buffer_scale_factor is < 0. see above */ | |||
| jack_shmsize_t buffer_size; | |||
| jack_shm_registry_index_t shm_registry_index; | |||
| jack_shmsize_t zero_buffer_offset; | |||
| } POST_PACKED_STRUCTURE jack_port_type_info_t; | |||
| /* Allocated by the engine in shared memory. */ | |||
| typedef struct _jack_port_shared { | |||
| jack_port_type_id_t ptype_id; /* index into port type array */ | |||
| jack_shmsize_t offset; /* buffer offset in shm segment */ | |||
| jack_port_id_t id; /* index into engine port array */ | |||
| uint32_t flags; | |||
| char name[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE]; | |||
| char alias1[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE]; | |||
| char alias2[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE]; | |||
| jack_client_id_t client_id; /* who owns me */ | |||
| volatile jack_nframes_t latency; | |||
| volatile jack_nframes_t total_latency; | |||
| volatile jack_latency_range_t playback_latency; | |||
| volatile jack_latency_range_t capture_latency; | |||
| volatile uint8_t monitor_requests; | |||
| char has_mixdown; /* port has a mixdown function */ | |||
| char in_use; | |||
| char unused; /* legacy locked field */ | |||
| } POST_PACKED_STRUCTURE jack_port_shared_t; | |||
| typedef struct _jack_port_functions { | |||
| /* Function to initialize port buffer. Cannot be NULL. | |||
| * NOTE: This must take a buffer rather than jack_port_t as it is called | |||
| * in jack_engine_place_buffers() before any port creation. | |||
| * A better solution is to make jack_engine_place_buffers to be type-specific, | |||
| * but this works. | |||
| */ | |||
| void (*buffer_init)(void *buffer, size_t size, jack_nframes_t); | |||
| /* Function to mixdown multiple inputs to a buffer. Can be NULL, | |||
| * indicating that multiple input connections are not legal for | |||
| * this data type. | |||
| */ | |||
| void (*mixdown)(jack_port_t *, jack_nframes_t); | |||
| } jack_port_functions_t; | |||
| /** | |||
| * Get port functions. | |||
| * @param ptid port type id. | |||
| * | |||
| * @return pointer to port type functions or NULL if port type is unknown. | |||
| */ | |||
| /*const*/ jack_port_functions_t * | |||
| jack_get_port_functions(jack_port_type_id_t ptid); | |||
| /* Allocated by the client in local memory. */ | |||
| struct _jack_port { | |||
| void **client_segment_base; | |||
| void *mix_buffer; | |||
| jack_port_type_info_t *type_info; /* shared memory type info */ | |||
| struct _jack_port_shared *shared; /* corresponding shm struct */ | |||
| struct _jack_port *tied; /* locally tied source port */ | |||
| jack_port_functions_t fptr; | |||
| pthread_mutex_t connection_lock; | |||
| JSList *connections; | |||
| }; | |||
| /* Inline would be cleaner, but it needs to be fast even in | |||
| * non-optimized code. jack_output_port_buffer() only handles output | |||
| * ports. jack_port_buffer() works for both input and output ports. | |||
| */ | |||
| #define jack_port_buffer(p) \ | |||
| ((void *) ((p)->mix_buffer? (p)->mix_buffer: \ | |||
| *(p)->client_segment_base + (p)->shared->offset)) | |||
| #define jack_output_port_buffer(p) \ | |||
| ((void *) (*(p)->client_segment_base + (p)->shared->offset)) | |||
| /* not for use by JACK applications */ | |||
| size_t jack_port_type_buffer_size (jack_port_type_info_t* port_type_info, jack_nframes_t nframes); | |||
| #endif /* __jack_port_h__ */ | |||
| @@ -0,0 +1,235 @@ | |||
| /* | |||
| Copyright (C) 2000 Paul Davis | |||
| Copyright (C) 2003 Rohan Drape | |||
| 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 _RINGBUFFER_H | |||
| #define _RINGBUFFER_H | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| #include <sys/types.h> | |||
| /** @file ringbuffer.h | |||
| * | |||
| * A set of library functions to make lock-free ringbuffers available | |||
| * to JACK clients. The `capture_client.c' (in the example_clients | |||
| * directory) is a fully functioning user of this API. | |||
| * | |||
| * The key attribute of a ringbuffer is that it can be safely accessed | |||
| * by two threads simultaneously -- one reading from the buffer and | |||
| * the other writing to it -- without using any synchronization or | |||
| * mutual exclusion primitives. For this to work correctly, there can | |||
| * only be a single reader and a single writer thread. Their | |||
| * identities cannot be interchanged. | |||
| */ | |||
| typedef struct | |||
| { | |||
| char *buf; | |||
| size_t len; | |||
| } | |||
| jack_ringbuffer_data_t ; | |||
| typedef struct | |||
| { | |||
| char *buf; | |||
| volatile size_t write_ptr; | |||
| volatile size_t read_ptr; | |||
| size_t size; | |||
| size_t size_mask; | |||
| int mlocked; | |||
| } | |||
| jack_ringbuffer_t ; | |||
| /** | |||
| * Allocates a ringbuffer data structure of a specified size. The | |||
| * caller must arrange for a call to jack_ringbuffer_free() to release | |||
| * the memory associated with the ringbuffer. | |||
| * | |||
| * @param sz the ringbuffer size in bytes. | |||
| * | |||
| * @return a pointer to a new jack_ringbuffer_t, if successful; NULL | |||
| * otherwise. | |||
| */ | |||
| jack_ringbuffer_t *jack_ringbuffer_create(size_t sz); | |||
| /** | |||
| * Frees the ringbuffer data structure allocated by an earlier call to | |||
| * jack_ringbuffer_create(). | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| */ | |||
| void jack_ringbuffer_free(jack_ringbuffer_t *rb); | |||
| /** | |||
| * Fill a data structure with a description of the current readable | |||
| * data held in the ringbuffer. This description is returned in a two | |||
| * element array of jack_ringbuffer_data_t. Two elements are needed | |||
| * because the data to be read may be split across the end of the | |||
| * ringbuffer. | |||
| * | |||
| * The first element will always contain a valid @a len field, which | |||
| * may be zero or greater. If the @a len field is non-zero, then data | |||
| * can be read in a contiguous fashion using the address given in the | |||
| * corresponding @a buf field. | |||
| * | |||
| * If the second element has a non-zero @a len field, then a second | |||
| * contiguous stretch of data can be read from the address given in | |||
| * its corresponding @a buf field. | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| * @param vec a pointer to a 2 element array of jack_ringbuffer_data_t. | |||
| * | |||
| */ | |||
| void jack_ringbuffer_get_read_vector(const jack_ringbuffer_t *rb, | |||
| jack_ringbuffer_data_t *vec); | |||
| /** | |||
| * Fill a data structure with a description of the current writable | |||
| * space in the ringbuffer. The description is returned in a two | |||
| * element array of jack_ringbuffer_data_t. Two elements are needed | |||
| * because the space available for writing may be split across the end | |||
| * of the ringbuffer. | |||
| * | |||
| * The first element will always contain a valid @a len field, which | |||
| * may be zero or greater. If the @a len field is non-zero, then data | |||
| * can be written in a contiguous fashion using the address given in | |||
| * the corresponding @a buf field. | |||
| * | |||
| * If the second element has a non-zero @a len field, then a second | |||
| * contiguous stretch of data can be written to the address given in | |||
| * the corresponding @a buf field. | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| * @param vec a pointer to a 2 element array of jack_ringbuffer_data_t. | |||
| */ | |||
| void jack_ringbuffer_get_write_vector(const jack_ringbuffer_t *rb, | |||
| jack_ringbuffer_data_t *vec); | |||
| /** | |||
| * Read data from the ringbuffer. | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| * @param dest a pointer to a buffer where data read from the | |||
| * ringbuffer will go. | |||
| * @param cnt the number of bytes to read. | |||
| * | |||
| * @return the number of bytes read, which may range from 0 to cnt. | |||
| */ | |||
| size_t jack_ringbuffer_read(jack_ringbuffer_t *rb, char *dest, size_t cnt); | |||
| /** | |||
| * Read data from the ringbuffer. Opposed to jack_ringbuffer_read() | |||
| * this function does not move the read pointer. Thus it's | |||
| * a convenient way to inspect data in the ringbuffer in a | |||
| * continous fashion. The price is that the data is copied | |||
| * into a user provided buffer. For "raw" non-copy inspection | |||
| * of the data in the ringbuffer use jack_ringbuffer_get_read_vector(). | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| * @param dest a pointer to a buffer where data read from the | |||
| * ringbuffer will go. | |||
| * @param cnt the number of bytes to read. | |||
| * | |||
| * @return the number of bytes read, which may range from 0 to cnt. | |||
| */ | |||
| size_t jack_ringbuffer_peek(jack_ringbuffer_t *rb, char *dest, size_t cnt); | |||
| /** | |||
| * Advance the read pointer. | |||
| * | |||
| * After data have been read from the ringbuffer using the pointers | |||
| * returned by jack_ringbuffer_get_read_vector(), use this function to | |||
| * advance the buffer pointers, making that space available for future | |||
| * write operations. | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| * @param cnt the number of bytes read. | |||
| */ | |||
| void jack_ringbuffer_read_advance(jack_ringbuffer_t *rb, size_t cnt); | |||
| /** | |||
| * Return the number of bytes available for reading. | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| * | |||
| * @return the number of bytes available to read. | |||
| */ | |||
| size_t jack_ringbuffer_read_space(const jack_ringbuffer_t *rb); | |||
| /** | |||
| * Lock a ringbuffer data block into memory. | |||
| * | |||
| * Uses the mlock() system call. This is not a realtime operation. | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| */ | |||
| int jack_ringbuffer_mlock(jack_ringbuffer_t *rb); | |||
| /** | |||
| * Reset the read and write pointers, making an empty buffer. | |||
| * | |||
| * This is not thread safe. | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| */ | |||
| void jack_ringbuffer_reset(jack_ringbuffer_t *rb); | |||
| /** | |||
| * Write data into the ringbuffer. | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| * @param src a pointer to the data to be written to the ringbuffer. | |||
| * @param cnt the number of bytes to write. | |||
| * | |||
| * @return the number of bytes write, which may range from 0 to cnt | |||
| */ | |||
| size_t jack_ringbuffer_write(jack_ringbuffer_t *rb, const char *src, | |||
| size_t cnt); | |||
| /** | |||
| * Advance the write pointer. | |||
| * | |||
| * After data have been written the ringbuffer using the pointers | |||
| * returned by jack_ringbuffer_get_write_vector(), use this function | |||
| * to advance the buffer pointer, making the data available for future | |||
| * read operations. | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| * @param cnt the number of bytes written. | |||
| */ | |||
| void jack_ringbuffer_write_advance(jack_ringbuffer_t *rb, size_t cnt); | |||
| /** | |||
| * Return the number of bytes available for writing. | |||
| * | |||
| * @param rb a pointer to the ringbuffer structure. | |||
| * | |||
| * @return the amount of free space (in bytes) available for writing. | |||
| */ | |||
| size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,22 @@ | |||
| #ifndef __jack_sanitycheck_h__ | |||
| #define __jack_sanitycheck_h__ | |||
| /** | |||
| * GPL etc. | |||
| * | |||
| * @author Florian Faber | |||
| * | |||
| * @version 0.1 (2009-01-17) [FF] | |||
| * - initial version | |||
| **/ | |||
| /** | |||
| * Performs a range of sanity checks on the system. The number of | |||
| * found problems is returned. | |||
| * | |||
| **/ | |||
| int sanitycheck (int do_realtime_check, | |||
| int do_freqscaling_check); | |||
| #endif /* __jack_sanitycheck_h__ */ | |||
| @@ -0,0 +1,289 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| Copyright (C) 2004 Jack O'Quin | |||
| Copyright (C) 2010 Torben Hohn | |||
| 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 __jack_session_h__ | |||
| #define __jack_session_h__ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| #include <jack/types.h> | |||
| #include <jack/weakmacros.h> | |||
| /** | |||
| * @defgroup SessionClientFunctions Session API for clients. | |||
| * @{ | |||
| */ | |||
| /** | |||
| * Session event type. | |||
| * | |||
| * if a client cant save templates, i might just do a normal save. | |||
| * | |||
| * There is no "quit without saving" event because a client might refuse to | |||
| * quit when it has unsaved data, but other clients may have already quit. | |||
| * This results in too much confusion, so it is unsupported. | |||
| */ | |||
| enum JackSessionEventType { | |||
| /** | |||
| * Save the session completely. | |||
| * | |||
| * The client may save references to data outside the provided directory, | |||
| * but it must do so by creating a link inside the provided directory and | |||
| * referring to that in any save files. The client must not refer to data | |||
| * files outside the provided directory directly in save files, because | |||
| * this makes it impossible for the session manager to create a session | |||
| * archive for distribution or archival. | |||
| */ | |||
| JackSessionSave = 1, | |||
| /** | |||
| * Save the session completly, then quit. | |||
| * | |||
| * The rules for saving are exactly the same as for JackSessionSave. | |||
| */ | |||
| JackSessionSaveAndQuit = 2, | |||
| /** | |||
| * Save a session template. | |||
| * | |||
| * A session template is a "skeleton" of the session, but without any data. | |||
| * Clients must save a session that, when restored, will create the same | |||
| * ports as a full save would have. However, the actual data contained in | |||
| * the session may not be saved (e.g. a DAW would create the necessary | |||
| * tracks, but not save the actual recorded data). | |||
| */ | |||
| JackSessionSaveTemplate = 3 | |||
| }; | |||
| typedef enum JackSessionEventType jack_session_event_type_t; | |||
| /** | |||
| * @ref jack_session_flags_t bits | |||
| */ | |||
| enum JackSessionFlags { | |||
| /** | |||
| * An error occured while saving. | |||
| */ | |||
| JackSessionSaveError = 0x01, | |||
| /** | |||
| * Client needs to be run in a terminal. | |||
| */ | |||
| JackSessionNeedTerminal = 0x02 | |||
| }; | |||
| /** | |||
| * Session flags. | |||
| */ | |||
| typedef enum JackSessionFlags jack_session_flags_t; | |||
| struct _jack_session_event { | |||
| /** | |||
| * The type of this session event. | |||
| */ | |||
| jack_session_event_type_t type; | |||
| /** | |||
| * Session directory path, with trailing separator. | |||
| * | |||
| * This directory is exclusive to the client; when saving the client may | |||
| * create any files it likes in this directory. | |||
| */ | |||
| const char *session_dir; | |||
| /** | |||
| * Client UUID which must be passed to jack_client_open on session load. | |||
| * | |||
| * The client can specify this in the returned command line, or save it | |||
| * in a state file within the session directory. | |||
| */ | |||
| const char *client_uuid; | |||
| /** | |||
| * Reply (set by client): the command line needed to restore the client. | |||
| * | |||
| * This is a platform dependent command line. It must contain | |||
| * ${SESSION_DIR} instead of the actual session directory path. More | |||
| * generally, just as in session files, clients should not include any | |||
| * paths outside the session directory here as this makes | |||
| * archival/distribution impossible. | |||
| * | |||
| * This field is set to NULL by Jack when the event is delivered to the | |||
| * client. The client must set to allocated memory that is safe to | |||
| * free(). This memory will be freed by jack_session_event_free. | |||
| */ | |||
| char *command_line; | |||
| /** | |||
| * Reply (set by client): Session flags. | |||
| */ | |||
| jack_session_flags_t flags; | |||
| /** | |||
| * Future flags. Set to zero for now. | |||
| */ | |||
| uint32_t future; | |||
| }; | |||
| typedef struct _jack_session_event jack_session_event_t; | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * whenever a session notification is sent via jack_session_notify(). | |||
| * | |||
| * Ownership of the memory of @a event is passed to the application. | |||
| * It must be freed using jack_session_event_free when its not used anymore. | |||
| * | |||
| * The client must promptly call jack_session_reply for this event. | |||
| * | |||
| * @param event The event structure. | |||
| * @param arg Pointer to a client supplied structure. | |||
| */ | |||
| typedef void (*JackSessionCallback)(jack_session_event_t *event, | |||
| void *arg); | |||
| /** | |||
| * Tell the JACK server to call @a session_callback when a session event | |||
| * is to be delivered. | |||
| * | |||
| * setting more than one session_callback per process is probably a design | |||
| * error. if you have a multiclient application its more sensible to create | |||
| * a jack_client with only a session callback set. | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_set_session_callback (jack_client_t *client, | |||
| JackSessionCallback session_callback, | |||
| void *arg) JACK_WEAK_EXPORT; | |||
| /** | |||
| * Reply to a session event. | |||
| * | |||
| * This can either be called directly from the callback, or later from a | |||
| * different thread. For example, it is possible to push the event through a | |||
| * queue and execute the save code from the GUI thread. | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int jack_session_reply (jack_client_t *client, | |||
| jack_session_event_t *event) JACK_WEAK_EXPORT; | |||
| /** | |||
| * free memory used by a jack_session_event_t | |||
| * this also frees the memory used by the command_line pointer. | |||
| * if its non NULL. | |||
| */ | |||
| void jack_session_event_free (jack_session_event_t *event) JACK_WEAK_EXPORT; | |||
| /** | |||
| * get the assigned uuid for client. | |||
| * safe to call from callback and all other threads. | |||
| * memory needs to be freed. | |||
| */ | |||
| char *jack_client_get_uuid (jack_client_t *client) JACK_WEAK_EXPORT; | |||
| /** | |||
| * @} | |||
| */ | |||
| /** | |||
| * @defgroup JackSessionManagerAPI API for a session manager. | |||
| * | |||
| * @{ | |||
| */ | |||
| typedef struct { | |||
| const char *uuid; | |||
| const char *client_name; | |||
| const char *command; | |||
| jack_session_flags_t flags; | |||
| } jack_session_command_t; | |||
| /** | |||
| * Send an event to all clients listening for session callbacks. | |||
| * | |||
| * The returned strings of the clients are accumulated and returned as an array | |||
| * of jack_session_command_t. its terminated by ret[i].uuid == NULL target == | |||
| * NULL means send to all interested clients. otherwise a clientname | |||
| */ | |||
| jack_session_command_t *jack_session_notify ( | |||
| jack_client_t* client, | |||
| const char *target, | |||
| jack_session_event_type_t type, | |||
| const char *path) JACK_WEAK_EXPORT; | |||
| /** | |||
| * Free the memory allocated by a session command. | |||
| */ | |||
| void jack_session_commands_free (jack_session_command_t *cmds) JACK_WEAK_EXPORT; | |||
| /** | |||
| * Get the session ID for a client name. | |||
| * The session manager needs this to reassociate a client name to the session_id. | |||
| */ | |||
| char *jack_get_uuid_for_client_name (jack_client_t *client, | |||
| const char *client_name) JACK_WEAK_EXPORT; | |||
| /** | |||
| * Get the client name for a session_id. | |||
| * | |||
| * In order to snapshot the graph connections, the session manager needs to map | |||
| * session_ids to client names. | |||
| */ | |||
| char *jack_get_client_name_by_uuid (jack_client_t *client, | |||
| const char *client_uuid ) JACK_WEAK_EXPORT; | |||
| /** | |||
| * Reserve a client name and associate it with a UUID. | |||
| * | |||
| * When a client later calls jack_client_open() and specifies the UUID, jackd | |||
| * will assign the reserved name. This allows a session manager to know in | |||
| * advance under which client name its managed clients will appear. | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code | |||
| */ | |||
| int | |||
| jack_reserve_client_name (jack_client_t *client, | |||
| const char *name, | |||
| const char *uuid) JACK_WEAK_EXPORT; | |||
| /** | |||
| * Find out whether a client has set up a session callback. | |||
| * | |||
| * @return 0 when the client has no session callback, 1 when it has one. | |||
| * -1 on error. | |||
| */ | |||
| int | |||
| jack_client_has_session_callback (jack_client_t *client, const char *client_name) JACK_WEAK_EXPORT; | |||
| /** | |||
| * @} | |||
| */ | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif | |||
| @@ -0,0 +1,110 @@ | |||
| #ifndef __jack_shm_h__ | |||
| #define __jack_shm_h__ | |||
| #include <limits.h> | |||
| #include <sys/types.h> | |||
| #include <jack/types.h> | |||
| #define MAX_SERVERS 8 /* maximum concurrent servers */ | |||
| #define MAX_SHM_ID 256 /* generally about 16 per server */ | |||
| #define JACK_SERVER_NAME_SIZE 256 /* maximum length of server name */ | |||
| #define JACK_SHM_MAGIC 0x4a41434b /* shm magic number: "JACK" */ | |||
| #define JACK_SHM_NULL_INDEX -1 /* NULL SHM index */ | |||
| #define JACK_SHM_REGISTRY_INDEX -2 /* pseudo SHM index for registry */ | |||
| /* On Mac OS X, SHM_NAME_MAX is the maximum length of a shared memory | |||
| * segment name (instead of NAME_MAX or PATH_MAX as defined by the | |||
| * standard). | |||
| */ | |||
| #ifdef USE_POSIX_SHM | |||
| #ifndef SHM_NAME_MAX | |||
| #define SHM_NAME_MAX NAME_MAX | |||
| #endif | |||
| typedef char shm_name_t[SHM_NAME_MAX]; | |||
| typedef shm_name_t jack_shm_id_t; | |||
| #else /* System V SHM */ | |||
| typedef int jack_shm_id_t; | |||
| #endif /* SHM type */ | |||
| /* shared memory type */ | |||
| typedef enum { | |||
| shm_POSIX = 1, /* POSIX shared memory */ | |||
| shm_SYSV = 2 /* System V shared memory */ | |||
| } jack_shmtype_t; | |||
| typedef int16_t jack_shm_registry_index_t; | |||
| /** | |||
| * A structure holding information about shared memory allocated by | |||
| * JACK. this persists across invocations of JACK, and can be used by | |||
| * multiple JACK servers. It contains no pointers and is valid across | |||
| * address spaces. | |||
| * | |||
| * The registry consists of two parts: a header including an array of | |||
| * server names, followed by an array of segment registry entries. | |||
| */ | |||
| typedef struct _jack_shm_server { | |||
| pid_t pid; /* process ID */ | |||
| char name[JACK_SERVER_NAME_SIZE]; | |||
| } jack_shm_server_t; | |||
| typedef struct _jack_shm_header { | |||
| uint32_t magic; /* magic number */ | |||
| uint16_t protocol; /* JACK protocol version */ | |||
| jack_shmtype_t type; /* shm type */ | |||
| jack_shmsize_t size; /* total registry segment size */ | |||
| jack_shmsize_t hdr_len; /* size of header */ | |||
| jack_shmsize_t entry_len; /* size of registry entry */ | |||
| jack_shm_server_t server[MAX_SERVERS]; /* current server array */ | |||
| } jack_shm_header_t; | |||
| typedef struct _jack_shm_registry { | |||
| jack_shm_registry_index_t index; /* offset into the registry */ | |||
| pid_t allocator; /* PID that created shm segment */ | |||
| jack_shmsize_t size; /* for POSIX unattach */ | |||
| jack_shm_id_t id; /* API specific, see above */ | |||
| } jack_shm_registry_t; | |||
| #define JACK_SHM_REGISTRY_SIZE (sizeof (jack_shm_header_t) \ | |||
| + sizeof (jack_shm_registry_t) * MAX_SHM_ID) | |||
| /** | |||
| * a structure holding information about shared memory | |||
| * allocated by JACK. this version is valid only | |||
| * for a given address space. It contains a pointer | |||
| * indicating where the shared memory has been | |||
| * attached to the address space. | |||
| */ | |||
| typedef struct _jack_shm_info { | |||
| jack_shm_registry_index_t index; /* offset into the registry */ | |||
| void *attached_at; /* address where attached */ | |||
| } jack_shm_info_t; | |||
| /* utility functions used only within JACK */ | |||
| extern void jack_shm_copy_from_registry (jack_shm_info_t*, | |||
| jack_shm_registry_index_t); | |||
| extern void jack_shm_copy_to_registry (jack_shm_info_t*, | |||
| jack_shm_registry_index_t*); | |||
| extern void jack_release_shm_info (jack_shm_registry_index_t); | |||
| static inline char* jack_shm_addr (jack_shm_info_t* si) { | |||
| return si->attached_at; | |||
| } | |||
| /* here beginneth the API */ | |||
| extern int jack_register_server (const char *server_name, int new_registry); | |||
| extern void jack_unregister_server (const char *server_name); | |||
| extern int jack_initialize_shm (const char *server_name); | |||
| extern int jack_cleanup_shm (void); | |||
| extern int jack_shmalloc (jack_shmsize_t size, jack_shm_info_t* result); | |||
| extern void jack_release_shm (jack_shm_info_t*); | |||
| extern void jack_destroy_shm (jack_shm_info_t*); | |||
| extern int jack_attach_shm (jack_shm_info_t*); | |||
| extern int jack_resize_shm (jack_shm_info_t*, jack_shmsize_t size); | |||
| #endif /* __jack_shm_h__ */ | |||
| @@ -0,0 +1,21 @@ | |||
| /* | |||
| Copyright (C) 2002 Fernando Lopez-Lezcano | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #define PIPE_READ_FD (3) | |||
| #define PIPE_WRITE_FD (4) | |||
| @@ -0,0 +1,56 @@ | |||
| /* | |||
| * Copyright (C) 2004 Rui Nuno Capela, Lee Revell | |||
| * | |||
| * 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 __statistics_h__ | |||
| #define __statistics_h__ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| #include <jack/types.h> | |||
| /** | |||
| * @return the maximum delay reported by the backend since | |||
| * startup or reset. When compared to the period size in usecs, this | |||
| * can be used to estimate the ideal period size for a given setup. | |||
| */ | |||
| float jack_get_max_delayed_usecs (jack_client_t *client); | |||
| /** | |||
| * @return the delay in microseconds due to the most recent XRUN | |||
| * occurrence. This probably only makes sense when called from a @ref | |||
| * JackXRunCallback defined using jack_set_xrun_callback(). | |||
| */ | |||
| float jack_get_xrun_delayed_usecs (jack_client_t *client); | |||
| /** | |||
| * Reset the maximum delay counter. This would be useful | |||
| * to estimate the effect that a change to the configuration of a running | |||
| * system (e.g. toggling kernel preemption) has on the delay | |||
| * experienced by JACK, without having to restart the JACK engine. | |||
| */ | |||
| void jack_reset_max_delayed_usecs (jack_client_t *client); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __statistics_h__ */ | |||
| @@ -0,0 +1,97 @@ | |||
| #ifndef __jack_systemtest_h__ | |||
| #define __jack_systemtest_h__ | |||
| /** | |||
| * GPL, yabbadabba | |||
| * | |||
| * Set of functions to gather system information for the jack setup wizard. | |||
| * | |||
| * @author Florian Faber, faber@faberman.de | |||
| * | |||
| * @version 0.1 (2009-01-15) [FF] | |||
| * - initial version | |||
| * | |||
| **/ | |||
| /** | |||
| * This function checks for the existence of known frequency scaling mechanisms | |||
| * in this system. | |||
| * | |||
| * @returns 0 if the system has no frequency scaling capabilities non-0 otherwise. | |||
| **/ | |||
| int system_has_frequencyscaling(); | |||
| /** | |||
| * This function determines wether the CPU has a variable clock speed if frequency | |||
| * scaling is available. | |||
| * | |||
| * @returns 0 if system doesn't use frequency scaling at the moment, non-0 otherwise | |||
| **/ | |||
| int system_uses_frequencyscaling(); | |||
| /*** | |||
| * Checks for a definition in /etc/security/limits.conf that looks | |||
| * as if it allows RT scheduling priority. | |||
| * | |||
| * @returns 1 if there appears to be such a line | |||
| **/ | |||
| int system_has_rtprio_limits_conf (); | |||
| /** | |||
| * Checks for the existence of the 'audio' group on this system | |||
| * | |||
| * @returns 0 is there is no 'audio' group, non-0 otherwise | |||
| **/ | |||
| int system_has_audiogroup(); | |||
| /** | |||
| * Tests wether the owner of this process is in the 'audio' group. | |||
| * | |||
| * @returns 0 if the owner of this process is not in the audio group, non-0 otherwise | |||
| **/ | |||
| int system_user_in_audiogroup(); | |||
| /** | |||
| * Determines wether the owner of this process can enable rt priority. | |||
| * | |||
| * @returns 0 if this process can not be switched to rt prio, non-0 otherwise | |||
| **/ | |||
| int system_user_can_rtprio(); | |||
| long long unsigned int system_memlock_amount(); | |||
| /** | |||
| * Checks wether the memlock limit is unlimited | |||
| * | |||
| * @returns 0 if the memlock limit is limited, non-0 otherwise | |||
| **/ | |||
| int system_memlock_is_unlimited(); | |||
| long long unsigned int system_available_physical_mem(); | |||
| /** | |||
| * Gets the version of the currently running kernel | |||
| * | |||
| * @returns String with the full version of the kernel | |||
| **/ | |||
| char* system_kernel_version(); | |||
| /** | |||
| * Returns the username. The caller is in charge of disposal of | |||
| * the returned name. | |||
| * | |||
| * @returns Pointer to a username or NULL | |||
| **/ | |||
| char* system_get_username(); | |||
| #endif /* __jack_systemtest_h__ */ | |||
| @@ -0,0 +1,135 @@ | |||
| /* | |||
| Copyright (C) 2004 Paul Davis | |||
| 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 __jack_thread_h__ | |||
| #define __jack_thread_h__ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| #include <pthread.h> | |||
| #include <jack/weakmacros.h> | |||
| /* use 512KB stack per thread - the default is way too high to be feasible | |||
| * with mlockall() on many systems */ | |||
| #define THREAD_STACK 524288 | |||
| /** @file thread.h | |||
| * | |||
| * Library functions to standardize thread creation for JACK and its | |||
| * clients. These interfaces hide some system variations in the | |||
| * handling of realtime scheduling and associated privileges. | |||
| */ | |||
| /** | |||
| * @defgroup ClientThreads Creating and managing client threads | |||
| * @{ | |||
| */ | |||
| /** | |||
| * @returns if JACK is running with realtime scheduling, this returns | |||
| * the priority that any JACK-created client threads will run at. | |||
| * Otherwise returns -1. | |||
| */ | |||
| int jack_client_real_time_priority (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * @returns if JACK is running with realtime scheduling, this returns | |||
| * the maximum priority that a JACK client thread should use if the thread | |||
| * is subject to realtime scheduling. Otherwise returns -1. | |||
| */ | |||
| int jack_client_max_real_time_priority (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Attempt to enable realtime scheduling for a thread. On some | |||
| * systems that may require special privileges. | |||
| * | |||
| * @param thread POSIX thread ID. | |||
| * @param priority requested thread priority. | |||
| * | |||
| * @returns 0, if successful; EPERM, if the calling process lacks | |||
| * required realtime privileges; otherwise some other error number. | |||
| */ | |||
| int jack_acquire_real_time_scheduling (jack_native_thread_t thread, int priority) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Create a thread for JACK or one of its clients. The thread is | |||
| * created executing @a start_routine with @a arg as its sole | |||
| * argument. | |||
| * | |||
| * @param client the JACK client for whom the thread is being created. May be | |||
| * NULL if the client is being created within the JACK server. | |||
| * @param thread place to return POSIX thread ID. | |||
| * @param priority thread priority, if realtime. | |||
| * @param realtime true for the thread to use realtime scheduling. On | |||
| * some systems that may require special privileges. | |||
| * @param start_routine function the thread calls when it starts. | |||
| * @param arg parameter passed to the @a start_routine. | |||
| * | |||
| * @returns 0, if successful; otherwise some error number. | |||
| */ | |||
| int jack_client_create_thread (jack_client_t* client, | |||
| jack_native_thread_t *thread, | |||
| int priority, | |||
| int realtime, /* boolean */ | |||
| void *(*start_routine)(void*), | |||
| void *arg) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Drop realtime scheduling for a thread. | |||
| * | |||
| * @param thread POSIX thread ID. | |||
| * | |||
| * @returns 0, if successful; otherwise an error number. | |||
| */ | |||
| int jack_drop_real_time_scheduling (jack_native_thread_t thread) JACK_OPTIONAL_WEAK_EXPORT; | |||
| typedef int (*jack_thread_creator_t)(jack_native_thread_t*, | |||
| const pthread_attr_t*, | |||
| void* (*function)(void*), | |||
| void* arg) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * This function can be used in very very specialized cases | |||
| * where it is necessary that client threads created by JACK | |||
| * are created by something other than pthread_create(). After | |||
| * it is used, any threads that JACK needs for the client will | |||
| * will be created by calling the function passed to this | |||
| * function. | |||
| * | |||
| * No normal application/client should consider calling this. | |||
| * The specific case for which it was created involves running | |||
| * win32/x86 plugins under Wine on Linux, where it is necessary | |||
| * that all threads that might call win32 functions are known | |||
| * to Wine. | |||
| * | |||
| * @param creator a function that creates a new thread | |||
| * | |||
| */ | |||
| void jack_set_thread_creator (jack_thread_creator_t creator) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /* @} */ | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __jack_thread_h__ */ | |||
| @@ -0,0 +1,40 @@ | |||
| /* | |||
| Copyright (C) 2002 Paul Davis | |||
| 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 __jack_timestamps_h__ | |||
| #define __jack_timestamps_h__ | |||
| #include <stdio.h> | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| void jack_init_timestamps (unsigned long howmany); | |||
| void jack_timestamp (const char *what); | |||
| void jack_dump_timestamps (FILE *out); | |||
| void jack_reset_timestamps (); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __jack_timestamps_h__ */ | |||
| @@ -0,0 +1,544 @@ | |||
| /* | |||
| Copyright (C) 2002 Paul Davis | |||
| Copyright (C) 2003 Jack O'Quin | |||
| 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 __jack_transport_h__ | |||
| #define __jack_transport_h__ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| #include <jack/types.h> | |||
| #include <jack/weakmacros.h> | |||
| #ifndef POST_PACKED_STRUCTURE | |||
| #ifdef __GNUC__ | |||
| /* POST_PACKED_STRUCTURE needs to be a macro which | |||
| expands into a compiler directive. The directive must | |||
| tell the compiler to arrange the preceding structure | |||
| declaration so that it is packed on byte-boundaries rather | |||
| than use the natural alignment of the processor and/or | |||
| compiler. | |||
| */ | |||
| #define POST_PACKED_STRUCTURE __attribute__((__packed__)) | |||
| #else | |||
| /* Add other things here for non-gcc platforms */ | |||
| #endif | |||
| #endif | |||
| /** | |||
| * Transport states. | |||
| */ | |||
| typedef enum { | |||
| /* the order matters for binary compatibility */ | |||
| JackTransportStopped = 0, /**< Transport halted */ | |||
| JackTransportRolling = 1, /**< Transport playing */ | |||
| JackTransportLooping = 2, /**< For OLD_TRANSPORT, now ignored */ | |||
| JackTransportStarting = 3 /**< Waiting for sync ready */ | |||
| } jack_transport_state_t; | |||
| typedef uint64_t jack_unique_t; /**< Unique ID (opaque) */ | |||
| /** | |||
| * Optional struct jack_position_t fields. | |||
| */ | |||
| 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 */ | |||
| } jack_position_bits_t; | |||
| /** all valid position bits */ | |||
| #define JACK_POSITION_MASK (JackPositionBBT|JackPositionTimecode|JackBBTFrameOffset|JackAudioVideoRatio|JackVideoFrameOffset) | |||
| #define EXTENDED_TIME_INFO | |||
| /** | |||
| * Struct for transport position information. | |||
| */ | |||
| typedef struct { | |||
| /*@{*/ | |||
| /** @name Server-set fields | |||
| * these cannot be set from clients; the server sets them */ | |||
| jack_unique_t unique_1; /**< unique ID */ | |||
| jack_time_t usecs; /**< microsecond timestamp that is guaranteed to be | |||
| monotonic, but not neccessarily | |||
| linear. | |||
| The absolute value is | |||
| implementation-dependent (i.e. it | |||
| could be wall-clock, time since | |||
| jack started, uptime, etc). */ | |||
| jack_nframes_t frame_rate; /**< current frame rate, in frames per second */ | |||
| /*}@*/ | |||
| /*@{*/ | |||
| /** @name Mandatory fields | |||
| */ | |||
| jack_nframes_t frame; /**< frame number, always present/required. | |||
| This is the frame number on the | |||
| transport timeline, which is not | |||
| the same as what @ref | |||
| jack_frame_time returns. */ | |||
| jack_position_bits_t valid; /**< which other fields are valid, as a | |||
| bitmask constructed from values in | |||
| \ref jack_position_bits_t */ | |||
| /*}@*/ | |||
| /*@{*/ | |||
| /** @name JackPositionBBT fields | |||
| * Bar:Beat.Tick-related information. | |||
| * | |||
| * Applications that support | |||
| * JackPositionBBT are encouraged to also fill the JackBBTFrameOffset | |||
| */ | |||
| int32_t bar; /**< current bar | |||
| Should be >0: the first bar is | |||
| bar '1'. */ | |||
| int32_t beat; /**< current beat-within-bar | |||
| Should be >0 and <=beats_per_bar: | |||
| the first beat is beat '1'. | |||
| */ | |||
| int32_t tick; /**< current tick-within-beat | |||
| Should be >0 and <=ticks_per_beat: | |||
| the first tick is tick '0'. */ | |||
| double bar_start_tick; /**< number of ticks that have elapsed | |||
| between frame 0 and the first beat | |||
| of the current measure. */ | |||
| float beats_per_bar; /**< time signature "numerator" */ | |||
| float beat_type; /**< time signature "denominator" */ | |||
| double ticks_per_beat; /**< number of ticks within a bar. | |||
| Usually a moderately large integer | |||
| with many denominators, such as | |||
| 1920.0 */ | |||
| double beats_per_minute; /**< BPM, quantized to block size. This | |||
| means when the tempo is not constant | |||
| within this block, the BPM value should | |||
| adapted to compensate for this. This | |||
| is different from most fields in this | |||
| struct, which specify the value at | |||
| the beginning of the block rather | |||
| than an average.*/ | |||
| /*}@*/ | |||
| /*@{*/ | |||
| /** @name JackPositionTimecode fields | |||
| * EXPERIMENTAL: could change */ | |||
| double frame_time; /**< current time in seconds */ | |||
| double next_time; /**< next sequential frame_time | |||
| (unless repositioned) */ | |||
| /*}@*/ | |||
| /*@{*/ | |||
| /* JackBBTFrameOffset fields */ | |||
| jack_nframes_t bbt_offset; /**< frame offset for the BBT fields | |||
| (the given bar, beat, and tick | |||
| values actually refer to a time | |||
| frame_offset frames before the | |||
| start of the cycle), should | |||
| be assumed to be 0 if | |||
| JackBBTFrameOffset is not | |||
| set. If JackBBTFrameOffset is | |||
| set and this value is zero, the BBT | |||
| time refers to the first frame of this | |||
| cycle. If the value is positive, | |||
| the BBT time refers to a frame that | |||
| many frames before the start of the | |||
| cycle. */ | |||
| /*}@*/ | |||
| /*@{*/ | |||
| /* JACK video positional data | |||
| * EXPERIMENTAL: could change */ | |||
| float audio_frames_per_video_frame; /**< number of audio frames | |||
| per video frame. Should be assumed | |||
| zero if JackAudioVideoRatio is not | |||
| set. If JackAudioVideoRatio is set | |||
| and the value is zero, no video | |||
| data exists within the JACK graph */ | |||
| jack_nframes_t video_offset; /**< audio frame at which the first video | |||
| frame in this cycle occurs. Should | |||
| be assumed to be 0 if JackVideoFrameOffset | |||
| is not set. If JackVideoFrameOffset is | |||
| set, but the value is zero, there is | |||
| no video frame within this cycle. */ | |||
| /*}@*/ | |||
| /*@{*/ | |||
| /** @name Other fields */ | |||
| /* For binary compatibility, new fields should be allocated from | |||
| * this padding area with new valid bits controlling access, so | |||
| * the existing structure size and offsets are preserved. */ | |||
| int32_t padding[7]; | |||
| /*}@*/ | |||
| /* When (unique_1 == unique_2) the contents are consistent. */ | |||
| jack_unique_t unique_2; /**< unique ID */ | |||
| } POST_PACKED_STRUCTURE jack_position_t; | |||
| /** | |||
| * @defgroup TransportControl Transport and Timebase control | |||
| * @{ | |||
| */ | |||
| /** | |||
| * Called by the timebase master to release itself from that | |||
| * responsibility. | |||
| * | |||
| * If the timebase master releases the timebase or leaves the JACK | |||
| * graph for any reason, the JACK engine takes over at the start of | |||
| * the next process cycle. The transport state does not change. If | |||
| * rolling, it continues to play, with frame numbers as the only | |||
| * available position information. | |||
| * | |||
| * @see jack_set_timebase_callback | |||
| * | |||
| * @param client the JACK client structure. | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code. | |||
| */ | |||
| int jack_release_timebase (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Prototype for the @a sync_callback defined by @ref slowsyncclients | |||
| * "slow-sync clients". When the client is active, this callback is | |||
| * invoked just before process() in the same thread. This occurs once | |||
| * after registration, then subsequently whenever some client requests | |||
| * a new position, or the transport enters the ::JackTransportStarting | |||
| * state. This realtime function must not wait. | |||
| * | |||
| * The transport @a state will be: | |||
| * | |||
| * - ::JackTransportStopped when a new position is requested; | |||
| * - ::JackTransportStarting when the transport is waiting to start; | |||
| * - ::JackTransportRolling when the timeout has expired, and the | |||
| * position is now a moving target. | |||
| * | |||
| * @param state current transport state. | |||
| * @param pos new transport position. | |||
| * @param arg the argument supplied by jack_set_sync_callback(). | |||
| * | |||
| * @return TRUE (non-zero) when ready to roll. | |||
| */ | |||
| typedef int (*JackSyncCallback)(jack_transport_state_t state, | |||
| jack_position_t *pos, | |||
| void *arg); | |||
| /** | |||
| * Register (or unregister) as a @ref slowsyncclients "slow-sync client", that cannot | |||
| * respond immediately to transport position changes. | |||
| * | |||
| * The @a sync_callback will be invoked at the first available | |||
| * opportunity after its registration is complete. If the client is | |||
| * currently active this will be the following process cycle, | |||
| * otherwise it will be the first cycle after calling jack_activate(). | |||
| * After that, it runs according to the ::JackSyncCallback rules. | |||
| * Clients that don't set a @a sync_callback are assumed to be ready | |||
| * immediately any time the transport wants to start. | |||
| * | |||
| * @param client the JACK client structure. | |||
| * @param sync_callback is a realtime function that returns TRUE when | |||
| * the client is ready. Setting @a sync_callback to NULL declares that | |||
| * this client no longer requires slow-sync processing. | |||
| * @param arg an argument for the @a sync_callback function. | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code. | |||
| */ | |||
| int jack_set_sync_callback (jack_client_t *client, | |||
| JackSyncCallback sync_callback, | |||
| void *arg) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Set the timeout value for @ref slowsyncclients "slow-sync clients". | |||
| * | |||
| * This timeout prevents unresponsive slow-sync clients from | |||
| * completely halting the transport mechanism. The default is two | |||
| * seconds. When the timeout expires, the transport starts rolling, | |||
| * even if some slow-sync clients are still unready. The @a | |||
| * sync_callbacks of these clients continue being invoked, giving them | |||
| * a chance to catch up. | |||
| * | |||
| * @see jack_set_sync_callback | |||
| * | |||
| * @param client the JACK client structure. | |||
| * @param timeout is delay (in microseconds) before the timeout expires. | |||
| * | |||
| * @return 0 on success, otherwise a non-zero error code. | |||
| */ | |||
| int jack_set_sync_timeout (jack_client_t *client, | |||
| jack_time_t timeout) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Prototype for the @a timebase_callback used to provide extended | |||
| * position information. Its output affects all of the following | |||
| * process cycle. This realtime function must not wait. | |||
| * | |||
| * This function is called immediately after process() in the same | |||
| * thread whenever the transport is rolling, or when any client has | |||
| * requested a new position in the previous cycle. The first cycle | |||
| * after jack_set_timebase_callback() is also treated as a new | |||
| * position, or the first cycle after jack_activate() if the client | |||
| * had been inactive. | |||
| * | |||
| * The timebase master may not use its @a pos argument to set @a | |||
| * pos->frame. To change position, use jack_transport_reposition() or | |||
| * jack_transport_locate(). These functions are realtime-safe, the @a | |||
| * timebase_callback can call them directly. | |||
| * | |||
| * @param state current transport state. | |||
| * @param nframes number of frames in current period. | |||
| * @param pos address of the position structure for the next cycle; @a | |||
| * pos->frame will be its frame number. If @a new_pos is FALSE, this | |||
| * structure contains extended position information from the current | |||
| * cycle. If TRUE, it contains whatever was set by the requester. | |||
| * The @a timebase_callback's task is to update the extended | |||
| * information here. | |||
| * @param new_pos TRUE (non-zero) for a newly requested @a pos, or for | |||
| * the first cycle after the @a timebase_callback is defined. | |||
| * @param arg the argument supplied by jack_set_timebase_callback(). | |||
| */ | |||
| typedef void (*JackTimebaseCallback)(jack_transport_state_t state, | |||
| jack_nframes_t nframes, | |||
| jack_position_t *pos, | |||
| int new_pos, | |||
| void *arg); | |||
| /** | |||
| * Register as timebase master for the JACK subsystem. | |||
| * | |||
| * The timebase master registers a callback that updates extended | |||
| * position information such as beats or timecode whenever necessary. | |||
| * Without this extended information, there is no need for this | |||
| * function. | |||
| * | |||
| * There is never more than one master at a time. When a new client | |||
| * takes over, the former @a timebase_callback is no longer called. | |||
| * Taking over the timebase may be done conditionally, so it fails if | |||
| * there was a master already. | |||
| * | |||
| * The method may be called whether the client has been activated or not. | |||
| * | |||
| * @param client the JACK client structure. | |||
| * @param conditional non-zero for a conditional request. | |||
| * @param timebase_callback is a realtime function that returns | |||
| * position information. | |||
| * @param arg an argument for the @a timebase_callback function. | |||
| * | |||
| * @return | |||
| * - 0 on success; | |||
| * - EBUSY if a conditional request fails because there was already a | |||
| * timebase master; | |||
| * - other non-zero error code. | |||
| */ | |||
| int jack_set_timebase_callback (jack_client_t *client, | |||
| int conditional, | |||
| JackTimebaseCallback timebase_callback, | |||
| void *arg) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Reposition the transport to a new frame number. | |||
| * | |||
| * May be called at any time by any client. The new position takes | |||
| * effect in two process cycles. If there are @ref slowsyncclients | |||
| * "slow-sync clients" and the transport is already rolling, it will | |||
| * enter the ::JackTransportStarting state and begin invoking their @a | |||
| * sync_callbacks until ready. This function is realtime-safe. | |||
| * | |||
| * @see jack_transport_reposition, jack_set_sync_callback | |||
| * | |||
| * @param client the JACK client structure. | |||
| * @param frame frame number of new transport position. | |||
| * | |||
| * @return 0 if valid request, non-zero otherwise. | |||
| */ | |||
| int jack_transport_locate (jack_client_t *client, | |||
| jack_nframes_t frame) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Query the current transport state and position. | |||
| * | |||
| * This function is realtime-safe, and can be called from any thread. | |||
| * If called from the process thread, @a pos corresponds to the first | |||
| * frame of the current cycle and the state returned is valid for the | |||
| * entire cycle. | |||
| * | |||
| * @param client the JACK client structure. | |||
| * @param pos pointer to structure for returning current transport | |||
| * position; @a pos->valid will show which fields contain valid data. | |||
| * If @a pos is NULL, do not return position information. | |||
| * | |||
| * @return Current transport state. | |||
| */ | |||
| jack_transport_state_t jack_transport_query (const jack_client_t *client, | |||
| jack_position_t *pos) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Return an estimate of the current transport frame, | |||
| * including any time elapsed since the last transport | |||
| * positional update. | |||
| * | |||
| * @param client the JACK client structure | |||
| */ | |||
| jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Request a new transport position. | |||
| * | |||
| * May be called at any time by any client. The new position takes | |||
| * effect in two process cycles. If there are @ref slowsyncclients | |||
| * "slow-sync clients" and the transport is already rolling, it will | |||
| * enter the ::JackTransportStarting state and begin invoking their @a | |||
| * sync_callbacks until ready. This function is realtime-safe. | |||
| * | |||
| * @see jack_transport_locate, jack_set_sync_callback | |||
| * | |||
| * @param client the JACK client structure. | |||
| * @param pos requested new transport position. Fill pos->valid to specify | |||
| * which fields should be taken into account. If you mark a set of fields | |||
| * as valid, you are expected to fill them all. | |||
| * | |||
| * @return 0 if valid request, EINVAL if position structure rejected. | |||
| */ | |||
| int jack_transport_reposition (jack_client_t *client, | |||
| const jack_position_t *pos) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Start the JACK transport rolling. | |||
| * | |||
| * Any client can make this request at any time. It takes effect no | |||
| * sooner than the next process cycle, perhaps later if there are | |||
| * @ref slowsyncclients "slow-sync clients". This function is realtime-safe. | |||
| * | |||
| * @see jack_set_sync_callback | |||
| * | |||
| * @param client the JACK client structure. | |||
| */ | |||
| void jack_transport_start (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /** | |||
| * Stop the JACK transport. | |||
| * | |||
| * Any client can make this request at any time. It takes effect on | |||
| * the next process cycle. This function is realtime-safe. | |||
| * | |||
| * @param client the JACK client structure. | |||
| */ | |||
| void jack_transport_stop (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT; | |||
| /*@}*/ | |||
| /********************************************************************* | |||
| * The following interfaces are DEPRECATED. They are only provided | |||
| * for compatibility with the earlier JACK transport implementation. | |||
| *********************************************************************/ | |||
| /** | |||
| * Optional struct jack_transport_info_t fields. | |||
| * | |||
| * @see jack_position_bits_t. | |||
| */ | |||
| typedef enum { | |||
| JackTransportState = 0x1, /**< Transport state */ | |||
| JackTransportPosition = 0x2, /**< Frame number */ | |||
| JackTransportLoop = 0x4, /**< Loop boundaries (ignored) */ | |||
| JackTransportSMPTE = 0x8, /**< SMPTE (ignored) */ | |||
| JackTransportBBT = 0x10 /**< Bar, Beat, Tick */ | |||
| } jack_transport_bits_t; | |||
| /** | |||
| * Deprecated struct for transport position information. | |||
| * | |||
| * @deprecated This is for compatibility with the earlier transport | |||
| * interface. Use the jack_position_t struct, instead. | |||
| */ | |||
| typedef struct { | |||
| /* these two cannot be set from clients: the server sets them */ | |||
| jack_nframes_t frame_rate; /**< current frame rate (per second) */ | |||
| jack_time_t usecs; /**< monotonic, free-rolling */ | |||
| jack_transport_bits_t valid; /**< which fields are legal to read */ | |||
| jack_transport_state_t transport_state; | |||
| jack_nframes_t frame; | |||
| jack_nframes_t loop_start; | |||
| jack_nframes_t loop_end; | |||
| long smpte_offset; /**< SMPTE offset (from frame 0) */ | |||
| float smpte_frame_rate; /**< 29.97, 30, 24 etc. */ | |||
| int bar; | |||
| int beat; | |||
| int tick; | |||
| double bar_start_tick; | |||
| float beats_per_bar; | |||
| float beat_type; | |||
| double ticks_per_beat; | |||
| double beats_per_minute; | |||
| } jack_transport_info_t; | |||
| /** | |||
| * Gets the current transport info structure (deprecated). | |||
| * | |||
| * @param client the JACK client structure. | |||
| * @param tinfo current transport info structure. The "valid" field | |||
| * describes which fields contain valid data. | |||
| * | |||
| * @deprecated This is for compatibility with the earlier transport | |||
| * interface. Use jack_transport_query(), instead. | |||
| * | |||
| * @pre Must be called from the process thread. | |||
| */ | |||
| void jack_get_transport_info (jack_client_t *client, | |||
| jack_transport_info_t *tinfo) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; | |||
| /** | |||
| * Set the transport info structure (deprecated). | |||
| * | |||
| * @deprecated This function still exists for compatibility with the | |||
| * earlier transport interface, but it does nothing. Instead, define | |||
| * a ::JackTimebaseCallback. | |||
| */ | |||
| void jack_set_transport_info (jack_client_t *client, | |||
| jack_transport_info_t *tinfo) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __jack_transport_h__ */ | |||
| @@ -0,0 +1,506 @@ | |||
| /* | |||
| Copyright (C) 2001 Paul Davis | |||
| Copyright (C) 2004 Jack O'Quin | |||
| 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 __jack_types_h__ | |||
| #define __jack_types_h__ | |||
| #include <inttypes.h> | |||
| #include <pthread.h> | |||
| typedef int32_t jack_shmsize_t; | |||
| /** | |||
| * Type used to represent sample frame counts. | |||
| */ | |||
| typedef uint32_t jack_nframes_t; | |||
| /** | |||
| * Maximum value that can be stored in jack_nframes_t | |||
| */ | |||
| #define JACK_MAX_FRAMES (4294967295U) /* This should be UINT32_MAX, but | |||
| C++ has a problem with that. */ | |||
| /** | |||
| * Type used to represent the value of free running | |||
| * monotonic clock with units of microseconds. | |||
| */ | |||
| typedef uint64_t jack_time_t; | |||
| /** | |||
| * Maximum size of @a load_init string passed to an internal client | |||
| * jack_initialize() function via jack_internal_client_load(). | |||
| */ | |||
| #define JACK_LOAD_INIT_LIMIT 1024 | |||
| /** | |||
| * jack_intclient_t is an opaque type representing a loaded internal | |||
| * client. You may only access it using the API provided in @ref | |||
| * intclient.h "<jack/intclient.h>". | |||
| */ | |||
| typedef uint64_t jack_intclient_t; | |||
| /** | |||
| * jack_port_t is an opaque type. You may only access it using the | |||
| * API provided. | |||
| */ | |||
| typedef struct _jack_port jack_port_t; | |||
| /** | |||
| * jack_client_t is an opaque type. You may only access it using the | |||
| * API provided. | |||
| */ | |||
| typedef struct _jack_client jack_client_t; | |||
| /** | |||
| * Ports have unique ids. A port registration callback is the only | |||
| * place you ever need to know their value. | |||
| */ | |||
| typedef uint32_t jack_port_id_t; | |||
| /** | |||
| * to make jack API independent of different thread implementations, | |||
| * we define jack_native_thread_t to pthread_t here. | |||
| * (all platforms that jack1 runs on, have pthread) | |||
| */ | |||
| typedef pthread_t jack_native_thread_t; | |||
| /** | |||
| * @ref jack_options_t bits | |||
| */ | |||
| enum JackOptions { | |||
| /** | |||
| * Null value to use when no option bits are needed. | |||
| */ | |||
| JackNullOption = 0x00, | |||
| /** | |||
| * Do not automatically start the JACK server when it is not | |||
| * already running. This option is always selected if | |||
| * \$JACK_NO_START_SERVER is defined in the calling process | |||
| * environment. | |||
| */ | |||
| JackNoStartServer = 0x01, | |||
| /** | |||
| * Use the exact client name requested. Otherwise, JACK | |||
| * automatically generates a unique one, if needed. | |||
| */ | |||
| JackUseExactName = 0x02, | |||
| /** | |||
| * Open with optional <em>(char *) server_name</em> parameter. | |||
| */ | |||
| JackServerName = 0x04, | |||
| /** | |||
| * Load internal client from optional <em>(char *) | |||
| * load_name</em>. Otherwise use the @a client_name. | |||
| */ | |||
| JackLoadName = 0x08, | |||
| /** | |||
| * Pass optional <em>(char *) load_init</em> string to the | |||
| * jack_initialize() entry point of an internal client. | |||
| */ | |||
| JackLoadInit = 0x10, | |||
| /** | |||
| * pass a SessionID Token this allows the sessionmanager to identify the client again. | |||
| */ | |||
| JackSessionID = 0x20 | |||
| }; | |||
| /** Valid options for opening an external client. */ | |||
| #define JackOpenOptions (JackSessionID|JackServerName|JackNoStartServer|JackUseExactName) | |||
| /** Valid options for loading an internal client. */ | |||
| #define JackLoadOptions (JackLoadInit|JackLoadName|JackUseExactName) | |||
| /** | |||
| * Options for several JACK operations, formed by OR-ing together the | |||
| * relevant @ref JackOptions bits. | |||
| */ | |||
| typedef enum JackOptions jack_options_t; | |||
| /** | |||
| * @ref jack_status_t bits | |||
| */ | |||
| enum JackStatus { | |||
| /** | |||
| * Overall operation failed. | |||
| */ | |||
| JackFailure = 0x01, | |||
| /** | |||
| * The operation contained an invalid or unsupported option. | |||
| */ | |||
| JackInvalidOption = 0x02, | |||
| /** | |||
| * The desired client name was not unique. With the @ref | |||
| * JackUseExactName option this situation is fatal. Otherwise, | |||
| * the name was modified by appending a dash and a two-digit | |||
| * number in the range "-01" to "-99". The | |||
| * jack_get_client_name() function will return the exact string | |||
| * that was used. If the specified @a client_name plus these | |||
| * extra characters would be too long, the open fails instead. | |||
| */ | |||
| JackNameNotUnique = 0x04, | |||
| /** | |||
| * The JACK server was started as a result of this operation. | |||
| * Otherwise, it was running already. In either case the caller | |||
| * is now connected to jackd, so there is no race condition. | |||
| * When the server shuts down, the client will find out. | |||
| */ | |||
| JackServerStarted = 0x08, | |||
| /** | |||
| * Unable to connect to the JACK server. | |||
| */ | |||
| JackServerFailed = 0x10, | |||
| /** | |||
| * Communication error with the JACK server. | |||
| */ | |||
| JackServerError = 0x20, | |||
| /** | |||
| * Requested client does not exist. | |||
| */ | |||
| JackNoSuchClient = 0x40, | |||
| /** | |||
| * Unable to load internal client | |||
| */ | |||
| JackLoadFailure = 0x80, | |||
| /** | |||
| * Unable to initialize client | |||
| */ | |||
| JackInitFailure = 0x100, | |||
| /** | |||
| * Unable to access shared memory | |||
| */ | |||
| JackShmFailure = 0x200, | |||
| /** | |||
| * Client's protocol version does not match | |||
| */ | |||
| JackVersionError = 0x400, | |||
| /* | |||
| * BackendError | |||
| */ | |||
| JackBackendError = 0x800, | |||
| /* | |||
| * Client is being shutdown against its will | |||
| */ | |||
| JackClientZombie = 0x1000 | |||
| }; | |||
| /** | |||
| * Status word returned from several JACK operations, formed by | |||
| * OR-ing together the relevant @ref JackStatus bits. | |||
| */ | |||
| typedef enum JackStatus jack_status_t; | |||
| /** | |||
| * @ref jack_latency_callback_mode_t | |||
| */ | |||
| enum JackLatencyCallbackMode { | |||
| /** | |||
| * Latency Callback for Capture Latency. | |||
| * Input Ports have their latency value setup. | |||
| * In the Callback the client needs to set the latency of the output ports | |||
| */ | |||
| JackCaptureLatency, | |||
| /** | |||
| * Latency Callback for Playback Latency. | |||
| * Output Ports have their latency value setup. | |||
| * In the Callback the client needs to set the latency of the input ports | |||
| */ | |||
| JackPlaybackLatency | |||
| }; | |||
| /** | |||
| * Type of Latency Callback (Capture or Playback) | |||
| */ | |||
| typedef enum JackLatencyCallbackMode jack_latency_callback_mode_t; | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * by the engine when port latencies need to be recalculated | |||
| * | |||
| * @param mode playback or capture latency | |||
| * @param arg pointer to a client supplied data | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| typedef void (*JackLatencyCallback)(jack_latency_callback_mode_t mode, void *arg); | |||
| /** | |||
| * the new latency API operates on Ranges. | |||
| */ | |||
| struct _jack_latency_range | |||
| { | |||
| /** | |||
| * minimum latency | |||
| */ | |||
| jack_nframes_t min; | |||
| /** | |||
| * maximum latency | |||
| */ | |||
| jack_nframes_t max; | |||
| }; | |||
| typedef struct _jack_latency_range jack_latency_range_t; | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * by the engine anytime there is work to be done. | |||
| * | |||
| * @pre nframes == jack_get_buffer_size() | |||
| * @pre nframes == pow(2,x) | |||
| * | |||
| * @param nframes number of frames to process | |||
| * @param arg pointer to a client supplied data | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| typedef int (*JackProcessCallback)(jack_nframes_t nframes, void *arg); | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * once after the creation of the thread in which other | |||
| * callbacks will be made. Special thread characteristics | |||
| * can be set from this callback, for example. This is a | |||
| * highly specialized callback and most clients will not | |||
| * and should not use it. | |||
| * | |||
| * @param arg pointer to a client supplied structure | |||
| * | |||
| * @return void | |||
| */ | |||
| typedef void (*JackThreadInitCallback)(void *arg); | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * whenever the processing graph is reordered. | |||
| * | |||
| * @param arg pointer to a client supplied data | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| typedef int (*JackGraphOrderCallback)(void *arg); | |||
| /** | |||
| * Prototype for the client-supplied function that is called whenever | |||
| * an xrun has occured. | |||
| * | |||
| * @see jack_get_xrun_delayed_usecs() | |||
| * | |||
| * @param arg pointer to a client supplied data | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| typedef int (*JackXRunCallback)(void *arg); | |||
| /** | |||
| * Prototype for the @a bufsize_callback that is invoked whenever the | |||
| * JACK engine buffer size changes. Although this function is called | |||
| * in the JACK process thread, the normal process cycle is suspended | |||
| * during its operation, causing a gap in the audio flow. So, the @a | |||
| * bufsize_callback can allocate storage, touch memory not previously | |||
| * referenced, and perform other operations that are not realtime | |||
| * safe. | |||
| * | |||
| * @param nframes buffer size | |||
| * @param arg pointer supplied by jack_set_buffer_size_callback(). | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| typedef int (*JackBufferSizeCallback)(jack_nframes_t nframes, void *arg); | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * when the engine sample rate changes. | |||
| * | |||
| * @param nframes new engine sample rate | |||
| * @param arg pointer to a client supplied data | |||
| * | |||
| * @return zero on success, non-zero on error | |||
| */ | |||
| typedef int (*JackSampleRateCallback)(jack_nframes_t nframes, void *arg); | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * whenever a port is registered or unregistered. | |||
| * | |||
| * @param port the ID of the port | |||
| * @param arg pointer to a client supplied data | |||
| * @param register non-zero if the port is being registered, | |||
| * zero if the port is being unregistered | |||
| */ | |||
| typedef void (*JackPortRegistrationCallback)(jack_port_id_t port, int register, void *arg); | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * whenever a client is registered or unregistered. | |||
| * | |||
| * @param name a null-terminated string containing the client name | |||
| * @param register non-zero if the client is being registered, | |||
| * zero if the client is being unregistered | |||
| * @param arg pointer to a client supplied data | |||
| */ | |||
| typedef void (*JackClientRegistrationCallback)(const char* name, int register, void *arg); | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * whenever a client is registered or unregistered. | |||
| * | |||
| * @param a one of two ports connected or disconnected | |||
| * @param b one of two ports connected or disconnected | |||
| * @param connect non-zero if ports were connected | |||
| * zero if ports were disconnected | |||
| * @param arg pointer to a client supplied data | |||
| */ | |||
| typedef void (*JackPortConnectCallback)(jack_port_id_t a, jack_port_id_t b, int connect, void* arg); | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * whenever jackd starts or stops freewheeling. | |||
| * | |||
| * @param starting non-zero if we start starting to freewheel, zero otherwise | |||
| * @param arg pointer to a client supplied structure | |||
| */ | |||
| typedef void (*JackFreewheelCallback)(int starting, void *arg); | |||
| typedef void *(*JackThreadCallback)(void* arg); | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * whenever jackd is shutdown. Note that after server shutdown, | |||
| * the client pointer is *not* deallocated by libjack, | |||
| * the application is responsible to properly use jack_client_close() | |||
| * to release client ressources. Warning: jack_client_close() cannot be | |||
| * safely used inside the shutdown callback and has to be called outside of | |||
| * the callback context. | |||
| * | |||
| * @param arg pointer to a client supplied structure | |||
| */ | |||
| typedef void (*JackShutdownCallback)(void *arg); | |||
| /** | |||
| * Prototype for the client supplied function that is called | |||
| * whenever jackd is shutdown. Note that after server shutdown, | |||
| * the client pointer is *not* deallocated by libjack, | |||
| * the application is responsible to properly use jack_client_close() | |||
| * to release client ressources. Warning: jack_client_close() cannot be | |||
| * safely used inside the shutdown callback and has to be called outside of | |||
| * the callback context. | |||
| * | |||
| * @param code a shutdown code | |||
| * @param reason a string describing the shutdown reason (backend failure, server crash... etc...) | |||
| * @param arg pointer to a client supplied structure | |||
| */ | |||
| typedef void (*JackInfoShutdownCallback)(jack_status_t code, const char* reason, void *arg); | |||
| /** | |||
| * Used for the type argument of jack_port_register() for default | |||
| * audio and midi ports. | |||
| */ | |||
| #define JACK_DEFAULT_AUDIO_TYPE "32 bit float mono audio" | |||
| #define JACK_DEFAULT_MIDI_TYPE "8 bit raw midi" | |||
| /** | |||
| * For convenience, use this typedef if you want to be able to change | |||
| * between float and double. You may want to typedef sample_t to | |||
| * jack_default_audio_sample_t in your application. | |||
| */ | |||
| typedef float jack_default_audio_sample_t; | |||
| /** | |||
| * A port has a set of flags that are formed by OR-ing together the | |||
| * desired values from the list below. The flags "JackPortIsInput" and | |||
| * "JackPortIsOutput" are mutually exclusive and it is an error to use | |||
| * them both. | |||
| */ | |||
| enum JackPortFlags { | |||
| /** | |||
| * if JackPortIsInput is set, then the port can receive | |||
| * data. | |||
| */ | |||
| JackPortIsInput = 0x1, | |||
| /** | |||
| * if JackPortIsOutput is set, then data can be read from | |||
| * the port. | |||
| */ | |||
| JackPortIsOutput = 0x2, | |||
| /** | |||
| * if JackPortIsPhysical is set, then the port corresponds | |||
| * to some kind of physical I/O connector. | |||
| */ | |||
| JackPortIsPhysical = 0x4, | |||
| /** | |||
| * if JackPortCanMonitor is set, then a call to | |||
| * jack_port_request_monitor() makes sense. | |||
| * | |||
| * Precisely what this means is dependent on the client. A typical | |||
| * result of it being called with TRUE as the second argument is | |||
| * that data that would be available from an output port (with | |||
| * JackPortIsPhysical set) is sent to a physical output connector | |||
| * as well, so that it can be heard/seen/whatever. | |||
| * | |||
| * Clients that do not control physical interfaces | |||
| * should never create ports with this bit set. | |||
| */ | |||
| JackPortCanMonitor = 0x8, | |||
| /** | |||
| * JackPortIsTerminal means: | |||
| * | |||
| * for an input port: the data received by the port | |||
| * will not be passed on or made | |||
| * available at any other port | |||
| * | |||
| * for an output port: the data available at the port | |||
| * does not originate from any other port | |||
| * | |||
| * Audio synthesizers, I/O hardware interface clients, HDR | |||
| * systems are examples of clients that would set this flag for | |||
| * their ports. | |||
| */ | |||
| JackPortIsTerminal = 0x10 | |||
| }; | |||
| #endif /* __jack_types_h__ */ | |||
| @@ -0,0 +1,26 @@ | |||
| /* -*- mode: c; c-file-style: "bsd"; -*- */ | |||
| /* | |||
| Copyright (C) 2001-2003 Paul Davis | |||
| 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 __jack_mlock_h__ | |||
| #define __jack_mlock_h__ | |||
| extern void cleanup_mlock (void); | |||
| #endif /* __jack_mlock_h__ */ | |||
| @@ -0,0 +1,65 @@ | |||
| /* | |||
| * Copyright (C) 2004 Jack O'Quin | |||
| * | |||
| * 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 __jack_varargs_h__ | |||
| #define __jack_varargs_h__ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /* variable argument structure */ | |||
| typedef struct { | |||
| char *server_name; /* server name */ | |||
| char *load_name; /* load module name */ | |||
| char *load_init; /* initialization string */ | |||
| char *sess_uuid; | |||
| } jack_varargs_t; | |||
| static inline void | |||
| jack_varargs_init (jack_varargs_t *va) | |||
| { | |||
| memset (va, 0, sizeof(jack_varargs_t)); | |||
| va->server_name = jack_default_server_name (); | |||
| } | |||
| static inline void | |||
| jack_varargs_parse (jack_options_t options, va_list ap, jack_varargs_t *va) | |||
| { | |||
| /* initialize default settings */ | |||
| jack_varargs_init (va); | |||
| if ((options & JackServerName)) { | |||
| char *sn = va_arg(ap, char *); | |||
| if (sn) | |||
| va->server_name = sn; | |||
| } | |||
| if ((options & JackLoadName)) | |||
| va->load_name = va_arg(ap, char *); | |||
| if ((options & JackLoadInit)) | |||
| va->load_init = va_arg(ap, char *); | |||
| if ((options & JackSessionID)) | |||
| va->sess_uuid = va_arg(ap, char *); | |||
| } | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* __jack_varargs_h__ */ | |||
| @@ -0,0 +1,20 @@ | |||
| /* | |||
| Copyright (C) 2003 Paul Davis | |||
| @configure_input@ | |||
| This program is free software; you can redistribute it and/or modify | |||
| it under the terms of the GNU General Public License as published by | |||
| the Free Software Foundation; either version 2 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 General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with this program; if not, write to the Free Software | |||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #define jack_protocol_version @JACK_PROTOCOL_VERSION@ | |||
| @@ -0,0 +1,125 @@ | |||
| /* | |||
| Copyright (C) 2010 Paul Davis | |||
| 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 __weakjack_h__ | |||
| #define __weakjack_h__ | |||
| /** | |||
| * @defgroup WeakLinkage managing support for newer/older versions of JACK | |||
| * @{ One challenge faced by developers is that of taking | |||
| * advantage of new features introduced in new versions | |||
| * of [ JACK ] while still supporting older versions of | |||
| * the system. Normally, if an application uses a new | |||
| * feature in a library/API, it is unable to run on | |||
| * earlier versions of the library/API that do not | |||
| * support that feature. Such applications would either | |||
| * fail to launch or crash when an attempt to use the | |||
| * feature was made. This problem cane be solved using | |||
| * weakly-linked symbols. | |||
| * | |||
| * When a symbol in a framework is defined as weakly | |||
| * linked, the symbol does not have to be present at | |||
| * runtime for a process to continue running. The static | |||
| * linker identifies a weakly linked symbol as such in | |||
| * any code module that references the symbol. The | |||
| * dynamic linker uses this same information at runtime | |||
| * to determine whether a process can continue | |||
| * running. If a weakly linked symbol is not present in | |||
| * the framework, the code module can continue to run as | |||
| * long as it does not reference the symbol. However, if | |||
| * the symbol is present, the code can use it normally. | |||
| * | |||
| * (adapted from: http://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html) | |||
| * | |||
| * A concrete example will help. Suppose that someone uses a version | |||
| * of a JACK client we'll call "Jill". Jill was linked against a version | |||
| * of JACK that contains a newer part of the API (say, jack_set_latency_callback()) | |||
| * and would like to use it if it is available. | |||
| * | |||
| * When Jill is run on a system that has a suitably "new" version of | |||
| * JACK, this function will be available entirely normally. But if Jill | |||
| * is run on a system with an old version of JACK, the function isn't | |||
| * available. | |||
| * | |||
| * With normal symbol linkage, this would create a startup error whenever | |||
| * someone tries to run Jill with the "old" version of JACK. However, functions | |||
| * added to JACK after version 0.116.2 are all declared to have "weak" linkage | |||
| * which means that their abscence doesn't cause an error during program | |||
| * startup. Instead, Jill can test whether or not the symbol jack_set_latency_callback | |||
| * is null or not. If its null, it means that the JACK installed on this machine | |||
| * is too old to support this function. If its not null, then Jill can use it | |||
| * just like any other function in the API. For example: | |||
| * | |||
| * \code | |||
| * if (jack_set_latency_callback) { | |||
| * jack_set_latency_callback (jill_client, jill_latency_callback, arg); | |||
| * } | |||
| * \endcode | |||
| * | |||
| * However, there are clients that may want to use this approach to parts of the | |||
| * the JACK API that predate 0.116.2. For example, they might want to see if even | |||
| * really old basic parts of the API like jack_client_open() exist at runtime. | |||
| * | |||
| * Such clients should include <jack/weakjack.h> before any other JACK header. | |||
| * This will make the \b entire JACK API be subject to weak linkage, so that any | |||
| * and all functions can be checked for existence at runtime. It is important | |||
| * to understand that very few clients need to do this - if you use this | |||
| * feature you should have a clear reason to do so. | |||
| * | |||
| * | |||
| */ | |||
| #ifdef __APPLE__ | |||
| #define WEAK_ATTRIBUTE weak_import | |||
| #else | |||
| #define WEAK_ATTRIBUTE __weak__ | |||
| #endif | |||
| #ifndef JACK_OPTIONAL_WEAK_EXPORT | |||
| /* JACK_OPTIONAL_WEAK_EXPORT needs to be a macro which | |||
| expands into a compiler directive. If non-null, the directive | |||
| must tell the compiler to arrange for weak linkage of | |||
| the symbol it used with. For this to work fully may | |||
| require linker arguments for the client as well. | |||
| */ | |||
| #ifdef __GNUC__ | |||
| #define JACK_OPTIONAL_WEAK_EXPORT __attribute__((WEAK_ATTRIBUTE)) | |||
| #else | |||
| /* Add other things here for non-gcc platforms */ | |||
| #endif | |||
| #endif | |||
| #ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT | |||
| /* JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT needs to be a macro | |||
| which expands into a compiler directive. If non-null, the directive | |||
| must tell the compiler to arrange for weak linkage of the | |||
| symbol it is used with AND optionally to mark the symbol | |||
| as deprecated. For this to work fully may require | |||
| linker arguments for the client as well. | |||
| */ | |||
| #ifdef __GNUC__ | |||
| #define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT __attribute__((WEAK_ATTRIBUTE,__deprecated__)) | |||
| #else | |||
| /* Add other things here for non-gcc platforms */ | |||
| #endif | |||
| #endif | |||
| /*@}*/ | |||
| #endif /* weakjack */ | |||
| @@ -0,0 +1,67 @@ | |||
| /* | |||
| Copyright (C) 2010 Paul Davis | |||
| 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 __weakmacros_h__ | |||
| #define __weakmacros_h__ | |||
| /************************************************************* | |||
| * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function | |||
| * added to the JACK API after the 0.116.2 release. | |||
| * | |||
| * Functions that predate this release are marked with | |||
| * JACK_WEAK_OPTIONAL_EXPORT which can be defined at compile | |||
| * time in a variety of ways. The default definition is empty, | |||
| * so that these symbols get normal linkage. If you wish to | |||
| * use all JACK symbols with weak linkage, include | |||
| * <jack/weakjack.h> before jack.h. | |||
| *************************************************************/ | |||
| #ifdef __APPLE__ | |||
| #define WEAK_ATTRIBUTE weak_import | |||
| #else | |||
| #define WEAK_ATTRIBUTE __weak__ | |||
| #endif | |||
| #ifndef JACK_WEAK_EXPORT | |||
| #ifdef __GNUC__ | |||
| /* JACK_WEAK_EXPORT needs to be a macro which | |||
| expands into a compiler directive. If non-null, the directive | |||
| must tell the compiler to arrange for weak linkage of | |||
| the symbol it used with. For this to work full may | |||
| require linker arguments in the client as well. | |||
| */ | |||
| #define JACK_WEAK_EXPORT __attribute__((WEAK_ATTRIBUTE)) | |||
| #else | |||
| /* Add other things here for non-gcc platforms */ | |||
| #endif | |||
| #endif | |||
| #ifndef JACK_OPTIONAL_WEAK_EXPORT | |||
| #define JACK_OPTIONAL_WEAK_EXPORT | |||
| #endif | |||
| #ifndef JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT | |||
| #ifdef __GNUC__ | |||
| #define JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT __attribute__((__deprecated__)) | |||
| #else | |||
| /* Add other things here for non-gcc platforms */ | |||
| #endif /* __GNUC__ */ | |||
| #endif | |||
| #endif /* __weakmacros_h__ */ | |||