/* -*- 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. $Id$ */ #ifndef __jack_internal_h__ #define __jack_internal_h__ #include #include #include #include #include #include #include #if defined(__APPLE__) && defined(__POWERPC__) #include "mach_port.h" #endif #include #include #include #include #include #ifdef DEBUG_ENABLED #define DEBUG(format,args...) \ fprintf (stderr, "jack:%5d:%" PRIu64 " %s:%s:%d: " format "\n", getpid(), jack_get_microseconds(), __FILE__, __FUNCTION__, __LINE__ , ## args) #else #if defined(__APPLE__) && defined(__POWERPC__) #define DEBUG(format...) #else #define DEBUG(format,args...) #endif #endif #ifndef FALSE #define FALSE (0) #endif #ifndef TRUE #define TRUE (!FALSE) #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 jack_time_t guard1; volatile jack_nframes_t frames; volatile jack_time_t stamp; volatile jack_time_t guard2; } 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 uint32_t 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 */ uint32_t sync_clients; /* number of is_slowsync clients */ uint32_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_nframes_t frames_at_cycle_start; pid_t engine_pid; jack_nframes_t buffer_size; int8_t real_time; int32_t client_priority; int32_t has_capabilities; float cpu_load; uint32_t port_max; int32_t engine_ok; uint32_t n_port_types; jack_port_type_info_t port_types[JACK_MAX_PORT_TYPES]; jack_port_shared_t ports[0]; } jack_control_t; typedef enum { BufferSizeChange, SampleRateChange, AttachPortSegment, PortConnected, PortDisconnected, GraphReordered, PortRegistered, PortUnregistered, XRun, StartFreewheel, StopFreewheel } EventType; typedef struct { EventType type; union { uint32_t n; 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; } 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_nframes_t nframes; /* w: engine r: client */ volatile jack_client_state_t state; /* w: engine and client r: engine */ volatile int8_t name[JACK_CLIENT_NAME_SIZE+1]; volatile ClientType type; /* w: engine r: engine and client */ volatile int8_t active : 1; /* w: engine r: engine and client */ volatile int8_t dead : 1; /* r/w: engine */ volatile int8_t timed_out : 1; /* r/w: engine */ volatile int8_t is_timebase : 1; /* w: engine, r: engine and client */ volatile int8_t is_slowsync : 1; /* w: engine, r: engine and client */ volatile int8_t sync_poll : 1; /* w: engine and client, r: engine */ volatile int8_t sync_new : 1; /* 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; /* JOQ: all these pointers are trouble for 32/64 compatibility, * they should move to non-shared memory. */ /* callbacks */ JackProcessCallback process; void *process_arg; JackBufferSizeCallback bufsize; void *bufsize_arg; JackSampleRateCallback srate; void *srate_arg; JackPortRegistrationCallback port_register; void *port_register_arg; JackGraphOrderCallback graph_order; void *graph_order_arg; JackXRunCallback xrun; void *xrun_arg; JackSyncCallback sync_cb; void *sync_arg; JackTimebaseCallback timebase_cb; void *timebase_arg; /* external clients: set by libjack * internal clients: set by engine */ int (*deliver_request)(void*, jack_request_t*); void *deliver_arg; /* for engine use only */ void *private_client; } jack_client_control_t; typedef struct { int32_t load; ClientType type; char name[JACK_CLIENT_NAME_SIZE+1]; char object_path[PATH_MAX+1]; char object_data[1024]; } jack_client_connect_request_t; typedef struct { int32_t status; uint32_t protocol_v; jack_shm_info_t client_shm; jack_shm_info_t engine_shm; char fifo_prefix[PATH_MAX+1]; int32_t realtime; int32_t realtime_priority; /* these two are valid only if the connect request was for type == ClientDriver. */ jack_client_control_t *client_control; /* JOQ: 64/32 problem */ jack_control_t *engine_control; /* JOQ: 64/32 problem */ #if defined(__APPLE__) && defined(__POWERPC__) /* specific resources for server/client real-time thread communication */ int32_t portnum; #endif } jack_client_connect_result_t; typedef struct { jack_client_id_t client_id; } jack_client_connect_ack_request_t; typedef struct { int8_t status; } 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, } RequestType; struct _jack_request { RequestType type; union { struct { char name[JACK_PORT_NAME_SIZE+1]; char type[JACK_PORT_TYPE_SIZE+1]; uint32_t flags; jack_shmsize_t buffer_size; jack_port_id_t port_id; jack_client_id_t client_id; } port_info; struct { char source_port[JACK_PORT_NAME_SIZE+1]; char destination_port[JACK_PORT_NAME_SIZE+1]; } connect; struct { int32_t nports; const char **ports; /* JOQ: 32/64 problem? */ } port_connections; struct { jack_client_id_t client_id; int32_t conditional; } timebase; jack_client_id_t client_id; jack_nframes_t nframes; jack_time_t timeout; } x; int32_t status; }; /* per-client structure allocated in the server's address space * its 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 *fed_by; /* protected by engine->client_lock */ 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; #if defined(__APPLE__) && defined(__POWERPC__) /* specific resources for server/client real-time thread communication */ mach_port_t serverport; trivial_message message; int running; int portnum; #endif } jack_client_internal_t; extern void jack_cleanup_files (); 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_server_dir; extern void *jack_zero_filled_buffer; extern void jack_error (const char *fmt, ...); extern jack_port_functions_t jack_builtin_audio_functions; extern jack_port_type_info_t jack_builtin_port_types[]; extern void jack_client_invalidate_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 int jack_acquire_real_time_scheduling (pthread_t, int priority); extern int jack_drop_real_time_scheduling (pthread_t); void silent_jack_error_callback (const char *desc); #endif /* __jack_internal_h__ */