ref: 3822b73d67375f4a25d241ae8120c090887cd3a4
dir: /ext/jackio.c/
/*
Copyright (C) 2003 Paul Brossier
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "config.h"
#ifdef JACK_SUPPORT
#include <jack/jack.h>
#include "aubio_priv.h"
#include "jackio.h"
/*typedef jack_default_audio_sample_t jack_sample_t; */
/* work with float, never tried in double */
typedef smpl_t jack_sample_t;
/**
* jack device structure
*/
struct _aubio_jack_t {
/** jack client */
jack_client_t *client;
/** jack output ports */
jack_port_t **oports;
/** jack input ports */
jack_port_t **iports;
/** jack input buffer */
jack_sample_t **ibufs;
/** jack output buffer */
jack_sample_t **obufs;
/** jack input channels */
uint_t ichan;
/** jack output channels */
uint_t ochan;
/** jack samplerate (Hz) */
uint_t samplerate;
/** jack processing function */
aubio_process_func_t callback;
};
/* static memory management */
static aubio_jack_t * aubio_jack_alloc(uint_t ichan, uint_t ochan);
static uint_t aubio_jack_free(aubio_jack_t * jack_setup);
/* jack callback functions */
static int aubio_jack_process(jack_nframes_t nframes, void *arg);
static void aubio_jack_shutdown (void *arg);
aubio_jack_t * new_aubio_jack(uint_t ichan, uint_t ochan,
aubio_process_func_t callback) {
aubio_jack_t * jack_setup = aubio_jack_alloc (ichan, ochan);
uint_t i;
char * client_name = "aubio";
char name[64];
/* initial jack client setup */
if ((jack_setup->client = jack_client_new (client_name)) == 0) {
AUBIO_ERR ("jack server not running?\n");
AUBIO_QUIT(AUBIO_FAIL);
}
/* set callbacks */
jack_set_process_callback (jack_setup->client, aubio_jack_process,
(void*) jack_setup);
jack_on_shutdown (jack_setup->client, aubio_jack_shutdown,
(void*) jack_setup);
/* register jack output ports */
for (i = 0; i < ochan; i++)
{
AUBIO_SPRINTF(name, "out_%d", i+1);
AUBIO_MSG("%s\n", name);
if ((jack_setup->oports[i] =
jack_port_register (jack_setup->client, name,
JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) == 0)
{
AUBIO_ERR("failed registering output port \"%s\"!\n", name);
jack_client_close (jack_setup->client);
AUBIO_QUIT(AUBIO_FAIL);
}
}
/* register jack input ports */
for (i = 0; i < ichan; i++)
{
AUBIO_SPRINTF(name, "in_%d", i+1);
AUBIO_MSG("%s\n", name);
if ((jack_setup->iports[i] =
jack_port_register (jack_setup->client, name,
JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0)
{
AUBIO_ERR("failed registering input port \"%s\"!\n", name);
jack_client_close (jack_setup->client);
AUBIO_QUIT(AUBIO_FAIL);
}
}
/* set processing callback */
jack_setup->callback = callback;
return jack_setup;
}
uint_t aubio_jack_activate(aubio_jack_t *jack_setup) {
/* get sample rate */
jack_setup->samplerate = jack_get_sample_rate (jack_setup->client);
/* actual jack process activation */
if (jack_activate (jack_setup->client))
{
AUBIO_ERR("jack client activation failed");
return 1;
}
return 0;
}
void aubio_jack_close(aubio_jack_t *jack_setup) {
/* bug : should disconnect all ports first */
jack_client_close(jack_setup->client);
aubio_jack_free(jack_setup);
}
/* memory management */
static aubio_jack_t * aubio_jack_alloc(uint_t ichan, uint_t ochan) {
aubio_jack_t *jack_setup = AUBIO_NEW(aubio_jack_t);
jack_setup->ichan = ichan;
jack_setup->ochan = ochan;
jack_setup->oports = AUBIO_ARRAY(jack_port_t*, ichan);
jack_setup->iports = AUBIO_ARRAY(jack_port_t*, ochan);
jack_setup->ibufs = AUBIO_ARRAY(jack_sample_t*, ichan);
jack_setup->obufs = AUBIO_ARRAY(jack_sample_t*, ochan);
return jack_setup;
}
static uint_t aubio_jack_free(aubio_jack_t * jack_setup) {
AUBIO_FREE(jack_setup->oports);
AUBIO_FREE(jack_setup->iports);
AUBIO_FREE(jack_setup->ibufs );
AUBIO_FREE(jack_setup->obufs );
AUBIO_FREE(jack_setup);
return AUBIO_OK;
}
/* jack callback functions */
static void aubio_jack_shutdown (void *arg UNUSED){
AUBIO_ERR("jack shutdown\n");
AUBIO_QUIT(AUBIO_OK);
}
static int aubio_jack_process(jack_nframes_t nframes, void *arg) {
aubio_jack_t* dev = (aubio_jack_t *)arg;
uint_t i;
for (i=0;i<dev->ichan;i++) {
/* get readable input */
dev->ibufs[i] =
(jack_sample_t *) jack_port_get_buffer (dev->iports[i], nframes);
/* get writable output */
dev->obufs[i] =
(jack_sample_t *) jack_port_get_buffer (dev->oports[i], nframes);
}
dev->callback(dev->ibufs,dev->obufs,nframes);
return 0;
}
#endif /* JACK_SUPPORT */