mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-28 06:46:42 -04:00
midi: don't convert Midi in nodes
Avoid doing conversions in the nodes between Midi formats, just assume the imput is what we expect and output what we naturally produce. For ALSA this means we produce and consume Midi1 or Midi2 depending on the configurtation. All of the other modules (ffado, RTP, netjack and VBAN) really only produce and consume MIDI1. Set the default MIDI format to MIDI1 in ALSA. Whith this change, almost everything now produces and consumes MIDI1 again (previously the buffer format was forced to MIDI2). The problem is that MIDI2 to and from MIDI1 conversion has problems in some cases in PipeWire and ALSA and breaks compatibility with some hardware. The idea is to let elements produce their prefered format and that the control mixer also negotiates and converts to the node prefered format. There is then a mix of MIDI2 and MIDI1 on ports but with the control port adapting, this should not be a problem. There is one remaining problem to make this work, the port format is taken from the node port and not the mixer port, which would then expose the prefered format on the port and force negotiation to it with the peer instead of in the mixer. See #5183
This commit is contained in:
parent
67070762d0
commit
ea28343166
9 changed files with 177 additions and 293 deletions
|
|
@ -163,9 +163,6 @@ static int vban_midi_receive_midi(struct impl *impl, uint8_t *packet,
|
|||
|
||||
while (offs < plen) {
|
||||
int size;
|
||||
uint8_t *midi_data;
|
||||
size_t midi_size;
|
||||
uint64_t midi_state = 0;
|
||||
|
||||
size = get_midi_size(&packet[offs], plen - offs);
|
||||
if (size <= 0 || offs + size > plen) {
|
||||
|
|
@ -174,18 +171,9 @@ static int vban_midi_receive_midi(struct impl *impl, uint8_t *packet,
|
|||
break;
|
||||
}
|
||||
|
||||
midi_data = &packet[offs];
|
||||
midi_size = size;
|
||||
while (midi_size > 0) {
|
||||
uint32_t ump[4];
|
||||
int ump_size = spa_ump_from_midi(&midi_data, &midi_size,
|
||||
ump, sizeof(ump), 0, &midi_state);
|
||||
if (ump_size <= 0)
|
||||
break;
|
||||
spa_pod_builder_control(&b, timestamp, SPA_CONTROL_Midi);
|
||||
spa_pod_builder_bytes(&b, &packet[offs], size);
|
||||
|
||||
spa_pod_builder_control(&b, timestamp, SPA_CONTROL_UMP);
|
||||
spa_pod_builder_bytes(&b, ump, ump_size);
|
||||
}
|
||||
offs += size;
|
||||
}
|
||||
spa_pod_builder_pop(&b, &f[0]);
|
||||
|
|
@ -237,34 +225,25 @@ static void vban_midi_flush_packets(struct impl *impl,
|
|||
len = 0;
|
||||
|
||||
while (spa_pod_parser_get_control_body(parser, &c, &c_body) >= 0) {
|
||||
int size;
|
||||
uint8_t event[16];
|
||||
uint64_t state = 0;
|
||||
size_t c_size = c.value.size;
|
||||
uint32_t size = c.value.size;
|
||||
const void *data = c_body;
|
||||
|
||||
if (c.type != SPA_CONTROL_UMP)
|
||||
if (c.type != SPA_CONTROL_Midi)
|
||||
continue;
|
||||
|
||||
while (c_size > 0) {
|
||||
size = spa_ump_to_midi((const uint32_t**)&c_body,
|
||||
&c_size, event, sizeof(event), &state);
|
||||
if (size <= 0)
|
||||
break;
|
||||
if (len == 0) {
|
||||
/* start new packet */
|
||||
header.n_frames++;
|
||||
} else if (len + size > impl->mtu) {
|
||||
/* flush packet when we have one and when it's too large */
|
||||
iov[1].iov_len = len;
|
||||
|
||||
if (len == 0) {
|
||||
/* start new packet */
|
||||
header.n_frames++;
|
||||
} else if (len + size > impl->mtu) {
|
||||
/* flush packet when we have one and when it's too large */
|
||||
iov[1].iov_len = len;
|
||||
|
||||
pw_log_debug("sending %d", len);
|
||||
vban_stream_emit_send_packet(impl, iov, 2);
|
||||
len = 0;
|
||||
}
|
||||
memcpy(&impl->buffer[len], event, size);
|
||||
len += size;
|
||||
pw_log_debug("sending %d", len);
|
||||
vban_stream_emit_send_packet(impl, iov, 2);
|
||||
len = 0;
|
||||
}
|
||||
memcpy(&impl->buffer[len], data, size);
|
||||
len += size;
|
||||
}
|
||||
if (len > 0) {
|
||||
/* flush last packet */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue