LADI
/
spa
1
Fork 0

jack: improve jack-sink and jack-source

Add more properties to sink/source to make them always process and
have the right priorities. Make sure the sink has higher priority than
the source so that we can pull in samples through the graph.

Only trigger the graph cycle when driving the graph.

Make sure to return something from process to signal that the graph can
continue processing.
This commit is contained in:
Wim Taymans 2023-04-25 20:17:11 +02:00
parent b9381a9da6
commit 815501cc1f
4 changed files with 42 additions and 14 deletions

View File

@ -18,6 +18,8 @@ static int jack_process(jack_nframes_t nframes, void *arg)
client->buffer_size = nframes;
spa_log_trace_fp(client->log, "frames %u", nframes);
spa_jack_client_emit_process(client);
return 0;
@ -27,6 +29,8 @@ static void jack_shutdown(void* arg)
{
struct spa_jack_client *client = arg;
spa_log_warn(client->log, "%p", client);
spa_jack_client_emit_shutdown(client);
spa_hook_list_init(&client->listener_list);
@ -67,6 +71,8 @@ int spa_jack_client_open(struct spa_jack_client *client,
spa_hook_list_init(&client->listener_list);
spa_log_info(client->log, "%p: %s", client, client_name);
jack_set_process_callback(client->client, jack_process, client);
jack_on_shutdown(client->client, jack_shutdown, client);
client->frame_rate = jack_get_sample_rate(client->client);
@ -81,6 +87,8 @@ int spa_jack_client_close(struct spa_jack_client *client)
if (client->client == NULL)
return 0;
spa_log_info(client->log, "%p:", client);
spa_jack_client_emit_destroy(client);
if (jack_client_close(client->client) != 0)

View File

@ -393,6 +393,7 @@ impl_init(const struct spa_handle_factory *factory,
this = (struct impl *) handle;
this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
this->client.log = this->log;
this->device.iface = SPA_INTERFACE_INIT(
SPA_TYPE_INTERFACE_Device,

View File

@ -67,7 +67,6 @@ struct impl {
struct spa_node node;
struct spa_log *log;
struct spa_loop *data_loop;
uint64_t info_all;
struct spa_node_info info;
@ -169,6 +168,11 @@ static int impl_node_enum_params(void *object, int seq,
return 0;
}
static inline bool is_following(struct impl *impl)
{
return impl->position && impl->clock && impl->position->clock.id != impl->clock->id;
}
static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size)
{
struct impl *this = object;
@ -235,15 +239,18 @@ static void emit_node_info(struct impl *this, bool full)
if (full)
this->info.change_mask = this->info_all;
if (this->info.change_mask) {
struct spa_dict_item items[5];
struct spa_dict_item items[8];
char latency[64];
snprintf(latency, sizeof(latency), "%d/%d",
this->client->buffer_size, this->client->frame_rate);
items[0] = SPA_DICT_ITEM_INIT(SPA_KEY_MEDIA_CLASS, "Audio/Sink");
items[1] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_NAME, "JACK System");
items[1] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_NAME, "JACK Sink");
items[2] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_DRIVER, "true");
items[3] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_PAUSE_ON_IDLE, "false");
items[4] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_LATENCY, latency);
items[4] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_ALWAYS_PROCESS, "true");
items[5] = SPA_DICT_ITEM_INIT("priority.driver", "30001");
items[6] = SPA_DICT_ITEM_INIT("node.group", "jack-group");
items[7] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_LATENCY, latency);
this->info.props = &SPA_DICT_INIT_ARRAY(items);
spa_node_emit_info(&this->hooks, &this->info);
this->info.change_mask = old;
@ -319,6 +326,9 @@ static void client_process(void *data)
{
struct impl *this = data;
if (is_following(this))
return;
if (this->clock) {
struct spa_io_clock *c = this->clock;
c->nsec = this->client->current_usecs * SPA_NSEC_PER_USEC;
@ -755,10 +765,8 @@ static int impl_node_process(void *object)
spa_memcpy(dst, src->data, n_frames * port->stride);
io->status = SPA_STATUS_NEED_DATA;
res |= SPA_STATUS_NEED_DATA;
}
return res;
return res | SPA_STATUS_NEED_DATA;
}
static const struct spa_node_methods impl_node = {

View File

@ -69,7 +69,6 @@ struct impl {
struct spa_node node;
struct spa_log *log;
struct spa_loop *data_loop;
uint64_t info_all;
struct spa_node_info info;
@ -263,15 +262,18 @@ static void emit_node_info(struct impl *this, bool full)
if (full)
this->info.change_mask = this->info_all;
if (this->info.change_mask) {
struct spa_dict_item items[5];
struct spa_dict_item items[8];
char latency[64];
snprintf(latency, sizeof(latency), "%d/%d",
this->client->buffer_size, this->client->frame_rate);
items[0] = SPA_DICT_ITEM_INIT(SPA_KEY_MEDIA_CLASS, "Audio/Source");
items[1] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_NAME, "JACK System");
items[1] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_NAME, "JACK Source");
items[2] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_DRIVER, "true");
items[3] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_PAUSE_ON_IDLE, "false");
items[4] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_LATENCY, latency);
items[4] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_ALWAYS_PROCESS, "true");
items[5] = SPA_DICT_ITEM_INIT("priority.driver", "30000");
items[6] = SPA_DICT_ITEM_INIT("node.group", "jack-group");
items[7] = SPA_DICT_ITEM_INIT(SPA_KEY_NODE_LATENCY, latency);
this->info.props = &SPA_DICT_INIT_ARRAY(items);
spa_node_emit_info(&this->hooks, &this->info);
this->info.change_mask = old;
@ -342,15 +344,24 @@ impl_node_set_callbacks(void *object,
return 0;
}
static inline bool is_following(struct impl *impl)
{
return impl->position && impl->clock && impl->position->clock.id != impl->clock->id;
}
static void client_process(void *data)
{
struct impl *this = data;
int res;
if (is_following(this))
return;
spa_log_trace_fp(this->log, "%p, process", this);
res = spa_node_process(&this->node);
if (res != SPA_STATUS_OK)
spa_node_call_ready(&this->callbacks, res);
spa_node_call_ready(&this->callbacks, res);
}
static const struct spa_jack_client_events client_events = {
@ -780,7 +791,7 @@ static int impl_node_process(void *object)
res |= SPA_STATUS_HAVE_DATA;
}
return res;
return res | SPA_STATUS_HAVE_DATA;
}
static const struct spa_node_methods impl_node = {