ext/jackio.{c,h}: convert data from smpl_t to jack_default_audio_sample_t when needed
[aubio.git] / ext / jackio.c
1 /*
2    Copyright (C) 2003 Paul Brossier
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <aubio.h>
21
22 #if HAVE_JACK
23 #include <jack/jack.h>
24 #include "aubio_priv.h"
25 #include "jackio.h"
26
27 typedef jack_default_audio_sample_t jack_sample_t;
28
29 #if !AUBIO_SINGLE_PRECISION
30 #define AUBIO_JACK_MAX_FRAMES 4096
31 #define AUBIO_JACK_NEEDS_CONVERSION
32 #endif
33
34 /**
35  * jack device structure 
36  */
37 struct _aubio_jack_t {
38   /** jack client */
39   jack_client_t *client;
40   /** jack output ports */
41   jack_port_t **oports;
42   /** jack input ports */
43   jack_port_t **iports;
44   /** jack input buffer */
45   jack_sample_t **ibufs;
46   /** jack output buffer */
47   jack_sample_t **obufs;
48 #ifdef AUBIO_JACK_NEEDS_CONVERSION 
49   /** converted jack input buffer */
50   smpl_t **sibufs;
51   /** converted jack output buffer */
52   smpl_t **sobufs;
53 #endif
54   /** jack input channels */
55   uint_t ichan;
56   /** jack output channels */
57   uint_t ochan;
58   /** jack samplerate (Hz) */
59   uint_t samplerate;
60   /** jack processing function */
61   aubio_process_func_t callback; 
62 };
63
64 /* static memory management */
65 static aubio_jack_t * aubio_jack_alloc(uint_t ichan, uint_t ochan);
66 static uint_t aubio_jack_free(aubio_jack_t * jack_setup);
67 /* jack callback functions */
68 static int aubio_jack_process(jack_nframes_t nframes, void *arg);
69 static void aubio_jack_shutdown (void *arg);
70
71 aubio_jack_t * new_aubio_jack(uint_t ichan, uint_t ochan, 
72     aubio_process_func_t callback) {
73   aubio_jack_t * jack_setup = aubio_jack_alloc (ichan, ochan);
74   uint_t i;
75   char * client_name = "aubio";
76   char name[64];
77   /* initial jack client setup */
78   if ((jack_setup->client = jack_client_new (client_name)) == 0) {
79     AUBIO_ERR ("jack server not running?\n");
80     AUBIO_QUIT(AUBIO_FAIL);
81   }
82
83   /* set callbacks */
84   jack_set_process_callback (jack_setup->client, aubio_jack_process, 
85       (void*) jack_setup);
86   jack_on_shutdown (jack_setup->client, aubio_jack_shutdown, 
87       (void*) jack_setup);
88
89   /* register jack output ports */
90   for (i = 0; i < ochan; i++) 
91   {
92     AUBIO_SPRINTF(name, "out_%d", i+1);
93     AUBIO_MSG("%s\n", name);
94     if ((jack_setup->oports[i] = 
95           jack_port_register (jack_setup->client, name, 
96             JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == 0) 
97     {
98       AUBIO_ERR("failed registering output port \"%s\"!\n", name);
99       jack_client_close (jack_setup->client);
100       AUBIO_QUIT(AUBIO_FAIL);
101     }
102   }
103
104   /* register jack input ports */
105   for (i = 0; i < ichan; i++) 
106   {
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     {
113       AUBIO_ERR("failed registering input port \"%s\"!\n", name);
114       jack_client_close (jack_setup->client);
115       AUBIO_QUIT(AUBIO_FAIL);
116     }
117   }
118
119   /* set processing callback */
120   jack_setup->callback = callback;
121   return jack_setup;
122 }
123
124 uint_t aubio_jack_activate(aubio_jack_t *jack_setup) {
125   /* get sample rate */
126   jack_setup->samplerate = jack_get_sample_rate (jack_setup->client);
127   /* actual jack process activation */
128   if (jack_activate (jack_setup->client)) 
129   {
130     AUBIO_ERR("jack client activation failed");
131     return 1;
132   }
133   return 0;
134 }
135
136 void aubio_jack_close(aubio_jack_t *jack_setup) {
137   /* bug : should disconnect all ports first */
138   jack_client_close(jack_setup->client);
139   aubio_jack_free(jack_setup);
140 }
141
142 /* memory management */
143 static aubio_jack_t * aubio_jack_alloc(uint_t ichan, uint_t ochan) {
144   aubio_jack_t *jack_setup = AUBIO_NEW(aubio_jack_t);
145   jack_setup->ichan = ichan;
146   jack_setup->ochan = ochan;
147   jack_setup->oports = AUBIO_ARRAY(jack_port_t*, ichan); 
148   jack_setup->iports = AUBIO_ARRAY(jack_port_t*, ochan); 
149   jack_setup->ibufs  = AUBIO_ARRAY(jack_sample_t*, ichan); 
150   jack_setup->obufs  = AUBIO_ARRAY(jack_sample_t*, ochan); 
151 #ifdef AUBIO_JACK_NEEDS_CONVERSION 
152   jack_setup->sibufs = AUBIO_ARRAY(smpl_t*, ichan); 
153   uint_t i;
154   for (i = 0; i < ichan; i++) {
155     jack_setup->sibufs[i] = AUBIO_ARRAY(smpl_t, AUBIO_JACK_MAX_FRAMES);
156   }
157   jack_setup->sobufs = AUBIO_ARRAY(smpl_t*, ochan); 
158   for (i = 0; i < ochan; i++) {
159     jack_setup->sobufs[i] = AUBIO_ARRAY(smpl_t, AUBIO_JACK_MAX_FRAMES);
160   }
161 #endif
162   return jack_setup;
163 }
164
165 static uint_t aubio_jack_free(aubio_jack_t * jack_setup) {
166   AUBIO_FREE(jack_setup->oports);
167   AUBIO_FREE(jack_setup->iports);
168   AUBIO_FREE(jack_setup->ibufs );
169   AUBIO_FREE(jack_setup->obufs );
170   AUBIO_FREE(jack_setup);
171   return AUBIO_OK;
172 }
173
174 /* jack callback functions */
175 static void aubio_jack_shutdown (void *arg UNUSED){
176   AUBIO_ERR("jack shutdown\n");
177   AUBIO_QUIT(AUBIO_OK);
178 }
179
180 static int aubio_jack_process(jack_nframes_t nframes, void *arg) {
181   aubio_jack_t* dev = (aubio_jack_t *)arg;
182   uint_t i;
183   for (i=0;i<dev->ichan;i++) { 
184     /* get readable input */
185     dev->ibufs[i] = 
186       (jack_sample_t *) jack_port_get_buffer (dev->iports[i], nframes);
187     /* get writable output */
188     dev->obufs[i] = 
189       (jack_sample_t *) jack_port_get_buffer (dev->oports[i], nframes);
190   }
191 #ifndef AUBIO_JACK_NEEDS_CONVERSION
192   dev->callback(dev->ibufs,dev->obufs,nframes);
193 #else
194   uint_t j;
195   for (j = 0; j < MIN(nframes, AUBIO_JACK_MAX_FRAMES); j++) {
196     for (i = 0; i < dev->ichan; i++) { 
197       dev->sibufs[i][j] = (smpl_t)dev->ibufs[i][j];
198     }
199   }
200   dev->callback(dev->sibufs, dev->sobufs, nframes);
201   for (j = 0; j < MIN(nframes, AUBIO_JACK_MAX_FRAMES); j++) {
202     for (i = 0; i < dev->ichan; i++) { 
203       dev->obufs[i][j] = (jack_sample_t)dev->sobufs[i][j];
204     }
205   }
206 #endif
207   return 0;
208 }
209
210
211 #endif /* HAVE_JACK */