1 /* jackspa.c - LADSPA plugin instance with JACK audio ports
2 * Copyright © 2007 Nick Thomas
3 * Copyright © 2013 Géraud Meyer <graud@gmx.com>
5 * jackspa.c is part of ng-jackspa.
7 * ng-jackpsa is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License version 2 as published by the
9 * Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
28 /* Initial config (command line) */
29 static gboolean jackexactname
= FALSE
;
30 static gboolean jacknostartserver
= FALSE
;
31 const GOptionEntry jackspa_entries
[] =
33 /* long, short, flags, arg_type, arg_data, description, arg_description */
34 { "jack-exactname", 'N', 0, G_OPTION_ARG_NONE
, &jackexactname
,
35 "Do not allow JACK to generate an unused client name", NULL
},
36 { "jack-nostartserver", 'S', 0, G_OPTION_ARG_NONE
, &jacknostartserver
,
37 "Do not start a JACK server if none is running", NULL
},
40 static char *ladspa_library
= NULL
;
41 static unsigned long ladspa_id
= 0;
44 /* Finds the plugin descriptor with the given ID in the given object file,
45 * storing it in state->descriptor. Returns 1 on success. On failure, returns 0
46 * and sets *error to an appropriate error message.
48 int find_plugin(state_t
*state
, const char *file
, const unsigned long id
,
52 unsigned long i
; /* port index */
54 LADSPA_Descriptor
*(*descriptor_fun
)(unsigned long index
);
55 LADSPA_Descriptor
*descriptor
;
57 /* Open the library. */
58 library
= dlopen(file
, RTLD_LAZY
);
60 err
= 1, *error
= dlerror();
62 /* Find the ladspa_descriptor() function. */
64 descriptor_fun
= (LADSPA_Descriptor
*(*)(unsigned long))
65 dlsym(library
, "ladspa_descriptor");
67 err
= 1, *error
= dlerror();
70 /* Find the appropriate descriptor. */
71 for (i
= 0; !err
; i
++) {
72 descriptor
= descriptor_fun(i
);
75 err
= 1, *error
= "no such plugin index in the given file";
76 else if (descriptor
->UniqueID
== id
) {
77 state
->descriptor
= descriptor
;
85 /* The JACK processing callback. */
86 int process(jack_nframes_t nframes
, void *arg
)
88 state_t
*state
= (state_t
*)arg
;
89 unsigned long p
; /* loop variable for ports */
90 LADSPA_Data buf
; /* buffer for the control outputs */
92 /* Connect audio ports and unused control ports */
93 for (p
= 0; p
< state
->descriptor
->PortCount
; p
++)
94 if (LADSPA_IS_PORT_AUDIO(state
->descriptor
->PortDescriptors
[p
]))
95 state
->descriptor
->connect_port
97 (LADSPA_Data
*)jack_port_get_buffer(state
->jack_ports
[p
], nframes
) );
98 else if ( LADSPA_IS_PORT_CONTROL(state
->descriptor
->PortDescriptors
[p
]) &&
99 LADSPA_IS_PORT_OUTPUT(state
->descriptor
->PortDescriptors
[p
]) )
100 state
->descriptor
->connect_port(state
->handle
, p
, &buf
);
101 /* forget the control output ports values */
103 /* Run the plugin. */
104 state
->descriptor
->run(state
->handle
, nframes
);
109 /* Initializes JACK, opening the appropriate ports, instantiating the LADSPA
110 * Plugin, and starting the synthesis thread running.. Returns 1 on success. On
111 * failure, returns 0 and sets *error to an appropriate error message.
113 int init_jack(state_t
*state
, const char **error
)
115 static char client_name_prefix
[] = "jackspa_";
117 jack_options_t oflags
;
118 jack_status_t jack_status
;
119 unsigned long p
; /* loop variable for ports */
120 enum JackPortFlags pflags
;
122 /* Allocate memory for the client name. */
123 state
->client_name
= (char *)calloc
124 ( sizeof(client_name_prefix
) + strlen(state
->descriptor
->Label
),
126 if (!state
->client_name
)
127 err
= 1, *error
= strerror(errno
);
129 /* Set the client name. */
131 /* state->client_name[0] = '\0'; */ /* done by calloc */
132 strcat(state
->client_name
, client_name_prefix
);
133 strcat(state
->client_name
, state
->descriptor
->Label
);
138 oflags
= JackNullOption
;
139 if (jackexactname
) oflags
|= JackUseExactName
;
140 if (jacknostartserver
) oflags
|= JackNoStartServer
;
142 jack_client_open(state
->client_name
, oflags
, &jack_status
);
143 if (!state
->jack_client
)
144 err
= 1, *error
= "could not connect to JACK";
147 /* Free memory for the client name */
148 free(state
->client_name
);
149 if (!err
) state
->client_name
= jack_get_client_name(state
->jack_client
);
151 /* Allocate memory for the list of ports. */
153 state
->jack_ports
= (jack_port_t
**)calloc
154 (state
->descriptor
->PortCount
, sizeof(jack_port_t
*));
155 if (!state
->jack_ports
)
156 err
= 1, *error
= strerror(errno
);
159 /* Allocate memory for the list of control port values. */
161 state
->control_port_values
= (LADSPA_Data
*)calloc
162 ((size_t)state
->descriptor
->PortCount
, sizeof(LADSPA_Data
));
163 if (!state
->control_port_values
)
164 err
= 1, *error
= strerror(errno
);
167 /* Register ports. */
168 state
->num_control_ports
= 0;
169 for (p
= 0; !err
&& p
< state
->descriptor
->PortCount
; p
++) {
170 if ( LADSPA_IS_PORT_CONTROL(state
->descriptor
-> PortDescriptors
[p
]) &&
171 LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]) )
173 state
->num_control_ports
++;
177 if (LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]))
178 pflags
= JackPortIsInput
;
179 else if (LADSPA_IS_PORT_AUDIO(state
->descriptor
->PortDescriptors
[p
]))
180 pflags
= JackPortIsOutput
;
182 continue; /* skip the control outputs (aka meters) */
184 state
->jack_ports
[p
] = jack_port_register
185 ( state
->jack_client
, state
->descriptor
->PortNames
[p
],
186 JACK_DEFAULT_AUDIO_TYPE
, pflags
, 0 );
188 if (!state
->jack_ports
[p
])
189 err
= 1, *error
= "could not register JACK ports";
192 /* Register our processing callback. */
194 if (jack_set_process_callback(state
->jack_client
, &process
, state
))
195 err
= 1, *error
= "could not register the JACK processing callback";
197 /* Instantiate the LADSPA plugin. */
199 state
->handle
= state
->descriptor
->instantiate
200 (state
->descriptor
, jack_get_sample_rate(state
->jack_client
));
202 err
= 1, *error
= "could not instantiate the plugin.";
205 /* Connect input control ports. */
207 for (p
= 0; p
< state
->descriptor
->PortCount
; p
++)
208 if ( LADSPA_IS_PORT_CONTROL(state
->descriptor
->PortDescriptors
[p
]) &&
209 LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]))
211 state
->descriptor
->connect_port
212 (state
->handle
, p
, &state
->control_port_values
[p
]);
213 /* state->control_port_values[p] = 0.0; */ /* done by calloc() */
216 /* Activate the LADSPA plugin. */
218 if (state
->descriptor
->activate
)
219 state
->descriptor
->activate(state
->handle
);
221 /* Get the bits flowing. */
223 if (jack_activate(state
->jack_client
))
224 err
= 1, *error
= "could not activate audio processing";
235 /* Parses command-line arguments. Returns 1 on success. On failure, returns 0
236 * and sets *error to an appropriate error message.
238 int parse_args(state_t
*state
, int argc
, char **argv
, char **plugin_file
,
239 unsigned long *plugin_id
, const char **error
)
242 int i
; /* arg index */
243 arg_parser_state st
= st_want_plugin_file
;
245 argc
--, argv
++; /* skip the program name */
247 for (i
= 0; i
< argc
; i
++)
249 case st_want_plugin_file
:
250 *plugin_file
= argv
[i
];
251 st
= st_want_plugin_id
;
254 case st_want_plugin_id
:
255 *plugin_id
= atol(argv
[i
]);
261 err
= 1, *error
= "extra arguments given";
266 err
= 1, *error
= "must supply a plugin file and a plugin ID";
271 int jackspa_init(state_t
*state
, int argc
, char **argv
)
276 state
->jack_client
= 0;
278 err
= !parse_args(state
, argc
, argv
, &ladspa_library
, &ladspa_id
, &error
);
281 err
= !find_plugin(state
, ladspa_library
, ladspa_id
, &error
);
284 err
= !init_jack(state
, &error
);
287 fprintf(stderr
, "jackspa error: %s\n", error
);