mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
jack: Add UMP to MIDI conversions
Add 2 new port format extensions, one for OSC and another for UMP. Make sure we convert the events from UMP/OSC/MIDI to jack events depending on the port type. Try to produce UMP by default.
This commit is contained in:
parent
7b03a41e3d
commit
648ba982d4
2 changed files with 180 additions and 46 deletions
|
|
@ -25,6 +25,13 @@ int jack_get_video_image_size(jack_client_t *client, jack_image_size_t *size);
|
|||
|
||||
int jack_set_sample_rate (jack_client_t *client, jack_nframes_t nframes);
|
||||
|
||||
/* raw OSC message */
|
||||
#define JACK_DEFAULT_OSC_TYPE "8 bit raw OSC"
|
||||
|
||||
/* MIDI 2.0 UMP type. This contains raw UMP data, which can have MIDI 1.0 or
|
||||
* MIDI 2.0 packets. The data is an array of 32 bit ints. */
|
||||
#define JACK_DEFAULT_UMP_TYPE "32 bit raw UMP"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <spa/utils/result.h>
|
||||
#include <spa/utils/string.h>
|
||||
#include <spa/utils/ringbuffer.h>
|
||||
#include <spa/control/ump-utils.h>
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
#include <pipewire/private.h>
|
||||
|
|
@ -39,8 +40,6 @@
|
|||
#include "pipewire/extensions/metadata.h"
|
||||
#include "pipewire-jack-extensions.h"
|
||||
|
||||
#define JACK_DEFAULT_VIDEO_TYPE "32 bit float RGBA video"
|
||||
|
||||
/* use 512KB stack per thread - the default is way too high to be feasible
|
||||
* with mlockall() on many systems */
|
||||
#define THREAD_STACK 524288
|
||||
|
|
@ -65,9 +64,16 @@ PW_LOG_TOPIC_STATIC(jack_log_topic, "jack");
|
|||
#define PW_LOG_TOPIC_DEFAULT jack_log_topic
|
||||
|
||||
#define TYPE_ID_AUDIO 0
|
||||
#define TYPE_ID_MIDI 1
|
||||
#define TYPE_ID_VIDEO 2
|
||||
#define TYPE_ID_OTHER 3
|
||||
#define TYPE_ID_VIDEO 1
|
||||
#define TYPE_ID_MIDI 2
|
||||
#define TYPE_ID_OSC 3
|
||||
#define TYPE_ID_UMP 4
|
||||
#define TYPE_ID_OTHER 5
|
||||
|
||||
#define TYPE_ID_IS_EVENT(t) ((t) >= TYPE_ID_MIDI && (t) <= TYPE_ID_UMP)
|
||||
#define TYPE_ID_CAN_OSC(t) ((t) == TYPE_ID_MIDI || (t) == TYPE_ID_OSC)
|
||||
#define TYPE_ID_IS_HIDDEN(t) ((t) >= TYPE_ID_OTHER)
|
||||
#define TYPE_ID_IS_COMPATIBLE(a,b)(((a) == (b)) || (TYPE_ID_IS_EVENT(a) && TYPE_ID_IS_EVENT(b)))
|
||||
|
||||
#define SELF_CONNECT_ALLOW 0
|
||||
#define SELF_CONNECT_FAIL_EXT -1
|
||||
|
|
@ -638,7 +644,7 @@ static struct mix *find_port_peer(struct port *port, uint32_t peer_id)
|
|||
{
|
||||
struct mix *mix;
|
||||
spa_list_for_each(mix, &port->mix, port_link) {
|
||||
pw_log_info("%p %d %d", port, mix->peer_id, peer_id);
|
||||
pw_log_trace("%p %d %d", port, mix->peer_id, peer_id);
|
||||
if (mix->peer_id == peer_id)
|
||||
return mix;
|
||||
}
|
||||
|
|
@ -1381,12 +1387,25 @@ static inline bool is_osc(jack_midi_event_t *ev)
|
|||
return ev->size >= 1 && (ev->buffer[0] == '#' || ev->buffer[0] == '/');
|
||||
}
|
||||
|
||||
static size_t convert_from_midi(void *midi, void *buffer, size_t size)
|
||||
static size_t convert_from_event(void *midi, void *buffer, size_t size, uint32_t type)
|
||||
{
|
||||
struct spa_pod_builder b = { 0, };
|
||||
uint32_t i, count;
|
||||
struct spa_pod_frame f;
|
||||
uint32_t event_type;
|
||||
|
||||
switch (type) {
|
||||
case TYPE_ID_MIDI:
|
||||
case TYPE_ID_OSC:
|
||||
/* we handle MIDI as OSC, check below */
|
||||
event_type = SPA_CONTROL_OSC;
|
||||
break;
|
||||
case TYPE_ID_UMP:
|
||||
event_type = SPA_CONTROL_UMP;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
count = jack_midi_get_event_count(midi);
|
||||
|
||||
spa_pod_builder_init(&b, buffer, size);
|
||||
|
|
@ -1395,14 +1414,43 @@ static size_t convert_from_midi(void *midi, void *buffer, size_t size)
|
|||
for (i = 0; i < count; i++) {
|
||||
jack_midi_event_t ev;
|
||||
jack_midi_event_get(&ev, midi, i);
|
||||
spa_pod_builder_control(&b, ev.time,
|
||||
is_osc(&ev) ? SPA_CONTROL_OSC : SPA_CONTROL_Midi);
|
||||
spa_pod_builder_bytes(&b, ev.buffer, ev.size);
|
||||
|
||||
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;
|
||||
|
||||
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_pop(&b, &f);
|
||||
return b.state.offset;
|
||||
}
|
||||
|
||||
static inline int event_compare(uint8_t s1, uint8_t s2)
|
||||
{
|
||||
/* 11 (controller) > 12 (program change) >
|
||||
* 8 (note off) > 9 (note on) > 10 (aftertouch) >
|
||||
* 13 (channel pressure) > 14 (pitch bend) */
|
||||
static int priotab[] = { 5,4,3,7,6,2,1,0 };
|
||||
if ((s1 & 0xf) != (s2 & 0xf))
|
||||
return 0;
|
||||
return priotab[(s2>>4) & 7] - priotab[(s1>>4) & 7];
|
||||
}
|
||||
|
||||
static inline int event_sort(struct spa_pod_control *a, struct spa_pod_control *b)
|
||||
{
|
||||
if (a->offset < b->offset)
|
||||
|
|
@ -1414,21 +1462,20 @@ static inline int event_sort(struct spa_pod_control *a, struct spa_pod_control *
|
|||
switch(a->type) {
|
||||
case SPA_CONTROL_Midi:
|
||||
{
|
||||
/* 11 (controller) > 12 (program change) >
|
||||
* 8 (note off) > 9 (note on) > 10 (aftertouch) >
|
||||
* 13 (channel pressure) > 14 (pitch bend) */
|
||||
static int priotab[] = { 5,4,3,7,6,2,1,0 };
|
||||
uint8_t *da, *db;
|
||||
|
||||
if (SPA_POD_BODY_SIZE(&a->value) < 1 ||
|
||||
SPA_POD_BODY_SIZE(&b->value) < 1)
|
||||
uint8_t *sa = SPA_POD_BODY(&a->value), *sb = SPA_POD_BODY(&b->value);
|
||||
if (SPA_POD_BODY_SIZE(&a->value) < 1 || SPA_POD_BODY_SIZE(&b->value) < 1)
|
||||
return 0;
|
||||
|
||||
da = SPA_POD_BODY(&a->value);
|
||||
db = SPA_POD_BODY(&b->value);
|
||||
if ((da[0] & 0xf) != (db[0] & 0xf))
|
||||
return event_compare(sa[0], sb[0]);
|
||||
}
|
||||
case SPA_CONTROL_UMP:
|
||||
{
|
||||
uint32_t *sa = SPA_POD_BODY(&a->value), *sb = SPA_POD_BODY(&b->value);
|
||||
if (SPA_POD_BODY_SIZE(&a->value) < 4 || SPA_POD_BODY_SIZE(&b->value) < 4)
|
||||
return 0;
|
||||
return priotab[(db[0]>>4) & 7] - priotab[(da[0]>>4) & 7];
|
||||
if ((sa[0] >> 28) != 2 || (sa[0] >> 28) != 4 ||
|
||||
(sb[0] >> 28) != 2 || (sb[0] >> 28) != 4)
|
||||
return 0;
|
||||
return event_compare(sa[0] >> 16, sb[0] >> 16);
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -1487,11 +1534,12 @@ static inline int midi_event_write(void *port_buffer,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void convert_to_midi(struct spa_pod_sequence **seq, uint32_t n_seq, void *midi, bool fix)
|
||||
static void convert_to_event(struct spa_pod_sequence **seq, uint32_t n_seq, void *midi, bool fix, uint32_t type)
|
||||
{
|
||||
struct spa_pod_control *c[n_seq];
|
||||
uint64_t state = 0;
|
||||
uint32_t i;
|
||||
int res;
|
||||
int res = 0;
|
||||
|
||||
for (i = 0; i < n_seq; i++)
|
||||
c[i] = spa_pod_control_first(&seq[i]->body);
|
||||
|
|
@ -1515,16 +1563,51 @@ static void convert_to_midi(struct spa_pod_sequence **seq, uint32_t n_seq, void
|
|||
|
||||
switch(next->type) {
|
||||
case SPA_CONTROL_OSC:
|
||||
if (!TYPE_ID_CAN_OSC(type))
|
||||
break;
|
||||
SPA_FALLTHROUGH;
|
||||
case SPA_CONTROL_Midi:
|
||||
{
|
||||
uint8_t *data = SPA_POD_BODY(&next->value);
|
||||
size_t size = SPA_POD_BODY_SIZE(&next->value);
|
||||
|
||||
if ((res = midi_event_write(midi, next->offset, data, size, fix)) < 0)
|
||||
if (type == TYPE_ID_UMP) {
|
||||
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;
|
||||
if ((res = midi_event_write(midi, next->offset,
|
||||
(uint8_t*)ump, ump_size, false)) < 0)
|
||||
break;
|
||||
}
|
||||
} 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));
|
||||
break;
|
||||
}
|
||||
case SPA_CONTROL_UMP:
|
||||
{
|
||||
void *data = SPA_POD_BODY(&next->value);
|
||||
size_t size = SPA_POD_BODY_SIZE(&next->value);
|
||||
uint8_t ev[32];
|
||||
|
||||
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;
|
||||
} else if (type != TYPE_ID_UMP)
|
||||
break;
|
||||
|
||||
if ((res = midi_event_write(midi, next->offset, data, size, fix)) < 0)
|
||||
pw_log_warn("midi %p: can't write event: %s", midi,
|
||||
spa_strerror(res));
|
||||
}
|
||||
}
|
||||
c[next_index] = spa_pod_control_next(c[next_index]);
|
||||
}
|
||||
|
|
@ -1591,19 +1674,22 @@ static inline void process_empty(struct port *p, uint32_t frames)
|
|||
struct client *c = p->client;
|
||||
void *ptr, *src = p->emptyptr;
|
||||
struct port *tied = p->tied;
|
||||
uint32_t type = p->object->port.type_id;
|
||||
|
||||
if (SPA_UNLIKELY(tied != NULL)) {
|
||||
if ((src = tied->get_buffer(tied, frames)) == NULL)
|
||||
src = p->emptyptr;
|
||||
}
|
||||
|
||||
switch (p->object->port.type_id) {
|
||||
switch (type) {
|
||||
case TYPE_ID_AUDIO:
|
||||
ptr = get_buffer_output(p, frames, sizeof(float), NULL);
|
||||
if (SPA_LIKELY(ptr != NULL))
|
||||
memcpy(ptr, src, frames * sizeof(float));
|
||||
break;
|
||||
case TYPE_ID_MIDI:
|
||||
case TYPE_ID_OSC:
|
||||
case TYPE_ID_UMP:
|
||||
{
|
||||
struct buffer *b;
|
||||
ptr = get_buffer_output(p, c->max_frames, 1, &b);
|
||||
|
|
@ -1611,8 +1697,8 @@ static inline void process_empty(struct port *p, uint32_t frames)
|
|||
/* first build the complete pod in scratch memory, then copy it
|
||||
* to the target buffer. This makes it possible for multiple threads
|
||||
* to do this concurrently */
|
||||
b->datas[0].chunk->size = convert_from_midi(src,
|
||||
midi_scratch, MIDI_SCRATCH_FRAMES * sizeof(float));
|
||||
b->datas[0].chunk->size = convert_from_event(src, midi_scratch,
|
||||
MIDI_SCRATCH_FRAMES * sizeof(float), type);
|
||||
memcpy(ptr, midi_scratch, b->datas[0].chunk->size);
|
||||
}
|
||||
break;
|
||||
|
|
@ -2393,6 +2479,8 @@ static int param_enum_format(struct client *c, struct port *p,
|
|||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_DSP_F32));
|
||||
break;
|
||||
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,
|
||||
|
|
@ -2424,6 +2512,8 @@ static int param_format(struct client *c, struct port *p,
|
|||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_DSP_F32));
|
||||
break;
|
||||
case TYPE_ID_MIDI:
|
||||
case TYPE_ID_OSC:
|
||||
case TYPE_ID_UMP:
|
||||
*param = spa_pod_builder_add_object(b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_Format,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application),
|
||||
|
|
@ -2448,6 +2538,8 @@ static int param_buffers(struct client *c, struct port *p,
|
|||
switch (p->object->port.type_id) {
|
||||
case TYPE_ID_AUDIO:
|
||||
case TYPE_ID_MIDI:
|
||||
case TYPE_ID_OSC:
|
||||
case TYPE_ID_UMP:
|
||||
*param = spa_pod_builder_add_object(b,
|
||||
SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
|
||||
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(1, 1, MAX_BUFFERS),
|
||||
|
|
@ -2781,7 +2873,7 @@ static inline void *init_buffer(struct port *p, uint32_t nframes)
|
|||
if (p->zeroed)
|
||||
return data;
|
||||
|
||||
if (p->object->port.type_id == TYPE_ID_MIDI) {
|
||||
if (TYPE_ID_IS_EVENT(p->object->port.type_id)) {
|
||||
struct midi_buffer *mb = data;
|
||||
midi_init_buffer(data, c->max_frames, nframes);
|
||||
pw_log_debug("port %p: init midi buffer size:%d frames:%d", p,
|
||||
|
|
@ -3266,10 +3358,14 @@ static jack_port_type_id_t string_to_type(const char *port_type)
|
|||
{
|
||||
if (spa_streq(JACK_DEFAULT_AUDIO_TYPE, port_type))
|
||||
return TYPE_ID_AUDIO;
|
||||
else if (spa_streq(JACK_DEFAULT_MIDI_TYPE, port_type))
|
||||
return TYPE_ID_MIDI;
|
||||
else if (spa_streq(JACK_DEFAULT_VIDEO_TYPE, port_type))
|
||||
return TYPE_ID_VIDEO;
|
||||
else if (spa_streq(JACK_DEFAULT_MIDI_TYPE, port_type))
|
||||
return TYPE_ID_MIDI;
|
||||
else if (spa_streq(JACK_DEFAULT_OSC_TYPE, port_type))
|
||||
return TYPE_ID_OSC;
|
||||
else if (spa_streq(JACK_DEFAULT_UMP_TYPE, port_type))
|
||||
return TYPE_ID_UMP;
|
||||
else if (spa_streq("other", port_type))
|
||||
return TYPE_ID_OTHER;
|
||||
else
|
||||
|
|
@ -3281,22 +3377,46 @@ static const char* type_to_string(jack_port_type_id_t type_id)
|
|||
switch(type_id) {
|
||||
case TYPE_ID_AUDIO:
|
||||
return JACK_DEFAULT_AUDIO_TYPE;
|
||||
case TYPE_ID_MIDI:
|
||||
return JACK_DEFAULT_MIDI_TYPE;
|
||||
case TYPE_ID_VIDEO:
|
||||
return JACK_DEFAULT_VIDEO_TYPE;
|
||||
case TYPE_ID_MIDI:
|
||||
case TYPE_ID_OSC:
|
||||
case TYPE_ID_UMP:
|
||||
/* all returned as MIDI */
|
||||
return JACK_DEFAULT_MIDI_TYPE;
|
||||
case TYPE_ID_OTHER:
|
||||
return "other";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
case TYPE_ID_UMP:
|
||||
/* all exposed to PipeWire as UMP */
|
||||
return JACK_DEFAULT_UMP_TYPE;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool type_is_dsp(jack_port_type_id_t type_id)
|
||||
{
|
||||
switch(type_id) {
|
||||
case TYPE_ID_AUDIO:
|
||||
case TYPE_ID_MIDI:
|
||||
case TYPE_ID_VIDEO:
|
||||
case TYPE_ID_OSC:
|
||||
case TYPE_ID_UMP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
@ -3686,7 +3806,7 @@ static void registry_event_global(void *data, uint32_t id,
|
|||
}
|
||||
if (is_monitor && !c->show_monitor)
|
||||
goto exit;
|
||||
if (type_id == TYPE_ID_MIDI && !c->show_midi)
|
||||
if (TYPE_ID_IS_EVENT(type_id) && !c->show_midi)
|
||||
goto exit;
|
||||
|
||||
o = NULL;
|
||||
|
|
@ -3747,6 +3867,8 @@ static void registry_event_global(void *data, uint32_t id,
|
|||
(int)(sizeof(tmp)-11), tmp, serial);
|
||||
else
|
||||
snprintf(o->port.name, sizeof(o->port.name), "%s", tmp);
|
||||
|
||||
o->port.type_id = type_id;
|
||||
}
|
||||
|
||||
if (c->fill_aliases) {
|
||||
|
|
@ -3766,7 +3888,6 @@ static void registry_event_global(void *data, uint32_t id,
|
|||
}
|
||||
|
||||
o->port.flags = flags;
|
||||
o->port.type_id = type_id;
|
||||
o->port.node_id = node_id;
|
||||
o->port.is_monitor = is_monitor;
|
||||
|
||||
|
|
@ -5094,7 +5215,7 @@ jack_nframes_t jack_get_sample_rate (jack_client_t *client)
|
|||
}
|
||||
}
|
||||
c->sample_rate = res;
|
||||
pw_log_debug("sample_rate: %u", res);
|
||||
pw_log_trace_fp("sample_rate: %u", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -5225,6 +5346,8 @@ jack_port_t * jack_port_register (jack_client_t *client,
|
|||
p->get_buffer = get_buffer_input_float;
|
||||
break;
|
||||
case TYPE_ID_MIDI:
|
||||
case TYPE_ID_OSC:
|
||||
case TYPE_ID_UMP:
|
||||
p->get_buffer = get_buffer_input_midi;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -5238,6 +5361,8 @@ jack_port_t * jack_port_register (jack_client_t *client,
|
|||
p->get_buffer = get_buffer_output_float;
|
||||
break;
|
||||
case TYPE_ID_MIDI:
|
||||
case TYPE_ID_OSC:
|
||||
case TYPE_ID_UMP:
|
||||
p->get_buffer = get_buffer_output_midi;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -5250,7 +5375,7 @@ jack_port_t * jack_port_register (jack_client_t *client,
|
|||
|
||||
spa_list_init(&p->mix);
|
||||
|
||||
pw_properties_set(p->props, PW_KEY_FORMAT_DSP, port_type);
|
||||
pw_properties_set(p->props, PW_KEY_FORMAT_DSP, type_to_format_dsp(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,
|
||||
|
|
@ -5493,15 +5618,13 @@ static void *get_buffer_input_midi(struct port *p, jack_nframes_t frames)
|
|||
/* first convert to a thread local scratch buffer, then memcpy into
|
||||
* the per port buffer. This makes it possible to call this function concurrently
|
||||
* but also have different pointers per port */
|
||||
convert_to_midi(seq, n_seq, mb, p->client->fix_midi_events);
|
||||
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;
|
||||
memcpy(SPA_PTROFF(ptr, offs, void), SPA_PTROFF(mb, offs, void), mb->write_pos);
|
||||
}
|
||||
if (mb->event_count > 0)
|
||||
spa_debug_mem(0, ptr, 64);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
@ -5561,7 +5684,7 @@ void * jack_port_get_buffer (jack_port_t *port, jack_nframes_t frames)
|
|||
if ((b = get_mix_buffer(c, mix, frames)) == NULL)
|
||||
goto done;
|
||||
|
||||
if (o->port.type_id == TYPE_ID_MIDI) {
|
||||
if (TYPE_ID_IS_EVENT(o->port.type_id)) {
|
||||
struct spa_pod_sequence *seq[1];
|
||||
struct spa_data *d;
|
||||
void *pod;
|
||||
|
|
@ -5576,7 +5699,7 @@ void * jack_port_get_buffer (jack_port_t *port, jack_nframes_t frames)
|
|||
if (!spa_pod_is_sequence(pod))
|
||||
goto done;
|
||||
seq[0] = pod;
|
||||
convert_to_midi(seq, 1, ptr, c->fix_midi_events);
|
||||
convert_to_event(seq, 1, ptr, c->fix_midi_events, o->port.type_id);
|
||||
} else {
|
||||
ptr = get_buffer_data(b, frames);
|
||||
}
|
||||
|
|
@ -5584,7 +5707,7 @@ void * jack_port_get_buffer (jack_port_t *port, jack_nframes_t frames)
|
|||
ptr = p->get_buffer(p, frames);
|
||||
}
|
||||
done:
|
||||
pw_log_warn("%p: port:%p buffer:%p frames:%d", c, p, ptr, frames);
|
||||
pw_log_trace_fp("%p: port:%p buffer:%p frames:%d", c, p, ptr, frames);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
|
@ -6140,7 +6263,7 @@ int jack_connect (jack_client_t *client,
|
|||
if (src == NULL || dst == NULL ||
|
||||
!(src->port.flags & JackPortIsOutput) ||
|
||||
!(dst->port.flags & JackPortIsInput) ||
|
||||
src->port.type_id != dst->port.type_id) {
|
||||
!TYPE_ID_IS_COMPATIBLE(src->port.type_id, dst->port.type_id)) {
|
||||
res = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
|
@ -6297,6 +6420,10 @@ size_t jack_port_type_get_buffer_size (jack_client_t *client, const char *port_t
|
|||
return jack_get_buffer_size(client) * sizeof(float);
|
||||
else if (spa_streq(JACK_DEFAULT_MIDI_TYPE, port_type))
|
||||
return c->max_frames * sizeof(float);
|
||||
else if (spa_streq(JACK_DEFAULT_OSC_TYPE, port_type))
|
||||
return c->max_frames * sizeof(float);
|
||||
else if (spa_streq(JACK_DEFAULT_UMP_TYPE, port_type))
|
||||
return c->max_frames * sizeof(float);
|
||||
else if (spa_streq(JACK_DEFAULT_VIDEO_TYPE, port_type))
|
||||
return 320 * 240 * 4 * sizeof(float);
|
||||
else
|
||||
|
|
@ -6559,7 +6686,7 @@ const char ** jack_get_ports (jack_client_t *client,
|
|||
continue;
|
||||
pw_log_debug("%p: check port type:%d flags:%08lx name:\"%s\"", c,
|
||||
o->port.type_id, o->port.flags, o->port.name);
|
||||
if (o->port.type_id > TYPE_ID_VIDEO)
|
||||
if (TYPE_ID_IS_HIDDEN(o->port.type_id))
|
||||
continue;
|
||||
if (!SPA_FLAG_IS_SET(o->port.flags, flags))
|
||||
continue;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue