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/>.
27 /* Finds the plugin descriptor with the given ID in the given object file,
28 * storing it in state->descriptor. Returns 1 on success. On failure, returns 0
29 * and sets *error to an appropriate error message.
31 int find_plugin(state_t
*state
, const char *file
, const unsigned long id
,
35 unsigned long i
; /* port index */
37 LADSPA_Descriptor
*(*descriptor_fun
)(unsigned long index
);
38 LADSPA_Descriptor
*descriptor
;
40 /* Open the library. */
41 library
= dlopen(file
, RTLD_LAZY
);
43 err
= 1, *error
= dlerror();
45 /* Find the ladspa_descriptor() function. */
47 descriptor_fun
= (LADSPA_Descriptor
*(*)(unsigned long))
48 dlsym(library
, "ladspa_descriptor");
50 err
= 1, *error
= dlerror();
53 /* Find the appropriate descriptor. */
54 for (i
= 0; !err
; i
++) {
55 descriptor
= descriptor_fun(i
);
58 err
= 1, *error
= "no such plugin index in the given file";
59 else if (descriptor
->UniqueID
== id
) {
60 state
->descriptor
= descriptor
;
68 /* The JACK processing callback. */
69 int process(jack_nframes_t nframes
, void *arg
)
71 state_t
*state
= (state_t
*)arg
;
72 unsigned long p
; /* loop variable for ports */
73 LADSPA_Data buf
; /* buffer for the control outputs */
75 /* Connect audio ports and unused control ports */
76 for (p
= 0; p
< state
->descriptor
->PortCount
; p
++)
77 if (LADSPA_IS_PORT_AUDIO(state
->descriptor
->PortDescriptors
[p
]))
78 state
->descriptor
->connect_port
80 (LADSPA_Data
*)jack_port_get_buffer(state
->jack_ports
[p
], nframes
) );
81 else if ( LADSPA_IS_PORT_CONTROL(state
->descriptor
->PortDescriptors
[p
]) &&
82 LADSPA_IS_PORT_OUTPUT(state
->descriptor
->PortDescriptors
[p
]) )
83 state
->descriptor
->connect_port(state
->handle
, p
, &buf
);
84 /* forget the control output ports values */
87 state
->descriptor
->run(state
->handle
, nframes
);
92 /* Initializes JACK, opening the appropriate ports, instantiating the LADSPA
93 * Plugin, and starting the synthesis thread running.. Returns 1 on success. On
94 * failure, returns 0 and sets *error to an appropriate error message.
96 int init_jack(state_t
*state
, const char **error
)
98 static char client_name_prefix
[] = "jackspa_";
100 jack_status_t jack_status
;
101 unsigned long p
; /* loop variable for ports */
104 /* Allocate memory for the client name. */
105 state
->client_name
= (char *)calloc
106 ( sizeof(client_name_prefix
) + strlen(state
->descriptor
->Label
),
108 if (!state
->client_name
)
109 err
= 1, *error
= strerror(errno
);
111 /* Set the client name. */
113 /* state->client_name[0] = '\0'; */ /* done by calloc */
114 strcat(state
->client_name
, client_name_prefix
);
115 strcat(state
->client_name
, state
->descriptor
->Label
);
121 jack_client_open(state
->client_name
, JackNullOption
, &jack_status
);
122 if (!state
->jack_client
)
123 err
= 1, *error
= "could not connect to JACK";
126 /* Free memory for the client name */
127 free(state
->client_name
);
128 if (!err
) state
->client_name
= jack_get_client_name(state
->jack_client
);
130 /* Allocate memory for the list of ports. */
132 state
->jack_ports
= (jack_port_t
**)calloc
133 (state
->descriptor
->PortCount
, sizeof(jack_port_t
*));
134 if (!state
->jack_ports
)
135 err
= 1, *error
= strerror(errno
);
138 /* Allocate memory for the list of control port values. */
140 state
->control_port_values
= (LADSPA_Data
*)calloc
141 ((size_t)state
->descriptor
->PortCount
, sizeof(LADSPA_Data
));
142 if (!state
->control_port_values
)
143 err
= 1, *error
= strerror(errno
);
146 /* Register ports. */
147 state
->num_control_ports
= 0;
148 for (p
= 0; !err
&& p
< state
->descriptor
->PortCount
; p
++) {
149 if ( LADSPA_IS_PORT_CONTROL(state
->descriptor
-> PortDescriptors
[p
]) &&
150 LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]) )
152 state
->num_control_ports
++;
156 if (LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]))
157 flags
= JackPortIsInput
;
158 else if (LADSPA_IS_PORT_AUDIO(state
->descriptor
->PortDescriptors
[p
]))
159 flags
= JackPortIsOutput
;
161 continue; /* skip the control outputs (aka meters) */
163 state
->jack_ports
[p
] = jack_port_register
164 ( state
->jack_client
, state
->descriptor
->PortNames
[p
],
165 JACK_DEFAULT_AUDIO_TYPE
, flags
, 0 );
167 if (!state
->jack_ports
[p
])
168 err
= 1, *error
= "could not register JACK ports";
171 /* Register our processing callback. */
173 if (jack_set_process_callback(state
->jack_client
, &process
, state
))
174 err
= 1, *error
= "could not register the JACK processing callback";
176 /* Instantiate the LADSPA plugin. */
178 state
->handle
= state
->descriptor
->instantiate
179 (state
->descriptor
, jack_get_sample_rate(state
->jack_client
));
181 err
= 1, *error
= "could not instantiate the plugin.";
184 /* Connect input control ports. */
186 for (p
= 0; p
< state
->descriptor
->PortCount
; p
++)
187 if ( LADSPA_IS_PORT_CONTROL(state
->descriptor
->PortDescriptors
[p
]) &&
188 LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]))
190 state
->descriptor
->connect_port
191 (state
->handle
, p
, &state
->control_port_values
[p
]);
192 /* state->control_port_values[p] = 0.0; */ /* done by calloc() */
195 /* Activate the LADSPA plugin. */
197 if (state
->descriptor
->activate
)
198 state
->descriptor
->activate(state
->handle
);
200 /* Get the bits flowing. */
202 if (jack_activate(state
->jack_client
))
203 err
= 1, *error
= "could not activate audio processing";
214 /* Parses command-line arguments. Returns 1 on success. On failure, returns 0
215 * and sets *error to an appropriate error message.
217 int parse_args(state_t
*state
, int argc
, char **argv
, char **plugin_file
,
218 unsigned long *plugin_id
, const char **error
)
221 int i
; /* arg index */
222 arg_parser_state st
= st_want_plugin_file
;
224 argc
--, argv
++; /* skip the program name */
226 for (i
= 0; i
< argc
; i
++)
228 case st_want_plugin_file
:
229 *plugin_file
= argv
[i
];
230 st
= st_want_plugin_id
;
233 case st_want_plugin_id
:
234 *plugin_id
= atol(argv
[i
]);
240 err
= 1, *error
= "extra arguments given";
245 err
= 1, *error
= "must supply a plugin file and a plugin ID";
250 int jackspa_init(state_t
*state
, int argc
, char **argv
)
255 unsigned long plugin_id
;
257 state
->jack_client
= 0;
259 err
= !parse_args(state
, argc
, argv
, &plugin_file
, &plugin_id
, &error
);
262 err
= !find_plugin(state
, plugin_file
, plugin_id
, &error
);
265 err
= !init_jack(state
, &error
);
268 fprintf(stderr
, "jackspa error: %s\n", error
);