2 Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
4 This file is part of aubio.
6 aubio is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 aubio is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with aubio. If not, see <http://www.gnu.org/licenses/>.
25 #include "utils.h" // for aubio_process_func_t
27 #include "aubio_priv.h"
29 typedef jack_default_audio_sample_t jack_sample_t;
32 #define AUBIO_JACK_MAX_FRAMES 4096
33 #define AUBIO_JACK_NEEDS_CONVERSION
36 #define RINGBUFFER_SIZE 1024*sizeof(jack_midi_event_t)
39 * jack device structure
44 jack_client_t *client;
45 /** jack output ports */
47 /** jack input ports */
49 /** jack input buffer */
50 jack_sample_t **ibufs;
51 /** jack output buffer */
52 jack_sample_t **obufs;
53 #ifdef AUBIO_JACK_NEEDS_CONVERSION
54 /** converted jack input buffer */
56 /** converted jack output buffer */
59 /** jack input audio channels */
61 /** jack output audio channels */
63 /** jack input midi channels */
65 /** jack output midi channels */
67 /** midi output ringbuffer */
68 jack_ringbuffer_t *midi_out_ring;
69 /** jack samplerate (Hz) */
71 /** jack processing function */
72 aubio_process_func_t callback;
80 /* static memory management */
81 static aubio_jack_t *aubio_jack_alloc (uint_t ichan, uint_t ochan,
82 uint_t imidichan, uint_t omidichan);
83 /* jack callback functions */
84 static int aubio_jack_process (jack_nframes_t nframes, void *arg);
85 static void aubio_jack_shutdown (void *arg);
88 new_aubio_jack (uint_t hop_size, uint_t ichan, uint_t ochan,
89 uint_t imidichan, uint_t omidichan)
91 aubio_jack_t *jack_setup = aubio_jack_alloc (ichan, ochan,
92 imidichan, omidichan);
94 char *client_name = "aubio";
97 /* initial jack client setup */
98 jack_options_t options = JackNullOption;
99 jack_status_t *status = NULL;
100 if ((jack_setup->client = jack_client_open (client_name, options, status)) == 0) {
101 AUBIO_ERR ("jack server not running?\n");
102 AUBIO_QUIT (AUBIO_FAIL);
105 if (jack_setup->omidichan) {
106 jack_setup->midi_out_ring = jack_ringbuffer_create (RINGBUFFER_SIZE);
108 if (jack_setup->midi_out_ring == NULL) {
109 AUBIO_ERR ("Failed creating jack midi output ringbuffer.");
110 AUBIO_QUIT (AUBIO_FAIL);
113 jack_ringbuffer_mlock (jack_setup->midi_out_ring);
117 jack_set_process_callback (jack_setup->client, aubio_jack_process,
118 (void *) jack_setup);
119 jack_on_shutdown (jack_setup->client, aubio_jack_shutdown,
120 (void *) jack_setup);
122 /* register jack output audio and midi ports */
123 for (i = 0; i < ochan + omidichan; i++) {
125 jack_port_type = JACK_DEFAULT_AUDIO_TYPE;
126 AUBIO_SPRINTF (name, "out_%d", i + 1);
128 jack_port_type = JACK_DEFAULT_MIDI_TYPE;
129 AUBIO_SPRINTF (name, "midi_out_%d", i - ochan + 1);
131 if ((jack_setup->oports[i] =
132 jack_port_register (jack_setup->client, name,
133 jack_port_type, JackPortIsOutput, 0)) == 0) {
136 AUBIO_DBG ("%s:%s\n", client_name, name);
139 /* register jack input audio ports */
140 for (i = 0; i < ichan + imidichan; i++) {
142 jack_port_type = JACK_DEFAULT_AUDIO_TYPE;
143 AUBIO_SPRINTF (name, "in_%d", i + 1);
145 jack_port_type = JACK_DEFAULT_MIDI_TYPE;
146 AUBIO_SPRINTF (name, "midi_in_%d", i - ichan + 1);
148 if ((jack_setup->iports[i] =
149 jack_port_register (jack_setup->client, name,
150 jack_port_type, JackPortIsInput, 0)) == 0) {
153 AUBIO_DBG ("%s:%s\n", client_name, name);
156 /* get sample rate */
157 jack_setup->samplerate = jack_get_sample_rate (jack_setup->client);
159 jack_setup->hop_size = hop_size;
160 jack_setup->ibuf = new_fvec(hop_size);
161 jack_setup->obuf = new_fvec(hop_size);
166 AUBIO_ERR ("failed registering port \"%s:%s\"!\n", client_name, name);
167 jack_client_close (jack_setup->client);
168 AUBIO_QUIT (AUBIO_FAIL);
172 aubio_jack_get_samplerate (aubio_jack_t * jack_setup) {
173 return jack_setup->samplerate;
177 aubio_jack_activate (aubio_jack_t * jack_setup, aubio_process_func_t callback)
179 /* set processing callback */
180 jack_setup->callback = callback;
181 /* actual jack process activation */
182 if (jack_activate (jack_setup->client)) {
183 AUBIO_ERR ("jack client activation failed");
190 aubio_jack_close (aubio_jack_t * jack_setup)
192 /* bug : should disconnect all ports first */
193 jack_client_close (jack_setup->client);
196 /* memory management */
197 static aubio_jack_t *
198 aubio_jack_alloc (uint_t ichan, uint_t ochan,
199 uint_t imidichan, uint_t omidichan)
201 aubio_jack_t *jack_setup = AUBIO_NEW (aubio_jack_t);
202 jack_setup->ichan = ichan;
203 jack_setup->ochan = ochan;
204 jack_setup->imidichan = imidichan;
205 jack_setup->omidichan = omidichan;
206 jack_setup->oports = AUBIO_ARRAY (jack_port_t *, ichan + imidichan);
207 jack_setup->iports = AUBIO_ARRAY (jack_port_t *, ochan + omidichan);
208 jack_setup->ibufs = AUBIO_ARRAY (jack_sample_t *, ichan);
209 jack_setup->obufs = AUBIO_ARRAY (jack_sample_t *, ochan);
210 #ifdef AUBIO_JACK_NEEDS_CONVERSION
211 /* allocate arrays for data conversion */
212 jack_setup->sibufs = AUBIO_ARRAY (smpl_t *, ichan);
214 for (i = 0; i < ichan; i++) {
215 jack_setup->sibufs[i] = AUBIO_ARRAY (smpl_t, AUBIO_JACK_MAX_FRAMES);
217 jack_setup->sobufs = AUBIO_ARRAY (smpl_t *, ochan);
218 for (i = 0; i < ochan; i++) {
219 jack_setup->sobufs[i] = AUBIO_ARRAY (smpl_t, AUBIO_JACK_MAX_FRAMES);
226 del_aubio_jack (aubio_jack_t * jack_setup)
228 if (jack_setup->omidichan && jack_setup->midi_out_ring) {
229 jack_ringbuffer_free (jack_setup->midi_out_ring);
231 del_fvec (jack_setup->ibuf);
232 del_fvec (jack_setup->obuf);
233 AUBIO_FREE (jack_setup->oports);
234 AUBIO_FREE (jack_setup->iports);
235 AUBIO_FREE (jack_setup->ibufs);
236 AUBIO_FREE (jack_setup->obufs);
237 AUBIO_FREE (jack_setup);
240 /* jack callback functions */
242 aubio_jack_shutdown (void *arg UNUSED)
244 AUBIO_ERR ("jack shutdown\n");
245 AUBIO_QUIT (AUBIO_OK);
248 static void process_midi_output (aubio_jack_t * dev, jack_nframes_t nframes);
250 static int block_process(aubio_jack_t *dev,
251 smpl_t **input, smpl_t **output, int nframes) {
252 unsigned int j; /*frames*/
253 for (j=0;j<(unsigned)nframes;j++) {
254 /* put synthnew in output */
255 output[0][j] = fvec_get_sample(dev->obuf, dev->pos);
256 /* write input to datanew */
257 fvec_set_sample(dev->ibuf, input[0][j], dev->pos);
259 if (dev->pos == (int)(dev->hop_size) - 1) {
261 dev->callback(dev->ibuf, dev->obuf);
262 /* end of block loop */
263 dev->pos = -1; /* so it will be zero next j loop */
271 aubio_jack_process (jack_nframes_t nframes, void *arg)
273 aubio_jack_t *dev = (aubio_jack_t *) arg;
275 for (i = 0; i < dev->ichan; i++) {
276 /* get readable input */
278 (jack_sample_t *) jack_port_get_buffer (dev->iports[i], nframes);
280 for (i = 0; i < dev->ochan; i++) {
281 /* get writable output */
283 (jack_sample_t *) jack_port_get_buffer (dev->oports[i], nframes);
285 #ifndef AUBIO_JACK_NEEDS_CONVERSION
286 block_process(dev, dev->ibufs, dev->obufs, nframes);
289 for (j = 0; j < MIN (nframes, AUBIO_JACK_MAX_FRAMES); j++) {
290 for (i = 0; i < dev->ichan; i++) {
291 dev->sibufs[i][j] = (smpl_t) dev->ibufs[i][j];
294 block_process(dev, dev->sibufs, dev->sobufs, nframes);
295 for (j = 0; j < MIN (nframes, AUBIO_JACK_MAX_FRAMES); j++) {
296 for (i = 0; i < dev->ochan; i++) {
297 dev->obufs[i][j] = (jack_sample_t) dev->sobufs[i][j];
302 /* now process midi stuff */
303 if (dev->omidichan) {
304 process_midi_output (dev, nframes);
311 aubio_jack_midi_event_write (aubio_jack_t * dev, jack_midi_event_t * event)
315 if (jack_ringbuffer_write_space (dev->midi_out_ring) < sizeof (*event)) {
316 AUBIO_ERR ("Not enough space to write midi output, midi event lost!\n");
320 written = jack_ringbuffer_write (dev->midi_out_ring,
321 (char *) event, sizeof (*event));
323 if (written != sizeof (*event)) {
324 AUBIO_WRN ("Call to jack_ringbuffer_write failed, midi event lost! \n");
329 process_midi_output (aubio_jack_t * dev, jack_nframes_t nframes)
332 jack_midi_event_t ev;
333 unsigned char *buffer;
334 jack_nframes_t last_frame_time = jack_last_frame_time (dev->client);
335 // TODO for each omidichan
336 void *port_buffer = jack_port_get_buffer (dev->oports[dev->ochan], nframes);
338 if (port_buffer == NULL) {
339 AUBIO_WRN ("Failed to get jack midi output port, will not send anything\n");
343 jack_midi_clear_buffer (port_buffer);
345 // TODO add rate_limit
347 while (jack_ringbuffer_read_space (dev->midi_out_ring)) {
348 read = jack_ringbuffer_peek (dev->midi_out_ring, (char *) &ev, sizeof (ev));
350 if (read != sizeof (ev)) {
351 AUBIO_WRN ("Short read from the ringbuffer, possible note loss.\n");
352 jack_ringbuffer_read_advance (dev->midi_out_ring, read);
356 sendtime = ev.time + nframes - last_frame_time;
358 /* send time is after current period, will do this one later */
359 if (sendtime >= (int) nframes) {
367 jack_ringbuffer_read_advance (dev->midi_out_ring, sizeof (ev));
369 buffer = jack_midi_event_reserve (port_buffer, sendtime, ev.size);
371 if (buffer == NULL) {
372 AUBIO_WRN ("Call to jack_midi_event_reserve failed, note lost.\n");
376 AUBIO_MEMCPY (buffer, ev.buffer, ev.size);
380 #endif /* HAVE_JACK */