mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
Improve loop callbacks
Pass just one data item to the callbacks. Add properties to port. Add user data to link Handle autolink with multiple ports More work on jack support
This commit is contained in:
parent
cfd9967637
commit
9ad1f911b2
38 changed files with 1773 additions and 271 deletions
|
|
@ -27,10 +27,6 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/mman.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <jack/jack.h>
|
||||
#include <jack/session.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
|
@ -48,11 +44,8 @@
|
|||
#include "pipewire/data-loop.h"
|
||||
#include "pipewire/main-loop.h"
|
||||
|
||||
#include "modules/module-jack/defs.h"
|
||||
#include "modules/module-jack/shm.h"
|
||||
#include "modules/module-jack/shared.h"
|
||||
#include "modules/module-jack/synchro.h"
|
||||
#include "modules/module-jack/server.h"
|
||||
#include "modules/module-jack/jack.h"
|
||||
#include "modules/module-jack/jack-node.h"
|
||||
|
||||
#ifndef UNIX_PATH_MAX
|
||||
#define UNIX_PATH_MAX 108
|
||||
|
|
@ -72,7 +65,6 @@ struct socket {
|
|||
|
||||
struct pw_loop *loop;
|
||||
struct spa_source *source;
|
||||
char *core_name;
|
||||
struct spa_list link;
|
||||
};
|
||||
|
||||
|
|
@ -82,6 +74,8 @@ struct impl {
|
|||
struct pw_module *module;
|
||||
struct spa_list link;
|
||||
|
||||
struct spa_source *timer;
|
||||
|
||||
struct pw_properties *properties;
|
||||
|
||||
struct spa_list socket_list;
|
||||
|
|
@ -90,6 +84,8 @@ struct impl {
|
|||
struct spa_loop_control_hooks hooks;
|
||||
|
||||
struct jack_server server;
|
||||
|
||||
struct pw_link *sink_link;
|
||||
};
|
||||
|
||||
struct client {
|
||||
|
|
@ -101,6 +97,31 @@ struct client {
|
|||
struct spa_source *source;
|
||||
};
|
||||
|
||||
static bool init_socket_name(struct sockaddr_un *addr, const char *name, bool promiscuous, int which)
|
||||
{
|
||||
int name_size;
|
||||
const char *runtime_dir;
|
||||
|
||||
runtime_dir = JACK_SOCKET_DIR;
|
||||
|
||||
addr->sun_family = AF_UNIX;
|
||||
if (promiscuous) {
|
||||
name_size = snprintf(addr->sun_path, sizeof(addr->sun_path),
|
||||
"%s/jack_%s_%d", runtime_dir, name, which) + 1;
|
||||
} else {
|
||||
name_size = snprintf(addr->sun_path, sizeof(addr->sun_path),
|
||||
"%s/jack_%s_%d_%d", runtime_dir, name, getuid(), which) + 1;
|
||||
}
|
||||
|
||||
if (name_size > (int) sizeof(addr->sun_path)) {
|
||||
pw_log_error("socket path \"%s/%s\" plus null terminator exceeds 108 bytes",
|
||||
runtime_dir, name);
|
||||
*addr->sun_path = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int process_messages(struct client *client);
|
||||
|
||||
static void client_destroy(void *data)
|
||||
|
|
@ -116,6 +137,10 @@ static void client_destroy(void *data)
|
|||
static int
|
||||
handle_register_port(struct client *client)
|
||||
{
|
||||
struct impl *impl = client->impl;
|
||||
struct jack_server *server = &impl->server;
|
||||
struct jack_graph_manager *mgr = server->graph_manager;
|
||||
struct jack_connection_manager *conn;
|
||||
int result = 0;
|
||||
int ref_num;
|
||||
char name[JACK_PORT_NAME_SIZE + 1];
|
||||
|
|
@ -123,6 +148,8 @@ handle_register_port(struct client *client)
|
|||
unsigned int flags;
|
||||
unsigned int buffer_size;
|
||||
static jack_port_id_t port_index = 0;
|
||||
jack_port_type_id_t type_id;
|
||||
struct jack_client *jc;
|
||||
|
||||
CheckSize(kRegisterPort_size);
|
||||
CheckRead(&ref_num, sizeof(int));
|
||||
|
|
@ -131,10 +158,45 @@ handle_register_port(struct client *client)
|
|||
CheckRead(&flags, sizeof(unsigned int));
|
||||
CheckRead(&buffer_size, sizeof(unsigned int));
|
||||
|
||||
pw_log_error("protocol-jack %p: kRegisterPort %d %s %s %u %u", client->impl,
|
||||
pw_log_debug("protocol-jack %p: kRegisterPort %d %s %s %u %u", impl,
|
||||
ref_num, name, port_type, flags, buffer_size);
|
||||
port_index++;
|
||||
|
||||
type_id = jack_port_get_type_id(port_type);
|
||||
|
||||
if (jack_graph_manager_find_port(mgr, name) != NO_PORT) {
|
||||
pw_log_error("protocol-jack %p: port_name %s exists", impl, name);
|
||||
result = -1;
|
||||
goto reply;
|
||||
}
|
||||
|
||||
port_index = jack_graph_manager_allocate_port(mgr, ref_num, name, type_id, flags);
|
||||
if (port_index == NO_PORT) {
|
||||
pw_log_error("protocol-jack %p: failed to create port name %s", impl, name);
|
||||
result = -1;
|
||||
goto reply;
|
||||
}
|
||||
|
||||
jc = server->client_table[ref_num];
|
||||
pw_jack_node_add_port(jc->node,
|
||||
flags & JackPortIsInput ?
|
||||
PW_DIRECTION_INPUT :
|
||||
PW_DIRECTION_OUTPUT,
|
||||
port_index);
|
||||
|
||||
conn = jack_graph_manager_next_start(mgr);
|
||||
|
||||
if (jack_connection_manager_add_port(conn, (flags & JackPortIsInput) ? true : false,
|
||||
ref_num, port_index) < 0) {
|
||||
pw_log_error("protocol-jack %p: failed to add port", impl);
|
||||
jack_graph_manager_release_port(mgr, port_index);
|
||||
result = -1;
|
||||
goto reply_stop;
|
||||
}
|
||||
|
||||
reply_stop:
|
||||
jack_graph_manager_next_stop(mgr);
|
||||
|
||||
reply:
|
||||
CheckWrite(&result, sizeof(int));
|
||||
CheckWrite(&port_index, sizeof(jack_port_id_t));
|
||||
return 0;
|
||||
|
|
@ -143,6 +205,10 @@ handle_register_port(struct client *client)
|
|||
static int
|
||||
handle_activate_client(struct client *client)
|
||||
{
|
||||
struct impl *impl = client->impl;
|
||||
struct jack_server *server = &impl->server;
|
||||
struct jack_graph_manager *mgr = server->graph_manager;
|
||||
struct jack_connection_manager *conn;
|
||||
int result = 0;
|
||||
int ref_num;
|
||||
int is_real_time;
|
||||
|
|
@ -151,9 +217,16 @@ handle_activate_client(struct client *client)
|
|||
CheckRead(&ref_num, sizeof(int));
|
||||
CheckRead(&is_real_time, sizeof(int));
|
||||
|
||||
pw_log_error("protocol-jack %p: kActivateClient %d %d", client->impl,
|
||||
pw_log_debug("protocol-jack %p: kActivateClient %d %d", client->impl,
|
||||
ref_num, is_real_time);
|
||||
|
||||
conn = jack_graph_manager_next_start(mgr);
|
||||
|
||||
jack_connection_manager_direct_connect(conn, server->freewheel_ref_num, ref_num);
|
||||
jack_connection_manager_direct_connect(conn, ref_num, server->freewheel_ref_num);
|
||||
|
||||
jack_graph_manager_next_stop(mgr);
|
||||
|
||||
CheckWrite(&result, sizeof(int));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -161,15 +234,31 @@ handle_activate_client(struct client *client)
|
|||
static int
|
||||
handle_deactivate_client(struct client *client)
|
||||
{
|
||||
struct impl *impl = client->impl;
|
||||
struct jack_server *server = &impl->server;
|
||||
struct jack_graph_manager *mgr = server->graph_manager;
|
||||
struct jack_connection_manager *conn;
|
||||
int result = 0;
|
||||
int ref_num;
|
||||
int ref_num, fw_ref;
|
||||
|
||||
CheckSize(kDeactivateClient_size);
|
||||
CheckRead(&ref_num, sizeof(int));
|
||||
|
||||
pw_log_error("protocol-jack %p: kDeactivateClient %d", client->impl,
|
||||
pw_log_debug("protocol-jack %p: kDeactivateClient %d", client->impl,
|
||||
ref_num);
|
||||
|
||||
fw_ref = server->freewheel_ref_num;
|
||||
|
||||
conn = jack_graph_manager_next_start(mgr);
|
||||
|
||||
if (jack_connection_manager_is_direct_connection(conn, fw_ref, ref_num))
|
||||
jack_connection_manager_direct_disconnect(conn, fw_ref, ref_num);
|
||||
|
||||
if (jack_connection_manager_is_direct_connection(conn, ref_num, fw_ref))
|
||||
jack_connection_manager_direct_disconnect(conn, ref_num, fw_ref);
|
||||
|
||||
jack_graph_manager_next_stop(mgr);
|
||||
|
||||
CheckWrite(&result, sizeof(int));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -192,7 +281,7 @@ handle_client_check(struct client *client)
|
|||
CheckRead(&UUID, sizeof(int));
|
||||
CheckRead(&open, sizeof(int));
|
||||
|
||||
pw_log_error("protocol-jack %p: kClientCheck %s %d %d %d %d", client->impl,
|
||||
pw_log_debug("protocol-jack %p: kClientCheck %s %d %d %d %d", client->impl,
|
||||
name, protocol, options, UUID, open);
|
||||
|
||||
status = 0;
|
||||
|
|
@ -215,16 +304,74 @@ handle_client_check(struct client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
notify_client(struct jack_client *client, int ref_num, const char *name, int notify,
|
||||
int sync, const char* message, int value1, int value2)
|
||||
{
|
||||
int size, result = 0;
|
||||
char _name[JACK_CLIENT_NAME_SIZE+1];
|
||||
char _message[JACK_MESSAGE_SIZE+1];
|
||||
|
||||
if (client->fd == 0)
|
||||
return 0;
|
||||
|
||||
snprintf(_name, sizeof(_name), "%s", name);
|
||||
snprintf(_message, sizeof(_message), "%s", message);
|
||||
|
||||
size = sizeof(int) + sizeof(_name) + 5 * sizeof(int) + sizeof(_message);
|
||||
CheckWrite(&size, sizeof(int));
|
||||
CheckWrite(_name, sizeof(_name));
|
||||
CheckWrite(&ref_num, sizeof(int));
|
||||
CheckWrite(¬ify, sizeof(int));
|
||||
CheckWrite(&value1, sizeof(int));
|
||||
CheckWrite(&value2, sizeof(int));
|
||||
CheckWrite(&sync, sizeof(int));
|
||||
CheckWrite(_message, sizeof(_message));
|
||||
|
||||
if (sync)
|
||||
CheckRead(&result, sizeof(int));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
notify_add_client(struct impl *impl, struct jack_client *client, const char *name, int ref_num)
|
||||
{
|
||||
struct jack_server *server = &impl->server;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CLIENT_NUM; i++) {
|
||||
struct jack_client *c = server->client_table[i];
|
||||
const char *n;
|
||||
|
||||
if (c == NULL || c == client)
|
||||
continue;
|
||||
|
||||
n = c->control->name;
|
||||
if (notify_client(c, ref_num, name, jack_notify_AddClient, false, "", 0, 0) < 0) {
|
||||
pw_log_warn("module-jack %p: can't notify client", impl);
|
||||
}
|
||||
if (notify_client(client, i, n, jack_notify_AddClient, true, "", 0, 0) < 0) {
|
||||
pw_log_error("module-jack %p: can't notify client", impl);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_client_open(struct client *client)
|
||||
{
|
||||
struct impl *impl = client->impl;
|
||||
struct jack_server *server = &impl->server;
|
||||
struct jack_graph_manager *mgr = server->graph_manager;
|
||||
struct jack_connection_manager *conn;
|
||||
int PID, UUID;
|
||||
char name[JACK_CLIENT_NAME_SIZE+1];
|
||||
int result, ref_num, shared_engine, shared_client, shared_graph;
|
||||
int result = -1, ref_num, shared_engine, shared_client, shared_graph;
|
||||
struct jack_client *jc;
|
||||
const struct ucred *ucred;
|
||||
struct sockaddr_un addr;
|
||||
|
||||
CheckSize(kClientOpen_size);
|
||||
CheckRead(&PID, sizeof(int));
|
||||
|
|
@ -233,7 +380,7 @@ handle_client_open(struct client *client)
|
|||
|
||||
ref_num = jack_server_allocate_ref_num(server);
|
||||
if (ref_num == -1) {
|
||||
result = -1;
|
||||
pw_log_error("module-jack %p: can't allocated ref_num", impl);
|
||||
goto reply;
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +394,20 @@ handle_client_open(struct client *client)
|
|||
0,
|
||||
false,
|
||||
server->promiscuous) < 0) {
|
||||
result = -1;
|
||||
pw_log_error("module-jack %p: can't init synchro", impl);
|
||||
goto reply;
|
||||
}
|
||||
|
||||
if ((jc->fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
pw_log_error("module-jack %p: can't create socket %s", impl, strerror(errno));
|
||||
goto reply;
|
||||
}
|
||||
|
||||
if (!init_socket_name(&addr, name, server->promiscuous, 0))
|
||||
goto reply;
|
||||
|
||||
if (connect(jc->fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||
pw_log_error("module-jack %p: can't connect socket %s", impl, strerror(errno));
|
||||
goto reply;
|
||||
}
|
||||
|
||||
|
|
@ -255,17 +415,31 @@ handle_client_open(struct client *client)
|
|||
|
||||
jc->control = jack_client_control_alloc(name, ucred ? ucred->pid : 0, ref_num, -1);
|
||||
if (jc->control == NULL) {
|
||||
result = -1;
|
||||
pw_log_error("module-jack %p: can't create control", impl);
|
||||
goto reply;
|
||||
}
|
||||
|
||||
server->client_table[ref_num] = jc;
|
||||
pw_log_debug("module-jack %p: Added client %d \"%s\"", impl, ref_num, name);
|
||||
|
||||
conn = jack_graph_manager_next_start(mgr);
|
||||
jack_connection_manager_init_ref_num(conn, ref_num);
|
||||
jack_graph_manager_next_stop(mgr);
|
||||
|
||||
jc->node = pw_jack_node_new(impl->core, pw_module_get_global(impl->module),
|
||||
server, ref_num, NULL);
|
||||
|
||||
if (notify_add_client(impl, jc, name, ref_num) < 0) {
|
||||
pw_log_error("module-jack %p: can't notify add_client", impl);
|
||||
goto reply;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
shared_engine = impl->server.engine_control->info.index;
|
||||
shared_client = jc->control->info.index;
|
||||
shared_graph = impl->server.graph_manager->info.index;
|
||||
|
||||
result = 0;
|
||||
|
||||
reply:
|
||||
CheckWrite(&result, sizeof(int));
|
||||
CheckWrite(&shared_engine, sizeof(int));
|
||||
|
|
@ -290,16 +464,123 @@ handle_client_close(struct client *client)
|
|||
static int
|
||||
handle_connect_name_ports(struct client *client)
|
||||
{
|
||||
struct impl *impl = client->impl;
|
||||
struct jack_server *server = &impl->server;
|
||||
struct jack_graph_manager *mgr = server->graph_manager;
|
||||
struct jack_connection_manager *conn;
|
||||
struct jack_client *jc;
|
||||
int ref_num;
|
||||
char src[REAL_JACK_PORT_NAME_SIZE+1];
|
||||
char dst[REAL_JACK_PORT_NAME_SIZE+1];
|
||||
int result = 0;
|
||||
int result = -1, in_ref, out_ref;
|
||||
jack_port_id_t src_id, dst_id;
|
||||
struct jack_port *src_port, *dst_port;
|
||||
struct pw_port *out_port, *in_port;
|
||||
struct pw_link *link;
|
||||
|
||||
CheckSize(kConnectNamePorts_size);
|
||||
CheckRead(&ref_num, sizeof(int));
|
||||
CheckRead(src, sizeof(src));
|
||||
CheckRead(dst, sizeof(dst));
|
||||
|
||||
src_id = jack_graph_manager_find_port(mgr, src);
|
||||
if (src_id == NO_PORT) {
|
||||
pw_log_error("protocol-jack %p: port_name %s does not exist", impl, src);
|
||||
goto reply;
|
||||
}
|
||||
dst_id = jack_graph_manager_find_port(mgr, dst);
|
||||
if (dst_id == NO_PORT) {
|
||||
pw_log_error("protocol-jack %p: port_name %s does not exist", impl, dst);
|
||||
goto reply;
|
||||
}
|
||||
|
||||
pw_log_debug("protocol-jack %p: kConnectNamePort %d %s %s %u %u", impl,
|
||||
ref_num, src, dst, src_id, dst_id);
|
||||
|
||||
src_port = jack_graph_manager_get_port(mgr, src_id);
|
||||
dst_port = jack_graph_manager_get_port(mgr, dst_id);
|
||||
|
||||
if (((src_port->flags & JackPortIsOutput) == 0) ||
|
||||
((dst_port->flags & JackPortIsInput) == 0)) {
|
||||
pw_log_error("protocol-jack %p: ports are not input and output", impl);
|
||||
goto reply;
|
||||
}
|
||||
|
||||
if (!src_port->in_use || !dst_port->in_use) {
|
||||
pw_log_error("protocol-jack %p: ports are not in use", impl);
|
||||
goto reply;
|
||||
}
|
||||
if (src_port->type_id != dst_port->type_id) {
|
||||
pw_log_error("protocol-jack %p: ports are not of the same type", impl);
|
||||
goto reply;
|
||||
}
|
||||
|
||||
conn = jack_graph_manager_next_start(mgr);
|
||||
|
||||
out_ref = jack_connection_manager_get_output_refnum(conn, src_id);
|
||||
if (out_ref == -1) {
|
||||
pw_log_error("protocol-jack %p: unknown port_id %d", impl, src_id);
|
||||
goto reply_stop;
|
||||
}
|
||||
if ((jc = server->client_table[out_ref]) == NULL) {
|
||||
pw_log_error("protocol-jack %p: unknown client %d", impl, out_ref);
|
||||
goto reply_stop;
|
||||
}
|
||||
if (!jc->control->active) {
|
||||
pw_log_error("protocol-jack %p: can't connect ports of inactive client", impl);
|
||||
goto reply_stop;
|
||||
}
|
||||
out_port = pw_jack_node_find_port(jc->node, PW_DIRECTION_OUTPUT, src_id);
|
||||
|
||||
in_ref = jack_connection_manager_get_input_refnum(conn, dst_id);
|
||||
if (in_ref == -1) {
|
||||
pw_log_error("protocol-jack %p: unknown port_id %d", impl, dst_id);
|
||||
goto reply_stop;
|
||||
}
|
||||
if ((jc = server->client_table[in_ref]) == NULL) {
|
||||
pw_log_error("protocol-jack %p: unknown client %d", impl, in_ref);
|
||||
goto reply_stop;
|
||||
}
|
||||
if (!jc->control->active) {
|
||||
pw_log_error("protocol-jack %p: can't connect ports of inactive client", impl);
|
||||
goto reply_stop;
|
||||
}
|
||||
in_port = pw_jack_node_find_port(jc->node, PW_DIRECTION_INPUT, dst_id);
|
||||
|
||||
if (jack_connection_manager_is_connected(conn, src_id, dst_id)) {
|
||||
pw_log_error("protocol-jack %p: ports are already connected", impl);
|
||||
goto reply_stop;
|
||||
}
|
||||
if (jack_connection_manager_connect(conn, src_id, dst_id) < 0) {
|
||||
pw_log_error("protocol-jack %p: connection table is full", impl);
|
||||
goto reply_stop;
|
||||
}
|
||||
if (jack_connection_manager_connect(conn, dst_id, src_id) < 0) {
|
||||
pw_log_error("protocol-jack %p: connection table is full", impl);
|
||||
goto reply_stop;
|
||||
}
|
||||
if (jack_connection_manager_is_loop_path(conn, src_id, dst_id) < 0)
|
||||
jack_connection_manager_inc_feedback_connection(conn, src_id, dst_id);
|
||||
else
|
||||
jack_connection_manager_inc_direct_connection(conn, src_id, dst_id);
|
||||
|
||||
pw_log_debug("%p %p", out_port, in_port);
|
||||
|
||||
link = pw_link_new(impl->core,
|
||||
pw_module_get_global(impl->module),
|
||||
out_port,
|
||||
in_port,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
pw_link_activate(link);
|
||||
|
||||
result = 0;
|
||||
reply_stop:
|
||||
jack_graph_manager_next_stop(mgr);
|
||||
|
||||
reply:
|
||||
CheckWrite(&result, sizeof(int));
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -417,8 +698,7 @@ client_busy_changed(void *data, bool busy)
|
|||
}
|
||||
|
||||
static void
|
||||
connection_data(struct spa_loop_utils *utils,
|
||||
struct spa_source *source, int fd, enum spa_io mask, void *data)
|
||||
connection_data(void *data, int fd, enum spa_io mask)
|
||||
{
|
||||
struct client *client = data;
|
||||
|
||||
|
|
@ -473,7 +753,7 @@ static struct client *client_new(struct impl *impl, int fd)
|
|||
|
||||
pw_client_add_listener(client, &this->client_listener, &client_events, this);
|
||||
|
||||
pw_log_error("module-jack %p: added new client", impl);
|
||||
pw_log_debug("module-jack %p: added new client", impl);
|
||||
|
||||
return this;
|
||||
|
||||
|
|
@ -484,9 +764,10 @@ static struct client *client_new(struct impl *impl, int fd)
|
|||
}
|
||||
|
||||
static int
|
||||
make_int_client(struct impl *impl, struct pw_node *node)
|
||||
make_audio_client(struct impl *impl)
|
||||
{
|
||||
struct jack_server *server = &impl->server;
|
||||
struct jack_graph_manager *mgr = server->graph_manager;
|
||||
struct jack_connection_manager *conn;
|
||||
int ref_num;
|
||||
struct jack_client *jc;
|
||||
|
|
@ -507,7 +788,6 @@ make_int_client(struct impl *impl, struct pw_node *node)
|
|||
|
||||
jc = calloc(1,sizeof(struct jack_client));
|
||||
jc->ref_num = ref_num;
|
||||
jc->node = node;
|
||||
jc->control = jack_client_control_alloc("system", -1, ref_num, -1);
|
||||
jc->control->active = true;
|
||||
|
||||
|
|
@ -515,26 +795,89 @@ make_int_client(struct impl *impl, struct pw_node *node)
|
|||
|
||||
impl->server.engine_control->driver_num++;
|
||||
|
||||
conn = jack_graph_manager_next_start(server->graph_manager);
|
||||
conn = jack_graph_manager_next_start(mgr);
|
||||
|
||||
jack_connection_manager_init_ref_num(conn, ref_num);
|
||||
jack_connection_manager_direct_connect(conn, ref_num, ref_num);
|
||||
|
||||
port_id = jack_graph_manager_allocate_port(server->graph_manager,
|
||||
ref_num, "system:playback_1", 2,
|
||||
JackPortIsInput | JackPortIsPhysical | JackPortIsTerminal);
|
||||
|
||||
port_id = jack_graph_manager_allocate_port(mgr,
|
||||
ref_num, "system:playback_1", 0,
|
||||
JackPortIsInput |
|
||||
JackPortIsPhysical |
|
||||
JackPortIsTerminal);
|
||||
jack_connection_manager_add_port(conn, true, ref_num, port_id);
|
||||
|
||||
jack_graph_manager_next_stop(server->graph_manager);
|
||||
port_id = jack_graph_manager_allocate_port(mgr,
|
||||
ref_num, "system:playback_2", 0,
|
||||
JackPortIsInput |
|
||||
JackPortIsPhysical |
|
||||
JackPortIsTerminal);
|
||||
jack_connection_manager_add_port(conn, true, ref_num, port_id);
|
||||
|
||||
jack_graph_manager_next_stop(mgr);
|
||||
|
||||
server->audio_ref_num = ref_num;
|
||||
|
||||
server->audio_node = pw_jack_node_new(impl->core, pw_module_get_global(impl->module),
|
||||
server, ref_num, NULL);
|
||||
server->audio_node_node = pw_jack_node_get_node(server->audio_node);
|
||||
jc->node = server->audio_node;
|
||||
|
||||
pw_log_debug("module-jack %p: Added audio driver %d", impl, ref_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
make_freewheel_client(struct impl *impl)
|
||||
{
|
||||
struct jack_server *server = &impl->server;
|
||||
struct jack_graph_manager *mgr = server->graph_manager;
|
||||
struct jack_connection_manager *conn;
|
||||
int ref_num;
|
||||
struct jack_client *jc;
|
||||
|
||||
ref_num = jack_server_allocate_ref_num(server);
|
||||
if (ref_num == -1)
|
||||
return -1;
|
||||
|
||||
if (jack_synchro_init(&server->synchro_table[ref_num],
|
||||
"freewheel",
|
||||
server->engine_control->server_name,
|
||||
0,
|
||||
false,
|
||||
server->promiscuous) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
jc = calloc(1,sizeof(struct jack_client));
|
||||
jc->ref_num = ref_num;
|
||||
jc->control = jack_client_control_alloc("freewheel", -1, ref_num, -1);
|
||||
jc->control->active = true;
|
||||
|
||||
server->client_table[ref_num] = jc;
|
||||
|
||||
impl->server.engine_control->driver_num++;
|
||||
|
||||
conn = jack_graph_manager_next_start(mgr);
|
||||
|
||||
jack_connection_manager_init_ref_num(conn, ref_num);
|
||||
jack_connection_manager_direct_connect(conn, ref_num, ref_num);
|
||||
|
||||
jack_graph_manager_next_stop(mgr);
|
||||
|
||||
server->freewheel_ref_num = ref_num;
|
||||
pw_log_debug("module-jack %p: Added freewheel driver %d", impl, ref_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool on_global(void *data, struct pw_global *global)
|
||||
|
||||
{
|
||||
struct impl *impl = data;
|
||||
struct pw_node *node;
|
||||
struct pw_properties *properties;
|
||||
struct pw_node *node, *n;
|
||||
const struct pw_properties *properties;
|
||||
const char *str;
|
||||
|
||||
if (pw_global_get_type(global) != impl->t->node)
|
||||
|
|
@ -549,16 +892,78 @@ static bool on_global(void *data, struct pw_global *global)
|
|||
if (strcmp(str, "Audio/Sink") != 0)
|
||||
return true;
|
||||
|
||||
make_int_client(impl, node);
|
||||
return true;
|
||||
n = pw_jack_node_get_node(impl->server.audio_node);
|
||||
|
||||
impl->sink_link = pw_link_new(impl->core, pw_module_get_global(impl->module),
|
||||
pw_node_get_free_port(n, PW_DIRECTION_OUTPUT),
|
||||
pw_node_get_free_port(node, PW_DIRECTION_INPUT),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
pw_link_inc_idle(impl->sink_link);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void on_timeout(void *data, uint64_t expirations)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
struct jack_server *server = &impl->server;
|
||||
struct jack_graph_manager *mgr = server->graph_manager;
|
||||
struct jack_connection_manager *conn;
|
||||
struct jack_client *client;
|
||||
int activation;
|
||||
|
||||
client = server->client_table[server->freewheel_ref_num];
|
||||
|
||||
conn = jack_graph_manager_try_switch(mgr);
|
||||
|
||||
jack_connection_manager_reset(conn, mgr->client_timing);
|
||||
|
||||
activation = jack_connection_manager_get_activation(conn, server->freewheel_ref_num);
|
||||
if (activation == 0)
|
||||
return;
|
||||
|
||||
pw_log_trace("resume %d", activation);
|
||||
jack_connection_manager_resume_ref_num(conn,
|
||||
client->control,
|
||||
server->synchro_table,
|
||||
mgr->client_timing);
|
||||
|
||||
if (server->engine_control->sync_mode) {
|
||||
pw_log_trace("suspend");
|
||||
jack_connection_manager_suspend_ref_num(conn,
|
||||
client->control,
|
||||
server->synchro_table,
|
||||
mgr->client_timing);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool init_nodes(struct impl *impl)
|
||||
{
|
||||
struct pw_core *core = impl->core;
|
||||
#if 0
|
||||
struct timespec timeout, interval;
|
||||
#endif
|
||||
|
||||
make_audio_client(impl);
|
||||
make_freewheel_client(impl);
|
||||
|
||||
#if 0
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_nsec = 1;
|
||||
interval.tv_sec = 0;
|
||||
interval.tv_nsec = 10 * SPA_NSEC_PER_MSEC;
|
||||
|
||||
impl->timer = pw_loop_add_timer(pw_core_get_main_loop(impl->core), on_timeout, impl);
|
||||
pw_loop_update_timer(pw_core_get_main_loop(impl->core), impl->timer, &timeout, &interval, false);
|
||||
#endif
|
||||
|
||||
pw_core_for_each_global(core, on_global, impl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -586,36 +991,8 @@ static void destroy_socket(struct socket *s)
|
|||
free(s);
|
||||
}
|
||||
|
||||
static bool init_socket_name(struct socket *s, const char *name, bool promiscuous, int which)
|
||||
{
|
||||
int name_size;
|
||||
const char *runtime_dir;
|
||||
|
||||
runtime_dir = JACK_SOCKET_DIR;
|
||||
|
||||
s->addr.sun_family = AF_UNIX;
|
||||
if (promiscuous) {
|
||||
name_size = snprintf(s->addr.sun_path, sizeof(s->addr.sun_path),
|
||||
"%s/jack_%s_%d", runtime_dir, name, which) + 1;
|
||||
} else {
|
||||
name_size = snprintf(s->addr.sun_path, sizeof(s->addr.sun_path),
|
||||
"%s/jack_%s_%d_%d", runtime_dir, name, getuid(), which) + 1;
|
||||
}
|
||||
|
||||
s->core_name = (s->addr.sun_path + name_size - 1) - strlen(name);
|
||||
|
||||
if (name_size > (int) sizeof(s->addr.sun_path)) {
|
||||
pw_log_error("socket path \"%s/%s\" plus null terminator exceeds 108 bytes",
|
||||
runtime_dir, name);
|
||||
*s->addr.sun_path = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
socket_data(struct spa_loop_utils *utils,
|
||||
struct spa_source *source, int fd, enum spa_io mask, void *data)
|
||||
socket_data(void *data, int fd, enum spa_io mask)
|
||||
{
|
||||
struct impl *impl = data;
|
||||
struct client *client;
|
||||
|
|
@ -682,6 +1059,8 @@ static int init_server(struct impl *impl, const char *name, bool promiscuous)
|
|||
|
||||
jack_cleanup_shm();
|
||||
|
||||
server->promiscuous = promiscuous;
|
||||
|
||||
/* graph manager */
|
||||
server->graph_manager = jack_graph_manager_alloc(2048);
|
||||
|
||||
|
|
@ -696,7 +1075,7 @@ static int init_server(struct impl *impl, const char *name, bool promiscuous)
|
|||
|
||||
s = create_socket();
|
||||
|
||||
if (!init_socket_name(s, name, promiscuous, 0))
|
||||
if (!init_socket_name(&s->addr, name, promiscuous, 0))
|
||||
goto error;
|
||||
|
||||
if (!add_socket(impl, s))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue