UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
jack_common.h File Reference
#include <cassert>
#include <cerrno>
#include <cstring>
#include <jack/jack.h>
#include <stdio.h>
#include <stdlib.h>
#include "compat/dlfunc.h"
#include "debug.h"
#include "types.h"
#include "utils/macros.h"
Include dependency graph for jack_common.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  libjack_connection
 

Macros

#define JACK_DLSYM(sym)
 
#define MOD_NAME   "[jack_common] "
 

Typedefs

typedef int(* jack_activate_t) (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT
 
typedef int(* jack_client_close_t) (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT
 
typedef jack_client_t *(* jack_client_open_t) (const char *client_name, jack_options_t options, jack_status_t *status,...) JACK_OPTIONAL_WEAK_EXPORT
 
typedef int(* jack_connect_t) (jack_client_t *client, const char *source_port, const char *destination_port) JACK_OPTIONAL_WEAK_EXPORT
 
typedef int(* jack_deactivate_t) (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT
 
typedef int(* jack_disconnect_t) (jack_client_t *client, const char *source_port, const char *destination_port) JACK_OPTIONAL_WEAK_EXPORT
 
typedef void(* jack_free_t) (void *ptr) JACK_OPTIONAL_WEAK_EXPORT
 
typedef const char **(* jack_get_ports_t) (jack_client_t *client, const char *port_name_pattern, const char *type_name_pattern, unsigned long flags) JACK_OPTIONAL_WEAK_EXPORT
 
typedef jack_nframes_t(* jack_get_sample_rate_t) (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT
 
typedef void *(* jack_port_get_buffer_t) (jack_port_t *port, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT
 
typedef const char *(* jack_port_name_t) (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT
 
typedef jack_port_t *(* jack_port_register_t) (jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size) JACK_OPTIONAL_WEAK_EXPORT
 
typedef int(* jack_set_process_callback_t) (jack_client_t *client, JackProcessCallback process_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT
 
typedef int(* jack_set_sample_rate_callback_t) (jack_client_t *client, JackSampleRateCallback srate_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT
 

Functions

static struct device_info * audio_jack_probe (const char *client_name, unsigned long port_flags, int *count)
 
static void close_libjack (struct libjack_connection *s)
 
static bool load_jack_symbols (struct libjack_connection *s)
 
static struct libjack_connection * open_libjack (void)
 

Detailed Description

Macro Definition Documentation

◆ JACK_DLSYM

#define JACK_DLSYM ( sym)
Value:
s->sym = (void *) dlsym(s->libjack, "jack_" #sym); if (s->sym == NULL) { log_msg(LOG_LEVEL_ERROR, "JACK symbol %s not found: %s\n", "jack_" #sym, dlerror()); return false; }
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59

Definition at line 135 of file jack_common.h.

Referenced by load_jack_symbols().

◆ MOD_NAME

#define MOD_NAME   "[jack_common] "

Definition at line 67 of file jack_common.h.

Typedef Documentation

◆ jack_activate_t

typedef int(* jack_activate_t) (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 69 of file jack_common.h.

◆ jack_client_close_t

typedef int(* jack_client_close_t) (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 70 of file jack_common.h.

◆ jack_client_open_t

typedef jack_client_t *(* jack_client_open_t) (const char *client_name, jack_options_t options, jack_status_t *status,...) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 71 of file jack_common.h.

◆ jack_connect_t

typedef int(* jack_connect_t) (jack_client_t *client, const char *source_port, const char *destination_port) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 74 of file jack_common.h.

◆ jack_deactivate_t

typedef int(* jack_deactivate_t) (jack_client_t *client) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 77 of file jack_common.h.

◆ jack_disconnect_t

typedef int(* jack_disconnect_t) (jack_client_t *client, const char *source_port, const char *destination_port) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 78 of file jack_common.h.

◆ jack_free_t

typedef void(* jack_free_t) (void *ptr) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 81 of file jack_common.h.

◆ jack_get_ports_t

typedef const char **(* jack_get_ports_t) (jack_client_t *client, const char *port_name_pattern, const char *type_name_pattern, unsigned long flags) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 82 of file jack_common.h.

◆ jack_get_sample_rate_t

typedef jack_nframes_t(* jack_get_sample_rate_t) (jack_client_t *) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 86 of file jack_common.h.

◆ jack_port_get_buffer_t

typedef void *(* jack_port_get_buffer_t) (jack_port_t *port, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 87 of file jack_common.h.

◆ jack_port_name_t

typedef const char *(* jack_port_name_t) (const jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 88 of file jack_common.h.

◆ jack_port_register_t

typedef jack_port_t *(* jack_port_register_t) (jack_client_t *client, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 89 of file jack_common.h.

◆ jack_set_process_callback_t

typedef int(* jack_set_process_callback_t) (jack_client_t *client, JackProcessCallback process_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 94 of file jack_common.h.

◆ jack_set_sample_rate_callback_t

typedef int(* jack_set_sample_rate_callback_t) (jack_client_t *client, JackSampleRateCallback srate_callback, void *arg) JACK_OPTIONAL_WEAK_EXPORT

Definition at line 97 of file jack_common.h.

Function Documentation

◆ audio_jack_probe()

static struct device_info * audio_jack_probe ( const char * client_name,
unsigned long port_flags,
int * count )
inlinestatic

Definition at line 213 of file jack_common.h.

216{
217 jack_client_t *client;
218 jack_status_t status;
219 char *last_name = NULL;
220 int i;
221 const char **ports;
222 int port_count = 0;
224 if (!libjack) {
225 return NULL;
226 }
227
228 *count = 0;
229 client = libjack->client_open(client_name, JackNoStartServer, &status);
230 if(status & JackFailure) {
231 log_msg(LOG_LEVEL_ERROR, "Opening JACK client failed.\n");
233 return NULL;
234 }
235
236 ports = libjack->get_ports(client, NULL, NULL, port_flags);
237 if(ports == NULL) {
238 log_msg(LOG_LEVEL_ERROR, "Unable to enumerate JACK ports.\n");
240 return NULL;
241 }
242
243 for(port_count = 0; ports[port_count] != NULL; port_count++);
244
245 struct device_info *available_devices = port_count > 0 ? calloc(port_count, sizeof(struct device_info)) : NULL;
246
247 int channel_count = 0;
248 for(i = 0; ports[i] != NULL; i++) {
249 char *item = strdup(ports[i]);
250 assert(item != NULL);
251 char *save_ptr = NULL;
252 char *name;
253
254 ++channel_count;
255 name = strtok_r(item, "_", &save_ptr);
256 if (name == NULL) { // shouldn't happen
257 log_msg(LOG_LEVEL_ERROR, "Incorrect JACK name: %s!\n", ports[i]);
258 free(item);
259 continue;
260 }
261 if(last_name && strcmp(last_name, name) != 0) {
262 snprintf(available_devices[*count].name, sizeof available_devices[*count].name, "jack:%s (%d channels)", last_name, channel_count);
263 snprintf(available_devices[*count].dev, sizeof available_devices[*count].dev, ":\"%s\"", last_name);
264 channel_count = 0;
265 (*count)++;
266 }
267 free(last_name);
268 last_name = strdup(name);
269 free(item);
270 }
271 if(last_name) {
272 snprintf(available_devices[*count].name, sizeof available_devices[*count].name, "jack:%s (%d channels)", last_name, channel_count);
273 snprintf(available_devices[*count].dev, sizeof available_devices[*count].dev, ":\"%s\"", last_name);
274 (*count)++;
275 }
276 free(last_name);
277 libjack->free(ports);
278 libjack->client_close(client);
279 close_libjack(libjack);
280
281 return available_devices;
282}
int count
Definition hd-rum.c:44
static void close_libjack(struct libjack_connection *s)
static struct libjack_connection * open_libjack(void)
const char * name
Definition settings.cpp:193
char dev[1024]
Definition types.h:383
Definition hd-rum.c:27
jack_client_close_t client_close
LIB_HANDLE libjack
lib connection

References libjack_connection::client_close, close_libjack(), count, device_info::dev, libjack_connection::free, libjack_connection::libjack, LOG_LEVEL_ERROR, log_msg(), name, and open_libjack().

Referenced by audio_cap_jack_help(), audio_cap_jack_probe(), audio_play_jack_help(), and audio_play_jack_probe().

Here is the call graph for this function:

◆ close_libjack()

static void close_libjack ( struct libjack_connection * s)
static

Definition at line 120 of file jack_common.h.

121{
122 if (s == NULL) {
123 return;
124 }
125#ifdef RTLD_DEFAULT
126 if (s->libjack != RTLD_DEFAULT) {
127 dlclose(s->libjack);
128 }
129#else
130 dlclose(s->libjack);
131#endif // defined RTLD_DEFAULT
132 free(s);
133}

References libjack_connection::libjack.

Referenced by audio_cap_jack_done(), audio_cap_jack_init(), audio_jack_probe(), audio_play_jack_done(), audio_play_jack_init(), jack_start(), and open_libjack().

◆ load_jack_symbols()

static bool load_jack_symbols ( struct libjack_connection * s)
static

Definition at line 137 of file jack_common.h.

138{
139 JACK_DLSYM(activate);
140 JACK_DLSYM(client_close)
141 JACK_DLSYM(client_open)
142 JACK_DLSYM(connect);
143 JACK_DLSYM(deactivate);
144 JACK_DLSYM(disconnect);
145 JACK_DLSYM(free)
146 JACK_DLSYM(get_ports)
147 JACK_DLSYM(get_sample_rate);
148 JACK_DLSYM(set_sample_rate_callback);
149 JACK_DLSYM(port_get_buffer);
150 JACK_DLSYM(port_name);
151 JACK_DLSYM(port_register);
152 JACK_DLSYM(set_process_callback);
153 return true;
154}
#define JACK_DLSYM(sym)

References JACK_DLSYM.

Referenced by open_libjack().

◆ open_libjack()

static struct libjack_connection * open_libjack ( void )
static

Definition at line 156 of file jack_common.h.

157{
158 struct libjack_connection *s = calloc(1, sizeof(struct libjack_connection));
159
160#ifdef RTLD_DEFAULT
161 // try to load from already loaded library (eg. by LD_PRELOAD), RTLD_DEFAULT is POSIX-only
162 if (dlsym(RTLD_DEFAULT, "jack_activate") != NULL) {
163 s->libjack = RTLD_DEFAULT;
164 if (load_jack_symbols(s)) {
165 log_msg(LOG_LEVEL_VERBOSE, "Using preloaded JACK library.\n");
166 return s;
167 }
168 }
169#endif
170
171 const char *shlib[] = {
172#ifdef _WIN32
173 "C:/Windows/libjack64.dll"
174#elif defined(__APPLE__)
175#ifdef __aarch64__
176 "/opt/homebrew/lib/libjack.dylib",
177#endif // defined __aarch64__
178 "libjack.dylib",
179 "/usr/local/lib/libjack.dylib"
180#elif defined(__linux__)
181 "libjack.so"
182#endif
183 };
184 char err[STR_LEN];
185 err[0] = '\0';
186 for (unsigned i = 0; i < sizeof shlib / sizeof shlib[0]; ++i) {
187 s->libjack = dlopen(shlib[i], RTLD_NOW);
188 if (s->libjack != NULL) {
189 MSG(VERBOSE, "library loaded from: %s\n", shlib[i]);
190 break;
191 }
192 snprintf(err + strlen(err), sizeof err - strlen(err),
193 "JACK library \"%s\" opening failed: %s\n", shlib[i],
194 dlerror());
195 }
196 if (s->libjack == NULL) {
197 log_msg(LOG_LEVEL_ERROR, "%s", err);
198 free(s);
199 return NULL;
200 }
201 if (!load_jack_symbols(s)) {
202 close_libjack(s);
203 return NULL;
204 }
205#ifdef HAVE_DLINFO
206 char path[MAX_PATH_SIZE] = "(unknown)";
207 dlinfo(s->libjack, RTLD_DI_ORIGIN, path); // nonstandard GNU extension
208 log_msg(LOG_LEVEL_VERBOSE, "Loaded JACK library from %s.\n", path);
209#endif // defined HAVE_DLINFO
210 return s;
211}
#define LOG_LEVEL_VERBOSE
Definition debug.h:63
#define MSG(l, fmt,...)
Definition debug.h:96
#define MAX_PATH_SIZE
Definition fs.h:48
static bool load_jack_symbols(struct libjack_connection *s)
@ STR_LEN
"standard" string length placeholder
Definition macros.h:134

References close_libjack(), libjack_connection::free, libjack_connection::libjack, load_jack_symbols(), LOG_LEVEL_ERROR, LOG_LEVEL_VERBOSE, log_msg(), MAX_PATH_SIZE, MSG, and STR_LEN.

Referenced by audio_cap_jack_init(), audio_jack_probe(), audio_play_jack_init(), and jack_start().

Here is the call graph for this function: