ext/jackio.c: write to ochan output buffers, not ichan
[aubio.git] / ext / jackio.c
1 /*
2   Copyright (C) 2003-2009 Paul Brossier <piem@aubio.org>
3
4   This file is part of aubio.
5
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.
10
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.
15
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/>.
18
19 */
20
21 #include <aubio.h>
22
23 #if HAVE_JACK
24 #include <jack/jack.h>
25 #include "aubio_priv.h"
26 #include "jackio.h"
27
28 typedef jack_default_audio_sample_t jack_sample_t;
29
30 #if !AUBIO_SINGLE_PRECISION
31 #define AUBIO_JACK_MAX_FRAMES 4096
32 #define AUBIO_JACK_NEEDS_CONVERSION
33 #endif
34
35 /**
36  * jack device structure 
37  */
38 struct _aubio_jack_t
39 {
40   /** jack client */
41   jack_client_t *client;
42   /** jack output ports */
43   jack_port_t **oports;
44   /** jack input ports */
45   jack_port_t **iports;
46   /** jack input buffer */
47   jack_sample_t **ibufs;
48   /** jack output buffer */
49   jack_sample_t **obufs;
50 #ifdef AUBIO_JACK_NEEDS_CONVERSION
51   /** converted jack input buffer */
52   smpl_t **sibufs;
53   /** converted jack output buffer */
54   smpl_t **sobufs;
55 #endif
56   /** jack input channels */
57   uint_t ichan;
58   /** jack output channels */
59   uint_t ochan;
60   /** jack samplerate (Hz) */
61   uint_t samplerate;
62   /** jack processing function */
63   aubio_process_func_t callback;
64 };
65
66 /* static memory management */
67 static aubio_jack_t *aubio_jack_alloc (uint_t ichan, uint_t ochan);
68 static uint_t aubio_jack_free (aubio_jack_t * jack_setup);
69 /* jack callback functions */
70 static int aubio_jack_process (jack_nframes_t nframes, void *arg);
71 static void aubio_jack_shutdown (void *arg);
72
73 aubio_jack_t *
74 new_aubio_jack (uint_t ichan, uint_t ochan, aubio_process_func_t callback)
75 {
76   aubio_jack_t *jack_setup = aubio_jack_alloc (ichan, ochan);
77   uint_t i;
78   char *client_name = "aubio";
79   char name[64];
80   /* initial jack client setup */
81   if ((jack_setup->client = jack_client_new (client_name)) == 0) {
82     AUBIO_ERR ("jack server not running?\n");
83     AUBIO_QUIT (AUBIO_FAIL);
84   }
85
86   /* set callbacks */
87   jack_set_process_callback (jack_setup->client, aubio_jack_process,
88       (void *) jack_setup);
89   jack_on_shutdown (jack_setup->client, aubio_jack_shutdown,
90       (void *) jack_setup);
91
92   /* register jack output ports */
93   for (i = 0; i < ochan; i++) {
94     AUBIO_SPRINTF (name, "out_%d", i + 1);
95     AUBIO_MSG ("%s\n", name);
96     if ((jack_setup->oports[i] =
97             jack_port_register (jack_setup->client, name,
98                 JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == 0) {
99       AUBIO_ERR ("failed registering output port \"%s\"!\n", name);
100       jack_client_close (jack_setup->client);
101       AUBIO_QUIT (AUBIO_FAIL);
102     }
103   }
104
105   /* register jack input ports */
106   for (i = 0; i < ichan; i++) {
107     AUBIO_SPRINTF (name, "in_%d", i + 1);
108     AUBIO_MSG ("%s\n", name);
109     if ((jack_setup->iports[i] =
110             jack_port_register (jack_setup->client, name,
111                 JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) {
112       AUBIO_ERR ("failed registering input port \"%s\"!\n", name);
113       jack_client_close (jack_setup->client);
114       AUBIO_QUIT (AUBIO_FAIL);
115     }
116   }
117
118   /* set processing callback */
119   jack_setup->callback = callback;
120   return jack_setup;
121 }
122
123 uint_t
124 aubio_jack_activate (aubio_jack_t * jack_setup)
125 {
126   /* get sample rate */
127   jack_setup->samplerate = jack_get_sample_rate (jack_setup->client);
128   /* actual jack process activation */
129   if (jack_activate (jack_setup->client)) {
130     AUBIO_ERR ("jack client activation failed");
131     return 1;
132   }
133   return 0;
134 }
135
136 void
137 aubio_jack_close (aubio_jack_t * jack_setup)
138 {
139   /* bug : should disconnect all ports first */
140   jack_client_close (jack_setup->client);
141   aubio_jack_free (jack_setup);
142 }
143
144 /* memory management */
145 static aubio_jack_t *
146 aubio_jack_alloc (uint_t ichan, uint_t ochan)
147 {
148   aubio_jack_t *jack_setup = AUBIO_NEW (aubio_jack_t);
149   jack_setup->ichan = ichan;
150   jack_setup->ochan = ochan;
151   jack_setup->oports = AUBIO_ARRAY (jack_port_t *, ichan);
152   jack_setup->iports = AUBIO_ARRAY (jack_port_t *, ochan);
153   jack_setup->ibufs = AUBIO_ARRAY (jack_sample_t *, ichan);
154   jack_setup->obufs = AUBIO_ARRAY (jack_sample_t *, ochan);
155 #ifdef AUBIO_JACK_NEEDS_CONVERSION
156   jack_setup->sibufs = AUBIO_ARRAY (smpl_t *, ichan);
157   uint_t i;
158   for (i = 0; i < ichan; i++) {
159     jack_setup->sibufs[i] = AUBIO_ARRAY (smpl_t, AUBIO_JACK_MAX_FRAMES);
160   }
161   jack_setup->sobufs = AUBIO_ARRAY (smpl_t *, ochan);
162   for (i = 0; i < ochan; i++) {
163     jack_setup->sobufs[i] = AUBIO_ARRAY (smpl_t, AUBIO_JACK_MAX_FRAMES);
164   }
165 #endif
166   return jack_setup;
167 }
168
169 static uint_t
170 aubio_jack_free (aubio_jack_t * jack_setup)
171 {
172   AUBIO_FREE (jack_setup->oports);
173   AUBIO_FREE (jack_setup->iports);
174   AUBIO_FREE (jack_setup->ibufs);
175   AUBIO_FREE (jack_setup->obufs);
176   AUBIO_FREE (jack_setup);
177   return AUBIO_OK;
178 }
179
180 /* jack callback functions */
181 static void
182 aubio_jack_shutdown (void *arg UNUSED)
183 {
184   AUBIO_ERR ("jack shutdown\n");
185   AUBIO_QUIT (AUBIO_OK);
186 }
187
188 static int
189 aubio_jack_process (jack_nframes_t nframes, void *arg)
190 {
191   aubio_jack_t *dev = (aubio_jack_t *) arg;
192   uint_t i;
193   for (i = 0; i < dev->ichan; i++) {
194     /* get readable input */
195     dev->ibufs[i] =
196         (jack_sample_t *) jack_port_get_buffer (dev->iports[i], nframes);
197   }
198   for (i = 0; i < dev->ochan; i++) {
199     /* get writable output */
200     dev->obufs[i] =
201         (jack_sample_t *) jack_port_get_buffer (dev->oports[i], nframes);
202   }
203 #ifndef AUBIO_JACK_NEEDS_CONVERSION
204   dev->callback (dev->ibufs, dev->obufs, nframes);
205 #else
206   uint_t j;
207   for (j = 0; j < MIN (nframes, AUBIO_JACK_MAX_FRAMES); j++) {
208     for (i = 0; i < dev->ichan; i++) {
209       dev->sibufs[i][j] = (smpl_t) dev->ibufs[i][j];
210     }
211   }
212   dev->callback (dev->sibufs, dev->sobufs, nframes);
213   for (j = 0; j < MIN (nframes, AUBIO_JACK_MAX_FRAMES); j++) {
214     for (i = 0; i < dev->ochan; i++) {
215       dev->obufs[i][j] = (jack_sample_t) dev->sobufs[i][j];
216     }
217   }
218 #endif
219   return 0;
220 }
221
222
223 #endif /* HAVE_JACK */