Browse Source

Import jack1 headers from svn r4772

tags/0.124.0
Nedko Arnaudov 13 years ago
commit
2476dca8c1
35 changed files with 6914 additions and 0 deletions
  1. +42
    -0
      Makefile.am
  2. +38
    -0
      atomicity.h
  3. +111
    -0
      bitset.h
  4. +565
    -0
      control.h
  5. +304
    -0
      driver.h
  6. +123
    -0
      driver_interface.h
  7. +212
    -0
      driver_parse.h
  8. +272
    -0
      engine.h
  9. +65
    -0
      hardware.h
  10. +129
    -0
      intclient.h
  11. +561
    -0
      internal.h
  12. +56
    -0
      intsimd.h
  13. +1226
    -0
      jack.h
  14. +303
    -0
      jslist.h
  15. +115
    -0
      memops.h
  16. +44
    -0
      messagebuffer.h
  17. +174
    -0
      midiport.h
  18. +28
    -0
      pool.h
  19. +188
    -0
      port.h
  20. +235
    -0
      ringbuffer.h
  21. +22
    -0
      sanitycheck.h
  22. +289
    -0
      session.h
  23. +110
    -0
      shm.h
  24. +21
    -0
      start.h
  25. +56
    -0
      statistics.h
  26. +97
    -0
      systemtest.h
  27. +135
    -0
      thread.h
  28. +40
    -0
      timestamps.h
  29. +544
    -0
      transport.h
  30. +506
    -0
      types.h
  31. +26
    -0
      unlock.h
  32. +65
    -0
      varargs.h
  33. +20
    -0
      version.h.in
  34. +125
    -0
      weakjack.h
  35. +67
    -0
      weakmacros.h

+ 42
- 0
Makefile.am View File

@@ -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

+ 38
- 0
atomicity.h View File

@@ -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__ */

+ 111
- 0
bitset.h View File

@@ -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__ */

+ 565
- 0
control.h View File

@@ -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 */

+ 304
- 0
driver.h View File

@@ -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__ */

+ 123
- 0
driver_interface.h View File

@@ -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__ */



+ 212
- 0
driver_parse.h View File

@@ -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__ */



+ 272
- 0
engine.h View File

@@ -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__ */

+ 65
- 0
hardware.h View File

@@ -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__ */

+ 129
- 0
intclient.h View File

@@ -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__ */

+ 561
- 0
internal.h View File

@@ -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__ */


+ 56
- 0
intsimd.h View File

@@ -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__ */


+ 1226
- 0
jack.h
File diff suppressed because it is too large
View File


+ 303
- 0
jslist.h View File

@@ -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__ */

+ 115
- 0
memops.h View File

@@ -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__ */

+ 44
- 0
messagebuffer.h View File

@@ -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__ */

+ 174
- 0
midiport.h View File

@@ -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 */



+ 28
- 0
pool.h View File

@@ -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__ */

+ 188
- 0
port.h View File

@@ -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__ */


+ 235
- 0
ringbuffer.h View File

@@ -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

+ 22
- 0
sanitycheck.h View File

@@ -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__ */

+ 289
- 0
session.h View File

@@ -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

+ 110
- 0
shm.h View File

@@ -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__ */

+ 21
- 0
start.h View File

@@ -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)

+ 56
- 0
statistics.h View File

@@ -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__ */

+ 97
- 0
systemtest.h View File

@@ -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__ */

+ 135
- 0
thread.h View File

@@ -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__ */

+ 40
- 0
timestamps.h View File

@@ -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__ */



+ 544
- 0
transport.h View File

@@ -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__ */

+ 506
- 0
types.h View File

@@ -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__ */

+ 26
- 0
unlock.h View File

@@ -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__ */

+ 65
- 0
varargs.h View File

@@ -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__ */

+ 20
- 0
version.h.in View File

@@ -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@

+ 125
- 0
weakjack.h View File

@@ -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 */

+ 67
- 0
weakmacros.h View File

@@ -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__ */

Loading…
Cancel
Save