mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
modules: accept and produce UMP only
This commit is contained in:
parent
40cd8535eb
commit
d9e7a10b0d
11 changed files with 199 additions and 126 deletions
|
|
@ -23,6 +23,7 @@
|
|||
#include <spa/utils/ringbuffer.h>
|
||||
#include <spa/monitor/device.h>
|
||||
#include <spa/control/control.h>
|
||||
#include <spa/control/ump-utils.h>
|
||||
|
||||
#include <spa/node/node.h>
|
||||
#include <spa/node/utils.h>
|
||||
|
|
@ -449,7 +450,7 @@ static void midi_event_recv(void *user_data, uint16_t timestamp, uint8_t *data,
|
|||
struct impl *this = user_data;
|
||||
struct port *port = &this->ports[PORT_OUT];
|
||||
struct time_sync *sync = &port->sync;
|
||||
uint64_t time;
|
||||
uint64_t time, state = 0;
|
||||
int res;
|
||||
|
||||
spa_assert(size > 0);
|
||||
|
|
@ -459,11 +460,19 @@ static void midi_event_recv(void *user_data, uint16_t timestamp, uint8_t *data,
|
|||
spa_log_trace(this->log, "%p: event:0x%x size:%d timestamp:%d time:%"PRIu64"",
|
||||
this, (int)data[0], (int)size, (int)timestamp, (uint64_t)time);
|
||||
|
||||
res = midi_event_ringbuffer_push(&this->event_rbuf, time, data, size);
|
||||
if (res < 0) {
|
||||
midi_event_ringbuffer_init(&this->event_rbuf);
|
||||
spa_log_warn(this->log, "%p: MIDI receive buffer overflow: %s",
|
||||
this, spa_strerror(res));
|
||||
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;
|
||||
|
||||
res = midi_event_ringbuffer_push(&this->event_rbuf, time, (uint8_t*)ump, ump_size);
|
||||
if (res < 0) {
|
||||
midi_event_ringbuffer_init(&this->event_rbuf);
|
||||
spa_log_warn(this->log, "%p: MIDI receive buffer overflow: %s",
|
||||
this, spa_strerror(res));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -704,7 +713,7 @@ static int process_output(struct impl *this)
|
|||
offset = time * this->rate / SPA_NSEC_PER_SEC;
|
||||
offset = SPA_CLAMP(offset, 0u, this->duration - 1);
|
||||
|
||||
spa_pod_builder_control(&port->builder, offset, SPA_CONTROL_Midi);
|
||||
spa_pod_builder_control(&port->builder, offset, SPA_CONTROL_UMP);
|
||||
buf = spa_pod_builder_reserve_bytes(&port->builder, size);
|
||||
if (buf) {
|
||||
midi_event_ringbuffer_pop(&this->event_rbuf, buf, size);
|
||||
|
|
@ -773,15 +782,18 @@ static int write_data(struct impl *this, struct spa_data *d)
|
|||
time = 0;
|
||||
|
||||
SPA_POD_SEQUENCE_FOREACH(pod, c) {
|
||||
uint8_t *event;
|
||||
size_t size;
|
||||
int size;
|
||||
uint8_t event[32];
|
||||
|
||||
if (c->type != SPA_CONTROL_Midi)
|
||||
if (c->type != SPA_CONTROL_UMP)
|
||||
continue;
|
||||
|
||||
time = SPA_MAX(time, this->current_time + c->offset * SPA_NSEC_PER_SEC / this->rate);
|
||||
event = SPA_POD_BODY(&c->value);
|
||||
size = SPA_POD_BODY_SIZE(&c->value);
|
||||
|
||||
size = spa_ump_to_midi(SPA_POD_BODY(&c->value),
|
||||
SPA_POD_BODY_SIZE(&c->value), event, sizeof(event));
|
||||
if (size <= 0)
|
||||
continue;
|
||||
|
||||
spa_log_trace(this->log, "%p: output event:0x%x time:%"PRIu64, this,
|
||||
(size > 0) ? event[0] : 0, time);
|
||||
|
|
@ -1555,7 +1567,8 @@ next:
|
|||
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_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control),
|
||||
SPA_FORMAT_CONTROL_types, SPA_POD_CHOICE_FLAGS_Int(1u<<SPA_CONTROL_UMP));
|
||||
break;
|
||||
|
||||
case SPA_PARAM_Format:
|
||||
|
|
@ -1567,7 +1580,8 @@ next:
|
|||
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_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control),
|
||||
SPA_FORMAT_CONTROL_types, SPA_POD_Int(1u<<SPA_CONTROL_UMP));
|
||||
break;
|
||||
|
||||
case SPA_PARAM_Buffers:
|
||||
|
|
@ -2008,13 +2022,13 @@ impl_init(const struct spa_handle_factory *factory,
|
|||
for (i = 0; i < N_PORTS; ++i) {
|
||||
struct port *port = &this->ports[i];
|
||||
static const struct spa_dict_item in_port_items[] = {
|
||||
SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "8 bit raw midi"),
|
||||
SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"),
|
||||
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, "8 bit raw midi"),
|
||||
SPA_DICT_ITEM_INIT(SPA_KEY_FORMAT_DSP, "32 bit raw UMP"),
|
||||
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"),
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ static void on_process(void *userdata, struct spa_io_position *position)
|
|||
while (sample_offset < position->clock.duration) {
|
||||
if (cycle % 2 == 0) {
|
||||
/* MIDI note on, channel 0, middle C, max velocity */
|
||||
uint8_t buf[] = { 0x90, 0x3c, 0x7f };
|
||||
uint32_t event = 0x20903c7f;
|
||||
|
||||
/* The time position of the message in the graph cycle
|
||||
* is given as offset from the cycle start, in
|
||||
|
|
@ -111,18 +111,18 @@ static void on_process(void *userdata, struct spa_io_position *position)
|
|||
* samples, and the sample offset should satisfy
|
||||
* 0 <= sample_offset < position->clock.duration.
|
||||
*/
|
||||
spa_pod_builder_control(&builder, sample_offset, SPA_CONTROL_Midi);
|
||||
spa_pod_builder_control(&builder, sample_offset, SPA_CONTROL_UMP);
|
||||
|
||||
/* Raw MIDI data for the message */
|
||||
spa_pod_builder_bytes(&builder, buf, sizeof(buf));
|
||||
spa_pod_builder_bytes(&builder, &event, sizeof(event));
|
||||
|
||||
pw_log_info("note on at %"PRIu64, sample_position + sample_offset);
|
||||
} else {
|
||||
/* MIDI note off, channel 0, middle C, max velocity */
|
||||
uint8_t buf[] = { 0x80, 0x3c, 0x7f };
|
||||
uint32_t event = 0x20803c7f;
|
||||
|
||||
spa_pod_builder_control(&builder, sample_offset, SPA_CONTROL_Midi);
|
||||
spa_pod_builder_bytes(&builder, buf, sizeof(buf));
|
||||
spa_pod_builder_control(&builder, sample_offset, SPA_CONTROL_UMP);
|
||||
spa_pod_builder_bytes(&builder, &event, sizeof(event));
|
||||
|
||||
pw_log_info("note off at %"PRIu64, sample_position + sample_offset);
|
||||
}
|
||||
|
|
@ -213,7 +213,7 @@ int main(int argc, char *argv[])
|
|||
PW_FILTER_PORT_FLAG_MAP_BUFFERS,
|
||||
sizeof(struct port),
|
||||
pw_properties_new(
|
||||
PW_KEY_FORMAT_DSP, "8 bit raw midi",
|
||||
PW_KEY_FORMAT_DSP, "32 bit raw UMP",
|
||||
PW_KEY_PORT_NAME, "output",
|
||||
NULL),
|
||||
NULL, 0);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/latency-utils.h>
|
||||
#include <spa/param/audio/raw.h>
|
||||
#include <spa/control/ump-utils.h>
|
||||
|
||||
#include <pipewire/impl.h>
|
||||
#include <pipewire/i18n.h>
|
||||
|
|
@ -333,30 +334,30 @@ static void midi_to_ffado(struct port *p, float *src, uint32_t n_samples)
|
|||
p->event_pos = 0;
|
||||
|
||||
SPA_POD_SEQUENCE_FOREACH(seq, c) {
|
||||
switch(c->type) {
|
||||
case SPA_CONTROL_Midi:
|
||||
{
|
||||
uint8_t *data = SPA_POD_BODY(&c->value);
|
||||
size_t size = SPA_POD_BODY_SIZE(&c->value);
|
||||
uint8_t data[16];
|
||||
int j, size;
|
||||
|
||||
if (index < c->offset)
|
||||
index = SPA_ROUND_UP_N(c->offset, 8);
|
||||
for (i = 0; i < size; i++) {
|
||||
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[i];
|
||||
else
|
||||
unhandled++;
|
||||
}
|
||||
if (c->type != SPA_CONTROL_UMP)
|
||||
continue;
|
||||
|
||||
size = spa_ump_to_midi(SPA_POD_BODY(&c->value),
|
||||
SPA_POD_BODY_SIZE(&c->value), data, sizeof(data));
|
||||
if (size <= 0)
|
||||
continue;
|
||||
|
||||
if (index < c->offset)
|
||||
index = SPA_ROUND_UP_N(c->offset, 8);
|
||||
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[i];
|
||||
index += 8;
|
||||
unhandled++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
else
|
||||
dst[index] = 0x01000000 | (uint32_t) data[j];
|
||||
index += 8;
|
||||
}
|
||||
}
|
||||
if (unhandled > 0)
|
||||
|
|
@ -481,8 +482,16 @@ 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)) {
|
||||
spa_pod_builder_control(&b, frame, SPA_CONTROL_Midi);
|
||||
spa_pod_builder_bytes(&b, 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_pop(&b, &f);
|
||||
|
|
@ -733,7 +742,7 @@ static int make_stream_ports(struct stream *s)
|
|||
break;
|
||||
case ffado_stream_type_midi:
|
||||
props = pw_properties_new(
|
||||
PW_KEY_FORMAT_DSP, "8 bit raw midi",
|
||||
PW_KEY_FORMAT_DSP, "32 bit raw UMP",
|
||||
PW_KEY_PORT_NAME, port->name,
|
||||
PW_KEY_PORT_PHYSICAL, "true",
|
||||
PW_KEY_PORT_TERMINAL, "true",
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/param/latency-utils.h>
|
||||
#include <spa/param/audio/raw.h>
|
||||
#include <spa/control/ump-utils.h>
|
||||
|
||||
#include <pipewire/impl.h>
|
||||
#include <pipewire/i18n.h>
|
||||
|
|
@ -254,23 +255,23 @@ static void midi_to_jack(struct impl *impl, float *dst, float *src, uint32_t n_s
|
|||
seq = (struct spa_pod_sequence*)pod;
|
||||
|
||||
SPA_POD_SEQUENCE_FOREACH(seq, c) {
|
||||
switch(c->type) {
|
||||
case SPA_CONTROL_Midi:
|
||||
{
|
||||
uint8_t *data = SPA_POD_BODY(&c->value);
|
||||
size_t size = SPA_POD_BODY_SIZE(&c->value);
|
||||
uint8_t data[16];
|
||||
int size;
|
||||
|
||||
if (impl->fix_midi)
|
||||
fix_midi_event(data, size);
|
||||
if (c->type != SPA_CONTROL_UMP)
|
||||
continue;
|
||||
|
||||
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));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -286,9 +287,19 @@ 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);
|
||||
spa_pod_builder_control(&b, ev.time, SPA_CONTROL_Midi);
|
||||
spa_pod_builder_bytes(&b, ev.buffer, ev.size);
|
||||
|
||||
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_pop(&b, &f);
|
||||
}
|
||||
|
|
@ -487,7 +498,7 @@ static void make_stream_ports(struct stream *s)
|
|||
} else {
|
||||
snprintf(name, sizeof(name), "%s_%d", prefix, i - s->info.channels);
|
||||
props = pw_properties_new(
|
||||
PW_KEY_FORMAT_DSP, "8 bit raw midi",
|
||||
PW_KEY_FORMAT_DSP, "32 bit raw UMP",
|
||||
PW_KEY_PORT_NAME, name,
|
||||
PW_KEY_PORT_PHYSICAL, "true",
|
||||
NULL);
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ static void make_stream_ports(struct stream *s)
|
|||
} else {
|
||||
snprintf(name, sizeof(name), "midi%d", i - s->info.channels);
|
||||
props = pw_properties_new(
|
||||
PW_KEY_FORMAT_DSP, "8 bit raw midi",
|
||||
PW_KEY_FORMAT_DSP, "32 bit raw UMP",
|
||||
PW_KEY_AUDIO_CHANNEL, name,
|
||||
PW_KEY_PORT_PHYSICAL, "true",
|
||||
NULL);
|
||||
|
|
|
|||
|
|
@ -543,7 +543,7 @@ static void make_stream_ports(struct stream *s)
|
|||
} else {
|
||||
snprintf(name, sizeof(name), "midi%d", i - s->info.channels);
|
||||
props = pw_properties_new(
|
||||
PW_KEY_FORMAT_DSP, "8 bit raw midi",
|
||||
PW_KEY_FORMAT_DSP, "32 bit raw UMP",
|
||||
PW_KEY_PORT_PHYSICAL, "true",
|
||||
PW_KEY_AUDIO_CHANNEL, name,
|
||||
NULL);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
#include <spa/utils/endian.h>
|
||||
#include <spa/control/ump-utils.h>
|
||||
|
||||
#ifdef HAVE_OPUS_CUSTOM
|
||||
#include <opus/opus.h>
|
||||
|
|
@ -248,7 +249,7 @@ static void midi_to_netjack2(struct netjack2_peer *peer,
|
|||
struct spa_pod_sequence *seq;
|
||||
struct spa_pod_control *c;
|
||||
struct nj2_midi_event *ev;
|
||||
uint32_t free_size;
|
||||
int free_size;
|
||||
|
||||
buf->magic = MIDI_BUFFER_MAGIC;
|
||||
buf->buffer_size = peer->quantum_limit * sizeof(float);
|
||||
|
|
@ -271,40 +272,41 @@ static void midi_to_netjack2(struct netjack2_peer *peer,
|
|||
free_size = buf->buffer_size - sizeof(*buf);
|
||||
|
||||
SPA_POD_SEQUENCE_FOREACH(seq, c) {
|
||||
switch(c->type) {
|
||||
case SPA_CONTROL_Midi:
|
||||
{
|
||||
uint8_t *data = SPA_POD_BODY(&c->value);
|
||||
size_t size = SPA_POD_BODY_SIZE(&c->value);
|
||||
void *ptr;
|
||||
int size;
|
||||
uint8_t data[16];
|
||||
void *ptr;
|
||||
|
||||
if (c->offset >= n_samples ||
|
||||
size >= free_size) {
|
||||
buf->lost_events++;
|
||||
continue;
|
||||
}
|
||||
if (peer->fix_midi)
|
||||
fix_midi_event(data, size);
|
||||
if (c->type != SPA_CONTROL_UMP)
|
||||
continue;
|
||||
|
||||
ev = &buf->event[buf->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);
|
||||
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 (c->offset >= n_samples ||
|
||||
size >= free_size) {
|
||||
buf->lost_events++;
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
||||
if (peer->fix_midi)
|
||||
fix_midi_event(data, size);
|
||||
|
||||
ev = &buf->event[buf->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 (buf->write_pos > 0)
|
||||
memmove(SPA_PTROFF(buf, sizeof(*buf) + buf->event_count * sizeof(struct nj2_midi_event), void),
|
||||
|
|
@ -322,7 +324,9 @@ static inline void netjack2_to_midi(float *dst, uint32_t size, struct nj2_midi_b
|
|||
spa_pod_builder_push_sequence(&b, &f, 0);
|
||||
for (i = 0; buf != NULL && i < buf->event_count; i++) {
|
||||
struct nj2_midi_event *ev = &buf->event[i];
|
||||
void *data;
|
||||
uint8_t *data;
|
||||
size_t s;
|
||||
uint64_t state = 0;
|
||||
|
||||
if (ev->size <= MIDI_INLINE_MAX)
|
||||
data = ev->buffer;
|
||||
|
|
@ -331,8 +335,16 @@ static inline void netjack2_to_midi(float *dst, uint32_t size, struct nj2_midi_b
|
|||
else
|
||||
continue;
|
||||
|
||||
spa_pod_builder_control(&b, ev->time, SPA_CONTROL_Midi);
|
||||
spa_pod_builder_bytes(&b, data, ev->size);
|
||||
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)
|
||||
break;
|
||||
|
||||
spa_pod_builder_control(&b, ev->time, SPA_CONTROL_UMP);
|
||||
spa_pod_builder_bytes(&b, ump, ump_size);
|
||||
}
|
||||
}
|
||||
spa_pod_builder_pop(&b, &f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ static void rtp_midi_process_playback(void *data)
|
|||
} else {
|
||||
timestamp = target;
|
||||
}
|
||||
spa_pod_builder_control(&b, target - timestamp, SPA_CONTROL_Midi);
|
||||
spa_pod_builder_control(&b, target - timestamp, c->type);
|
||||
spa_pod_builder_bytes(&b,
|
||||
SPA_POD_BODY(&c->value),
|
||||
SPA_POD_BODY_SIZE(&c->value));
|
||||
|
|
@ -242,25 +242,34 @@ 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;
|
||||
else
|
||||
offs += parse_varlen(&packet[offs], end - offs, &delta);
|
||||
|
||||
timestamp += (uint32_t)(delta * impl->corr);
|
||||
spa_pod_builder_control(&b, timestamp, SPA_CONTROL_Midi);
|
||||
|
||||
size = get_midi_size(&packet[offs], end - offs);
|
||||
|
||||
if (size <= 0 || offs + size > end) {
|
||||
pw_log_warn("invalid size (%08x) %d (%u %u)",
|
||||
packet[offs], size, offs, end);
|
||||
break;
|
||||
}
|
||||
|
||||
spa_pod_builder_bytes(&b, &packet[offs], size);
|
||||
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_UMP);
|
||||
spa_pod_builder_bytes(&b, ump, ump_size);
|
||||
}
|
||||
offs += size;
|
||||
first = false;
|
||||
}
|
||||
|
|
@ -373,14 +382,17 @@ static void rtp_midi_flush_packets(struct impl *impl,
|
|||
prev_offset = len = base = 0;
|
||||
|
||||
SPA_POD_SEQUENCE_FOREACH(sequence, c) {
|
||||
void *ev;
|
||||
uint32_t size, delta, offset;
|
||||
uint32_t delta, offset;
|
||||
uint8_t event[16];
|
||||
size_t size;
|
||||
|
||||
if (c->type != SPA_CONTROL_Midi)
|
||||
if (c->type != SPA_CONTROL_UMP)
|
||||
continue;
|
||||
|
||||
ev = SPA_POD_BODY(&c->value),
|
||||
size = SPA_POD_BODY_SIZE(&c->value);
|
||||
size = spa_ump_to_midi(SPA_POD_BODY(&c->value),
|
||||
SPA_POD_BODY_SIZE(&c->value), event, sizeof(event));
|
||||
if (size <= 0)
|
||||
continue;
|
||||
|
||||
offset = c->offset * impl->rate / rate;
|
||||
|
||||
|
|
@ -414,12 +426,12 @@ static void rtp_midi_flush_packets(struct impl *impl,
|
|||
header.sequence_number = htons(impl->seq);
|
||||
header.timestamp = htonl(impl->ts_offset + timestamp + base);
|
||||
|
||||
memcpy(&impl->buffer[len], ev, size);
|
||||
memcpy(&impl->buffer[len], event, size);
|
||||
len += size;
|
||||
} else {
|
||||
delta = offset - prev_offset;
|
||||
prev_offset = offset;
|
||||
len += write_event(&impl->buffer[len], delta, ev, size);
|
||||
len += write_event(&impl->buffer[len], delta, event, size);
|
||||
}
|
||||
}
|
||||
if (len > 0) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <spa/utils/dll.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/control/control.h>
|
||||
#include <spa/control/ump-utils.h>
|
||||
#include <spa/debug/types.h>
|
||||
#include <spa/debug/mem.h>
|
||||
#include <spa/debug/log.h>
|
||||
|
|
@ -385,7 +386,7 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core,
|
|||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
pw_properties_set(props, PW_KEY_FORMAT_DSP, "8 bit raw midi");
|
||||
pw_properties_set(props, PW_KEY_FORMAT_DSP, "32 bit raw UMP");
|
||||
impl->stride = impl->format_info->size;
|
||||
impl->rate = pw_properties_get_uint32(props, "midi.rate", 10000);
|
||||
if (impl->rate == 0)
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ static void vban_midi_process_playback(void *data)
|
|||
} else {
|
||||
timestamp = target;
|
||||
}
|
||||
spa_pod_builder_control(&b, target - timestamp, SPA_CONTROL_Midi);
|
||||
spa_pod_builder_control(&b, target - timestamp, c->type);
|
||||
spa_pod_builder_bytes(&b,
|
||||
SPA_POD_BODY(&c->value),
|
||||
SPA_POD_BODY_SIZE(&c->value));
|
||||
|
|
@ -162,19 +162,29 @@ static int vban_midi_receive_midi(struct impl *impl, uint8_t *packet,
|
|||
|
||||
while (offs < plen) {
|
||||
int size;
|
||||
|
||||
spa_pod_builder_control(&b, timestamp, SPA_CONTROL_Midi);
|
||||
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) {
|
||||
pw_log_warn("invalid size (%08x) %d (%u %u)",
|
||||
packet[offs], size, offs, plen);
|
||||
break;
|
||||
}
|
||||
|
||||
spa_pod_builder_bytes(&b, &packet[offs], size);
|
||||
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_UMP);
|
||||
spa_pod_builder_bytes(&b, ump, ump_size);
|
||||
}
|
||||
offs += size;
|
||||
}
|
||||
spa_pod_builder_pop(&b, &f[0]);
|
||||
|
|
@ -239,14 +249,17 @@ static void vban_midi_flush_packets(struct impl *impl,
|
|||
len = 0;
|
||||
|
||||
SPA_POD_SEQUENCE_FOREACH(sequence, c) {
|
||||
void *ev;
|
||||
uint32_t size;
|
||||
int size;
|
||||
uint8_t event[16];
|
||||
|
||||
if (c->type != SPA_CONTROL_Midi)
|
||||
if (c->type != SPA_CONTROL_UMP)
|
||||
continue;
|
||||
|
||||
size = spa_ump_to_midi(SPA_POD_BODY(&c->value),
|
||||
SPA_POD_BODY_SIZE(&c->value), event, sizeof(event));
|
||||
if (size <= 0)
|
||||
continue;
|
||||
|
||||
ev = SPA_POD_BODY(&c->value),
|
||||
size = SPA_POD_BODY_SIZE(&c->value);
|
||||
if (len == 0) {
|
||||
/* start new packet */
|
||||
header.n_frames++;
|
||||
|
|
@ -258,7 +271,7 @@ static void vban_midi_flush_packets(struct impl *impl,
|
|||
vban_stream_emit_send_packet(impl, iov, 2);
|
||||
len = 0;
|
||||
}
|
||||
memcpy(&impl->buffer[len], ev, size);
|
||||
memcpy(&impl->buffer[len], event, size);
|
||||
len += size;
|
||||
}
|
||||
if (len > 0) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <spa/utils/dll.h>
|
||||
#include <spa/param/audio/format-utils.h>
|
||||
#include <spa/control/control.h>
|
||||
#include <spa/control/ump-utils.h>
|
||||
#include <spa/debug/types.h>
|
||||
#include <spa/debug/mem.h>
|
||||
#include <spa/debug/log.h>
|
||||
|
|
@ -325,7 +326,7 @@ struct vban_stream *vban_stream_new(struct pw_core *core,
|
|||
res = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
pw_properties_set(props, PW_KEY_FORMAT_DSP, "8 bit raw midi");
|
||||
pw_properties_set(props, PW_KEY_FORMAT_DSP, "32 bit raw UMP");
|
||||
impl->stride = impl->format_info->size;
|
||||
impl->rate = pw_properties_get_uint32(props, "midi.rate", 10000);
|
||||
if (impl->rate == 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue