3
* Copyright (C) 2012, 2013 Robin Gareus
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
20
#ifndef UPDATE_FREQ_RATIO
21
#define UPDATE_FREQ_RATIO 10 // MAX # of audio-cycles per GUI-refresh
25
#define UI_UPDATE_FPS 15
28
///////////////////////////////////////////////////////////////////////////////
37
#define pthread_t //< override jack.h def
48
#include <jack/jack.h>
49
#include <jack/ringbuffer.h>
50
#include <jack/midiport.h>
54
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
55
#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
56
#include "lv2/lv2plug.in/ns/ext/uri-map/uri-map.h"
57
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
58
#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
59
#include "lv2/lv2plug.in/ns/ext/atom/forge.h"
60
#include "lv2/lv2plug.in/ns/ext/midi/midi.h"
61
#include "lv2/lv2plug.in/ns/ext/time/time.h"
63
#include "./gl/xternalui.h"
70
#define LV2_EXTERNAL_UI_RUN(ptr) (ptr)->run(ptr)
71
#define LV2_EXTERNAL_UI_SHOW(ptr) (ptr)->show(ptr)
72
#define LV2_EXTERNAL_UI_HIDE(ptr) (ptr)->hide(ptr)
76
const LV2_Descriptor* plugin_dsp;
77
const LV2UI_Descriptor *plugin_gui;
79
LV2_Handle plugin_instance = NULL;
80
LV2UI_Handle gui_instance = NULL;
82
float *plugin_ports_pre = NULL;
83
float *plugin_ports_post = NULL;
85
LV2_Atom_Sequence *atom_in = NULL;
86
LV2_Atom_Sequence *atom_out = NULL;
88
static jack_port_t **input_port = NULL;
89
static jack_port_t **output_port = NULL;
91
static jack_port_t *midi_in = NULL;
92
static jack_port_t *midi_out = NULL;
94
static jack_client_t *j_client = NULL;
95
static uint32_t j_samplerate = 48000;
97
struct transport_position {
98
jack_nframes_t position;
101
} j_transport = {0, 0, false};
103
static jack_ringbuffer_t *rb_ctrl_to_ui = NULL;
104
static jack_ringbuffer_t *rb_ctrl_from_ui = NULL;
105
static jack_ringbuffer_t *rb_atom_to_ui = NULL;
106
static jack_ringbuffer_t *rb_atom_from_ui = NULL;
108
static pthread_mutex_t gui_thread_lock = PTHREAD_MUTEX_INITIALIZER;
109
static pthread_cond_t data_ready = PTHREAD_COND_INITIALIZER;
111
extern const LV2_Descriptor* lv2_descriptor(uint32_t index);
112
extern const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index);
114
uint32_t uri_midi_MidiEvent = 0;
115
uint32_t uri_atom_Sequence = 0;
116
uint32_t uri_atom_EventTransfer = 0;
118
uint32_t uri_time_Position = 0;
119
uint32_t uri_time_frame = 0;
120
uint32_t uri_time_speed = 0;
121
uint32_t uri_time_bar = 0;
122
uint32_t uri_time_barBeat = 0;
123
uint32_t uri_time_beatUnit = 0;
124
uint32_t uri_time_beatsPerBar = 0;
125
uint32_t uri_time_beatsPerMinute = 0;
127
char **urimap = NULL;
128
uint32_t urimap_len = 0;
143
enum PortType porttype;
147
/* a simple state machine for this client */
148
static volatile enum {
152
} client_state = Init;
154
struct lv2_external_ui_host extui_host;
155
struct lv2_external_ui *extui = NULL;
157
LV2UI_Controller controller = NULL;
159
LV2_Atom_Forge lv2_forge;
160
uint32_t *portmap_a_in;
161
uint32_t *portmap_a_out;
162
uint32_t *portmap_rctl;
164
uint32_t portmap_atom_to_ui = -1;
165
uint32_t portmap_atom_from_ui = -1;
167
static uint32_t uri_to_id(LV2_URI_Map_Callback_Data callback_data, const char* uri);
169
///////////////////////////
170
// GET INFO FROM LV2 TTL //
172
///////////////////////////
173
#include JACK_DESCRIPT ////
174
///////////////////////////
176
/******************************************************************************
180
int process (jack_nframes_t nframes, void *arg) {
181
while (jack_ringbuffer_read_space(rb_ctrl_from_ui) >= sizeof(uint32_t) + sizeof(float)) {
183
jack_ringbuffer_read(rb_ctrl_from_ui, (char*) &idx, sizeof(uint32_t));
184
jack_ringbuffer_read(rb_ctrl_from_ui, (char*) &(plugin_ports_pre[idx]), sizeof(float));
187
/* Get Jack transport position */
189
const bool rolling = (jack_transport_query(j_client, &pos) == JackTransportRolling);
190
const bool transport_changed = (rolling != j_transport.rolling
191
|| pos.frame != j_transport.position
192
|| ((pos.valid & JackPositionBBT) && (pos.beats_per_minute != j_transport.bpm)));
195
if (nports_atom_in > 0 || nports_midi_in > 0) {
196
/* start Atom sequence */
197
atom_in->atom.type = uri_atom_Sequence;
198
atom_in->atom.size = 8;
199
LV2_Atom_Sequence_Body *body = &atom_in->body;
200
body->unit = 0; // URID of unit of event time stamp LV2_ATOM__timeUnit ??
201
body->pad = 0; // unused
202
uint8_t * seq = (uint8_t*) (body + 1);
204
if (transport_changed && send_time_info) {
205
uint8_t pos_buf[256];
206
LV2_Atom* lv2_pos = (LV2_Atom*)pos_buf;
208
lv2_atom_forge_set_buffer(&lv2_forge, pos_buf, sizeof(pos_buf));
209
LV2_Atom_Forge* forge = &lv2_forge;
210
LV2_Atom_Forge_Frame frame;
211
lv2_atom_forge_blank(&lv2_forge, &frame, 1, uri_time_Position);
212
lv2_atom_forge_property_head(forge, uri_time_frame, 0);
213
lv2_atom_forge_long(forge, pos.frame);
214
lv2_atom_forge_property_head(forge, uri_time_speed, 0);
215
lv2_atom_forge_float(forge, rolling ? 1.0 : 0.0);
216
if (pos.valid & JackPositionBBT) {
217
lv2_atom_forge_property_head(forge, uri_time_barBeat, 0);
218
lv2_atom_forge_float(
219
forge, pos.beat - 1 + (pos.tick / pos.ticks_per_beat));
220
lv2_atom_forge_property_head(forge, uri_time_bar, 0);
221
lv2_atom_forge_long(forge, pos.bar - 1);
222
lv2_atom_forge_property_head(forge, uri_time_beatUnit, 0);
223
lv2_atom_forge_int(forge, pos.beat_type);
224
lv2_atom_forge_property_head(forge, uri_time_beatsPerBar, 0);
225
lv2_atom_forge_float(forge, pos.beats_per_bar);
226
lv2_atom_forge_property_head(forge, uri_time_beatsPerMinute, 0);
227
lv2_atom_forge_float(forge, pos.beats_per_minute);
230
uint32_t size = lv2_pos->size;
231
uint32_t padded_size = ((sizeof(LV2_Atom_Event) + size) + 7) & (~7);
233
if (min_atom_bufsiz > padded_size) {
234
printf("send time..\n");
235
LV2_Atom_Event *aev = (LV2_Atom_Event *)seq;
236
aev->time.frames = 0;
237
aev->body.size = size;
238
aev->body.type = lv2_pos->type;
239
memcpy(LV2_ATOM_BODY(&aev->body), LV2_ATOM_BODY(lv2_pos), size);
240
atom_in->atom.size += padded_size;
244
// TODO only if UI..?
245
while (jack_ringbuffer_read_space(rb_atom_from_ui) > sizeof(LV2_Atom)) {
247
jack_ringbuffer_read(rb_atom_from_ui, (char *) &a, sizeof(LV2_Atom));
248
uint32_t padded_size = atom_in->atom.size + a.size + sizeof(int64_t);
249
if (min_atom_bufsiz > padded_size) {
250
memset(seq, 0, sizeof(int64_t)); // LV2_Atom_Event->time
251
seq += sizeof(int64_t);
252
jack_ringbuffer_read(rb_atom_from_ui, (char *) seq, a.size);
254
atom_in->atom.size += a.size + sizeof(int64_t);
257
if (nports_midi_in > 0) {
258
/* inject midi events */
259
void* buf = jack_port_get_buffer(midi_in, nframes);
260
for (uint32_t i = 0; i < jack_midi_get_event_count(buf); ++i) {
261
jack_midi_event_t ev;
262
jack_midi_event_get(&ev, buf, i);
264
uint32_t size = ev.size;
265
uint32_t padded_size = ((sizeof(LV2_Atom_Event) + size) + 7) & (~7);
267
if (min_atom_bufsiz > padded_size) {
268
LV2_Atom_Event *aev = (LV2_Atom_Event *)seq;
269
aev->time.frames = ev.time;
270
aev->body.size = size;
271
aev->body.type = uri_midi_MidiEvent;
272
memcpy(LV2_ATOM_BODY(&aev->body), ev.buffer, size);
273
atom_in->atom.size += padded_size;
280
if (nports_atom_out > 0 || nports_midi_out > 0) {
281
atom_out->atom.type = 0;
282
atom_out->atom.size = min_atom_bufsiz;
285
/* [re] connect jack audio buffers */
286
for (uint32_t i=0; i < nports_audio_in; i++) {
287
plugin_dsp->connect_port(plugin_instance, portmap_a_in[i], jack_port_get_buffer (input_port[i], nframes));
289
for (uint32_t i=0 ; i < nports_audio_out; i++) {
290
plugin_dsp->connect_port(plugin_instance, portmap_a_out[i], jack_port_get_buffer (output_port[i], nframes));
293
/* make a backup copy, to see what was changed */
294
memcpy(plugin_ports_post, plugin_ports_pre, nports_ctrl * sizeof(float));
296
/* expected transport state in next cycle */
297
j_transport.position = rolling ? pos.frame + nframes : pos.frame;
298
j_transport.bpm = pos.beats_per_minute;
299
j_transport.rolling = rolling;
302
plugin_dsp->run(plugin_instance, nframes);
304
/* create port-events for change values */
305
// TODO only if UI..?
306
for (uint32_t p = 0; p < nports_ctrl; p++) {
307
if (ports[portmap_rctl[p]].porttype != CONTROL_OUT) continue;
309
if (plugin_ports_pre[p] != plugin_ports_post[p]) {
310
if (jack_ringbuffer_write_space(rb_ctrl_to_ui) >= sizeof(uint32_t) + sizeof(float)) {
311
jack_ringbuffer_write(rb_ctrl_to_ui, (char *) &portmap_rctl[p], sizeof(uint32_t));
312
jack_ringbuffer_write(rb_ctrl_to_ui, (char *) &plugin_ports_pre[p], sizeof(float));
317
if (nports_midi_out > 0) {
318
void* buf = jack_port_get_buffer(midi_out, nframes);
319
jack_midi_clear_buffer(buf);
322
/* Atom sequence port-events */
323
if (nports_atom_out + nports_midi_out > 0 && atom_out->atom.size > sizeof(LV2_Atom)) {
324
// TODO only if UI..?
325
if (jack_ringbuffer_write_space(rb_atom_to_ui) >= atom_out->atom.size + 2 * sizeof(LV2_Atom)) {
326
LV2_Atom a = {atom_out->atom.size + (uint32_t) sizeof(LV2_Atom), 0};
327
jack_ringbuffer_write(rb_atom_to_ui, (char *) &a, sizeof(LV2_Atom));
328
jack_ringbuffer_write(rb_atom_to_ui, (char *) atom_out, a.size);
331
if (nports_midi_out) {
332
void* buf = jack_port_get_buffer(midi_out, nframes);
333
LV2_Atom_Event const* ev = (LV2_Atom_Event const*)((&(atom_out)->body) + 1); // lv2_atom_sequence_begin
334
while((const uint8_t*)ev < ((const uint8_t*) &(atom_out)->body + (atom_out)->atom.size)) {
335
if (ev->body.type == uri_midi_MidiEvent) {
336
jack_midi_event_write(buf, ev->time.frames, (const uint8_t*)(ev+1), ev->body.size);
338
ev = (LV2_Atom_Event const*) /* lv2_atom_sequence_next() */
339
((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7));
345
if (jack_ringbuffer_read_space(rb_ctrl_to_ui) > sizeof(uint32_t) + sizeof(float)
346
|| jack_ringbuffer_read_space(rb_atom_to_ui) > sizeof(LV2_Atom)
348
if (pthread_mutex_trylock (&gui_thread_lock) == 0) {
349
pthread_cond_signal (&data_ready);
350
pthread_mutex_unlock (&gui_thread_lock);
357
void jack_shutdown (void *arg) {
358
fprintf(stderr,"recv. shutdown request from jackd.\n");
360
pthread_cond_signal (&data_ready);
363
static int init_jack(const char *client_name) {
364
jack_status_t status;
365
j_client = jack_client_open (client_name, JackNullOption, &status);
366
if (j_client == NULL) {
367
fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n", status);
368
if (status & JackServerFailed) {
369
fprintf (stderr, "Unable to connect to JACK server\n");
373
if (status & JackServerStarted) {
374
fprintf (stderr, "JACK server started\n");
376
if (status & JackNameNotUnique) {
377
client_name = jack_get_client_name(j_client);
378
fprintf (stderr, "jack-client name: `%s'\n", client_name);
381
jack_set_process_callback (j_client, process, 0);
384
jack_on_shutdown (j_client, jack_shutdown, NULL);
386
j_samplerate=jack_get_sample_rate (j_client);
390
static int jack_portsetup(void) {
391
/* Allocate data structures that depend on the number of ports. */
392
input_port = (jack_port_t **) malloc (sizeof (jack_port_t *) * nports_audio_in);
394
for (uint32_t i = 0; i < nports_audio_in; i++) {
395
if ((input_port[i] = jack_port_register (j_client,
396
ports[portmap_a_in[i]].name,
397
JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) {
398
fprintf (stderr, "cannot register input port \"%s\"!\n", ports[portmap_a_in[i]].name);
403
output_port = (jack_port_t **) malloc (sizeof (jack_port_t *) * nports_audio_out);
405
for (uint32_t i = 0; i < nports_audio_out; i++) {
406
if ((output_port[i] = jack_port_register (j_client,
407
ports[portmap_a_out[i]].name,
408
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == 0) {
409
fprintf (stderr, "cannot register output port \"%s\"!\n", ports[portmap_a_out[i]].name);
415
if ((midi_in = jack_port_register (j_client,
416
ports[portmap_atom_from_ui].name,
417
JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0)) == 0) {
418
fprintf (stderr, "cannot register midi input port \"%s\"!\n", ports[portmap_atom_from_ui].name);
423
if (nports_midi_out){
424
if ((midi_out = jack_port_register (j_client,
425
ports[portmap_atom_to_ui].name,
426
JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0)) == 0) {
427
fprintf (stderr, "cannot register midi ouput port \"%s\"!\n", ports[portmap_atom_to_ui].name);
434
/******************************************************************************
438
static uint32_t uri_to_id(LV2_URI_Map_Callback_Data callback_data, const char* uri) {
439
for (uint32_t i=0; i < urimap_len; ++i) {
440
if (!strcmp(urimap[i], uri)) {
441
//printf("Found mapped URI '%s' -> %d\n", uri, i);
445
//printf("map URI '%s' -> %d\n", uri, urimap_len);
446
urimap = (char**) realloc(urimap, (urimap_len + 1) * sizeof(char*));
447
urimap[urimap_len] = strdup(uri);
451
static void free_uri_map() {
452
for (uint32_t i=0; i < urimap_len; ++i) {
459
LV2UI_Controller controller,
461
uint32_t buffer_size,
462
uint32_t port_protocol,
463
const void* buffer) {
465
if (buffer_size == 0) return;
467
if (port_protocol != 0) {
468
if (jack_ringbuffer_write_space(rb_atom_from_ui) >= buffer_size + sizeof(LV2_Atom)) {
469
LV2_Atom a = {buffer_size, 0};
470
jack_ringbuffer_write(rb_atom_from_ui, (char *) &a, sizeof(LV2_Atom));
471
jack_ringbuffer_write(rb_atom_from_ui, (char *) buffer, buffer_size);
475
if (buffer_size != sizeof(float)) {
476
fprintf(stderr, "LV2Host: write_function() unsupported buffer\n");
479
if (port_index >=0 && port_index < nports_total && portmap_ctrl[port_index] < 0) {
480
fprintf(stderr, "LV2Host: write_function() unmapped port\n");
483
if (jack_ringbuffer_write_space(rb_ctrl_from_ui) >= sizeof(uint32_t) + sizeof(float)) {
484
jack_ringbuffer_write(rb_ctrl_from_ui, (char *) &portmap_ctrl[port_index], sizeof(uint32_t));
485
jack_ringbuffer_write(rb_ctrl_from_ui, (char *) buffer, sizeof(float));
490
/******************************************************************************
494
static void cleanup(int sig) {
496
jack_client_close (j_client);
500
if (plugin_dsp && plugin_instance && plugin_dsp->deactivate) {
501
plugin_dsp->deactivate(plugin_instance);
503
if (plugin_gui && gui_instance && plugin_gui->cleanup) {
504
plugin_gui->cleanup(gui_instance);
506
if (plugin_dsp && plugin_instance && plugin_dsp->cleanup) {
507
plugin_dsp->cleanup(plugin_instance);
510
jack_ringbuffer_free(rb_ctrl_to_ui);
511
jack_ringbuffer_free(rb_ctrl_from_ui);
513
jack_ringbuffer_free(rb_atom_to_ui);
514
jack_ringbuffer_free(rb_atom_from_ui);
519
free(plugin_ports_pre);
520
free(plugin_ports_post);
526
fprintf(stderr, "bye.\n");
529
static void main_loop(void) {
530
struct timespec timeout;
531
LV2_Atom_Sequence *data = (LV2_Atom_Sequence*) malloc(min_atom_bufsiz * sizeof(uint8_t));
533
pthread_mutex_lock (&gui_thread_lock);
534
while (client_state != Exit) {
536
while (jack_ringbuffer_read_space(rb_ctrl_to_ui) >= sizeof(uint32_t) + sizeof(float)) {
539
jack_ringbuffer_read(rb_ctrl_to_ui, (char*) &idx, sizeof(uint32_t));
540
jack_ringbuffer_read(rb_ctrl_to_ui, (char*) &val, sizeof(float));
541
plugin_gui->port_event(gui_instance, idx, sizeof(float), 0, &val);
544
while (jack_ringbuffer_read_space(rb_atom_to_ui) > sizeof(LV2_Atom)) {
546
jack_ringbuffer_read(rb_atom_to_ui, (char *) &a, sizeof(LV2_Atom));
547
assert(a.size < min_atom_bufsiz);
548
jack_ringbuffer_read(rb_atom_to_ui, (char *) data, a.size);
549
LV2_Atom_Event const* ev = (LV2_Atom_Event const*)((&(data)->body) + 1); // lv2_atom_sequence_begin
550
while((const uint8_t*)ev < ((const uint8_t*) &(data)->body + (data)->atom.size)) {
551
plugin_gui->port_event(gui_instance, portmap_atom_to_ui,
552
ev->body.size, uri_atom_EventTransfer, &ev->body);
553
ev = (LV2_Atom_Event const*) /* lv2_atom_sequence_next() */
554
((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7));
558
LV2_EXTERNAL_UI_RUN(extui);
560
if (client_state == Exit) break;
562
clock_gettime(CLOCK_REALTIME, &timeout);
563
timeout.tv_nsec += 1000000000 / (UI_UPDATE_FPS);
564
if (timeout.tv_nsec >= 1000000000) {timeout.tv_nsec -= 1000000000; timeout.tv_sec+=1;}
565
pthread_cond_timedwait (&data_ready, &gui_thread_lock, &timeout);
567
} /* while running */
569
pthread_mutex_unlock (&gui_thread_lock);
572
static void catchsig (int sig) {
573
fprintf(stderr,"caught signal - shutting down.\n");
575
pthread_cond_signal (&data_ready);
578
static void on_external_ui_closed(void* controller) {
582
int main (int argc, char **argv) {
587
LV2_URID_Map uri_map = { NULL, &uri_to_id };
588
const LV2_Feature map_feature = { LV2_URID__map, &uri_map};
589
const LV2_Feature unmap_feature = { LV2_URID__unmap, NULL };
591
const LV2_Feature* features[] = {
592
&map_feature, &unmap_feature, NULL
595
const LV2_Feature external_lv_feature = { LV2_EXTERNAL_UI_URI, &extui_host};
596
const LV2_Feature external_kx_feature = { LV2_EXTERNAL_UI_URI__KX__Host, &extui_host};
597
LV2_Feature instance_feature = { "http://lv2plug.in/ns/ext/instance-access", NULL };
599
const LV2_Feature* ui_features[] = {
600
&map_feature, &unmap_feature,
602
&external_lv_feature,
603
&external_kx_feature,
607
/* check sourced settings */
608
assert ((nports_midi_in + nports_atom_in) <= 1);
609
assert ((nports_midi_out + nports_atom_out) <= 1);
610
assert (plugin_human_id);
611
assert (nports_total > 0);
613
extui_host.plugin_human_id = plugin_human_id;
615
// TODO check if allocs succeeded - OOM -> exit
616
/* allocate data structure */
617
portmap_a_in = (uint32_t*) malloc(nports_audio_in * sizeof(uint32_t));
618
portmap_a_out = (uint32_t*) malloc(nports_audio_out * sizeof(uint32_t));
619
portmap_rctl = (uint32_t*) malloc(nports_ctrl * sizeof(uint32_t));
620
portmap_ctrl = (int*) malloc(nports_total * sizeof(int));
622
plugin_ports_pre = (float*) calloc(nports_ctrl, sizeof(float));
623
plugin_ports_post = (float*) calloc(nports_ctrl, sizeof(float));
625
atom_in = (LV2_Atom_Sequence*) malloc(min_atom_bufsiz + sizeof(uint8_t));
626
atom_out = (LV2_Atom_Sequence*) malloc(min_atom_bufsiz + sizeof(uint8_t));
628
rb_ctrl_to_ui = jack_ringbuffer_create((UPDATE_FREQ_RATIO) * nports_ctrl * 2 * sizeof(float));
629
rb_ctrl_from_ui = jack_ringbuffer_create((UPDATE_FREQ_RATIO) * nports_ctrl * 2 * sizeof(float));
631
rb_atom_to_ui = jack_ringbuffer_create((UPDATE_FREQ_RATIO) * min_atom_bufsiz);
632
rb_atom_from_ui = jack_ringbuffer_create((UPDATE_FREQ_RATIO) * min_atom_bufsiz);
635
/* reolve descriptors */
636
plugin_dsp = lv2_descriptor(dsp_descriptor_id);
637
plugin_gui = lv2ui_descriptor(gui_descriptor_id);
640
fprintf(stderr, "cannot resolve LV2 descriptor\n");
643
/* jack-open -> samlerate */
644
if (init_jack(extui_host.plugin_human_id)) goto out;
647
plugin_instance = plugin_dsp->instantiate(plugin_dsp, j_samplerate, NULL, features);
648
if (!plugin_instance) {
649
fprintf(stderr, "instantiation failed\n");
654
for (uint32_t p=0; p < nports_total; ++p) {
655
portmap_ctrl[p] = -1;
656
switch (ports[p].porttype) {
658
plugin_ports_pre[c_ctrl] = ports[p].val_default;
660
portmap_ctrl[p] = c_ctrl;
661
portmap_rctl[c_ctrl] = p;
662
plugin_dsp->connect_port(plugin_instance, p , &plugin_ports_pre[c_ctrl++]);
665
portmap_a_in[c_ain++] = p;
668
portmap_a_out[c_aout++] = p;
672
portmap_atom_from_ui = p;
673
plugin_dsp->connect_port(plugin_instance, p , atom_in);
677
portmap_atom_to_ui = p;
678
plugin_dsp->connect_port(plugin_instance, p , atom_out);
681
fprintf(stderr, "yet unsupported port..\n");
686
assert(c_ain == nports_audio_in);
687
assert(c_aout == nports_audio_out);
688
assert(c_ctrl == nports_ctrl);
690
if (nports_atom_out > 0 || nports_atom_in > 0 || nports_midi_in > 0 || nports_midi_out > 0) {
691
uri_atom_Sequence = uri_to_id(NULL, LV2_ATOM__Sequence);
692
uri_atom_EventTransfer = uri_to_id(NULL, LV2_ATOM__eventTransfer);
693
uri_midi_MidiEvent = uri_to_id(NULL, LV2_MIDI__MidiEvent);
694
uri_time_Position = uri_to_id(NULL, LV2_TIME__Position);
695
uri_time_frame = uri_to_id(NULL, LV2_TIME__frame);
696
uri_time_speed = uri_to_id(NULL, LV2_TIME__speed);
697
uri_time_bar = uri_to_id(NULL, LV2_TIME__bar);
698
uri_time_barBeat = uri_to_id(NULL, LV2_TIME__barBeat);
699
uri_time_beatUnit = uri_to_id(NULL, LV2_TIME__beatUnit);
700
uri_time_beatsPerBar = uri_to_id(NULL, LV2_TIME__beatsPerBar);
701
uri_time_beatsPerMinute = uri_to_id(NULL, LV2_TIME__beatsPerMinute);
702
lv2_atom_forge_init(&lv2_forge, &uri_map);
705
if (jack_portsetup()) goto out;
708
/* init plugin GUI */
709
extui_host.ui_closed = on_external_ui_closed;
710
instance_feature.data = plugin_instance;
711
gui_instance = plugin_gui->instantiate(plugin_gui,
712
plugin_dsp->URI, NULL,
713
&write_function, controller,
714
(void **)&extui, ui_features);
719
if (!gui_instance || !extui) {
720
fprintf(stderr, "Error: GUI was not initialized.\n");
725
if (mlockall (MCL_CURRENT | MCL_FUTURE)) {
726
fprintf(stderr, "Warning: Can not lock memory.\n");
729
if (plugin_dsp->activate) {
730
plugin_dsp->activate(plugin_instance);
733
if (jack_activate (j_client)) {
734
fprintf (stderr, "cannot activate client.\n");
739
signal (SIGHUP, catchsig);
740
signal (SIGINT, catchsig);
743
if (!gui_instance || !extui) {
745
while (client_state != Exit) {
750
LV2_EXTERNAL_UI_SHOW(extui);
754
LV2_EXTERNAL_UI_HIDE(extui);
761
/* vi:set ts=2 sts=2 sw=2: */