Projects
Essentials
pipewire-aptx
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 54
View file
pipewire-aptx.changes
Changed
@@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Wed Jun 11 18:34:44 UTC 2025 - Bjørn Lie <zaitor@opensuse.org> + +- Update to version 1.4.4 + +------------------------------------------------------------------- Wed Apr 16 08:10:32 UTC 2025 - Bjørn Lie <zaitor@opensuse.org> - Update to version 1.4.2
View file
pipewire-aptx.spec
Changed
@@ -8,7 +8,7 @@ %define minimum_version 1.4.0 Name: pipewire-aptx -Version: 1.4.2 +Version: 1.4.4 Release: 0 Summary: PipeWire Bluetooth aptX codec plugin License: MIT
View file
_service
Changed
@@ -2,6 +2,6 @@ <service name="download_url"> <param name="host">gitlab.freedesktop.org</param> <param name="protocol">https</param> - <param name="path">/pipewire/pipewire/-/archive/1.4.2/pipewire-1.4.2.tar.bz2</param> + <param name="path">/pipewire/pipewire/-/archive/1.4.4/pipewire-1.4.4.tar.bz2</param> </service> </services> \ No newline at end of file
View file
_service:download_url:pipewire-1.4.2.tar.bz2/NEWS -> _service:download_url:pipewire-1.4.4.tar.bz2/NEWS
Changed
@@ -1,3 +1,68 @@ +# PipeWire 1.4.4 (2025-05-29) + +This is a quick bugfix release that is API and ABI compatible with +previous 1.x releases. + +## Highlights + - Provide better compatibility with 1.2 for MIDI. + - Fix mpv buffer negotiation regression. + - Improve GStreamer compatibility with libcamera. + + +## SPA + - Provide conversions to old style midi in the ALSA sequencer. + - Negotiate only to UMP when using a newer library. + - Fix negotiation direction for buffers, prefer the converter + suggestion instead of the application until we can be sure + applications make good suggestions. + +## GStreamer + - Allow a minimum of 1 buffers again instead of 8. libcamera will + allocate only 4 buffers so we need to support this. + + +Older versions: + +# PipeWire 1.4.3 (2025-05-22) + +This is a bugfix release that is API and ABI compatible with +previous 1.x releases. + +## Highlights + - Many netjack2 improvements. The driver/manager roles were fixed, + MIDI is written correctly and errors are handled better. + - Improvements to UMP sysex handling. + - More small bug fixes and improvements. + + +## PipeWire + - Let all commands go to the node. This makes it possible to send + custom commands. + +## Modules + - Many netjack2 improvements. The driver/manager roles were fixed, + MIDI is written correctly and errors are handled better. + - Improve the filter-graph state management in filter-chain. + +## SPA + - Use default value of filter. (#4619) + - Fix UMP program change conversion to MIDI 1.0. (#4664) + - Skip only the first buffer for raw formats in v4l2 to avoid + dropping important headers when dealing with encoded formats. + - Fix ebur128 port name. (#4667) + - Only convert UMP/MIDI, pass other controls. Fixes OSC and other + control types in the mixer. (#4692) + - Improve UMP sysex handling in alsa seq. + - Improve ALSA audio.channels support. Only use this when the value + is within the valid range. + +## Tools + - debug UMP SysRT messages correctly in pw-mididump. + +## JACK + - Handle sysex in UMP better by appending the converted midi1 + sysex. + # PipeWire 1.4.2 (2025-04-14) This is a bugfix release that is API and ABI compatible with @@ -29,9 +94,6 @@ - Fix a leak in the deviceprovider. (#4616) - Fix negotiation and make renegotiation better. - -Older versions: - # PipeWire 1.4.1 (2025-03-14) This is a quick bugfix release that is API and ABI compatible with
View file
_service:download_url:pipewire-1.4.2.tar.bz2/meson.build -> _service:download_url:pipewire-1.4.4.tar.bz2/meson.build
Changed
@@ -1,5 +1,5 @@ project('pipewire', 'c' , - version : '1.4.2', + version : '1.4.4', license : 'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' , meson_version : '>= 0.61.1', default_options : 'warning_level=3',
View file
_service:download_url:pipewire-1.4.2.tar.bz2/pipewire-jack/src/pipewire-jack.c -> _service:download_url:pipewire-1.4.4.tar.bz2/pipewire-jack/src/pipewire-jack.c
Changed
@@ -1538,7 +1538,7 @@ res = ev->inline_data; } else { mb->write_pos += data_size; - ev->byte_offset = mb->buffer_size - 1 - mb->write_pos; + ev->byte_offset = mb->buffer_size - mb->write_pos; res = SPA_PTROFF(mb, ev->byte_offset, uint8_t); } mb->event_count += 1; @@ -1546,14 +1546,37 @@ return res; } +static inline int midi_event_append(void *port_buffer, const jack_midi_data_t *data, size_t data_size) +{ + struct midi_buffer *mb = port_buffer; + struct midi_event *events = SPA_PTROFF(mb, sizeof(*mb), struct midi_event); + struct midi_event *ev; + size_t old_size; + uint8_t *old, *buf; + + ev = &events--mb->event_count; + mb->write_pos -= ev->size; + old_size = ev->size; + if (old_size <= MIDI_INLINE_MAX) + old = ev->inline_data; + else + old = SPA_PTROFF(mb, ev->byte_offset, uint8_t); + buf = midi_event_reserve(port_buffer, ev->time, old_size + data_size); + if (SPA_UNLIKELY(buf == NULL)) + return -ENOBUFS; + memmove(buf, old, old_size); + memcpy(buf+old_size, data, data_size); + return 0; +} + static inline int midi_event_write(void *port_buffer, jack_nframes_t time, const jack_midi_data_t *data, size_t data_size, bool fix) { jack_midi_data_t *retbuf = midi_event_reserve (port_buffer, time, data_size); - if (SPA_UNLIKELY(retbuf == NULL)) - return -ENOBUFS; + if (SPA_UNLIKELY(retbuf == NULL)) + return -ENOBUFS; memcpy (retbuf, data, data_size); if (fix) fix_midi_event(retbuf, data_size); @@ -1566,6 +1589,7 @@ uint64_t state = 0; uint32_t i; int res = 0; + bool in_sysex = false; for (i = 0; i < n_seq; i++) ci = spa_pod_control_first(&seqi->body); @@ -1620,17 +1644,30 @@ void *data = SPA_POD_BODY(&next->value); size_t size = SPA_POD_BODY_SIZE(&next->value); uint8_t ev32; + bool was_sysex = in_sysex; if (type == TYPE_ID_MIDI) { int ev_size = spa_ump_to_midi(data, size, ev, sizeof(ev)); if (ev_size <= 0) break; + size = ev_size; data = ev; + + if (!in_sysex && ev0 == 0xf0) + in_sysex = true; + if (in_sysex && evev_size-1 == 0xf7) + in_sysex = false; + } else if (type != TYPE_ID_UMP) break; - if ((res = midi_event_write(midi, next->offset, data, size, fix)) < 0) + if (was_sysex) + res = midi_event_append(midi, data, size); + else + res = midi_event_write(midi, next->offset, data, size, fix); + + if (res < 0) pw_log_warn("midi %p: can't write event: %s", midi, spa_strerror(res)); } @@ -2512,11 +2549,28 @@ case TYPE_ID_UMP: case TYPE_ID_OSC: case TYPE_ID_MIDI: - *param = spa_pod_builder_add_object(b, - SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, + { + struct spa_pod_frame f; + int32_t types = 0; + + spa_pod_builder_push_object(b, &f, + SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat); + spa_pod_builder_add(b, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), - SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control), + 0); + if (p->object->port.type_id == TYPE_ID_UMP) + types |= 1u<<SPA_CONTROL_UMP; + if (p->object->port.type_id == TYPE_ID_OSC) + types |= 1u<<SPA_CONTROL_OSC; + if (types != 0) + spa_pod_builder_add(b, + SPA_FORMAT_CONTROL_types, SPA_POD_CHOICE_FLAGS_Int(types), + 0); + + *param = spa_pod_builder_pop(b, &f); break; + } case TYPE_ID_VIDEO: *param = spa_pod_builder_add_object(b, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, @@ -3429,24 +3483,6 @@ } } -static const char* type_to_format_dsp(jack_port_type_id_t type_id) -{ - switch(type_id) { - case TYPE_ID_AUDIO: - return JACK_DEFAULT_AUDIO_TYPE; - case TYPE_ID_VIDEO: - return JACK_DEFAULT_VIDEO_TYPE; - case TYPE_ID_OSC: - return JACK_DEFAULT_OSC_TYPE; - case TYPE_ID_MIDI: - return JACK_DEFAULT_MIDI_TYPE; - case TYPE_ID_UMP: - return JACK_DEFAULT_UMP_TYPE; - default: - return NULL; - } -} - static bool type_is_dsp(jack_port_type_id_t type_id) { switch(type_id) { @@ -5507,7 +5543,7 @@ spa_list_init(&p->mix); - pw_properties_set(p->props, PW_KEY_FORMAT_DSP, type_to_format_dsp(type_id)); + pw_properties_set(p->props, PW_KEY_FORMAT_DSP, type_to_string(type_id)); pw_properties_set(p->props, PW_KEY_PORT_NAME, port_name); if (flags > 0x1f) { pw_properties_setf(p->props, PW_KEY_PORT_EXTRA, @@ -5754,8 +5790,8 @@ convert_to_event(seq, n_seq, mb, p->client->fix_midi_events, p->object->port.type_id); memcpy(ptr, mb, sizeof(struct midi_buffer) + (mb->event_count * sizeof(struct midi_event))); - if (mb->write_pos) { - size_t offs = mb->buffer_size - 1 - mb->write_pos; + if (mb->write_pos > 0) { + size_t offs = mb->buffer_size - mb->write_pos; memcpy(SPA_PTROFF(ptr, offs, void), SPA_PTROFF(mb, offs, void), mb->write_pos); } return ptr;
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/include/spa/control/ump-utils.h -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/include/spa/control/ump-utils.h
Changed
@@ -96,9 +96,17 @@ if (ump_size < 8) return 0; midisize++ = (ump0 >> 16) | 0x80; - if (midi0 < 0xc0 || midi0 > 0xdf) + switch (midi0 & 0xf0) { + case 0xc0: + midisize++ = (ump1 >> 24); + break; + default: midisize++ = (ump0 >> 8) & 0x7f; - midisize++ = (ump1 >> 25); + SPA_FALLTHROUGH; + case 0xd0: + midisize++ = (ump1 >> 25); + break; + } break; case 0x0: /* Utility Messages */
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/include/spa/pod/builder.h -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/include/spa/pod/builder.h
Changed
@@ -326,6 +326,31 @@ return SPA_POD_BODY(spa_pod_builder_deref(builder, offset)); } +SPA_API_POD_BUILDER uint32_t +spa_pod_builder_bytes_start(struct spa_pod_builder *builder) +{ + uint32_t offset = builder->state.offset; + const struct spa_pod_bytes p = SPA_POD_INIT_Bytes(0); + spa_pod_builder_raw(builder, &p, sizeof(p)); + return offset; +} +SPA_API_POD_BUILDER int +spa_pod_builder_bytes_append(struct spa_pod_builder *builder, uint32_t offset, + const void *data, uint32_t size) +{ + int res = spa_pod_builder_raw(builder, data, size); + struct spa_pod *pod = spa_pod_builder_deref(builder, offset); + if (pod) + pod->size += size; + return res; +} + +SPA_API_POD_BUILDER int +spa_pod_builder_bytes_end(struct spa_pod_builder *builder, uint32_t offset SPA_UNUSED) +{ + return spa_pod_builder_pad(builder, builder->state.offset); +} + #define SPA_POD_INIT_Pointer(type,value) ((struct spa_pod_pointer){ { sizeof(struct spa_pod_pointer_body), SPA_TYPE_Pointer }, { (type), 0, (value) } }) SPA_API_POD_BUILDER int
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/include/spa/pod/filter.h -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/include/spa/pod/filter.h
Changed
@@ -181,7 +181,7 @@ nc = &dummy; /* default value */ - spa_pod_builder_primitive(b, v1); + spa_pod_builder_primitive(b, v2); if ((p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_None) || (p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_Enum) || @@ -189,10 +189,10 @@ (p1c == SPA_CHOICE_Enum && p2c == SPA_CHOICE_Enum)) { int n_copied = 0; /* copy all equal values but don't copy the default value again */ - for (j = 0, a1 = alt1; j < nalt1; j++, a1 = SPA_PTROFF(a1, size, void)) { - for (k = 0, a2 = alt2; k < nalt2; k++, a2 = SPA_PTROFF(a2,size,void)) { + for (j = 0, a2 = alt2; j < nalt2; j++, a2 = SPA_PTROFF(a2, size, void)) { + for (k = 0, a1 = alt1; k < nalt1; k++, a1 = SPA_PTROFF(a1,size,void)) { if (spa_pod_compare_value(type, a1, a2, size) == 0) { - if (p1c == SPA_CHOICE_Enum || j > 0) + if (p2c == SPA_CHOICE_Enum || j > 0) spa_pod_builder_raw(b, a1, size); n_copied++; }
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/include/spa/utils/json-core.h -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/include/spa/utils/json-core.h
Changed
@@ -268,6 +268,8 @@ if (--utf8_remain == 0) iter->state = __STRING | flag; continue; + default: + break; } _SPA_ERROR(CHARACTERS_NOT_ALLOWED); case __ESC: @@ -276,12 +278,17 @@ case 'n': case 'r': case 't': case 'u': iter->state = __STRING | flag; continue; + default: + break; } _SPA_ERROR(INVALID_ESCAPE); case __COMMENT: switch (cur) { case '\n': case '\r': iter->state = __STRUCT | flag; + break; + default: + break; } break; default: @@ -299,6 +306,8 @@ case __COMMENT: /* trailing comment */ return 0; + default: + break; } if ((iter->state & __SUB_FLAG) && (iter->state & __KEY_FLAG)) {
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/alsa/alsa-pcm.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/alsa/alsa-pcm.c
Changed
@@ -162,6 +162,11 @@ int fmt_change = 0; if (spa_streq(k, SPA_KEY_AUDIO_CHANNELS)) { state->default_channels = atoi(s); + if (state->default_channels > SPA_AUDIO_MAX_CHANNELS) { + spa_log_warn(state->log, "%p: %s: %s > %d, clamping", + state, k, s, SPA_AUDIO_MAX_CHANNELS); + state->default_channels = SPA_AUDIO_MAX_CHANNELS; + } fmt_change++; } else if (spa_streq(k, SPA_KEY_AUDIO_RATE)) { state->default_rate = atoi(s); @@ -1563,15 +1568,18 @@ spa_log_debug(state->log, "channels (%d %d) default:%d all:%d", min, max, state->default_channels, all); - if (state->default_channels != 0 && !all) { - if (min < state->default_channels) - min = state->default_channels; - if (max > state->default_channels) - max = state->default_channels; - } min = SPA_MIN(min, SPA_AUDIO_MAX_CHANNELS); max = SPA_MIN(max, SPA_AUDIO_MAX_CHANNELS); + if (state->default_channels != 0 && !all) { + if (min > state->default_channels || + max < state->default_channels) + spa_log_warn(state->log, "given audio.channels %d out of range:%d-%d", + state->default_channels, min, max); + else + min = max = state->default_channels; + } + spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_channels, 0); if (state->props.use_chmap && (maps = snd_pcm_query_chmaps(hndl)) != NULL) { @@ -1842,10 +1850,12 @@ spa_log_debug(state->log, "rate (%d %d)", rmin, rmax); if (state->default_rate != 0) { - if (rmin < state->default_rate) - rmin = state->default_rate; - if (rmax > state->default_rate) - rmax = state->default_rate; + if (rmin > state->default_rate || + rmax < state->default_rate) + spa_log_warn(state->log, "given audio.rate %d out of range:%d-%d", + state->default_rate, rmin, rmax); + else + rmin = rmax = state->default_rate; } spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_iec958Codec, 0);
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/alsa/alsa-seq-bridge.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/alsa/alsa-seq-bridge.c
Changed
@@ -275,7 +275,7 @@ snprintf(alias, sizeof(alias), "%s:%s", client_name, port_name); clean_name(alias); - itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"); + itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_OBJECT_PATH, path); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, name); itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_ALIAS, alias); @@ -529,8 +529,7 @@ param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), - SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control), - SPA_FORMAT_CONTROL_types, SPA_POD_CHOICE_FLAGS_Int(1u<<SPA_CONTROL_UMP)); + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); break; case SPA_PARAM_Format: @@ -541,8 +540,7 @@ param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Format, SPA_PARAM_Format, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), - SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control), - SPA_FORMAT_CONTROL_types, SPA_POD_Int(1u<<SPA_CONTROL_UMP)); + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); break; case SPA_PARAM_Buffers: @@ -635,7 +633,7 @@ port->have_format = false; } else { struct spa_audio_info info = { 0 }; - uint32_t types; + uint32_t types = 0; if ((err = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0) return err; @@ -646,13 +644,12 @@ if ((err = spa_pod_parse_object(format, SPA_TYPE_OBJECT_Format, NULL, - SPA_FORMAT_CONTROL_types, SPA_POD_Int(&types))) < 0) + SPA_FORMAT_CONTROL_types, SPA_POD_OPT_Int(&types))) < 0) return err; - if (types != 1u << SPA_CONTROL_UMP) - return -EINVAL; port->current_format = info; port->have_format = true; + port->control_types = types; } port->info.change_mask |= SPA_PORT_CHANGE_MASK_RATE;
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/alsa/alsa-seq.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/alsa/alsa-seq.c
Changed
@@ -78,7 +78,6 @@ spa_log_debug(state->log, "%p: ALSA UMP MIDI enabled", state); state->ump = true; } - return 0; } @@ -404,7 +403,6 @@ state->sys.source.func = alsa_seq_on_sys; state->sys.source.data = state; - spa_loop_add_source(state->main_loop, &state->sys.source); /* increase event queue timer resolution */ snd_seq_queue_timer_alloca(&timer); @@ -449,6 +447,8 @@ state->timerfd = res; + spa_loop_add_source(state->main_loop, &state->sys.source); + state->opened = true; return 0; @@ -586,7 +586,8 @@ spa_pod_builder_init(&port->builder, port->buffer->buf->datas0.data, port->buffer->buf->datas0.maxsize); - spa_pod_builder_push_sequence(&port->builder, &port->frame, 0); + spa_pod_builder_push_sequence(&port->builder, &port->frame, 0); + port->ev_offset = SPA_IDX_INVALID; return 0; } @@ -620,10 +621,8 @@ struct seq_stream *stream = &state->streamsSPA_DIRECTION_OUTPUT; const bool ump = state->ump; uint32_t i; - uint32_t *data; uint8_t midi1_dataMAX_EVENT_SIZE; uint32_t ump_dataMAX_EVENT_SIZE; - long size; int res = -1; /* copy all new midi events into their port buffers */ @@ -631,10 +630,11 @@ const snd_seq_addr_t *addr; struct seq_port *port; uint64_t ev_time, diff; - uint32_t offset; + uint32_t offset, ev_type; void *event; - uint8_t *midi1_ptr; - size_t midi1_size = 0; + uint8_t *data_ptr; + size_t data_size = 0; + long size; uint64_t ump_state = 0; snd_seq_event_type_t SPA_UNUSED type; @@ -679,7 +679,7 @@ continue; if ((res = prepare_buffer(state, port)) < 0) { - spa_log_debug(state->log, "can't prepare buffer port:%p %d.%d: %s", + spa_log_warn(state->log, "can't prepare buffer port:%p %d.%d: %s", port, addr->client, addr->port, spa_strerror(res)); continue; } @@ -702,8 +702,8 @@ #ifdef HAVE_ALSA_UMP snd_seq_ump_event_t *ev = event; - data = (uint32_t*)&ev->ump0; - size = spa_ump_message_size(snd_ump_msg_hdr_type(ev->ump0)) * 4; + data_ptr = (uint8_t*)&ev->ump0; + data_size = spa_ump_message_size(snd_ump_msg_hdr_type(ev->ump0)) * 4; #else spa_assert_not_reached(); #endif @@ -712,40 +712,69 @@ snd_midi_event_reset_decode(stream->codec); if ((size = snd_midi_event_decode(stream->codec, midi1_data, sizeof(midi1_data), ev)) < 0) { - spa_log_warn(state->log, "decode failed: %s", snd_strerror(size)); + spa_log_warn(state->log, "decode failed: %s", snd_strerror(data_size)); continue; } + data_ptr = midi1_data; + data_size = size; + } - midi1_ptr = midi1_data; - midi1_size = size; + ev_type = (port->control_types & (1u << SPA_CONTROL_UMP)) ? + SPA_CONTROL_UMP : SPA_CONTROL_Midi; + + spa_log_trace_fp(state->log, "event %d time:%"PRIu64" offset:%d size:%ld port:%d.%d", + type, ev_time, offset, data_size, addr->client, addr->port); + + if ((ump && ev_type == SPA_CONTROL_UMP) || + (!ump && ev_type == SPA_CONTROL_Midi)) { + /* no conversion needed */ + spa_pod_builder_control(&port->builder, offset, ev_type); + spa_pod_builder_bytes(&port->builder, data_ptr, data_size); } + else if (ump) { + bool continued = port->ev_offset != SPA_IDX_INVALID; + + /* UMP -> MIDI */ + size = spa_ump_to_midi((uint32_t*)data_ptr, data_size, + midi1_data, sizeof(midi1_data)); + if (size < 0) + continue; - do { - if (!ump) { - data = ump_data; - size = spa_ump_from_midi(&midi1_ptr, &midi1_size, + if (!continued) { + spa_pod_builder_control(&port->builder, offset, ev_type); + port->ev_offset = spa_pod_builder_bytes_start(&port->builder); + if (midi1_data0 == 0xf0) + continued = true; + } else { + if (midi1_datasize-1 == 0xf7) + continued = false; + } + spa_pod_builder_bytes_append(&port->builder, port->ev_offset, midi1_data, size); + + if (!continued) { + spa_pod_builder_bytes_end(&port->builder, port->ev_offset); + port->ev_offset = SPA_IDX_INVALID; + } + } else { + /* MIDI -> UMP */ + while (data_size > 0) { + size = spa_ump_from_midi(&data_ptr, &data_size, ump_data, sizeof(ump_data), 0, &ump_state); if (size <= 0) break; - } - - spa_log_trace_fp(state->log, "event %d time:%"PRIu64" offset:%d size:%ld port:%d.%d", - type, ev_time, offset, size, addr->client, addr->port); - - spa_pod_builder_control(&port->builder, offset, SPA_CONTROL_UMP); - spa_pod_builder_bytes(&port->builder, data, size); - /* make sure we can fit at least one control event of max size otherwise - * we keep the event in the queue and try to copy it in the next cycle */ - if (port->builder.state.offset + - sizeof(struct spa_pod_control) + - MAX_EVENT_SIZE > port->buffer->buf->datas0.maxsize) - goto done; + spa_pod_builder_control(&port->builder, offset, ev_type); + spa_pod_builder_bytes(&port->builder, ump_data, size); + } + } - } while (!ump); + /* make sure we can fit at least one control event of max size otherwise + * we keep the event in the queue and try to copy it in the next cycle */ + if (port->builder.state.offset + + sizeof(struct spa_pod_control) + + MAX_EVENT_SIZE > port->buffer->buf->datas0.maxsize) + break; } - -done: if (res < 0 && res != -EAGAIN) spa_log_warn(state->log, "event read failed: %s", snd_strerror(res)); @@ -760,6 +789,8 @@ continue; if (prepare_buffer(state, port) >= 0) { + if (port->ev_offset != SPA_IDX_INVALID) + spa_pod_builder_bytes_end(&port->builder, port->ev_offset); spa_pod_builder_pop(&port->builder, &port->frame); port->buffer->buf->datas0.chunk->offset = 0; @@ -820,6 +851,7 @@ struct spa_pod_control *c; uint64_t out_time; snd_seq_real_time_t out_rt; + bool first = true; if (!port->valid || io == NULL) continue; @@ -845,9 +877,7 @@ SPA_POD_SEQUENCE_FOREACH(pod, c) { size_t body_size; uint8_t *body; - - if (c->type != SPA_CONTROL_UMP) - continue; + int size;
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/alsa/alsa-seq.h -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/alsa/alsa-seq.h
Changed
@@ -80,7 +80,10 @@ struct buffer *buffer; struct spa_pod_builder builder; struct spa_pod_frame frame; + uint32_t ev_offset; + uint64_t ump_state; + uint32_t control_types; struct spa_audio_info current_format; unsigned int have_format:1; unsigned int valid:1;
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/audioconvert/audioadapter.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/audioconvert/audioadapter.c
Changed
@@ -442,28 +442,32 @@ state = 0; param = NULL; - if ((res = node_port_enum_params_sync(this, this->follower, - this->direction, 0, + if ((res = node_port_enum_params_sync(this, this->target, + SPA_DIRECTION_REVERSE(this->direction), 0, SPA_PARAM_Buffers, &state, param, ¶m, &b)) < 0) { if (res == -ENOENT) param = NULL; else { - debug_params(this, this->follower, this->direction, 0, - SPA_PARAM_Buffers, param, "follower buffers", res); + debug_params(this, this->target, + SPA_DIRECTION_REVERSE(this->direction), 0, + SPA_PARAM_Buffers, param, "target buffers", res); return res; } } state = 0; - if ((res = node_port_enum_params_sync(this, this->target, - SPA_DIRECTION_REVERSE(this->direction), 0, + if ((res = node_port_enum_params_sync(this, this->follower, + this->direction, 0, SPA_PARAM_Buffers, &state, param, ¶m, &b)) != 1) { - debug_params(this, this->target, - SPA_DIRECTION_REVERSE(this->direction), 0, - SPA_PARAM_Buffers, param, "convert buffers", res); - return -ENOTSUP; + if (res == -ENOENT) + res = 0; + else { + debug_params(this, this->follower, this->direction, 0, + SPA_PARAM_Buffers, param, "follower buffers", res); + return res < 0 ? res : -ENOTSUP; + } } if (param == NULL) return -ENOTSUP; @@ -497,7 +501,7 @@ if (this->async) buffers = SPA_MAX(2u, buffers); - spa_log_debug(this->log, "%p: buffers:%d, blocks:%d, size:%d, stride:%d align:%d %d:%d", + spa_log_info(this->log, "%p: buffers:%d, blocks:%d, size:%d, stride:%d align:%d %d:%d", this, buffers, blocks, size, stride, align, follower_alloc, conv_alloc); align = SPA_MAX(align, this->max_align); @@ -941,27 +945,13 @@ spa_node_send_command(this->follower, &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_ParamBegin)); - /* first try the ideal converter format, which is likely passthrough */ - tstate = 0; - fres = node_port_enum_params_sync(this, this->target, - SPA_DIRECTION_REVERSE(this->direction), 0, - SPA_PARAM_EnumFormat, &tstate, - NULL, &format, &b); - if (fres == 1) { - fstate = 0; - res = node_port_enum_params_sync(this, this->follower, - this->direction, 0, - SPA_PARAM_EnumFormat, &fstate, - format, &format, &b); - if (res == 1) - goto found; - } - - /* then try something the follower can accept */ + /* The target has been negotiated on its other ports and so it can propose + * a passthrough format or an ideal conversion. We use the suggestions of the + * target to find the best follower format */ for (fstate = 0;;) { format = NULL; - res = node_port_enum_params_sync(this, this->follower, - this->direction, 0, + res = node_port_enum_params_sync(this, this->target, + SPA_DIRECTION_REVERSE(this->direction), 0, SPA_PARAM_EnumFormat, &fstate, NULL, &format, &b); @@ -971,8 +961,8 @@ break; tstate = 0; - fres = node_port_enum_params_sync(this, this->target, - SPA_DIRECTION_REVERSE(this->direction), 0, + fres = node_port_enum_params_sync(this, this->follower, + this->direction, 0, SPA_PARAM_EnumFormat, &tstate, format, &format, &b); if (fres == 0 && res == 1) @@ -981,7 +971,6 @@ res = fres; break; } -found: if (format == NULL) { debug_params(this, this->follower, this->direction, 0, SPA_PARAM_EnumFormat, format, "follower format", res); @@ -1045,7 +1034,10 @@ break; } - if ((res = spa_node_send_command(this->target, command)) < 0) { + res = spa_node_send_command(this->target, command); + if (res == -ENOTSUP && this->target != this->follower) + res = 0; + if (res < 0) { spa_log_error(this->log, "%p: can't send command %d: %s", this, SPA_NODE_COMMAND_ID(command), spa_strerror(res));
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/audioconvert/audioconvert.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/audioconvert/audioconvert.c
Changed
@@ -362,7 +362,7 @@ itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_IGNORE_LATENCY, "true"); } else if (PORT_IS_CONTROL(this, port->direction, port->id)) { itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, "control"); - itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"); + itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"); } if (this->group_name0 != '\0') itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_GROUP, this->group_name);
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/bluez5/midi-node.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/bluez5/midi-node.c
Changed
@@ -2024,13 +2024,13 @@ for (i = 0; i < N_PORTS; ++i) { struct port *port = &this->portsi; static const struct spa_dict_item in_port_items = { - SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"), + SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"), SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, "in"), SPA_DICT_ITEM_INIT(SPA_KEY_PORT_ALIAS, "in"), SPA_DICT_ITEM_INIT(SPA_KEY_PORT_GROUP, "group.0"), }; static const struct spa_dict_item out_port_items = { - SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"), + SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"), SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, "out"), SPA_DICT_ITEM_INIT(SPA_KEY_PORT_ALIAS, "out"), SPA_DICT_ITEM_INIT(SPA_KEY_PORT_GROUP, "group.0"),
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/control/mixer.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/control/mixer.c
Changed
@@ -298,7 +298,8 @@ *param = spa_pod_builder_add_object(builder, SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), - SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); + SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control), + SPA_FORMAT_CONTROL_types, SPA_POD_CHOICE_FLAGS_Int(SPA_ID_INVALID)); break; default: return 0; @@ -671,6 +672,14 @@ } } +static inline bool control_needs_conversion(struct port *port, uint32_t type) +{ + /* we only converter between midi and UMP and only when the port + * does not support the current type */ + return (type == SPA_CONTROL_Midi || type == SPA_CONTROL_UMP) && + port->types && (port->types & (1u << type)) == 0; +} + static int impl_node_process(void *object) { struct impl *this = object; @@ -782,7 +791,7 @@ if (next == NULL) break; - if (outport->types && (outport->types & (1u << next->type)) == 0) { + if (control_needs_conversion(outport, next->type)) { uint8_t *data = SPA_POD_BODY(&next->value); size_t size = SPA_POD_BODY_SIZE(&next->value);
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/filter-graph/ebur128_plugin.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/filter-graph/ebur128_plugin.c
Changed
@@ -356,7 +356,7 @@ .flags = SPA_FGA_PORT_OUTPUT | SPA_FGA_PORT_CONTROL, }, { .index = PORT_OUT_SHORTTERM, - .name = "Shorttem LUFS", + .name = "Shortterm LUFS", .flags = SPA_FGA_PORT_OUTPUT | SPA_FGA_PORT_CONTROL, }, { .index = PORT_OUT_GLOBAL,
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/filter-graph/filter-graph.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/filter-graph/filter-graph.c
Changed
@@ -256,9 +256,8 @@ if (outi == NULL) continue; - port = i < graph->n_output ? &graph->outputi : NULL; - - if (port && port->desc) + port = &graph->outputi; + if (port->desc) port->desc->connect_port(*port->hndl, port->port, outi); else memset(outi, 0, n_samples * sizeof(float));
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/filter-graph/lv2_plugin.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/filter-graph/lv2_plugin.c
Changed
@@ -234,7 +234,7 @@ LV2_Options_Option options6; LV2_Feature options_feature; - const LV2_Feature *features7; + const LV2_Feature *features8; const LV2_Worker_Interface *work_iface; @@ -328,9 +328,11 @@ c->atom_Float, &fsample_rate }; i->options5 = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, NULL }; - i->options_feature.URI = LV2_OPTIONS__options; - i->options_feature.data = i->options; - i->featuresn_features++ = &i->options_feature; + i->options_feature.URI = LV2_OPTIONS__options; + i->options_feature.data = i->options; + i->featuresn_features++ = &i->options_feature; + i->featuresn_features++ = NULL; + spa_assert(n_features <= SPA_N_ELEMENTS(i->features)); i->instance = lilv_plugin_instantiate(p->p, SampleRate, i->features); if (i->instance == NULL) {
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/libcamera/libcamera-source.cpp -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/libcamera/libcamera-source.cpp
Changed
@@ -273,7 +273,7 @@ default: return spa_libcamera_enum_controls(impl, GET_OUT_PORT(impl, 0), - seq, result.index - 2, num, filter); + seq, result.index, 2, num, filter); } break; } @@ -535,7 +535,7 @@ switch (id) { case SPA_PARAM_PropInfo: - return spa_libcamera_enum_controls(impl, port, seq, start, num, filter); + return spa_libcamera_enum_controls(impl, port, seq, start, 0, num, filter); case SPA_PARAM_EnumFormat: return spa_libcamera_enum_format(impl, port, seq, start, num, filter);
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/libcamera/libcamera-utils.cpp -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/libcamera/libcamera-utils.cpp
Changed
@@ -495,7 +495,7 @@ static int spa_libcamera_enum_controls(struct impl *impl, struct port *port, int seq, - uint32_t start, uint32_t num, + uint32_t start, uint32_t offset, uint32_t num, const struct spa_pod *filter) { const ControlInfoMap &info = impl->camera->controls(); @@ -513,7 +513,7 @@ result.next = start; auto it = info.begin(); - for (skip = result.next; skip; skip--) + for (skip = result.next - offset; skip; skip--) it++; if (false) {
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/v4l2/v4l2-utils.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/v4l2/v4l2-utils.c
Changed
@@ -1873,7 +1873,12 @@ spa_log_debug(this->log, "starting"); - port->first_buffer = true; + if (port->current_format.media_subtype == SPA_MEDIA_SUBTYPE_raw || + port->current_format.media_subtype == SPA_MEDIA_SUBTYPE_mjpg || + port->current_format.media_subtype == SPA_MEDIA_SUBTYPE_jpeg) + port->first_buffer = true; + else + port->first_buffer = false; mmap_read(this); type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/videoconvert/videoadapter.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/videoconvert/videoadapter.c
Changed
@@ -416,28 +416,32 @@ state = 0; param = NULL; - if ((res = spa_node_port_enum_params_sync(this->follower, - this->direction, 0, + if ((res = spa_node_port_enum_params_sync(this->target, + SPA_DIRECTION_REVERSE(this->direction), 0, SPA_PARAM_Buffers, &state, param, ¶m, &b)) < 0) { if (res == -ENOENT) param = NULL; else { - debug_params(this, this->follower, this->direction, 0, - SPA_PARAM_Buffers, param, "follower buffers", res); + debug_params(this, this->target, + SPA_DIRECTION_REVERSE(this->direction), 0, + SPA_PARAM_Buffers, param, "target buffers", res); return res; } } state = 0; - if ((res = spa_node_port_enum_params_sync(this->target, - SPA_DIRECTION_REVERSE(this->direction), 0, + if ((res = spa_node_port_enum_params_sync(this->follower, + this->direction, 0, SPA_PARAM_Buffers, &state, param, ¶m, &b)) != 1) { - debug_params(this, this->target, - SPA_DIRECTION_REVERSE(this->direction), 0, - SPA_PARAM_Buffers, param, "convert buffers", res); - return -ENOTSUP; + if (res == -ENOENT) + res = 0; + else { + debug_params(this, this->follower, this->direction, 0, + SPA_PARAM_Buffers, param, "follower buffers", res); + return res < 0 ? res : -ENOTSUP; + } } if (param == NULL) return -ENOTSUP; @@ -471,7 +475,7 @@ if (this->async) buffers = SPA_MAX(2u, buffers); - spa_log_debug(this->log, "%p: buffers:%d, blocks:%d, size:%d, stride:%d align:%d %d:%d", + spa_log_info(this->log, "%p: buffers:%d, blocks:%d, size:%d, stride:%d align:%d %d:%d", this, buffers, blocks, size, stride, align, follower_alloc, conv_alloc); align = SPA_MAX(align, this->max_align); @@ -908,27 +912,13 @@ spa_node_send_command(this->follower, &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_ParamBegin)); - /* first try the ideal converter format, which is likely passthrough */ - tstate = 0; - fres = spa_node_port_enum_params_sync(this->target, - SPA_DIRECTION_REVERSE(this->direction), 0, - SPA_PARAM_EnumFormat, &tstate, - NULL, &format, &b); - if (fres == 1) { - fstate = 0; - res = spa_node_port_enum_params_sync(this->follower, - this->direction, 0, - SPA_PARAM_EnumFormat, &fstate, - format, &format, &b); - if (res == 1) - goto found; - } - - /* then try something the follower can accept */ + /* The target has been negotiated on its other ports and so it can propose + * a passthrough format or an ideal conversion. We use the suggestions of the + * target to find the best follower format */ for (fstate = 0;;) { format = NULL; - res = spa_node_port_enum_params_sync(this->follower, - this->direction, 0, + res = spa_node_port_enum_params_sync(this->target, + SPA_DIRECTION_REVERSE(this->direction), 0, SPA_PARAM_EnumFormat, &fstate, NULL, &format, &b); @@ -938,8 +928,8 @@ break; tstate = 0; - fres = spa_node_port_enum_params_sync(this->target, - SPA_DIRECTION_REVERSE(this->direction), 0, + fres = spa_node_port_enum_params_sync(this->follower, + this->direction, 0, SPA_PARAM_EnumFormat, &tstate, format, &format, &b); if (fres == 0 && res == 1) @@ -948,7 +938,6 @@ res = fres; break; } -found: if (format == NULL) { debug_params(this, this->follower, this->direction, 0, SPA_PARAM_EnumFormat, format, "follower format", res); @@ -1012,7 +1001,10 @@ break; } - if ((res = spa_node_send_command(this->target, command)) < 0) { + res = spa_node_send_command(this->target, command); + if (res == -ENOTSUP && this->target != this->follower) + res = 0; + if (res < 0) { spa_log_error(this->log, "%p: can't send command %d: %s", this, SPA_NODE_COMMAND_ID(command), spa_strerror(res));
View file
_service:download_url:pipewire-1.4.2.tar.bz2/spa/plugins/videoconvert/videoconvert-ffmpeg.c -> _service:download_url:pipewire-1.4.4.tar.bz2/spa/plugins/videoconvert/videoconvert-ffmpeg.c
Changed
@@ -228,7 +228,7 @@ itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_IGNORE_LATENCY, "true"); } else if (PORT_IS_CONTROL(this, port->direction, port->id)) { itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_NAME, "control"); - itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"); + itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"); } if (this->group_name0 != '\0') itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_PORT_GROUP, this->group_name); @@ -1812,6 +1812,7 @@ } sbuf = &in_port->buffersinput->buffer_id; + input->status = SPA_STATUS_NEED_DATA; if ((dbuf = peek_buffer(this, out_port)) == NULL) { spa_log_error(this->log, "%p: out of buffers", this); @@ -1902,8 +1903,6 @@ output->buffer_id = dbuf->id; output->status = SPA_STATUS_HAVE_DATA; - input->status = SPA_STATUS_NEED_DATA; - return SPA_STATUS_HAVE_DATA; }
View file
_service:download_url:pipewire-1.4.4.tar.bz2/src/daemon/pipewire.conf.avail/50-raop.conf.in
Added
@@ -0,0 +1,4 @@ +context.modules = + # Use mDNS to detect and load module-raop-sink + { name = libpipewire-module-raop-discover } +
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/daemon/pipewire.conf.avail/meson.build -> _service:download_url:pipewire-1.4.4.tar.bz2/src/daemon/pipewire.conf.avail/meson.build
Changed
@@ -1,6 +1,7 @@ conf_files = '10-rates.conf', '20-upmix.conf', + '50-raop.conf', foreach c : conf_files
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/examples/midi-src.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/examples/midi-src.c
Changed
@@ -213,7 +213,7 @@ PW_FILTER_PORT_FLAG_MAP_BUFFERS, sizeof(struct port), pw_properties_new( - PW_KEY_FORMAT_DSP, "32 bit raw UMP", + PW_KEY_FORMAT_DSP, "8 bit raw midi", PW_KEY_PORT_NAME, "output", NULL), NULL, 0);
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/gst/gstpipewiresrc.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/gst/gstpipewiresrc.c
Changed
@@ -41,7 +41,7 @@ #define GST_CAT_DEFAULT pipewire_src_debug #define DEFAULT_ALWAYS_COPY false -#define DEFAULT_MIN_BUFFERS 8 +#define DEFAULT_MIN_BUFFERS 1 #define DEFAULT_MAX_BUFFERS INT32_MAX #define DEFAULT_RESEND_LAST false #define DEFAULT_KEEPALIVE_TIME 0
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/modules/module-client-node/remote-node.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/modules/module-client-node/remote-node.c
Changed
@@ -481,15 +481,16 @@ pw_proxy_error(proxy, res, "suspend failed"); } break; - case SPA_NODE_COMMAND_RequestProcess: - res = pw_impl_node_send_command(node, command); - break; default: - pw_log_warn("unhandled node command %d (%s)", id, - spa_debug_type_find_name(spa_type_node_command_id, id)); - res = -ENOTSUP; - pw_proxy_errorf(proxy, res, "command %d (%s) not supported", id, - spa_debug_type_find_name(spa_type_node_command_id, id)); + res = pw_impl_node_send_command(node, command); + if (res < 0) { + pw_log_warn("node command %d (%s) error: %s (%d)", id, + spa_debug_type_find_name(spa_type_node_command_id, id), + spa_strerror(res), res); + pw_proxy_errorf(proxy, res, "command %d (%s) error: %s (%d)", id, + spa_debug_type_find_name(spa_type_node_command_id, id), + spa_strerror(res), res); + } } return res; }
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/modules/module-ffado-driver.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/modules/module-ffado-driver.c
Changed
@@ -772,7 +772,7 @@ break; case ffado_stream_type_midi: props = pw_properties_new( - PW_KEY_FORMAT_DSP, "32 bit raw UMP", + PW_KEY_FORMAT_DSP, "8 bit raw midi", PW_KEY_PORT_NAME, port->name, PW_KEY_PORT_PHYSICAL, "true", PW_KEY_PORT_TERMINAL, "true",
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/modules/module-filter-chain.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/modules/module-filter-chain.c
Changed
@@ -972,7 +972,7 @@ pw_stream_update_params(impl->playback, params, 1); } -static void state_changed(void *data, enum pw_stream_state old, +static void capture_state_changed(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error) { struct impl *impl = data; @@ -1048,7 +1048,9 @@ struct spa_audio_info_raw info; spa_zero(info); if (param == NULL) { - spa_filter_graph_deactivate(graph); + pw_log_info("module %p: filter deactivate", impl); + if (capture) + spa_filter_graph_deactivate(graph); impl->rate = 0; } else { if ((res = spa_format_audio_raw_parse(param, &info)) < 0) @@ -1087,7 +1089,7 @@ .destroy = capture_destroy, .process = capture_process, .io_changed = io_changed, - .state_changed = state_changed, + .state_changed = capture_state_changed, .param_changed = capture_param_changed }; @@ -1108,7 +1110,6 @@ .destroy = playback_destroy, .process = playback_process, .io_changed = io_changed, - .state_changed = state_changed, .param_changed = playback_param_changed, }; @@ -1153,10 +1154,11 @@ SPA_PARAM_EnumFormat, &impl->capture_info); for (i = 0;; i++) { - if ((offs = pw_array_add(&offsets, sizeof(uint32_t))) != NULL) - *offs = b.b.state.offset; + uint32_t save = b.b.state.offset; if (spa_filter_graph_enum_prop_info(graph, i, &b.b, NULL) != 1) break; + if ((offs = pw_array_add(&offsets, sizeof(uint32_t))) != NULL) + *offs = save; } if ((offs = pw_array_add(&offsets, sizeof(uint32_t))) != NULL)
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/modules/module-jack-tunnel.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/modules/module-jack-tunnel.c
Changed
@@ -247,6 +247,8 @@ struct spa_pod_sequence *seq; struct spa_pod_control *c; int res; + uint8_t tmpn_samples * 4; + size_t tmp_size = 0; jack.midi_clear_buffer(dst); if (src == NULL) @@ -260,23 +262,32 @@ seq = (struct spa_pod_sequence*)pod; SPA_POD_SEQUENCE_FOREACH(seq, c) { - uint8_t data16; int size; if (c->type != SPA_CONTROL_UMP) continue; + switch (c->type) { + case SPA_CONTROL_UMP: + size = spa_ump_to_midi(SPA_POD_BODY(&c->value), + SPA_POD_BODY_SIZE(&c->value), &tmptmp_size, sizeof(tmp) - tmp_size); + if (size <= 0) + continue; + tmp_size += size; + break; + case SPA_CONTROL_Midi: + tmp_size = SPA_POD_BODY_SIZE(&c->value); + memcpy(tmp, SPA_POD_BODY(&c->value), SPA_MIN(sizeof(tmp), tmp_size)); + break; + } - size = spa_ump_to_midi(SPA_POD_BODY(&c->value), - SPA_POD_BODY_SIZE(&c->value), data, sizeof(data)); - if (size <= 0) - continue; - - if (impl->fix_midi) - fix_midi_event(data, size); - - if ((res = jack.midi_event_write(dst, c->offset, data, size)) < 0) - pw_log_warn("midi %p: can't write event: %s", dst, - spa_strerror(res)); + if (tmp0 != 0xf0 || tmptmp_size-1 == 0xf7) { + if (impl->fix_midi) + fix_midi_event(tmp, tmp_size); + if ((res = jack.midi_event_write(dst, c->offset, tmp, tmp_size)) < 0) + pw_log_warn("midi %p: can't write event: %s", dst, + spa_strerror(res)); + tmp_size = 0; + } } } @@ -503,7 +514,7 @@ } else { snprintf(name, sizeof(name), "%s_%d", prefix, i - s->info.channels); props = pw_properties_new( - PW_KEY_FORMAT_DSP, "32 bit raw UMP", + PW_KEY_FORMAT_DSP, "8 bit raw midi", PW_KEY_PORT_NAME, name, PW_KEY_PORT_PHYSICAL, "true", NULL);
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/modules/module-netjack2-driver.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/modules/module-netjack2-driver.c
Changed
@@ -45,7 +45,26 @@ /** \page page_module_netjack2_driver Netjack2 driver * * The netjack2-driver module provides a source or sink that is following a - * netjack2 manager. + * netjack2 manager. It is meant to be used over stable (ethernet) network + * connections with minimal latency and jitter. + * + * The driver normally decides how many ports it will send and receive from the + * manager. By default however, these values are set to -1 so that the manager + * decides on the number of ports. + * + * With the global or per stream audio.port and midi.ports properties this + * behaviour can be adjusted. + * + * The driver will send out UDP messages on a (typically) multicast address to + * inform the manager of the available driver. This will then instruct the manager + * to configure and start the driver. + * + * On the driver side, a sink and/or source with the specified numner of audio and + * midi ports will be created. On the manager side there will be a corresponding + * source and/or sink created respectively. + * + * The driver will be scheduled with exactly the same period as the manager but with + * a configurable number of periods of delay (see netjack2.latency, default 2). * * ## Module Name * @@ -53,7 +72,10 @@ * * ## Module Options * - * - `driver.mode`: the driver mode, sink|source|duplex, default duplex + * - `driver.mode`: the driver mode, sink|source|duplex, default duplex. This set the + * per stream audio.port and midi.ports default from -1 to 0. sink mode defaults to + * no source ports, source mode to no sink ports and duplex leaves the defaults as + * they are. * - `local.ifname = <str>`: interface name to use * - `net.ip =<str>`: multicast IP address, default "225.3.19.154" * - `net.port =<int>`: control port, default 19000 @@ -63,11 +85,11 @@ * - `source.ip =<str>`: IP address to bind to, default "0.0.0.0" * - `source.port =<int>`: port to bind to, default 0 (allocate) * - `netjack2.client-name`: the name of the NETJACK2 client. - * - `netjack2.save`: if jack port connections should be save automatically. Can also be - * placed per stream. * - `netjack2.latency`: the latency in cycles, default 2 - * - `audio.channels`: the number of audio ports. Can also be added to the stream props. + * - `audio.ports`: the number of audio ports. Can also be added to the stream props. + * A value of -1 will configure to the number of audio ports on the manager. * - `midi.ports`: the number of midi ports. Can also be added to the stream props. + * A value of -1 will configure to the number of midi ports on the manager. * - `source.props`: Extra properties for the source filter. * - `sink.props`: Extra properties for the sink filter. * @@ -93,15 +115,14 @@ * context.modules = * { name = libpipewire-module-netjack2-driver * args = { - * #driver.mode = duplex * #netjack2.client-name = PipeWire - * #netjack2.save = false * #netjack2.latency = 2 * #midi.ports = 0 + * #audio.ports = -1 * #audio.channels = 2 * #audio.position = FL FR * source.props = { - * # extra sink properties + * # extra source properties * } * sink.props = { * # extra sink properties @@ -133,15 +154,14 @@ #define NETWORK_MAX_LATENCY 30 #define DEFAULT_CLIENT_NAME "PipeWire" -#define DEFAULT_CHANNELS 2 -#define DEFAULT_POSITION " FL FR " -#define DEFAULT_MIDI_PORTS 1 +#define DEFAULT_MIDI_PORTS -1 +#define DEFAULT_AUDIO_PORTS -1 #define FOLLOWER_INIT_TIMEOUT 1 #define FOLLOWER_INIT_RETRY -1 #define MODULE_USAGE "( remote.name=<remote> ) " \ - "( driver.mode=<sink|source|duplex> ) " \ + "( driver.mode=<sink|source|duplex> ) " \ "( local.ifname=<interface name> ) " \ "( net.ip=<ip address to use, default 225.3.19.154> ) " \ "( net.port=<port to use, default 19000> ) " \ @@ -151,11 +171,11 @@ "( source.ip=<ip address to bind, default 0.0.0.0> ) " \ "( source.port=<port to bind, default 0> ) " \ "( netjack2.client-name=<name of the NETJACK2 client> ) " \ - "( netjack2.save=<bool, save ports> ) " \ "( netjack2.latency=<latency in cycles, default 2> ) " \ - "( midi.ports=<number of midi ports> ) " \ - "( audio.channels=<number of channels> ) " \ - "( audio.position=<channel map> ) " \ + "( audio.ports=<number of midi ports, default -1> ) " \ + "( midi.ports=<number of midi ports, default -1> ) " \ + "( audio.channels=<number of channels, default 0> ) " \ + "( audio.position=<channel map, default null> ) " \ "( source.props=<properties> ) " \ "( sink.props=<properties> ) " @@ -182,9 +202,13 @@ struct pw_filter *filter; struct spa_hook listener; + int32_t wanted_n_midi; + int32_t wanted_n_audio; + + struct spa_io_position *position; + struct spa_audio_info_raw info; - uint32_t n_midi; uint32_t n_ports; struct port *portsMAX_PORTS; @@ -222,8 +246,6 @@ struct spa_hook core_proxy_listener; struct spa_hook core_listener; - struct spa_io_position *position; - struct stream source; struct stream sink; @@ -369,11 +391,10 @@ static void stream_io_changed(void *data, void *port_data, uint32_t id, void *area, uint32_t size) { struct stream *s = data; - struct impl *impl = s->impl; if (port_data == NULL) { switch (id) { case SPA_IO_Position: - impl->position = area; + s->position = area; break; default: break; @@ -431,7 +452,7 @@ } else { snprintf(name, sizeof(name), "midi%d", i - s->info.channels); props = pw_properties_new( - PW_KEY_FORMAT_DSP, "32 bit raw UMP", + PW_KEY_FORMAT_DSP, "8 bit raw midi", PW_KEY_AUDIO_CHANNEL, name, PW_KEY_PORT_PHYSICAL, "true", NULL); @@ -458,6 +479,7 @@ s->portsi = port; } + pw_filter_set_active(s->filter, true); } static struct spa_pod *make_props_param(struct spa_pod_builder *b, @@ -523,7 +545,6 @@ case SPA_PARAM_PortConfig: pw_log_debug("PortConfig"); make_stream_ports(s); - pw_filter_set_active(s->filter, true); break; case SPA_PARAM_Props: pw_log_debug("Props"); @@ -558,6 +579,7 @@ const struct spa_pod *params4; uint8_t buffer1024; struct spa_pod_builder b; + int res; n_params = 0; spa_pod_builder_init(&b, buffer, sizeof(buffer)); @@ -583,12 +605,18 @@ SPA_PARAM_Format, &s->info); paramsn_params++ = make_props_param(&b, &s->volume); - return pw_filter_connect(s->filter, + if ((res = pw_filter_connect(s->filter, PW_FILTER_FLAG_INACTIVE | PW_FILTER_FLAG_DRIVER | PW_FILTER_FLAG_RT_PROCESS | PW_FILTER_FLAG_CUSTOM_LATENCY, - params, n_params); + params, n_params)) < 0) + return res; + + if (s->info.channels == 0) + make_stream_ports(s); + + return res; } static int create_filters(struct impl *impl) @@ -616,6 +644,24 @@
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/modules/module-netjack2-manager.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/modules/module-netjack2-manager.c
Changed
@@ -49,6 +49,19 @@ * The netjack2 manager module listens for new netjack2 driver messages and will * start a communication channel with them. * + * Messages are received on a (typically) multicast address. + * + * Normally, the driver will specify the number of send and receive channels it + * wants to set up with the manager. If the driver however specifies a don't-care + * value of -1, the audio.ports and midi.ports configuration values of the manager + * are used. + * + * The manager will create the corresponding streams to send and receive data + * to/from the drivers. These are usually sink and sources but with the + * netjack2.connect property, these will be streams that will be autoconnected to + * the default source and sink by the session manager. + * + * * ## Module Name * * `libpipewire-module-netjack2-manager` @@ -67,8 +80,11 @@ * - `netjack2.period-size`: the buffer size to use, default 1024 * - `netjack2.encoding`: the encoding, float|opus|int, default float * - `netjack2.kbps`: the number of kilobits per second when encoding, default 64 - * - `audio.channels`: the number of audio ports. Can also be added to the stream props. - * - `midi.ports`: the number of midi ports. Can also be added to the stream props. + * - `audio.ports`: the number of audio ports. Can also be added to the stream props. This + * is the default suggestion for drivers that don't specify any number of audio channels. + * - `midi.ports`: the number of midi ports. Can also be added to the stream props. This + * is the default suggestion for drivers that don't specify any number of midi channels. + * - `audio.position`: default channel position for the number of audio.ports. * - `source.props`: Extra properties for the source filter. * - `sink.props`: Extra properties for the sink filter. * @@ -99,11 +115,12 @@ * #netjack2.period-size = 1024 * #netjack2.encoding = float # float|opus * #netjack2.kbps = 64 + * #audio.ports = 0 * #midi.ports = 0 * #audio.channels = 2 * #audio.position = FL FR * source.props = { - * # extra sink properties + * # extra source properties * } * sink.props = { * # extra sink properties @@ -137,8 +154,7 @@ #define DEFAULT_PERIOD_SIZE 1024 #define DEFAULT_ENCODING "float" #define DEFAULT_KBPS 64 -#define DEFAULT_CHANNELS 2 -#define DEFAULT_POSITION " FL FR " +#define DEFAULT_AUDIO_PORTS 2 #define DEFAULT_MIDI_PORTS 1 #define MODULE_USAGE "( remote.name=<remote> ) " \ @@ -151,8 +167,8 @@ "( netjack2.connect=<autoconnect ports, default false> ) " \ "( netjack2.sample-rate=<sampl erate, default 48000> ) "\ "( netjack2.period-size=<period size, default 1024> ) " \ - "( midi.ports=<number of midi ports> ) " \ - "( audio.channels=<number of channels> ) " \ + "( midi.ports=<number of midi ports, default 1> ) " \ + "( audio.channels=<number of channels, default 2> ) " \ "( audio.position=<channel map> ) " \ "( source.props=<properties> ) " \ "( sink.props=<properties> ) " @@ -183,9 +199,12 @@ struct pw_filter *filter; struct spa_hook listener; - struct spa_audio_info_raw info; + struct spa_io_position *position; + struct spa_audio_info_raw info; + uint32_t n_audio; uint32_t n_midi; + uint32_t n_ports; struct port *portsMAX_PORTS; @@ -202,7 +221,10 @@ struct spa_list link; struct impl *impl; - struct spa_io_position *position; +#define MODE_SINK (1<<0) +#define MODE_SOURCE (1<<1) +#define MODE_DUPLEX (MODE_SINK|MODE_SOURCE) + uint32_t mode; struct stream source; struct stream sink; @@ -227,6 +249,7 @@ unsigned int done:1; unsigned int new_xrun:1; unsigned int started:1; + unsigned int freeing:1; }; struct impl { @@ -235,10 +258,6 @@ struct pw_loop *data_loop; struct spa_system *system; -#define MODE_SINK (1<<0) -#define MODE_SOURCE (1<<1) -#define MODE_DUPLEX (MODE_SINK|MODE_SOURCE) - uint32_t mode; struct pw_properties *props; struct pw_properties *sink_props; struct pw_properties *source_props; @@ -284,6 +303,7 @@ struct stream *s = d; uint32_t i; + s->running = false; spa_hook_remove(&s->listener); for (i = 0; i < s->n_ports; i++) s->portsi = NULL; @@ -354,9 +374,17 @@ pw_loop_update_io(s->impl->data_loop, follower->socket, SPA_IO_IN); } -static void source_process(void *d, struct spa_io_position *position) +static int stop_follower(struct follower *follower); + +static int do_stop_follower(struct spa_loop *loop, + bool async, uint32_t seq, const void *data, size_t size, void *user_data) +{ + stop_follower(user_data); + return 0; +} + +static inline void handle_source_process(struct stream *s, struct spa_io_position *position) { - struct stream *s = d; struct follower *follower = s->follower; uint32_t nframes = position->clock.duration; struct data_info midis->n_ports; @@ -365,28 +393,57 @@ set_info(s, nframes, midi, &n_midi, audio, &n_audio); - netjack2_manager_sync_wait(&follower->peer); + if (netjack2_manager_sync_wait(&follower->peer) < 0) { + pw_loop_invoke(s->impl->main_loop, do_stop_follower, 0, NULL, 0, false, follower); + return; + } netjack2_recv_data(&follower->peer, midi, n_midi, audio, n_audio); } +static void source_process(void *d, struct spa_io_position *position) +{ + struct stream *s = d; + struct follower *follower = s->follower; + + if (!(follower->mode & MODE_SINK)) + sink_process(&follower->sink, position); + + handle_source_process(s, position); +} + static void follower_free(struct follower *follower) { struct impl *impl = follower->impl; + if (follower->freeing) + return; + + follower->freeing = true; + spa_list_remove(&follower->link); - if (follower->source.filter) + if (follower->socket) { + pw_loop_destroy_source(impl->data_loop, follower->socket); + follower->socket = NULL; + } + if (follower->setup_socket) { + pw_loop_destroy_source(impl->main_loop, follower->setup_socket); + follower->setup_socket = NULL; + } + + if (follower->source.filter) { pw_filter_destroy(follower->source.filter); - if (follower->sink.filter) + follower->source.filter = NULL; + } + if (follower->sink.filter) { pw_filter_destroy(follower->sink.filter); + follower->sink.filter = NULL; + } pw_properties_free(follower->source.props); + follower->source.props = NULL; pw_properties_free(follower->sink.props); -
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/modules/module-netjack2/packets.h -> _service:download_url:pipewire-1.4.4.tar.bz2/src/modules/module-netjack2/packets.h
Changed
@@ -120,7 +120,7 @@ uint32_t cycle; /* process cycle counter */ uint32_t sub_cycle; /* midi/audio subcycle counter */ int32_t frames; /* process cycle size in frames (can be -1 to indicate entire buffer) */ - uint32_t is_last; /* is it the last packet of a given cycle ('y' or 'n') */ + uint32_t is_last; /* is it the last packet of a given cycle (1=yes or 0=no) */ } __attribute__ ((packed)); #define UDP_HEADER_SIZE 64 /* 40 bytes for IP header in IPV6, 20 in IPV4, 8 for UDP, so take 64 */
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/modules/module-netjack2/peer.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/modules/module-netjack2/peer.c
Changed
@@ -242,17 +242,78 @@ } } +static inline void *n2j_midi_buffer_reserve(struct nj2_midi_buffer *buf, + uint32_t offset, uint32_t size) +{ + struct nj2_midi_event *ev; + void *ptr; + + if (size <= 0) + return NULL; + + size_t used_size = sizeof(*buf) + buf->write_pos + + ((buf->event_count + 1) * sizeof(struct nj2_midi_event)); + + ev = &buf->eventbuf->event_count; + ev->time = offset; + ev->size = size; + if (size <= MIDI_INLINE_MAX) { + ptr = ev->buffer; + } else { + if (used_size + size > buf->buffer_size) + return NULL; + buf->write_pos += size; + ev->offset = buf->buffer_size - buf->write_pos; + ptr = SPA_PTROFF(buf, ev->offset, void); + } + buf->event_count++; + return ptr; +} + +static inline void n2j_midi_buffer_write(struct nj2_midi_buffer *buf, + uint32_t offset, void *data, uint32_t size) +{ + void *ptr = n2j_midi_buffer_reserve(buf, offset, size); + if (ptr != NULL) + memcpy(ptr, data, size); + else + buf->lost_events++; +} + +static inline void n2j_midi_buffer_append(struct nj2_midi_buffer *buf, + void *data, uint32_t size) +{ + struct nj2_midi_event *ev; + uint32_t old_size; + uint8_t *old_ptr, *new_ptr; + + ev = &buf->event--buf->event_count; + old_size = ev->size; + if (old_size <= MIDI_INLINE_MAX) { + old_ptr = ev->buffer; + } else { + buf->write_pos -= old_size; + old_ptr = SPA_PTROFF(buf, ev->offset, void); + } + new_ptr = n2j_midi_buffer_reserve(buf, ev->time, old_size + size); + if (new_ptr == NULL) { + buf->lost_events++; + } else { + memmove(new_ptr, old_ptr, old_size); + memcpy(new_ptr+old_size, data, size); + } +} + static void midi_to_netjack2(struct netjack2_peer *peer, struct nj2_midi_buffer *buf, float *src, uint32_t n_samples) { struct spa_pod *pod; struct spa_pod_sequence *seq; struct spa_pod_control *c; - struct nj2_midi_event *ev; - int free_size; + bool in_sysex = false; buf->magic = MIDI_BUFFER_MAGIC; - buf->buffer_size = peer->quantum_limit * sizeof(float); + buf->buffer_size = peer->params.period_size * sizeof(float); buf->nframes = n_samples; buf->write_pos = 0; buf->event_count = 0; @@ -269,12 +330,10 @@ seq = (struct spa_pod_sequence*)pod; - free_size = buf->buffer_size - sizeof(*buf); - SPA_POD_SEQUENCE_FOREACH(seq, c) { int size; uint8_t data16; - void *ptr; + bool was_sysex = in_sysex; if (c->type != SPA_CONTROL_UMP) continue; @@ -284,29 +343,24 @@ if (size <= 0) continue; - if (c->offset >= n_samples || - size >= free_size) { + if (c->offset >= n_samples) { buf->lost_events++; continue; } - if (peer->fix_midi) + if (!in_sysex && data0 == 0xf0) + in_sysex = true; + + if (!in_sysex && peer->fix_midi) fix_midi_event(data, size); - ev = &buf->eventbuf->event_count; - ev->time = c->offset; - ev->size = size; - if (size <= MIDI_INLINE_MAX) { - ptr = ev->buffer; - } else { - buf->write_pos += size; - ev->offset = buf->buffer_size - 1 - buf->write_pos; - free_size -= size; - ptr = SPA_PTROFF(buf, ev->offset, void); - } - memcpy(ptr, data, size); - buf->event_count++; - free_size -= sizeof(*ev); + if (in_sysex && datasize-1 == 0xf7) + in_sysex = false; + + if (was_sysex) + n2j_midi_buffer_append(buf, data, size); + else + n2j_midi_buffer_write(buf, c->offset, data, size); } if (buf->write_pos > 0) memmove(SPA_PTROFF(buf, sizeof(*buf) + buf->event_count * sizeof(struct nj2_midi_event), void), @@ -314,15 +368,27 @@ buf->write_pos); } +static inline void netjack2_clear_midi(float *dst, uint32_t size) +{ + struct spa_pod_builder b = { 0, }; + struct spa_pod_frame f; + spa_pod_builder_init(&b, dst, size); + spa_pod_builder_push_sequence(&b, &f, 0); + spa_pod_builder_pop(&b, &f); +} + static inline void netjack2_to_midi(float *dst, uint32_t size, struct nj2_midi_buffer *buf) { struct spa_pod_builder b = { 0, }; uint32_t i; struct spa_pod_frame f; + size_t offset = size - buf->write_pos - sizeof(*buf) - + (buf->event_count * sizeof(struct nj2_midi_event)); spa_pod_builder_init(&b, dst, size); spa_pod_builder_push_sequence(&b, &f, 0); - for (i = 0; buf != NULL && i < buf->event_count; i++) { + + for (i = 0; i < buf->event_count; i++) { struct nj2_midi_event *ev = &buf->eventi; uint8_t *data; size_t s; @@ -330,8 +396,8 @@ if (ev->size <= MIDI_INLINE_MAX) data = ev->buffer; - else if (ev->offset > buf->write_pos) - data = SPA_PTROFF(buf, ev->offset - buf->write_pos, void); + else if (ev->offset > offset) + data = SPA_PTROFF(buf, ev->offset - offset, void); else continue; @@ -339,9 +405,10 @@ while (s > 0) { uint32_t ump4; int ump_size = spa_ump_from_midi(&data, &s, ump, sizeof(ump), 0, &state); - if (ump_size <= 0) + if (ump_size <= 0) { + pw_log_warn("invalid MIDI received: %s", spa_strerror(ump_size)); break; - + } spa_pod_builder_control(&b, ev->time, SPA_CONTROL_UMP); spa_pod_builder_bytes(&b, ump, ump_size); } @@ -362,7 +429,7 @@ is_last = peer->params.send_midi_channels == 0 && peer->params.send_audio_channels == 0 ? 1 : 0; - strcpy(header.type, "header"); + strncpy(header.type, "header", sizeof(header.type)); header.data_type = htonl('s'); header.data_stream = htonl(peer->our_stream); header.id = htonl(peer->params.id);
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/modules/module-rtp/stream.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/modules/module-rtp/stream.c
Changed
@@ -390,7 +390,7 @@ res = -EINVAL; goto out; } - pw_properties_set(props, PW_KEY_FORMAT_DSP, "32 bit raw UMP"); + pw_properties_set(props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); impl->stride = impl->format_info->size; impl->rate = pw_properties_get_uint32(props, "midi.rate", 10000); if (impl->rate == 0)
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/modules/module-vban/stream.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/modules/module-vban/stream.c
Changed
@@ -307,7 +307,7 @@ res = -EINVAL; goto out; } - pw_properties_set(props, PW_KEY_FORMAT_DSP, "32 bit raw UMP"); + pw_properties_set(props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); impl->stride = impl->format_info->size; impl->rate = pw_properties_get_uint32(props, "midi.rate", 10000); if (impl->rate == 0)
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/pipewire/filter.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/pipewire/filter.c
Changed
@@ -1855,8 +1855,10 @@ add_control_dsp_port_params(impl, p, 1u << SPA_CONTROL_Midi); else if (spa_streq(str, "8 bit raw control")) add_control_dsp_port_params(impl, p, 0); - else if (spa_streq(str, "32 bit raw UMP")) + else if (spa_streq(str, "32 bit raw UMP")) { add_control_dsp_port_params(impl, p, 1u << SPA_CONTROL_UMP); + pw_properties_set(props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); + } } /* then override with user provided if any */ if (update_params(impl, p, SPA_ID_INVALID, params, n_params) < 0)
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/pipewire/impl-node.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/pipewire/impl-node.c
Changed
@@ -660,19 +660,20 @@ struct resource_data *data = object; struct pw_impl_node *node = data->node; uint32_t id = SPA_NODE_COMMAND_ID(command); + int res; pw_log_debug("%p: got command %d (%s)", node, id, spa_debug_type_find_name(spa_type_node_command_id, id)); switch (id) { case SPA_NODE_COMMAND_Suspend: - suspend_node(node); + res = suspend_node(node); break; default: - spa_node_send_command(node->node, command); + res = spa_node_send_command(node->node, command); break; } - return 0; + return res; } static const struct pw_node_methods node_methods = {
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/pipewire/stream.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/pipewire/stream.c
Changed
@@ -2053,7 +2053,7 @@ pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, str); else if (impl->media_type == SPA_MEDIA_TYPE_application && impl->media_subtype == SPA_MEDIA_SUBTYPE_control) - pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, "32 bit raw UMP"); + pw_properties_set(impl->port_props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); if (pw_properties_get(impl->port_props, PW_KEY_PORT_GROUP) == NULL) pw_properties_set(impl->port_props, PW_KEY_PORT_GROUP, "stream.0");
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/tools/midifile.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/tools/midifile.c
Changed
@@ -940,22 +940,58 @@ dump_mem(out, "Utility", ev->data, ev->size); break; case 0x1: - dump_mem(out, "SysRT", ev->data, ev->size); + { + uint8_t b3 = { (d0 >> 16) & 0x7f, (d0 >> 8) & 0x7f, d0 & 0x7f }; + switch (b0) { + case 0xf1: + fprintf(out, "MIDI Time Code Quarter Frame: type %d values %d", + b1 >> 4, b1 & 0xf); + break; + case 0xf2: + fprintf(out, "Song Position Pointer: value %d", + ((int)b2 << 7 | b1)); + break; + case 0xf3: + fprintf(out, "Song Select: value %d", b1); + break; + case 0xf6: + fprintf(out, "Tune Request"); + break; + case 0xf8: + fprintf(out, "Timing Clock"); + break; + case 0xfa: + fprintf(out, "Start Sequence"); + break; + case 0xfb: + fprintf(out, "Continue Sequence"); + break; + case 0xfc: + fprintf(out, "Stop Sequence"); + break; + case 0xfe: + fprintf(out, "Active Sensing"); + break; + case 0xff: + fprintf(out, "System Reset"); + break; + default: + dump_mem(out, "SysRT", ev->data, ev->size); + break; + } break; + } case 0x2: { struct midi_event ev1; - uint8_t msg4; + uint8_t b3 = { d0 >> 16, d0 >> 8, d0 }; ev1 = *ev; - msg0 = (d0 >> 16); - msg1 = (d0 >> 8); - msg2 = (d0); - if (msg0 >= 0xc0 && msg0 <= 0xdf) + if (b0 >= 0xc0 && b0 <= 0xdf) ev1.size = 2; else ev1.size = 3; - ev1.data = msg; + ev1.data = b; dump_event_midi1(out, &ev1); break; }
View file
_service:download_url:pipewire-1.4.2.tar.bz2/src/tools/pw-cat.c -> _service:download_url:pipewire-1.4.4.tar.bz2/src/tools/pw-cat.c
Changed
@@ -1985,7 +1985,7 @@ SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application), SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control)); - pw_properties_set(data.props, PW_KEY_FORMAT_DSP, "32 bit raw UMP"); + pw_properties_set(data.props, PW_KEY_FORMAT_DSP, "8 bit raw midi"); break; case TYPE_DSD: {
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.