static int _jack_init(prog_t *handle, const char *id) { jack_options_t opts = JackNullOption | JackNoStartServer; if(handle->server_name) opts |= JackServerName; if(handle->session_id) opts |= JackSessionID; jack_status_t status; if(!(handle->client = jack_client_open(id, opts, &status, handle->server_name ? handle->server_name : handle->session_id, handle->server_name ? handle->session_id : NULL))) { return -1; } //TODO check status // set client pretty name #if defined(JACK_HAS_METADATA_API) jack_uuid_t uuid; const char *client_name = jack_get_client_name(handle->client); const char *uuid_str = jack_get_uuid_for_client_name(handle->client, client_name); if(uuid_str) jack_uuid_parse(uuid_str, &uuid); else jack_uuid_clear(&uuid); if(!jack_uuid_empty(uuid)) { jack_set_property(handle->client, uuid, JACK_METADATA_PRETTY_NAME, "Synthpod", "text/plain"); } #endif // set client process callback if(jack_set_process_callback(handle->client, _process, handle)) return -1; if(jack_set_session_callback(handle->client, _session, handle)) return -1; if(jack_set_sample_rate_callback(handle->client, _sample_rate, handle)) return -1; if(jack_set_buffer_size_callback(handle->client, _buffer_size, handle)) return -1; jack_on_shutdown(handle->client, _shutdown, handle); jack_set_xrun_callback(handle->client, _xrun, handle); return 0; }
static void _jack_deinit(prog_t *handle) { if(handle->client) { // remove client properties #if defined(JACK_HAS_METADATA_API) jack_uuid_t uuid; const char *client_name = jack_get_client_name(handle->client); const char *uuid_str = jack_get_uuid_for_client_name(handle->client, client_name); if(uuid_str) jack_uuid_parse(uuid_str, &uuid); else jack_uuid_clear(&uuid); if(!jack_uuid_empty(uuid)) jack_remove_properties(handle->client, uuid); #endif jack_deactivate(handle->client); jack_client_close(handle->client); handle->client = NULL; } }
int jack_get_all_properties (jack_description_t** descriptions) { DBT key; DBT data; DBC* cursor; int ret; size_t dcnt = 0; size_t dsize = 0; size_t n = 0; jack_description_t* desc = NULL; jack_uuid_t uuid; jack_description_t* current_desc = NULL; jack_property_t* current_prop = NULL; size_t len1, len2; if (jack_property_init (NULL)) { return -1; } if ((ret = db->cursor (db, NULL, &cursor, 0)) != 0) { jack_error ("Cannot create cursor for metadata search (%s)", db_strerror (ret)); return -1; } memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); data.flags = DB_DBT_MALLOC; dsize = 8; /* initial guess at number of descriptions we need */ dcnt = 0; desc = (jack_description_t*) malloc (dsize * sizeof (jack_description_t)); while ((ret = cursor->get(cursor, &key, &data, DB_NEXT)) == 0) { /* require 2 extra chars (data+null) for key, which is composed of UUID str plus a key name */ if (key.size < JACK_UUID_STRING_SIZE + 2) { if (data.size > 0) { free (data.data); } continue; } if (jack_uuid_parse (key.data, uuid) != 0) { continue; } /* do we have an existing description for this UUID */ for (n = 0; n < dcnt ; ++n) { if (jack_uuid_compare (uuid, desc[n].subject) == 0) { break; } } if (n == dcnt) { /* we do not have an existing description, so grow the array */ if (dcnt == dsize) { dsize *= 2; desc = (jack_description_t*) realloc (desc, sizeof (jack_description_t) * dsize); } /* initialize */ desc[n].property_size = 0; desc[n].property_cnt = 0; desc[n].properties = NULL; /* set up UUID */ jack_uuid_copy (desc[n].subject, uuid); dcnt++; } current_desc = &desc[n]; /* see if there is room for the new property or if we need to realloc */ if (current_desc->property_cnt == current_desc->property_size) { if (current_desc->property_size == 0) { current_desc->property_size = 8; } else { current_desc->property_size *= 2; } current_desc->properties = (jack_property_t*) realloc (current_desc->properties, sizeof (jack_property_t) * current_desc->property_size); } current_prop = ¤t_desc->properties[current_desc->property_cnt++]; /* copy key (without leading UUID) */ len1 = key.size - JACK_UUID_STRING_SIZE; current_prop->key = malloc (len1); memcpy ((char*) current_prop->key, key.data + JACK_UUID_STRING_SIZE, len1); /* copy data (which contains 1 or 2 null terminated strings, the value and optionally a MIME type. */ len1 = strlen (data.data) + 1; current_prop->data = (char *) malloc (len1); memcpy ((char*) current_prop->data, data.data, len1); if (len1 < data.size) { len2 = strlen (data.data+len1) + 1; current_prop->type= (char *) malloc (len2); memcpy ((char*) current_prop->type, data.data+len1, len2); } else { /* no type specified, assume default */ current_prop->type = NULL; } if (data.size) { free (data.data); } } cursor->close (cursor); (*descriptions) = desc; return dcnt; }