mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
jack: add latency reporting
Rework the param handling a little. Keep properties for ports. Use this in the client and port info. Trigger the latency callback when the port latency changed. Update the port latency when it changed.
This commit is contained in:
parent
bae0622311
commit
4af2014168
1 changed files with 187 additions and 89 deletions
|
|
@ -136,8 +136,6 @@ struct object {
|
||||||
uint32_t node_id;
|
uint32_t node_id;
|
||||||
uint32_t port_id;
|
uint32_t port_id;
|
||||||
uint32_t monitor_requests;
|
uint32_t monitor_requests;
|
||||||
jack_latency_range_t capture_latency;
|
|
||||||
jack_latency_range_t playback_latency;
|
|
||||||
int32_t priority;
|
int32_t priority;
|
||||||
struct port *port;
|
struct port *port;
|
||||||
bool is_monitor;
|
bool is_monitor;
|
||||||
|
|
@ -207,6 +205,15 @@ struct port {
|
||||||
enum spa_direction direction;
|
enum spa_direction direction;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
struct object *object;
|
struct object *object;
|
||||||
|
struct pw_properties *props;
|
||||||
|
struct spa_port_info info;
|
||||||
|
#define IDX_EnumFormat 0
|
||||||
|
#define IDX_Buffers 1
|
||||||
|
#define IDX_IO 2
|
||||||
|
#define IDX_Format 3
|
||||||
|
#define IDX_Latency 4
|
||||||
|
#define N_PORT_PARAMS 5
|
||||||
|
struct spa_param_info params[N_PORT_PARAMS];
|
||||||
|
|
||||||
struct spa_io_buffers io;
|
struct spa_io_buffers io;
|
||||||
struct spa_list mix;
|
struct spa_list mix;
|
||||||
|
|
@ -215,6 +222,8 @@ struct port {
|
||||||
unsigned int empty_out:1;
|
unsigned int empty_out:1;
|
||||||
unsigned int zeroed:1;
|
unsigned int zeroed:1;
|
||||||
|
|
||||||
|
struct spa_latency_info latency[2];
|
||||||
|
|
||||||
float *emptyptr;
|
float *emptyptr;
|
||||||
float empty[MAX_BUFFER_FRAMES + MAX_ALIGN];
|
float empty[MAX_BUFFER_FRAMES + MAX_ALIGN];
|
||||||
|
|
||||||
|
|
@ -279,6 +288,8 @@ struct client {
|
||||||
int last_res;
|
int last_res;
|
||||||
bool error;
|
bool error;
|
||||||
|
|
||||||
|
struct spa_node_info info;
|
||||||
|
|
||||||
struct pw_registry *registry;
|
struct pw_registry *registry;
|
||||||
struct spa_hook registry_listener;
|
struct spa_hook registry_listener;
|
||||||
|
|
||||||
|
|
@ -528,6 +539,11 @@ static struct port * alloc_port(struct client *c, enum spa_direction direction)
|
||||||
p->client = c;
|
p->client = c;
|
||||||
p->object = o;
|
p->object = o;
|
||||||
spa_list_init(&p->mix);
|
spa_list_init(&p->mix);
|
||||||
|
p->props = pw_properties_new(NULL, NULL);
|
||||||
|
p->latency[SPA_DIRECTION_INPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
|
||||||
|
p->latency[SPA_DIRECTION_OUTPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
|
||||||
|
o->port.latency[SPA_DIRECTION_INPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
|
||||||
|
o->port.latency[SPA_DIRECTION_OUTPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
|
||||||
|
|
||||||
spa_list_append(&c->ports[direction], &p->link);
|
spa_list_append(&c->ports[direction], &p->link);
|
||||||
|
|
||||||
|
|
@ -551,6 +567,7 @@ static void free_port(struct client *c, struct port *p)
|
||||||
spa_list_remove(&p->link);
|
spa_list_remove(&p->link);
|
||||||
p->valid = false;
|
p->valid = false;
|
||||||
free_object(c, p->object);
|
free_object(c, p->object);
|
||||||
|
pw_properties_free(p->props);
|
||||||
spa_list_append(&c->free_ports[p->direction], &p->link);
|
spa_list_append(&c->free_ports[p->direction], &p->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1630,6 +1647,13 @@ static int param_io(struct client *c, struct port *p,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int param_latency(struct client *c, struct port *p,
|
||||||
|
struct spa_pod **param, struct spa_pod_builder *b)
|
||||||
|
{
|
||||||
|
*param = spa_latency_build(b, SPA_PARAM_Latency, &p->latency[p->direction]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int port_set_format(struct client *c, struct port *p,
|
static int port_set_format(struct client *c, struct port *p,
|
||||||
uint32_t flags, const struct spa_pod *param)
|
uint32_t flags, const struct spa_pod *param)
|
||||||
{
|
{
|
||||||
|
|
@ -1681,6 +1705,40 @@ static int port_set_format(struct client *c, struct port *p,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int port_set_latency(struct client *c, struct port *p,
|
||||||
|
uint32_t flags, const struct spa_pod *param)
|
||||||
|
{
|
||||||
|
struct spa_latency_info info;
|
||||||
|
jack_latency_callback_mode_t mode;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (param == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((res = spa_latency_parse(param, &info)) < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
p->latency[info.direction] = info;
|
||||||
|
if (p->object)
|
||||||
|
p->object->port.latency[info.direction] = info;
|
||||||
|
|
||||||
|
pw_log_info("port %p: set %s latency %f-%f %d-%d %"PRIu64"-%"PRIu64, p,
|
||||||
|
info.direction == SPA_DIRECTION_INPUT ? "playback" : "capture",
|
||||||
|
info.min_quantum, info.max_quantum,
|
||||||
|
info.min_rate, info.max_rate,
|
||||||
|
info.min_ns, info.max_ns);
|
||||||
|
|
||||||
|
if (info.direction == SPA_DIRECTION_INPUT)
|
||||||
|
mode = JackPlaybackLatency;
|
||||||
|
else
|
||||||
|
mode = JackCaptureLatency;
|
||||||
|
|
||||||
|
if (c->latency_callback)
|
||||||
|
c->latency_callback(mode, c->latency_arg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int client_node_port_set_param(void *object,
|
static int client_node_port_set_param(void *object,
|
||||||
enum spa_direction direction,
|
enum spa_direction direction,
|
||||||
uint32_t port_id,
|
uint32_t port_id,
|
||||||
|
|
@ -1689,26 +1747,34 @@ static int client_node_port_set_param(void *object,
|
||||||
{
|
{
|
||||||
struct client *c = (struct client *) object;
|
struct client *c = (struct client *) object;
|
||||||
struct port *p = GET_PORT(c, direction, port_id);
|
struct port *p = GET_PORT(c, direction, port_id);
|
||||||
struct spa_pod *params[4];
|
struct spa_pod *params[5];
|
||||||
uint8_t buffer[4096];
|
uint8_t buffer[4096];
|
||||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||||
|
|
||||||
pw_log_debug("port %p: %d.%d id:%d %p", p, direction, port_id, id, param);
|
pw_log_debug("port %p: %d.%d id:%d %p", p, direction, port_id, id, param);
|
||||||
|
|
||||||
if (id == SPA_PARAM_Format) {
|
switch (id) {
|
||||||
|
case SPA_PARAM_Format:
|
||||||
port_set_format(c, p, flags, param);
|
port_set_format(c, p, flags, param);
|
||||||
|
break;
|
||||||
|
case SPA_PARAM_Latency:
|
||||||
|
port_set_latency(c, p, flags, param);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
param_enum_format(c, p, ¶ms[0], &b);
|
param_enum_format(c, p, ¶ms[0], &b);
|
||||||
param_format(c, p, ¶ms[1], &b);
|
param_format(c, p, ¶ms[1], &b);
|
||||||
param_buffers(c, p, ¶ms[2], &b);
|
param_buffers(c, p, ¶ms[2], &b);
|
||||||
param_io(c, p, ¶ms[3], &b);
|
param_io(c, p, ¶ms[3], &b);
|
||||||
|
param_latency(c, p, ¶ms[4], &b);
|
||||||
|
|
||||||
return pw_client_node_port_update(c->node,
|
return pw_client_node_port_update(c->node,
|
||||||
direction,
|
direction,
|
||||||
port_id,
|
port_id,
|
||||||
PW_CLIENT_NODE_PORT_UPDATE_PARAMS,
|
PW_CLIENT_NODE_PORT_UPDATE_PARAMS,
|
||||||
4,
|
5,
|
||||||
(const struct spa_pod **) params,
|
(const struct spa_pod **) params,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -2370,6 +2436,8 @@ static void registry_event_global(void *data, uint32_t id,
|
||||||
o->port.port_id = SPA_ID_INVALID;
|
o->port.port_id = SPA_ID_INVALID;
|
||||||
o->port.priority = ot->node.priority;
|
o->port.priority = ot->node.priority;
|
||||||
o->port.node = ot;
|
o->port.node = ot;
|
||||||
|
o->port.latency[SPA_DIRECTION_INPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
|
||||||
|
o->port.latency[SPA_DIRECTION_OUTPUT] = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
|
||||||
|
|
||||||
o->proxy = pw_registry_bind(c->registry,
|
o->proxy = pw_registry_bind(c->registry,
|
||||||
id, type, PW_VERSION_PORT, 0);
|
id, type, PW_VERSION_PORT, 0);
|
||||||
|
|
@ -2584,7 +2652,6 @@ jack_client_t * jack_client_open (const char *client_name,
|
||||||
uint32_t n_support;
|
uint32_t n_support;
|
||||||
const char *str;
|
const char *str;
|
||||||
struct spa_cpu *cpu_iface;
|
struct spa_cpu *cpu_iface;
|
||||||
struct spa_node_info ni;
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
if (getenv("PIPEWIRE_NOJACK") != NULL ||
|
if (getenv("PIPEWIRE_NOJACK") != NULL ||
|
||||||
|
|
@ -2746,15 +2813,17 @@ jack_client_t * jack_client_open (const char *client_name,
|
||||||
pw_proxy_add_listener((struct pw_proxy*)client->node,
|
pw_proxy_add_listener((struct pw_proxy*)client->node,
|
||||||
&client->proxy_listener, &node_proxy_events, client);
|
&client->proxy_listener, &node_proxy_events, client);
|
||||||
|
|
||||||
ni = SPA_NODE_INFO_INIT();
|
client->info = SPA_NODE_INFO_INIT();
|
||||||
ni.max_input_ports = MAX_PORTS;
|
client->info.max_input_ports = MAX_PORTS;
|
||||||
ni.max_output_ports = MAX_PORTS;
|
client->info.max_output_ports = MAX_PORTS;
|
||||||
ni.change_mask = SPA_NODE_CHANGE_MASK_FLAGS;
|
client->info.change_mask = SPA_NODE_CHANGE_MASK_FLAGS |
|
||||||
ni.flags = SPA_NODE_FLAG_RT;
|
SPA_NODE_CHANGE_MASK_PROPS;
|
||||||
|
client->info.flags = SPA_NODE_FLAG_RT;
|
||||||
|
client->info.props = &client->props->dict;
|
||||||
|
|
||||||
pw_client_node_update(client->node,
|
pw_client_node_update(client->node,
|
||||||
PW_CLIENT_NODE_UPDATE_INFO,
|
PW_CLIENT_NODE_UPDATE_INFO,
|
||||||
0, NULL, &ni);
|
0, NULL, &client->info);
|
||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
*status = 0;
|
*status = 0;
|
||||||
|
|
@ -3343,21 +3412,19 @@ SPA_EXPORT
|
||||||
int jack_set_freewheel(jack_client_t* client, int onoff)
|
int jack_set_freewheel(jack_client_t* client, int onoff)
|
||||||
{
|
{
|
||||||
struct client *c = (struct client *) client;
|
struct client *c = (struct client *) client;
|
||||||
struct spa_node_info ni;
|
|
||||||
struct spa_dict_item items[1];
|
|
||||||
|
|
||||||
pw_log_info(NAME" %p: freewheel %d", client, onoff);
|
pw_log_info(NAME" %p: freewheel %d", client, onoff);
|
||||||
|
|
||||||
ni = SPA_NODE_INFO_INIT();
|
pw_properties_set(c->props, "node.group",
|
||||||
ni.max_input_ports = MAX_PORTS;
|
onoff ? "pipewire.freewheel" : NULL);
|
||||||
ni.max_output_ports = MAX_PORTS;
|
|
||||||
ni.change_mask = SPA_NODE_CHANGE_MASK_PROPS;
|
c->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS;
|
||||||
items[0] = SPA_DICT_ITEM_INIT("node.group", onoff ? "pipewire.freewheel" : "");
|
c->info.props = &c->props->dict;
|
||||||
ni.props = &SPA_DICT_INIT_ARRAY(items);
|
|
||||||
|
|
||||||
pw_client_node_update(c->node,
|
pw_client_node_update(c->node,
|
||||||
PW_CLIENT_NODE_UPDATE_INFO,
|
PW_CLIENT_NODE_UPDATE_INFO,
|
||||||
0, NULL, &ni);
|
0, NULL, &c->info);
|
||||||
|
c->info.change_mask = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -3366,8 +3433,6 @@ SPA_EXPORT
|
||||||
int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes)
|
int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes)
|
||||||
{
|
{
|
||||||
struct client *c = (struct client *) client;
|
struct client *c = (struct client *) client;
|
||||||
struct spa_node_info ni;
|
|
||||||
struct spa_dict_item items[1];
|
|
||||||
char latency[128];
|
char latency[128];
|
||||||
|
|
||||||
spa_return_val_if_fail(c != NULL, -EINVAL);
|
spa_return_val_if_fail(c != NULL, -EINVAL);
|
||||||
|
|
@ -3375,16 +3440,15 @@ int jack_set_buffer_size (jack_client_t *client, jack_nframes_t nframes)
|
||||||
snprintf(latency, sizeof(latency), "%d/%d", nframes, jack_get_sample_rate(client));
|
snprintf(latency, sizeof(latency), "%d/%d", nframes, jack_get_sample_rate(client));
|
||||||
pw_log_info(NAME" %p: buffer-size %s", client, latency);
|
pw_log_info(NAME" %p: buffer-size %s", client, latency);
|
||||||
|
|
||||||
ni = SPA_NODE_INFO_INIT();
|
pw_properties_set(c->props, PW_KEY_NODE_LATENCY, latency);
|
||||||
ni.max_input_ports = MAX_PORTS;
|
|
||||||
ni.max_output_ports = MAX_PORTS;
|
c->info.change_mask |= SPA_NODE_CHANGE_MASK_PROPS;
|
||||||
ni.change_mask = SPA_NODE_CHANGE_MASK_PROPS;
|
c->info.props = &c->props->dict;
|
||||||
items[0] = SPA_DICT_ITEM_INIT(PW_KEY_NODE_LATENCY, latency);
|
|
||||||
ni.props = &SPA_DICT_INIT_ARRAY(items);
|
|
||||||
|
|
||||||
pw_client_node_update(c->node,
|
pw_client_node_update(c->node,
|
||||||
PW_CLIENT_NODE_UPDATE_INFO,
|
PW_CLIENT_NODE_UPDATE_INFO,
|
||||||
0, NULL, &ni);
|
0, NULL, &c->info);
|
||||||
|
c->info.change_mask = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -3475,16 +3539,11 @@ jack_port_t * jack_port_register (jack_client_t *client,
|
||||||
{
|
{
|
||||||
struct client *c = (struct client *) client;
|
struct client *c = (struct client *) client;
|
||||||
enum spa_direction direction;
|
enum spa_direction direction;
|
||||||
struct spa_port_info port_info;
|
|
||||||
struct spa_param_info port_params[5];
|
|
||||||
struct spa_dict dict;
|
|
||||||
struct spa_dict_item items[10];
|
|
||||||
struct object *o;
|
struct object *o;
|
||||||
jack_port_type_id_t type_id;
|
jack_port_type_id_t type_id;
|
||||||
uint8_t buffer[1024];
|
uint8_t buffer[1024];
|
||||||
char port_flags[64];
|
|
||||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||||
struct spa_pod *params[4];
|
struct spa_pod *params[5];
|
||||||
uint32_t n_params = 0;
|
uint32_t n_params = 0;
|
||||||
struct port *p;
|
struct port *p;
|
||||||
int res;
|
int res;
|
||||||
|
|
@ -3548,33 +3607,35 @@ jack_port_t * jack_port_register (jack_client_t *client,
|
||||||
|
|
||||||
spa_list_init(&p->mix);
|
spa_list_init(&p->mix);
|
||||||
|
|
||||||
port_info = SPA_PORT_INFO_INIT();
|
pw_properties_set(p->props, PW_KEY_FORMAT_DSP, port_type);
|
||||||
port_info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
pw_properties_set(p->props, PW_KEY_PORT_NAME, port_name);
|
||||||
port_info.flags = SPA_PORT_FLAG_NO_REF;
|
|
||||||
port_info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
|
||||||
dict = SPA_DICT_INIT(items, 0);
|
|
||||||
items[dict.n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_FORMAT_DSP, port_type);
|
|
||||||
items[dict.n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_PORT_NAME, port_name);
|
|
||||||
if (flags > 0x1f) {
|
if (flags > 0x1f) {
|
||||||
snprintf(port_flags, sizeof(port_flags), "jack:flags:%lu", flags & ~0x1f);
|
pw_properties_setf(p->props, PW_KEY_PORT_EXTRA,
|
||||||
items[dict.n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_PORT_EXTRA, port_flags);
|
"jack:flags:%lu", flags & ~0x1f);
|
||||||
}
|
}
|
||||||
if (flags & JackPortIsPhysical)
|
if (flags & JackPortIsPhysical)
|
||||||
items[dict.n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_PORT_PHYSICAL, "true");
|
pw_properties_set(p->props, PW_KEY_PORT_PHYSICAL, "true");
|
||||||
if (flags & JackPortIsTerminal)
|
if (flags & JackPortIsTerminal)
|
||||||
items[dict.n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_PORT_TERMINAL, "true");
|
pw_properties_set(p->props, PW_KEY_PORT_TERMINAL, "true");
|
||||||
port_info.props = &dict;
|
|
||||||
port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
p->info = SPA_PORT_INFO_INIT();
|
||||||
port_params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
p->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
||||||
port_params[1] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
p->info.flags = SPA_PORT_FLAG_NO_REF;
|
||||||
port_params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
p->info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
||||||
port_params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
p->info.props = &p->props->dict;
|
||||||
port_info.params = port_params;
|
p->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||||
port_info.n_params = 4;
|
p->params[IDX_EnumFormat] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||||
|
p->params[IDX_Buffers] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||||
|
p->params[IDX_IO] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
||||||
|
p->params[IDX_Format] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||||
|
p->params[IDX_Latency] = SPA_PARAM_INFO(SPA_PARAM_Latency, SPA_PARAM_INFO_READWRITE);
|
||||||
|
p->info.params = p->params;
|
||||||
|
p->info.n_params = N_PORT_PARAMS;
|
||||||
|
|
||||||
param_enum_format(c, p, ¶ms[n_params++], &b);
|
param_enum_format(c, p, ¶ms[n_params++], &b);
|
||||||
param_buffers(c, p, ¶ms[n_params++], &b);
|
param_buffers(c, p, ¶ms[n_params++], &b);
|
||||||
param_io(c, p, ¶ms[n_params++], &b);
|
param_io(c, p, ¶ms[n_params++], &b);
|
||||||
|
param_latency(c, p, ¶ms[n_params++], &b);
|
||||||
|
|
||||||
pw_thread_loop_lock(c->context.loop);
|
pw_thread_loop_lock(c->context.loop);
|
||||||
|
|
||||||
|
|
@ -3585,7 +3646,9 @@ jack_port_t * jack_port_register (jack_client_t *client,
|
||||||
PW_CLIENT_NODE_PORT_UPDATE_INFO,
|
PW_CLIENT_NODE_PORT_UPDATE_INFO,
|
||||||
n_params,
|
n_params,
|
||||||
(const struct spa_pod **) params,
|
(const struct spa_pod **) params,
|
||||||
&port_info);
|
&p->info);
|
||||||
|
|
||||||
|
p->info.change_mask = 0;
|
||||||
|
|
||||||
res = do_sync(c);
|
res = do_sync(c);
|
||||||
|
|
||||||
|
|
@ -3945,9 +4008,6 @@ int jack_port_rename (jack_client_t* client, jack_port_t *port, const char *port
|
||||||
struct client *c = (struct client *) client;
|
struct client *c = (struct client *) client;
|
||||||
struct object *o = (struct object *) port;
|
struct object *o = (struct object *) port;
|
||||||
struct port *p;
|
struct port *p;
|
||||||
struct spa_port_info port_info;
|
|
||||||
struct spa_dict dict;
|
|
||||||
struct spa_dict_item items[1];
|
|
||||||
|
|
||||||
spa_return_val_if_fail(c != NULL, -EINVAL);
|
spa_return_val_if_fail(c != NULL, -EINVAL);
|
||||||
spa_return_val_if_fail(o != NULL, -EINVAL);
|
spa_return_val_if_fail(o != NULL, -EINVAL);
|
||||||
|
|
@ -3957,18 +4017,19 @@ int jack_port_rename (jack_client_t* client, jack_port_t *port, const char *port
|
||||||
|
|
||||||
p = GET_PORT(c, GET_DIRECTION(o->port.flags), o->port.port_id);
|
p = GET_PORT(c, GET_DIRECTION(o->port.flags), o->port.port_id);
|
||||||
|
|
||||||
port_info = SPA_PORT_INFO_INIT();
|
pw_properties_set(p->props, PW_KEY_PORT_NAME, port_name);
|
||||||
port_info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
|
||||||
dict = SPA_DICT_INIT(items, 0);
|
p->info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
||||||
items[dict.n_items++] = SPA_DICT_ITEM_INIT(PW_KEY_PORT_NAME, port_name);
|
p->info.props = &p->props->dict;
|
||||||
port_info.props = &dict;
|
|
||||||
|
|
||||||
pw_client_node_port_update(c->node,
|
pw_client_node_port_update(c->node,
|
||||||
p->direction,
|
p->direction,
|
||||||
p->id,
|
p->id,
|
||||||
PW_CLIENT_NODE_PORT_UPDATE_INFO,
|
PW_CLIENT_NODE_PORT_UPDATE_INFO,
|
||||||
0, NULL,
|
0, NULL,
|
||||||
&port_info);
|
&p->info);
|
||||||
|
p->info.change_mask = 0;
|
||||||
|
|
||||||
pw_thread_loop_unlock(c->context.loop);
|
pw_thread_loop_unlock(c->context.loop);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -3980,9 +4041,6 @@ int jack_port_set_alias (jack_port_t *port, const char *alias)
|
||||||
struct object *o = (struct object *) port;
|
struct object *o = (struct object *) port;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
struct port *p;
|
struct port *p;
|
||||||
struct spa_port_info port_info;
|
|
||||||
struct spa_dict dict;
|
|
||||||
struct spa_dict_item items[1];
|
|
||||||
const char *key;
|
const char *key;
|
||||||
|
|
||||||
spa_return_val_if_fail(o != NULL, -EINVAL);
|
spa_return_val_if_fail(o != NULL, -EINVAL);
|
||||||
|
|
@ -4005,18 +4063,19 @@ int jack_port_set_alias (jack_port_t *port, const char *alias)
|
||||||
|
|
||||||
p = GET_PORT(c, GET_DIRECTION(o->port.flags), o->port.port_id);
|
p = GET_PORT(c, GET_DIRECTION(o->port.flags), o->port.port_id);
|
||||||
|
|
||||||
port_info = SPA_PORT_INFO_INIT();
|
pw_properties_set(p->props, key, alias);
|
||||||
port_info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
|
||||||
dict = SPA_DICT_INIT(items, 0);
|
p->info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
||||||
items[dict.n_items++] = SPA_DICT_ITEM_INIT(key, alias);
|
p->info.props = &p->props->dict;
|
||||||
port_info.props = &dict;
|
|
||||||
|
|
||||||
pw_client_node_port_update(c->node,
|
pw_client_node_port_update(c->node,
|
||||||
p->direction,
|
p->direction,
|
||||||
p->id,
|
p->id,
|
||||||
PW_CLIENT_NODE_PORT_UPDATE_INFO,
|
PW_CLIENT_NODE_PORT_UPDATE_INFO,
|
||||||
0, NULL,
|
0, NULL,
|
||||||
&port_info);
|
&p->info);
|
||||||
|
p->info.change_mask = 0;
|
||||||
|
|
||||||
pw_thread_loop_unlock(c->context.loop);
|
pw_thread_loop_unlock(c->context.loop);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -4032,9 +4091,6 @@ int jack_port_unset_alias (jack_port_t *port, const char *alias)
|
||||||
struct object *o = (struct object *) port;
|
struct object *o = (struct object *) port;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
struct port *p;
|
struct port *p;
|
||||||
struct spa_port_info port_info;
|
|
||||||
struct spa_dict dict;
|
|
||||||
struct spa_dict_item items[1];
|
|
||||||
const char *key;
|
const char *key;
|
||||||
|
|
||||||
spa_return_val_if_fail(o != NULL, -EINVAL);
|
spa_return_val_if_fail(o != NULL, -EINVAL);
|
||||||
|
|
@ -4053,18 +4109,20 @@ int jack_port_unset_alias (jack_port_t *port, const char *alias)
|
||||||
|
|
||||||
p = GET_PORT(c, GET_DIRECTION(o->port.flags), o->port.port_id);
|
p = GET_PORT(c, GET_DIRECTION(o->port.flags), o->port.port_id);
|
||||||
|
|
||||||
port_info = SPA_PORT_INFO_INIT();
|
|
||||||
port_info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
pw_properties_set(p->props, key, NULL);
|
||||||
dict = SPA_DICT_INIT(items, 0);
|
|
||||||
items[dict.n_items++] = SPA_DICT_ITEM_INIT(key, NULL);
|
p->info.change_mask |= SPA_PORT_CHANGE_MASK_PROPS;
|
||||||
port_info.props = &dict;
|
p->info.props = &p->props->dict;
|
||||||
|
|
||||||
pw_client_node_port_update(c->node,
|
pw_client_node_port_update(c->node,
|
||||||
p->direction,
|
p->direction,
|
||||||
p->id,
|
p->id,
|
||||||
PW_CLIENT_NODE_PORT_UPDATE_INFO,
|
PW_CLIENT_NODE_PORT_UPDATE_INFO,
|
||||||
0, NULL,
|
0, NULL,
|
||||||
&port_info);
|
&p->info);
|
||||||
|
p->info.change_mask = 0;
|
||||||
|
|
||||||
pw_thread_loop_unlock(c->context.loop);
|
pw_thread_loop_unlock(c->context.loop);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -4428,20 +4486,60 @@ void jack_port_get_latency_range (jack_port_t *port, jack_latency_callback_mode_
|
||||||
info->min_rate + (info->min_ns * rate) / SPA_NSEC_PER_SEC;
|
info->min_rate + (info->min_ns * rate) / SPA_NSEC_PER_SEC;
|
||||||
range->max = (info->max_quantum * nframes) +
|
range->max = (info->max_quantum * nframes) +
|
||||||
info->max_rate + (info->max_ns * rate) / SPA_NSEC_PER_SEC;
|
info->max_rate + (info->max_ns * rate) / SPA_NSEC_PER_SEC;
|
||||||
|
|
||||||
|
pw_log_debug(NAME" %p: get %d latency range %d %d", o, mode, range->min, range->max);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPA_EXPORT
|
SPA_EXPORT
|
||||||
void jack_port_set_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
|
void jack_port_set_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range)
|
||||||
{
|
{
|
||||||
struct object *o = (struct object *) port;
|
struct object *o = (struct object *) port;
|
||||||
|
enum spa_direction direction;
|
||||||
|
struct spa_latency_info *info;
|
||||||
|
struct port *p;
|
||||||
|
struct client *c;
|
||||||
|
struct spa_pod *params[5];
|
||||||
|
uint8_t buffer[4096];
|
||||||
|
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||||
|
|
||||||
spa_return_if_fail(o != NULL);
|
spa_return_if_fail(o != NULL);
|
||||||
|
|
||||||
if (mode == JackCaptureLatency) {
|
if (mode == JackCaptureLatency)
|
||||||
o->port.capture_latency = *range;
|
direction = SPA_DIRECTION_OUTPUT;
|
||||||
} else {
|
else
|
||||||
o->port.playback_latency = *range;
|
direction = SPA_DIRECTION_INPUT;
|
||||||
}
|
|
||||||
|
pw_log_debug(NAME" %p: set %d latency range %d %d", o, mode, range->min, range->max);
|
||||||
|
info = &o->port.latency[direction];
|
||||||
|
info->direction = direction;
|
||||||
|
info->min_rate = range->min;
|
||||||
|
info->max_rate = range->max;
|
||||||
|
|
||||||
|
if ((p = o->port.port) == NULL)
|
||||||
|
return;
|
||||||
|
if (p->direction != direction)
|
||||||
|
return;
|
||||||
|
c = p->client;
|
||||||
|
|
||||||
|
p->latency[direction] = o->port.latency[direction];
|
||||||
|
|
||||||
|
param_enum_format(c, p, ¶ms[0], &b);
|
||||||
|
param_format(c, p, ¶ms[1], &b);
|
||||||
|
param_buffers(c, p, ¶ms[2], &b);
|
||||||
|
param_io(c, p, ¶ms[3], &b);
|
||||||
|
param_latency(c, p, ¶ms[4], &b);
|
||||||
|
|
||||||
|
p->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||||
|
p->params[IDX_Latency].flags ^= SPA_PARAM_INFO_SERIAL;
|
||||||
|
|
||||||
|
pw_client_node_port_update(c->node,
|
||||||
|
p->direction,
|
||||||
|
p->id,
|
||||||
|
PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
|
||||||
|
PW_CLIENT_NODE_PORT_UPDATE_INFO,
|
||||||
|
5,
|
||||||
|
(const struct spa_pod **) params,
|
||||||
|
&p->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPA_EXPORT
|
SPA_EXPORT
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue