diff --git a/spa/include/spa/format-builder.h b/spa/include/spa/format-builder.h index 8a7a44ced..1585a49df 100644 --- a/spa/include/spa/format-builder.h +++ b/spa/include/spa/format-builder.h @@ -52,7 +52,7 @@ spa_pod_builder_push_format(struct spa_pod_builder *builder, spa_pod_builder_object(b, f, 0, format_type, \ SPA_POD_TYPE_ID,media_type, \ SPA_POD_TYPE_ID,media_subtype, \ - __VA_ARGS__) + ## __VA_ARGS__) #ifdef __cplusplus } /* extern "C" */ diff --git a/spa/include/spa/format-utils.h b/spa/include/spa/format-utils.h index 1327a4456..74144da7c 100644 --- a/spa/include/spa/format-utils.h +++ b/spa/include/spa/format-utils.h @@ -114,6 +114,7 @@ struct spa_type_media_subtype_audio { uint32_t g729; uint32_t amr; uint32_t gsm; + uint32_t midi; }; static inline void @@ -133,6 +134,7 @@ spa_type_media_subtype_audio_map(struct spa_type_map *map, type->g729 = spa_type_map_get_id(map, SPA_TYPE_MEDIA_SUBTYPE__g729); type->amr = spa_type_map_get_id(map, SPA_TYPE_MEDIA_SUBTYPE__amr); type->gsm = spa_type_map_get_id(map, SPA_TYPE_MEDIA_SUBTYPE__gsm); + type->midi = spa_type_map_get_id(map, SPA_TYPE_MEDIA_SUBTYPE__midi); } } diff --git a/spa/include/spa/format.h b/spa/include/spa/format.h index cf1780130..4f4d72c14 100644 --- a/spa/include/spa/format.h +++ b/spa/include/spa/format.h @@ -75,6 +75,7 @@ struct spa_format; #define SPA_TYPE_MEDIA_SUBTYPE__g729 SPA_TYPE_MEDIA_SUBTYPE_BASE "g729" #define SPA_TYPE_MEDIA_SUBTYPE__amr SPA_TYPE_MEDIA_SUBTYPE_BASE "amr" #define SPA_TYPE_MEDIA_SUBTYPE__gsm SPA_TYPE_MEDIA_SUBTYPE_BASE "gsm" +#define SPA_TYPE_MEDIA_SUBTYPE__midi SPA_TYPE_MEDIA_SUBTYPE_BASE "midi" struct spa_format_body { struct spa_pod_object_body obj_body; diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c index c35a6487a..b638193c0 100644 --- a/spa/plugins/alsa/alsa-sink.c +++ b/spa/plugins/alsa/alsa-sink.c @@ -32,7 +32,7 @@ #define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0) static const char default_device[] = "hw:0"; -static const uint32_t default_min_latency = 1024; +static const uint32_t default_min_latency = 128; static void reset_props(struct props *props) { diff --git a/src/modules/module-jack.c b/src/modules/module-jack.c index 6fd5a2295..6b8af786f 100644 --- a/src/modules/module-jack.c +++ b/src/modules/module-jack.c @@ -126,23 +126,32 @@ struct link { static bool init_socket_name(struct sockaddr_un *addr, const char *name, bool promiscuous, int which) { - int name_size; + int name_size, i; const char *runtime_dir; + char cname[SYNC_MAX_NAME_SIZE+1]; + + for (i = 0; name[i] != '\0'; i++) { + if (name[i] == '/' || name[i] == '\\') + cname[i] = '_'; + else + cname[i] = name[i]; + } + cname[i] = name[i]; 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; + "%s/jack_%s_%d", runtime_dir, cname, which) + 1; } else { name_size = snprintf(addr->sun_path, sizeof(addr->sun_path), - "%s/jack_%s_%d_%d", runtime_dir, name, getuid(), which) + 1; + "%s/jack_%s_%d_%d", runtime_dir, cname, 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); + runtime_dir, cname); *addr->sun_path = 0; return false; } @@ -452,6 +461,38 @@ handle_deactivate_client(struct client *client) return 0; } +static int +handle_set_timebase_callback(struct client *client) +{ + struct impl *impl = client->impl; + struct jack_server *server = &impl->server; + int result = 0; + int ref_num, conditional, tbm; + + CheckSize(kSetTimebaseCallback_size); + CheckRead(&ref_num, sizeof(int)); + CheckRead(&conditional, sizeof(int)); + + pw_log_debug("protocol-jack %p: kSetTimebaseCallback %d", client->impl, ref_num); + + tbm = server->engine_control->transport.time_base_master; + + if (conditional && tbm > 0) { + if (ref_num != tbm) { + pw_log_error("ref = %d failed: %d is already the master", ref_num, tbm); + result = EBUSY; + } else { + pw_log_debug("ref = %d was already timebase master", ref_num); + } + } else { + server->engine_control->transport.time_base_master = ref_num; + server->engine_control->transport.conditional = conditional; + pw_log_debug("new timebase master: ref = %d", ref_num); + } + CheckWrite(&result, sizeof(int)); + return 0; +} + static int handle_client_check(struct client *client) { @@ -863,6 +904,8 @@ process_messages(struct client *client) case jack_request_GetPortNConnections: case jack_request_ReleaseTimebase: case jack_request_SetTimebaseCallback: + res = handle_set_timebase_callback(client); + break; case jack_request_SetBufferSize: case jack_request_SetFreeWheel: break; diff --git a/src/modules/module-jack/defs.h b/src/modules/module-jack/defs.h index 580ec2471..1bf4a952b 100644 --- a/src/modules/module-jack/defs.h +++ b/src/modules/module-jack/defs.h @@ -127,6 +127,7 @@ enum jack_notification_type { #define kActivateClient_size (2*sizeof(int)) #define kDeactivateClient_size (sizeof(int)) +#define kSetTimebaseCallback_size (sizeof(int) + sizeof(int)) #define kRegisterPort_size (sizeof(int) + JACK_PORT_NAME_SIZE+1 + JACK_PORT_TYPE_SIZE+1 + 2*sizeof(unsigned int)) #define kClientCheck_size (JACK_CLIENT_NAME_SIZE+1 + 4 * sizeof(int)) #define kClientOpen_size (JACK_CLIENT_NAME_SIZE+1 + 2 * sizeof(int)) diff --git a/src/modules/module-jack/jack-node.c b/src/modules/module-jack/jack-node.c index abad97cb6..edcb99601 100644 --- a/src/modules/module-jack/jack-node.c +++ b/src/modules/module-jack/jack-node.c @@ -52,6 +52,7 @@ struct type { struct spa_type_media_subtype media_subtype; struct spa_type_format_audio format_audio; struct spa_type_audio_format audio_format; + struct spa_type_media_subtype_audio media_subtype_audio; }; static inline void init_type(struct type *type, struct spa_type_map *map) @@ -62,6 +63,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map) spa_type_media_subtype_map(map, &type->media_subtype); spa_type_format_audio_map(map, &type->format_audio); spa_type_audio_format_map(map, &type->audio_format); + spa_type_media_subtype_audio_map(map, &type->media_subtype_audio); } struct node_data { @@ -372,7 +374,8 @@ static int port_enum_formats(void *data, PROP(&f[1], t->format_audio.channels, SPA_POD_TYPE_INT, 1)); } else if (pd->port.jack_port->type_id == 1) { - return SPA_RESULT_ENUM_END; + spa_pod_builder_format(&b, &f[0], t->format, + t->media_type.audio, t->media_subtype_audio.midi); } else return SPA_RESULT_ENUM_END; diff --git a/src/modules/module-jack/shared.h b/src/modules/module-jack/shared.h index 9faad39cf..da26c6e1c 100644 --- a/src/modules/module-jack/shared.h +++ b/src/modules/module-jack/shared.h @@ -888,7 +888,7 @@ struct jack_transport_engine { int time_base_master; bool pending_pos; bool network_sync; - bool conditionnal; + bool conditional; int32_t write_counter; } POST_PACKED_STRUCTURE; diff --git a/src/modules/module-jack/synchro.h b/src/modules/module-jack/synchro.h index 7f8f4a4db..4aacc0a4f 100644 --- a/src/modules/module-jack/synchro.h +++ b/src/modules/module-jack/synchro.h @@ -34,12 +34,22 @@ jack_synchro_init(struct jack_synchro *synchro, int value, bool promiscuous) { + char cname[SYNC_MAX_NAME_SIZE+1]; + int i; + for (i = 0; client_name[i] != '\0'; i++) { + if (client_name[i] == '/' || client_name[i] == '\\') + cname[i] = '_'; + else + cname[i] = client_name[i]; + } + cname[i] = client_name[i]; + if (promiscuous) snprintf(synchro->name, sizeof(synchro->name), - "jack_sem.%s_%s", server_name, client_name); + "jack_sem.%s_%s", server_name, cname); else snprintf(synchro->name, sizeof(synchro->name), - "jack_sem.%d_%s_%s", getuid(), server_name, client_name); + "jack_sem.%d_%s_%s", getuid(), server_name, cname); synchro->flush = false; if ((synchro->semaphore = sem_open(synchro->name, O_CREAT | O_RDWR, 0777, value)) == (sem_t*)SEM_FAILED) { diff --git a/src/pipewire/link.c b/src/pipewire/link.c index 578aebc7e..85eb5e126 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -163,7 +163,7 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st } } - pw_log_debug("link %p: doing set format", this); + pw_log_debug("link %p: doing set format %p", this, format); if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG)) spa_debug_format(format);