// -----------------------------------------------------------------------------
//
//  Copyright (C) 2006-2018 Fons Adriaensen <fons@linuxaudio.org>
//
//  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, see <http://www.gnu.org/licenses/>.
//
// -----------------------------------------------------------------------------


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <jack/jack.h>


#define MAXCHAN 16

static jack_client_t  *jack_handle;
static jack_port_t    *jack_capt [MAXCHAN];
static jack_port_t    *jack_play [MAXCHAN];
static bool            active = false;
static int             nchan = 0;


int jack_callback (jack_nframes_t nframes, void *arg)
{
    int   i;
    float *ip, *op;

    if (! active) return 0;
    for (i = 0; i < nchan; i++)
    {
        ip = (float *)(jack_port_get_buffer (jack_capt [i], nframes));
        op = (float *)(jack_port_get_buffer (jack_play [i], nframes));
	memcpy (op, ip, nframes * sizeof (float));
    }
    return 0;
}


static void sigint_handler (int)
{
    signal (SIGINT, SIG_IGN);
    active = false;
}


int main (int ac, char *av [])
{
    int            i;
    char           s [16];
    const char    *name;
    jack_status_t  stat;

    if (ac < 2)
    {
	fprintf (stderr, "jack_proxy  <nchan> [<name>]\n");
	return 1;
    }
    nchan = atoi (av [1]);
    if (nchan < 1) return 1;
    if (nchan > MAXCHAN) nchan = MAXCHAN;
    if (ac > 2)	name = av [2];
    else name = "jack_proxy";
    
    jack_handle = jack_client_open (name, JackNoStartServer, &stat);
    if (jack_handle == 0)
    {
        fprintf (stderr, "Can't connect to Jack, is the server running ?\n");
        return 1;
    }

    jack_set_process_callback (jack_handle, jack_callback, 0);
    if (jack_activate (jack_handle))
    {
        fprintf(stderr, "Can't activate Jack");
        return 1;
    }

    for (i = 0; i < nchan; i++)
    {
	sprintf (s, "in_%d", i);
        jack_capt [i] = jack_port_register (jack_handle, s,  JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
	sprintf (s, "out_%d", i);
        jack_play [i] = jack_port_register (jack_handle, s, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
    }

    signal (SIGINT, sigint_handler);
    active = true;
    while (active)
    {
	usleep (250000);
    }

    jack_deactivate (jack_handle);
    jack_client_close (jack_handle);
    return 0;
}

