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:
parent
b9381a9da6
commit
815501cc1f
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
Loading…
Reference in New Issue