2476adc7a09d3d67787b2357c5f718e8d06d8091
[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 "config.h"
21 #ifdef JACK_SUPPORT
22 #include <jack/jack.h>
23 #include "aubio_priv.h"
24 #include "jackio.h"
25
26 /*typedef jack_default_audio_sample_t jack_sample_t; */
27 /* work with float, never tried in double */
28 typedef smpl_t jack_sample_t;
29
30 /**
31  * jack device structure 
32  */
33 struct _aubio_jack_t {
34   /** jack client */
35   jack_client_t *client;
36   /** jack output ports */
37   jack_port_t **oports;
38   /** jack input ports */
39   jack_port_t **iports;
40   /** jack input buffer */
41   jack_sample_t **ibufs;
42   /** jack output buffer */
43   jack_sample_t **obufs;
44   /** jack input channels */
45   uint_t ichan;
46   /** jack output channels */
47   uint_t ochan;
48   /** jack samplerate (Hz) */
49   uint_t samplerate;
50   /** jack processing function */
51   aubio_process_func_t callback; 
52 };
53
54 /* static memory management */
55 static aubio_jack_t * aubio_jack_alloc(uint_t ichan, uint_t ochan);
56 static uint_t aubio_jack_free(aubio_jack_t * jack_setup);
57 /* jack callback functions */
58 static int aubio_jack_process(jack_nframes_t nframes, void *arg);
59 static void aubio_jack_shutdown (void *arg);
60
61 aubio_jack_t * new_aubio_jack(uint_t ichan, uint_t ochan, 
62     aubio_process_func_t callback) {
63   aubio_jack_t * jack_setup = aubio_jack_alloc (ichan, ochan);
64   uint_t i;
65   char * client_name = "aubio";
66   char name[64];
67   /* initial jack client setup */
68   if ((jack_setup->client = jack_client_new (client_name)) == 0) {
69     AUBIO_ERR ("jack server not running?\n");
70     AUBIO_QUIT(AUBIO_FAIL);
71   }
72
73   /* set callbacks */
74   jack_set_process_callback (jack_setup->client, aubio_jack_process, 
75       (void*) jack_setup);
76   jack_on_shutdown (jack_setup->client, aubio_jack_shutdown, 
77       (void*) jack_setup);
78
79   /* register jack output ports */
80   for (i = 0; i < ochan; i++) 
81   {
82     AUBIO_SPRINTF(name, "out_%d", i+1);
83     AUBIO_MSG("%s\n", name);
84     if ((jack_setup->oports[i] = 
85           jack_port_register (jack_setup->client, name, 
86             JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == 0) 
87     {
88       AUBIO_ERR("failed registering output port \"%s\"!\n", name);
89       jack_client_close (jack_setup->client);
90       AUBIO_QUIT(AUBIO_FAIL);
91     }
92   }
93
94   /* register jack input ports */
95   for (i = 0; i < ichan; i++) 
96   {
97     AUBIO_SPRINTF(name, "in_%d", i+1);
98     AUBIO_MSG("%s\n", name);
99     if ((jack_setup->iports[i] = 
100           jack_port_register (jack_setup->client, name, 
101             JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0)
102     {
103       AUBIO_ERR("failed registering input port \"%s\"!\n", name);
104       jack_client_close (jack_setup->client);
105       AUBIO_QUIT(AUBIO_FAIL);
106     }
107   }
108
109   /* set processing callback */
110   jack_setup->callback = callback;
111   return jack_setup;
112 }
113
114 uint_t aubio_jack_activate(aubio_jack_t *jack_setup) {
115   /* get sample rate */
116   jack_setup->samplerate = jack_get_sample_rate (jack_setup->client);
117   /* actual jack process activation */
118   if (jack_activate (jack_setup->client)) 
119   {
120     AUBIO_ERR("jack client activation failed");
121     return 1;
122   }
123   return 0;
124 }
125
126 void aubio_jack_close(aubio_jack_t *jack_setup) {
127   /* bug : should disconnect all ports first */
128   jack_client_close(jack_setup->client);
129   aubio_jack_free(jack_setup);
130 }
131
132 /* memory management */
133 static aubio_jack_t * aubio_jack_alloc(uint_t ichan, uint_t ochan) {
134   aubio_jack_t *jack_setup = AUBIO_NEW(aubio_jack_t);
135   jack_setup->ichan = ichan;
136   jack_setup->ochan = ochan;
137   jack_setup->oports = AUBIO_ARRAY(jack_port_t*, ichan); 
138   jack_setup->iports = AUBIO_ARRAY(jack_port_t*, ochan); 
139   jack_setup->ibufs  = AUBIO_ARRAY(jack_sample_t*, ichan); 
140   jack_setup->obufs  = AUBIO_ARRAY(jack_sample_t*, ochan); 
141   return jack_setup;
142 }
143
144 static uint_t aubio_jack_free(aubio_jack_t * jack_setup) {
145   AUBIO_FREE(jack_setup->oports);
146   AUBIO_FREE(jack_setup->iports);
147   AUBIO_FREE(jack_setup->ibufs );
148   AUBIO_FREE(jack_setup->obufs );
149   AUBIO_FREE(jack_setup);
150   return AUBIO_OK;
151 }
152
153 /* jack callback functions */
154 static void aubio_jack_shutdown (void *arg UNUSED){
155   AUBIO_ERR("jack shutdown\n");
156   AUBIO_QUIT(AUBIO_OK);
157 }
158
159 static int aubio_jack_process(jack_nframes_t nframes, void *arg) {
160   aubio_jack_t* dev = (aubio_jack_t *)arg;
161   uint_t i;
162   for (i=0;i<dev->ichan;i++) { 
163     /* get readable input */
164     dev->ibufs[i] = 
165       (jack_sample_t *) jack_port_get_buffer (dev->iports[i], nframes);
166     /* get writable output */
167     dev->obufs[i] = 
168       (jack_sample_t *) jack_port_get_buffer (dev->oports[i], nframes);
169   }
170   dev->callback(dev->ibufs,dev->obufs,nframes);
171   return 0;
172 }
173
174
175 #endif /* JACK_SUPPORT */