mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
jack: implement midi mixing
This commit is contained in:
parent
8d8ef587f5
commit
274d616fa6
1 changed files with 46 additions and 14 deletions
|
|
@ -48,7 +48,7 @@
|
||||||
#define JACK_PORT_NAME_SIZE 256
|
#define JACK_PORT_NAME_SIZE 256
|
||||||
#define JACK_PORT_MAX 4096
|
#define JACK_PORT_MAX 4096
|
||||||
#define JACK_PORT_TYPE_SIZE 32
|
#define JACK_PORT_TYPE_SIZE 32
|
||||||
#define CONNECTION_NUM_FOR_PORT 2048
|
#define CONNECTION_NUM_FOR_PORT 1024
|
||||||
|
|
||||||
#define BUFFER_SIZE_MAX 8192
|
#define BUFFER_SIZE_MAX 8192
|
||||||
|
|
||||||
|
|
@ -654,22 +654,45 @@ static void convert_from_midi(void *midi, void *buffer, size_t size)
|
||||||
spa_pod_builder_pop(&b, &f);
|
spa_pod_builder_pop(&b, &f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void convert_to_midi(struct spa_pod_sequence *seq, void *midi)
|
static void convert_to_midi(struct spa_pod_sequence **seq, uint32_t n_seq, void *midi)
|
||||||
{
|
{
|
||||||
struct spa_pod_control *c;
|
struct spa_pod_control *c[n_seq];
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
SPA_POD_SEQUENCE_FOREACH(seq, c) {
|
for (i = 0; i < n_seq; i++) {
|
||||||
switch(c->type) {
|
c[i] = spa_pod_control_first(&seq[i]->body);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
struct spa_pod_control *next = NULL;
|
||||||
|
uint32_t next_index = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < n_seq; i++) {
|
||||||
|
if (!spa_pod_control_is_inside(&seq[i]->body,
|
||||||
|
SPA_POD_BODY_SIZE(seq[i]), c[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (next == NULL || c[i]->offset < next->offset) {
|
||||||
|
next = c[i];
|
||||||
|
next_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch(next->type) {
|
||||||
case SPA_CONTROL_Midi:
|
case SPA_CONTROL_Midi:
|
||||||
jack_midi_event_write(midi,
|
jack_midi_event_write(midi,
|
||||||
c->offset,
|
next->offset,
|
||||||
SPA_POD_BODY(&c->value),
|
SPA_POD_BODY(&next->value),
|
||||||
SPA_POD_BODY_SIZE(&c->value));
|
SPA_POD_BODY_SIZE(&next->value));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
c[next_index] = spa_pod_control_next(c[next_index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *get_buffer_output(struct client *c, struct port *p, uint32_t frames, uint32_t stride)
|
static void *get_buffer_output(struct client *c, struct port *p, uint32_t frames, uint32_t stride)
|
||||||
{
|
{
|
||||||
struct mix *mix;
|
struct mix *mix;
|
||||||
|
|
@ -2749,13 +2772,17 @@ static void *mix_audio(struct client *c, struct port *p, jack_nframes_t frames)
|
||||||
static void *mix_midi(struct client *c, struct port *p, jack_nframes_t frames)
|
static void *mix_midi(struct client *c, struct port *p, jack_nframes_t frames)
|
||||||
{
|
{
|
||||||
struct mix *mix;
|
struct mix *mix;
|
||||||
struct buffer *b;
|
|
||||||
struct spa_io_buffers *io;
|
struct spa_io_buffers *io;
|
||||||
void *ptr = p->emptyptr;
|
void *ptr = p->emptyptr;
|
||||||
|
struct spa_pod_sequence *seq[CONNECTION_NUM_FOR_PORT];
|
||||||
|
uint32_t n_seq = 0;
|
||||||
|
|
||||||
jack_midi_reset_buffer(ptr);
|
jack_midi_reset_buffer(ptr);
|
||||||
|
|
||||||
spa_list_for_each(mix, &p->mix, port_link) {
|
spa_list_for_each(mix, &p->mix, port_link) {
|
||||||
|
struct spa_data *d;
|
||||||
|
void *pod;
|
||||||
|
|
||||||
pw_log_trace(NAME" %p: port %p mix %d.%d get buffer %d",
|
pw_log_trace(NAME" %p: port %p mix %d.%d get buffer %d",
|
||||||
c, p, p->id, mix->id, frames);
|
c, p, p->id, mix->id, frames);
|
||||||
|
|
||||||
|
|
@ -2764,12 +2791,17 @@ static void *mix_midi(struct client *c, struct port *p, jack_nframes_t frames)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
io->status = SPA_STATUS_NEED_DATA;
|
io->status = SPA_STATUS_NEED_DATA;
|
||||||
b = &mix->buffers[io->buffer_id];
|
d = &mix->buffers[io->buffer_id].datas[0];
|
||||||
/* FIXME, actually mix the midi */
|
|
||||||
convert_to_midi(b->datas[0].data, ptr);
|
if ((pod = spa_pod_from_data(d->data, d->maxsize, d->chunk->offset, d->chunk->size)) == NULL)
|
||||||
p->zeroed = false;
|
continue;
|
||||||
break;
|
if (!spa_pod_is_sequence(pod))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
seq[n_seq++] = pod;
|
||||||
}
|
}
|
||||||
|
convert_to_midi(seq, n_seq, ptr);
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue