diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 55f2d0d56..c82abc13f 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -1448,8 +1448,9 @@ static size_t convert_from_event(void *midi, void *buffer, size_t size, uint32_t switch (type) { case TYPE_ID_MIDI: + event_type = SPA_CONTROL_Midi; + break; case TYPE_ID_OSC: - /* we handle MIDI as OSC, check below */ event_type = SPA_CONTROL_OSC; break; case TYPE_ID_UMP: @@ -1466,27 +1467,15 @@ static size_t convert_from_event(void *midi, void *buffer, size_t size, uint32_t for (i = 0; i < count; i++) { jack_midi_event_t ev; jack_midi_event_get(&ev, midi, i); + uint32_t ev_type; - if (type != TYPE_ID_MIDI || is_osc(&ev)) { - /* no midi port or it's OSC */ - spa_pod_builder_control(&b, ev.time, event_type); - spa_pod_builder_bytes(&b, ev.buffer, ev.size); - } else { - /* midi port and it's not OSC, convert to UMP */ - uint8_t *data = ev.buffer; - size_t size = ev.size; - uint64_t state = 0; + if (type == TYPE_ID_MIDI && is_osc(&ev)) + ev_type = SPA_CONTROL_OSC; + else + ev_type = event_type; - while (size > 0) { - uint32_t ump[4]; - int ump_size = spa_ump_from_midi(&data, &size, - ump, sizeof(ump), 0, &state); - if (ump_size <= 0) - break; - spa_pod_builder_control(&b, ev.time, SPA_CONTROL_UMP); - spa_pod_builder_bytes(&b, ump, ump_size); - } - } + spa_pod_builder_control(&b, ev.time, ev_type); + spa_pod_builder_bytes(&b, ev.buffer, ev.size); } spa_pod_builder_pop(&b, &f); return b.state.offset; diff --git a/spa/plugins/alsa/alsa-seq-bridge.c b/spa/plugins/alsa/alsa-seq-bridge.c index 06c5bc28f..ffd9e98d8 100644 --- a/spa/plugins/alsa/alsa-seq-bridge.c +++ b/spa/plugins/alsa/alsa-seq-bridge.c @@ -501,6 +501,7 @@ impl_node_port_enum_params(void *object, int seq, struct seq_state *this = object; struct seq_port *port; struct spa_pod *param; + struct spa_pod_frame f[1]; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; struct spa_result_node_params result; @@ -524,10 +525,18 @@ impl_node_port_enum_params(void *object, int seq, case SPA_PARAM_EnumFormat: if (result.index > 0) return 0; - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, + spa_pod_builder_push_object(&b, &f[0], + 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 (port->control_types != 0) { + spa_pod_builder_add(&b, + SPA_FORMAT_CONTROL_types, SPA_POD_Int(port->control_types), + 0); + } + param = spa_pod_builder_pop(&b, &f[0]); break; case SPA_PARAM_Format: @@ -535,10 +544,18 @@ impl_node_port_enum_params(void *object, int seq, return -EIO; if (result.index > 0) return 0; - param = spa_pod_builder_add_object(&b, - SPA_TYPE_OBJECT_Format, SPA_PARAM_Format, + spa_pod_builder_push_object(&b, &f[0], + 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 (port->control_types != 0) { + spa_pod_builder_add(&b, + SPA_FORMAT_CONTROL_types, SPA_POD_Int(port->control_types), + 0); + } + param = spa_pod_builder_pop(&b, &f[0]); break; case SPA_PARAM_Buffers: @@ -955,7 +972,7 @@ impl_init(const struct spa_handle_factory *factory, this->quantum_limit = 8192; this->min_pool_size = 500; this->max_pool_size = 2000; - this->ump = true; + this->ump = false; for (i = 0; info && i < info->n_items; i++) { const char *k = info->items[i].key; diff --git a/spa/plugins/alsa/alsa-seq.c b/spa/plugins/alsa/alsa-seq.c index 8a4ba369c..c25b49420 100644 --- a/spa/plugins/alsa/alsa-seq.c +++ b/spa/plugins/alsa/alsa-seq.c @@ -620,9 +620,8 @@ static int process_read(struct seq_state *state) { struct seq_stream *stream = &state->streams[SPA_DIRECTION_OUTPUT]; const bool ump = state->ump; - uint32_t *data; + void *data; uint8_t midi1_data[MAX_EVENT_SIZE]; - uint32_t ump_data[MAX_EVENT_SIZE]; long size; int res = -1; struct seq_port *port; @@ -633,9 +632,6 @@ static int process_read(struct seq_state *state) uint64_t ev_time, diff; uint32_t offset; void *event; - uint8_t *midi1_ptr; - size_t midi1_size = 0; - uint64_t ump_state = 0; snd_seq_event_type_t SPA_UNUSED type; if (ump) { @@ -702,7 +698,7 @@ static int process_read(struct seq_state *state) #ifdef HAVE_ALSA_UMP snd_seq_ump_event_t *ev = event; - data = (uint32_t*)&ev->ump[0]; + data = &ev->ump[0]; size = spa_ump_message_size(snd_ump_msg_hdr_type(ev->ump[0])) * 4; #else spa_assert_not_reached(); @@ -715,34 +711,21 @@ static int process_read(struct seq_state *state) spa_log_warn(state->log, "decode failed: %s", snd_strerror(size)); continue; } - - midi1_ptr = midi1_data; - midi1_size = size; + data = midi1_data; } - do { - if (!ump) { - data = ump_data; - size = spa_ump_from_midi(&midi1_ptr, &midi1_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_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, ump ? SPA_CONTROL_UMP : SPA_CONTROL_Midi ); + spa_pod_builder_bytes(&port->builder, data, size); - 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->datas[0].maxsize) - goto done; - - } 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->datas[0].maxsize) + goto done; } done: @@ -819,7 +802,6 @@ static int process_write(struct seq_state *state) const void *c_body; uint64_t out_time; snd_seq_real_time_t out_rt; - bool first = true; if (io->status != SPA_STATUS_HAVE_DATA || io->buffer_id >= port->n_buffers) @@ -844,9 +826,6 @@ static int process_write(struct seq_state *state) size_t body_size; uint8_t *body; - if (c.type != SPA_CONTROL_UMP) - continue; - body = (uint8_t*)c_body; body_size = c.value.size; @@ -861,6 +840,9 @@ static int process_write(struct seq_state *state) #ifdef HAVE_ALSA_UMP snd_seq_ump_event_t ev; + if (c.type != SPA_CONTROL_UMP) + continue; + snd_seq_ump_ev_clear(&ev); snd_seq_ev_set_ump_data(&ev, body, SPA_MIN(sizeof(ev.ump), (size_t)body_size)); snd_seq_ev_set_source(&ev, state->event.addr.port); @@ -878,26 +860,26 @@ static int process_write(struct seq_state *state) #endif } else { snd_seq_event_t ev; - uint8_t data[MAX_EVENT_SIZE]; - int size; - uint64_t st = 0; + int size = 0; + long s; + + if (c.type != SPA_CONTROL_Midi) + continue; while (body_size > 0) { - if ((size = spa_ump_to_midi((const uint32_t **)&body, &body_size, - data, sizeof(data), &st)) <= 0) - break; - - if (first) + if (size == 0) snd_seq_ev_clear(&ev); - if ((size = snd_midi_event_encode(stream->codec, data, size, &ev)) < 0) { + if ((s = snd_midi_event_encode(stream->codec, body, body_size, &ev)) < 0) { spa_log_warn(state->log, "failed to encode event: %s", snd_strerror(size)); snd_midi_event_reset_encode(stream->codec); - first = true; + size = 0; continue; } - first = false; + body += s; + body_size -= s; + size += s; if (ev.type == SND_SEQ_EVENT_NONE) /* this can happen when the event is not complete yet, like * a sysex message and we need to encode some more data. */ @@ -913,7 +895,7 @@ static int process_write(struct seq_state *state) spa_log_warn(state->log, "failed to output event: %s", snd_strerror(err)); } - first = true; + size = 0; } } } diff --git a/spa/plugins/alsa/alsa-seq.h b/spa/plugins/alsa/alsa-seq.h index 354fa1d5d..3100b9587 100644 --- a/spa/plugins/alsa/alsa-seq.h +++ b/spa/plugins/alsa/alsa-seq.h @@ -82,6 +82,8 @@ struct seq_port { struct spa_pod_builder builder; struct spa_pod_frame frame; + uint32_t control_types; + struct spa_audio_info current_format; unsigned int have_format:1; unsigned int active:1; diff --git a/src/modules/module-ffado-driver.c b/src/modules/module-ffado-driver.c index 05b9218ce..c98b0efcd 100644 --- a/src/modules/module-ffado-driver.c +++ b/src/modules/module-ffado-driver.c @@ -345,34 +345,26 @@ static void midi_to_ffado(struct port *p, float *src, uint32_t n_samples) p->event_pos = 0; while (spa_pod_parser_get_control_body(&parser, &c, &c_body) >= 0) { - uint8_t data[16]; - int j, size; - size_t c_size = c.value.size; - uint64_t state = 0; + uint32_t j, size = c.value.size; + const uint8_t *data = c_body; - if (c.type != SPA_CONTROL_UMP) + if (c.type != SPA_CONTROL_Midi) continue; if (index < c.offset) index = SPA_ROUND_UP_N(c.offset, 8); - while (c_size > 0) { - size = spa_ump_to_midi((const uint32_t**)&c_body, &c_size, data, sizeof(data), &state); - if (size <= 0) - break; - - for (j = 0; j < size; j++) { - if (index >= n_samples) { - /* keep events that don't fit for the next cycle */ - if (p->event_pos < sizeof(p->event_buffer)) - p->event_buffer[p->event_pos++] = data[j]; - else - unhandled++; - } + for (j = 0; j < size; j++) { + if (index >= n_samples) { + /* keep events that don't fit for the next cycle */ + if (p->event_pos < sizeof(p->event_buffer)) + p->event_buffer[p->event_pos++] = data[j]; else - dst[index] = 0x01000000 | (uint32_t) data[j]; - index += 8; + unhandled++; } + else + dst[index] = 0x01000000 | (uint32_t) data[j]; + index += 8; } } if (unhandled > 0) @@ -497,16 +489,8 @@ static void ffado_to_midi(struct port *p, float *dst, uint32_t *src, uint32_t si continue; if (process_byte(p, i, data & 0xff, &frame, &bytes, &size)) { - uint64_t state = 0; - while (size > 0) { - uint32_t ev[4]; - int ev_size = spa_ump_from_midi(&bytes, &size, ev, sizeof(ev), 0, &state); - if (ev_size <= 0) - break; - - spa_pod_builder_control(&b, frame, SPA_CONTROL_UMP); - spa_pod_builder_bytes(&b, ev, ev_size); - } + spa_pod_builder_control(&b, frame, SPA_CONTROL_Midi); + spa_pod_builder_bytes(&b, bytes, size); } } spa_pod_builder_pop(&b, &f); diff --git a/src/modules/module-jack-tunnel.c b/src/modules/module-jack-tunnel.c index 0c0cee034..4b22f7883 100644 --- a/src/modules/module-jack-tunnel.c +++ b/src/modules/module-jack-tunnel.c @@ -243,13 +243,16 @@ static inline void do_volume(float *dst, const float *src, struct volume *vol, u } } -static inline void fix_midi_event(uint8_t *data, size_t size) +static inline bool fix_midi_event(const uint8_t *data, size_t size, uint8_t dst[3]) { /* fixup NoteOn with vel 0 */ if (size > 2 && (data[0] & 0xF0) == 0x90 && data[2] == 0x00) { - data[0] = 0x80 + (data[0] & 0x0F); - data[2] = 0x40; + dst[0] = 0x80 + (data[0] & 0x0F); + dst[1] = data[1]; + dst[2] = 0x40; + return true; } + return false; } static void midi_to_jack(struct impl *impl, float *dst, float *src, uint32_t n_samples) @@ -260,9 +263,6 @@ static void midi_to_jack(struct impl *impl, float *dst, float *src, uint32_t n_s struct spa_pod_control c; const void *seq_body, *c_body; int res; - bool in_sysex = false; - uint8_t tmp[n_samples * 4]; - size_t tmp_size = 0; jack.midi_clear_buffer(dst); if (src == NULL) @@ -274,36 +274,20 @@ static void midi_to_jack(struct impl *impl, float *dst, float *src, uint32_t n_s return; while (spa_pod_parser_get_control_body(&parser, &c, &c_body) >= 0) { - int size; - size_t c_size = c.value.size; - uint64_t state = 0; + uint32_t size = c.value.size; + const uint8_t *data = c_body; + uint8_t tmp[3]; - 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, - &tmp[tmp_size], sizeof(tmp) - tmp_size, &state); - if (size <= 0) - break; - - if (impl->fix_midi) - fix_midi_event(&tmp[tmp_size], size); - - if (!in_sysex && tmp[tmp_size] == 0xf0) - in_sysex = true; - - tmp_size += size; - if (in_sysex && tmp[tmp_size-1] == 0xf7) - in_sysex = false; - - if (!in_sysex) { - 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; - } + if (impl->fix_midi && fix_midi_event(data, size, tmp)) { + data = tmp; + size = 3; } + 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)); } } @@ -319,19 +303,11 @@ static void jack_to_midi(float *dst, float *src, uint32_t size) spa_pod_builder_push_sequence(&b, &f, 0); for (i = 0; i < count; i++) { jack_midi_event_t ev; - uint64_t state = 0; jack.midi_event_get(&ev, src, i); - while (ev.size > 0) { - uint32_t ump[4]; - int ump_size = spa_ump_from_midi(&ev.buffer, &ev.size, ump, sizeof(ump), 0, &state); - if (ump_size <= 0) - break; - - spa_pod_builder_control(&b, ev.time, SPA_CONTROL_UMP); - spa_pod_builder_bytes(&b, ump, ump_size); - } + spa_pod_builder_control(&b, ev.time, SPA_CONTROL_Midi); + spa_pod_builder_bytes(&b, ev.buffer, ev.size); } spa_pod_builder_pop(&b, &f); } diff --git a/src/modules/module-netjack2/peer.c b/src/modules/module-netjack2/peer.c index eacc1c95b..0486bcfe1 100644 --- a/src/modules/module-netjack2/peer.c +++ b/src/modules/module-netjack2/peer.c @@ -235,13 +235,16 @@ struct data_info { bool filled; }; -static inline void fix_midi_event(uint8_t *data, size_t size) +static inline bool fix_midi_event(const uint8_t *data, size_t size, uint8_t tmp[3]) { /* fixup NoteOn with vel 0 */ if (size > 2 && (data[0] & 0xF0) == 0x90 && data[2] == 0x00) { - data[0] = 0x80 + (data[0] & 0x0F); - data[2] = 0x40; + tmp[0] = 0x80 + (data[0] & 0x0F); + tmp[1] = data[1]; + tmp[2] = 0x40; + return true; } + return false; } static inline void *n2j_midi_buffer_reserve(struct nj2_midi_buffer *buf, @@ -273,7 +276,7 @@ static inline void *n2j_midi_buffer_reserve(struct nj2_midi_buffer *buf, } static inline void n2j_midi_buffer_write(struct nj2_midi_buffer *buf, - uint32_t offset, void *data, uint32_t size) + uint32_t offset, const void *data, uint32_t size) { void *ptr = n2j_midi_buffer_reserve(buf, offset, size); if (ptr != NULL) @@ -314,7 +317,6 @@ static void midi_to_netjack2(struct netjack2_peer *peer, struct spa_pod_sequence seq; struct spa_pod_control c; const void *seq_body, *c_body; - bool in_sysex = false; buf->magic = MIDI_BUFFER_MAGIC; buf->buffer_size = peer->params.period_size * sizeof(float); @@ -332,39 +334,22 @@ static void midi_to_netjack2(struct netjack2_peer *peer, return; while (spa_pod_parser_get_control_body(&parser, &c, &c_body) >= 0) { - int size; - uint8_t data[16]; - bool was_sysex = in_sysex; - size_t c_size = c.value.size; - uint64_t state = 0; + uint32_t size = c.value.size; + const uint8_t *data = c_body; + uint8_t tmp[3]; - 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, data, sizeof(data), &state); - if (size <= 0) - break; - - if (c.offset >= n_samples) { - buf->lost_events++; - continue; - } - - if (!in_sysex && data[0] == 0xf0) - in_sysex = true; - - if (!in_sysex && peer->fix_midi) - fix_midi_event(data, size); - - if (in_sysex && data[size-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 (c.offset >= n_samples) { + buf->lost_events++; + continue; } + if (peer->fix_midi && fix_midi_event(data, size, tmp)) { + data = tmp; + size = 3; + } + 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), @@ -395,8 +380,6 @@ static inline void netjack2_to_midi(float *dst, uint32_t size, struct nj2_midi_b for (i = 0; i < buf->event_count; i++) { struct nj2_midi_event *ev = &buf->event[i]; uint8_t *data; - size_t s; - uint64_t state = 0; if (ev->size <= MIDI_INLINE_MAX) data = ev->buffer; @@ -405,17 +388,8 @@ static inline void netjack2_to_midi(float *dst, uint32_t size, struct nj2_midi_b else continue; - s = ev->size; - while (s > 0) { - uint32_t ump[4]; - int ump_size = spa_ump_from_midi(&data, &s, ump, sizeof(ump), 0, &state); - 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); - } + spa_pod_builder_control(&b, ev->time, SPA_CONTROL_Midi); + spa_pod_builder_bytes(&b, data, ev->size); } spa_pod_builder_pop(&b, &f); } diff --git a/src/modules/module-rtp/midi.c b/src/modules/module-rtp/midi.c index 5fbdf3b63..d5c55740d 100644 --- a/src/modules/module-rtp/midi.c +++ b/src/modules/module-rtp/midi.c @@ -271,9 +271,6 @@ static int rtp_midi_receive_midi(struct impl *impl, uint8_t *packet, uint32_t ti while (offs < end) { uint32_t delta; int size; - uint64_t state = 0; - uint8_t *d; - size_t s; if (first && !hdr.z) delta = 0; @@ -294,17 +291,9 @@ static int rtp_midi_receive_midi(struct impl *impl, uint8_t *packet, uint32_t ti return -EINVAL; } - d = &packet[offs]; - s = size; - while (s > 0) { - uint32_t ump[4]; - int ump_size = spa_ump_from_midi(&d, &s, ump, sizeof(ump), 0, &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; first = false; } @@ -378,7 +367,7 @@ unexpected_ssrc: return -EINVAL; } -static int write_event(uint8_t *p, uint32_t buffer_size, uint32_t value, void *ev, uint32_t size) +static int write_event(uint8_t *p, uint32_t buffer_size, uint32_t value, const void *ev, uint32_t size) { uint64_t buffer; uint8_t b; @@ -437,62 +426,54 @@ static void rtp_midi_flush_packets(struct impl *impl, while (spa_pod_parser_get_control_body(parser, &c, &c_body) >= 0) { uint32_t delta, offset; - uint8_t event[16]; - int size; - size_t c_size = c.value.size; - uint64_t state = 0; + uint32_t size = c.value.size; + const uint8_t *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; + offset = c.offset * impl->rate / rate; - offset = c.offset * impl->rate / rate; - - if (len > 0 && (len + size > max_size || - offset - base > impl->psamples)) { - /* flush packet when we have one and when it's either - * too large or has too much data. */ - if (len < 16) { - midi_header.b = 0; - midi_header.len = len; - iov[1].iov_len = sizeof(midi_header) - 1; - } else { - midi_header.b = 1; - midi_header.len = (len >> 8) & 0xf; - midi_header.len_b = len & 0xff; - iov[1].iov_len = sizeof(midi_header); - } - iov[2].iov_len = len; - - pw_log_trace("sending %d timestamp:%d %u %u", - len, timestamp + base, - offset, impl->psamples); - rtp_stream_emit_send_packet(impl, iov, 3); - - impl->seq++; - len = 0; - } - if ((unsigned int)size > BUFFER_SIZE || len > BUFFER_SIZE - size) { - pw_log_error("Buffer overflow prevented!"); - return; // FIXME: what to do instead? - } - if (len == 0) { - /* start new packet */ - base = prev_offset = offset; - header.sequence_number = htons(impl->seq); - header.timestamp = htonl(impl->ts_offset + timestamp + base); - - memcpy(&impl->buffer[len], event, size); - len += size; + if (len > 0 && (len + size > max_size || + offset - base > impl->psamples)) { + /* flush packet when we have one and when it's either + * too large or has too much data. */ + if (len < 16) { + midi_header.b = 0; + midi_header.len = len; + iov[1].iov_len = sizeof(midi_header) - 1; } else { - delta = offset - prev_offset; - prev_offset = offset; - len += write_event(&impl->buffer[len], BUFFER_SIZE - len, delta, event, size); + midi_header.b = 1; + midi_header.len = (len >> 8) & 0xf; + midi_header.len_b = len & 0xff; + iov[1].iov_len = sizeof(midi_header); } + iov[2].iov_len = len; + + pw_log_trace("sending %d timestamp:%d %u %u", + len, timestamp + base, + offset, impl->psamples); + rtp_stream_emit_send_packet(impl, iov, 3); + + impl->seq++; + len = 0; + } + if ((unsigned int)size > BUFFER_SIZE || len > BUFFER_SIZE - size) { + pw_log_error("Buffer overflow prevented!"); + return; // FIXME: what to do instead? + } + if (len == 0) { + /* start new packet */ + base = prev_offset = offset; + header.sequence_number = htons(impl->seq); + header.timestamp = htonl(impl->ts_offset + timestamp + base); + + memcpy(&impl->buffer[len], data, size); + len += size; + } else { + delta = offset - prev_offset; + prev_offset = offset; + len += write_event(&impl->buffer[len], BUFFER_SIZE - len, delta, data, size); } } if (len > 0) { diff --git a/src/modules/module-vban/midi.c b/src/modules/module-vban/midi.c index f460bd274..484902448 100644 --- a/src/modules/module-vban/midi.c +++ b/src/modules/module-vban/midi.c @@ -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 */