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
);
123 err
= 1, *error
= "could not connect to JACK";
126 /* Allocate memory for the list of ports. */
128 state
->jack_ports
= (jack_port_t
**)calloc
129 (state
->descriptor
->PortCount
, sizeof(jack_port_t
*));
130 if (!state
->jack_ports
)
131 err
= 1, *error
= strerror(errno
);
134 /* Allocate memory for the list of control port values. */
136 state
->control_port_values
= (LADSPA_Data
*)calloc
137 ((size_t)state
->descriptor
->PortCount
, sizeof(LADSPA_Data
));
138 if (!state
->control_port_values
)
139 err
= 1, *error
= strerror(errno
);
142 /* Register ports. */
143 state
->num_control_ports
= 0;
144 for (p
= 0; !err
&& p
< state
->descriptor
->PortCount
; p
++) {
145 if ( LADSPA_IS_PORT_CONTROL(state
->descriptor
-> PortDescriptors
[p
]) &&
146 LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]) )
148 state
->num_control_ports
++;
152 if (LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]))
153 flags
= JackPortIsInput
;
154 else if (LADSPA_IS_PORT_AUDIO(state
->descriptor
->PortDescriptors
[p
]))
155 flags
= JackPortIsOutput
;
157 continue; /* skip the control outputs (aka meters) */
159 state
->jack_ports
[p
] = jack_port_register
160 ( state
->jack_client
, state
->descriptor
->PortNames
[p
],
161 JACK_DEFAULT_AUDIO_TYPE
, flags
, 0 );
163 if (!state
->jack_ports
[p
])
164 err
= 1, *error
= "could not register JACK ports";
167 /* Register our processing callback. */
169 if (jack_set_process_callback(state
->jack_client
, &process
, state
))
170 err
= 1, *error
= "could not register the JACK processing callback";
172 /* Instantiate the LADSPA plugin. */
174 state
->handle
= state
->descriptor
->instantiate
175 (state
->descriptor
, jack_get_sample_rate(state
->jack_client
));
177 err
= 1, *error
= "could not instantiate the plugin.";
180 /* Connect input control ports. */
182 for (p
= 0; p
< state
->descriptor
->PortCount
; p
++)
183 if ( LADSPA_IS_PORT_CONTROL(state
->descriptor
->PortDescriptors
[p
]) &&
184 LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]))
186 state
->descriptor
->connect_port
187 (state
->handle
, p
, &state
->control_port_values
[p
]);
188 /* state->control_port_values[p] = 0.0; */ /* done by calloc() */
191 /* Activate the LADSPA plugin. */
193 if (state
->descriptor
->activate
)
194 state
->descriptor
->activate(state
->handle
);
196 /* Get the bits flowing. */
198 if (jack_activate(state
->jack_client
))
199 err
= 1, *error
= "could not activate audio processing";
210 /* Parses command-line arguments. Returns 1 on success. On failure, returns 0
211 * and sets *error to an appropriate error message.
213 int parse_args(state_t
*state
, int argc
, char **argv
, char **plugin_file
,
214 unsigned long *plugin_id
, const char **error
)
217 int i
; /* arg index */
218 arg_parser_state st
= st_want_plugin_file
;
220 argc
--, argv
++; /* skip the program name */
222 for (i
= 0; i
< argc
; i
++)
224 case st_want_plugin_file
:
225 *plugin_file
= argv
[i
];
226 st
= st_want_plugin_id
;
229 case st_want_plugin_id
:
230 *plugin_id
= atol(argv
[i
]);
240 err
= 1, *error
= "must supply a plugin file and a plugin ID";
245 int jackspa_init(state_t
*state
, int argc
, char **argv
)
250 unsigned long plugin_id
;
252 state
->jack_client
= 0;
254 err
= !parse_args(state
, argc
, argv
, &plugin_file
, &plugin_id
, &error
);
257 err
= !find_plugin(state
, plugin_file
, plugin_id
, &error
);
260 err
= !init_jack(state
, &error
);
263 fprintf(stderr
, "jackspa error: %s\n", error
);