git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@3337 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.8
| @@ -23,6 +23,10 @@ Michael Voigt | |||||
| Jackdmp changes log | Jackdmp changes log | ||||
| --------------------------- | --------------------------- | ||||
| 2009-02-24 Stephane Letz <letz@grame.fr> | |||||
| * New libjacknet library with net.h and JackNetAPI.cpp files. New netmaster.c and netmaster.c examples. | |||||
| 2009-02-23 Stephane Letz <letz@grame.fr> | 2009-02-23 Stephane Letz <letz@grame.fr> | ||||
| * Another fix in systemdeps.h and types.h: jack_time_t now uniquely defined in types.h. | * Another fix in systemdeps.h and types.h: jack_time_t now uniquely defined in types.h. | ||||
| @@ -0,0 +1,300 @@ | |||||
| /* | |||||
| Copyright (C) 2009 Grame | |||||
| This program is free software; you can redistribute it and/or modify | |||||
| it under the terms of the GNU Lesser General Public License as published by | |||||
| the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. | |||||
| You should have received a copy of the GNU Lesser General Public License | |||||
| along with this program; if not, write to the Free Software | |||||
| Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||||
| */ | |||||
| #ifndef __net_h__ | |||||
| #define __net_h__ | |||||
| #ifdef __cplusplus | |||||
| extern "C" | |||||
| { | |||||
| #endif | |||||
| #include <jack/systemdeps.h> | |||||
| #include <jack/types.h> | |||||
| #define DEFAULT_MULTICAST_IP "225.3.19.154" | |||||
| #define DEFAULT_PORT 19000 | |||||
| #define DEFAULT_MTU 1500 | |||||
| #define MASTER_NAME_SIZE 256 | |||||
| #define SOCKET_ERROR -1 | |||||
| enum JackNetMode { | |||||
| JackFastMode = 'f', | |||||
| JackNormalMode = 'n', | |||||
| JackSlowMode = 's', | |||||
| }; | |||||
| typedef struct { | |||||
| int audio_input; | |||||
| int audio_output; | |||||
| int midi_input; | |||||
| int midi_ouput; | |||||
| int mtu; | |||||
| int time_out; // in millisecond, -1 means in infinite | |||||
| char mode; | |||||
| } jack_slave_t; | |||||
| typedef struct { | |||||
| jack_nframes_t buffer_size; | |||||
| jack_nframes_t sample_rate; | |||||
| char master_name[MASTER_NAME_SIZE]; | |||||
| } jack_master_t; | |||||
| /** | |||||
| * jack_net_t is an opaque type. You may only access it using the | |||||
| * API provided. | |||||
| */ | |||||
| typedef struct _jack_net_slave jack_net_slave_t; | |||||
| /** | |||||
| * Open a network connection with the master machine. | |||||
| * @param ip the multicast address of the master | |||||
| * @param port the connection port | |||||
| * @param request a connection request structure | |||||
| * @param result a connection result structure | |||||
| * | |||||
| * @return Opaque net handle if successful or NULL in case of error. | |||||
| */ | |||||
| jack_net_slave_t* jack_net_slave_open(const char* ip, int port, const char* name, jack_slave_t* request, jack_master_t* result); | |||||
| /** | |||||
| * Close the network connection with the master machine. | |||||
| * @param net the network connection to be closed | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_net_slave_close(jack_net_slave_t* net); | |||||
| /** | |||||
| * Prototype for Process callback. | |||||
| * @param nframes buffer size | |||||
| * @param audio_input number of audio inputs | |||||
| * @param audio_input_buffer an array of audio input buffers | |||||
| * @param midi_input number of MIDI inputs | |||||
| * @param midi_input_buffer an array of MIDI input buffers | |||||
| * @param audio_output number of audio outputs | |||||
| * @param audio_output_buffer an array of audio output buffers | |||||
| * @param midi_output number of MIDI outputs | |||||
| * @param midi_output_buffer an array of MIDI output buffers | |||||
| * @param arg pointer to a client supplied structure supplied by jack_set_net_process_callback(). | |||||
| * | |||||
| * @return zero on success, non-zero on error | |||||
| */ | |||||
| typedef int (* JackNetSlaveProcessCallback) (jack_nframes_t buffer_size, | |||||
| int audio_input, | |||||
| float** audio_input_buffer, | |||||
| int midi_input, | |||||
| void** midi_input_buffer, | |||||
| int audio_output, | |||||
| float** audio_output_buffer, | |||||
| int midi_output, | |||||
| void** midi_output_buffer, | |||||
| void* data); | |||||
| /** | |||||
| * Set network process callback. | |||||
| * @param net the network connection | |||||
| * @param net_callback the process callback | |||||
| * @param arg pointer to a client supplied structure | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_set_net_slave_process_callback(jack_net_slave_t * net, JackNetSlaveProcessCallback net_callback, void *arg); | |||||
| /** | |||||
| * Start processing thread, the net_callback will start to be called. | |||||
| * @param net the network connection | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_net_slave_activate(jack_net_slave_t* net); | |||||
| /** | |||||
| * Stop processing thread. | |||||
| * @param net the network connection | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_net_slave_deactivate(jack_net_slave_t* net); | |||||
| /** | |||||
| * Prototype for BufferSize callback. | |||||
| * @param nframes buffer size | |||||
| * @param arg pointer to a client supplied structure supplied by jack_set_net_buffer_size_callback(). | |||||
| * | |||||
| * @return zero on success, non-zero on error | |||||
| */ | |||||
| typedef int (*JackNetSlaveBufferSizeCallback)(jack_nframes_t nframes, void *arg); | |||||
| /** | |||||
| * Prototype for SampleRate callback | |||||
| * @param nframes sample rate | |||||
| * @param arg pointer to a client supplied structure supplied by jack_set_net_sample_rate_callback(). | |||||
| * | |||||
| * @return zero on success, non-zero on error | |||||
| */ | |||||
| typedef int (*JackNetSlaveSampleRateCallback)(jack_nframes_t nframes, void *arg); | |||||
| /** | |||||
| * Set network buffer size callback. | |||||
| * @param net the network connection | |||||
| * @param bufsize_callback the buffer size callback | |||||
| * @param arg pointer to a client supplied structure | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_set_net_slave_buffer_size_callback(jack_net_slave_t *net, JackNetSlaveBufferSizeCallback bufsize_callback, void *arg); | |||||
| /** | |||||
| * Set network sample rate callback. | |||||
| * @param net the network connection | |||||
| * @param samplerate_callback the sample rate callback | |||||
| * @param arg pointer to a client supplied structure | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_set_net_slave_sample_rate_callback(jack_net_slave_t *net, JackNetSlaveSampleRateCallback samplerate_callback, void *arg); | |||||
| /** | |||||
| * Prototype for server Shutdown callback (if not set, the client will just restart, waiting for an available master again.) | |||||
| * @param arg pointer to a client supplied structure supplied by jack_set_net_shutdown_callback(). | |||||
| */ | |||||
| typedef void (*JackNetSlaveShutdownCallback)(void* data); | |||||
| /** | |||||
| * Set network shutdown callback. | |||||
| * @param net the network connection | |||||
| * @param shutdown_callback the shutdown callback | |||||
| * @param arg pointer to a client supplied structure | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_set_net_slave_shutdown_callback(jack_net_slave_t *net, JackNetSlaveShutdownCallback shutdown_callback, void *arg); | |||||
| /** | |||||
| * jack_net_t is an opaque type. You may only access it using the | |||||
| * API provided. | |||||
| */ | |||||
| typedef struct _jack_net_master jack_net_master_t; | |||||
| /** | |||||
| * Open a network connection with the slave machine. | |||||
| * @param ip the multicast address of the master | |||||
| * @param port the connection port | |||||
| * @param request a connection request structure | |||||
| * @param result a connection result structure | |||||
| * | |||||
| * @return Opaque net handle if successful or NULL in case of error. | |||||
| */ | |||||
| jack_net_master_t* jack_net_master_open(const char* ip, int port, const char* name, jack_master_t* request, jack_slave_t* result); | |||||
| /** | |||||
| * Close the network connection with the master machine. | |||||
| * @param net the network connection to be closed | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_net_master_close(jack_net_master_t* net); | |||||
| /** | |||||
| * Receive sync and data from the network | |||||
| * @param net the network connection | |||||
| * @param audio_input number of audio inputs | |||||
| * @param audio_input_buffer an array of audio input buffers | |||||
| * @param midi_input number of MIDI inputs | |||||
| * @param midi_input_buffer an array of MIDI input buffers | |||||
| * | |||||
| * @return zero on success, non-zero on error | |||||
| */ | |||||
| int jack_net_master_recv(jack_net_master_t* net, int audio_input, float** audio_input_buffer, int midi_input, void** midi_input_buffer); | |||||
| /** | |||||
| * Send sync and data to the network | |||||
| * @param net the network connection | |||||
| * @param audio_output number of audio ouputs | |||||
| * @param audio_output_buffer an array of audio output buffers | |||||
| * @param midi_output number of MIDI ouputs | |||||
| * @param midi_output_buffer an array of MIDI output buffers | |||||
| * | |||||
| * @return zero on success, non-zero on error | |||||
| */ | |||||
| int jack_net_master_send(jack_net_master_t* net, int audio_output, float** audio_output_buffer, int midi_output, void** midi_output_buffer); | |||||
| // Experimental Adapter API | |||||
| /** | |||||
| * jack_adapter_t is an opaque type. You may only access it using the | |||||
| * API provided. | |||||
| */ | |||||
| typedef struct _jack_adapter jack_adapter_t; | |||||
| /** | |||||
| * Create an adapter. | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| jack_adapter_t* jack_create_adapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate); | |||||
| /** | |||||
| * Destroy an adapter. | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_destroy_adapter(jack_adapter_t* adapter); | |||||
| /** | |||||
| * Push input to ringbuffer | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_adapter_push_input(jack_adapter_t * adapter, int channels, float** buffers); | |||||
| /** | |||||
| * Pull input from ringbuffer | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_adapter_pull_input(jack_adapter_t * adapter, int channels, float** buffers); | |||||
| /** | |||||
| * Push output to ringbuffer | |||||
| * | |||||
| * @return error code. | |||||
| */ | |||||
| int jack_adapter_push_output(jack_adapter_t * adapter, int channels, float** buffers); | |||||
| /** | |||||
| * Pull output from ringbuffer | |||||
| * | |||||
| * @return 0 on success, otherwise a non-zero error code | |||||
| */ | |||||
| int jack_adapter_pull_output(jack_adapter_t * adapter, int channels, float** buffers); | |||||
| #ifdef __cplusplus | |||||
| } | |||||
| #endif | |||||
| #endif /* __net_h__ */ | |||||
| @@ -173,6 +173,31 @@ def build(bld): | |||||
| if bld.env['IS_SUN']: | if bld.env['IS_SUN']: | ||||
| serverlib.env.append_value("LINKFLAGS", "-lnsl -lsocket") | serverlib.env.append_value("LINKFLAGS", "-lnsl -lsocket") | ||||
| netlib = bld.new_task_gen('cxx', 'shlib') | |||||
| netlib.features.append('cc') | |||||
| netlib.defines = ['HAVE_CONFIG_H','SERVER_SIDE'] | |||||
| netlib.includes = includes | |||||
| netlib.name = 'netlib' | |||||
| netlib.target = 'jacknet' | |||||
| netlib.uselib = uselib | |||||
| netlib.install_path = '${LIBDIR}' | |||||
| netlib.source = ['JackNetAPI.cpp', 'JackNetInterface.cpp', 'JackNetTool.cpp', 'JackAudioAdapterInterface.cpp', 'JackResampler.cpp', 'ringbuffer.c'] | |||||
| if bld.env['IS_LINUX']: | |||||
| netlib.source += ['./posix/JackNetUnixSocket.cpp','./posix/JackPosixThread.cpp'] | |||||
| netlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||||
| if bld.env['IS_SUN']: | |||||
| netlib.source += ['./posix/JackNetUnixSocket.cpp','./posix/JackPosixThread.cpp'] | |||||
| netlib.env.append_value("CPPFLAGS", "-fvisibility=hidden") | |||||
| if bld.env['IS_MACOSX']: | |||||
| netlib.source += ['../posix/JackNetUnixSocket.cpp','../posix/JackPosixThread.cpp', '../macosx/JackMachThread.cpp', '../macosx/JackMachTime.c'] | |||||
| netlib.env.append_value("LINKFLAGS", "-framework CoreAudio -single_module") | |||||
| netlib.vnum = bld.env['JACK_API_VERSION'] | |||||
| clientlib = bld.new_task_gen('cxx', 'shlib') | clientlib = bld.new_task_gen('cxx', 'shlib') | ||||
| clientlib.features.append('cc') | clientlib.features.append('cc') | ||||
| clientlib.defines = 'HAVE_CONFIG_H' | clientlib.defines = 'HAVE_CONFIG_H' | ||||
| @@ -0,0 +1,165 @@ | |||||
| /* | |||||
| Copyright (C) 2009 Grame | |||||
| 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 <stdlib.h> | |||||
| #include <stdio.h> | |||||
| #include <errno.h> | |||||
| #ifndef WIN32 | |||||
| #include <unistd.h> | |||||
| #endif | |||||
| #include <math.h> | |||||
| #include <signal.h> | |||||
| #include <getopt.h> | |||||
| #include <string.h> | |||||
| #include <jack/net.h> | |||||
| jack_net_master_t* net; | |||||
| #define BUFFER_SIZE 512 | |||||
| #define SAMPLE_RATE 44100 | |||||
| static void signal_handler(int sig) | |||||
| { | |||||
| jack_net_master_close(net); | |||||
| fprintf(stderr, "signal received, exiting ...\n"); | |||||
| exit(0); | |||||
| } | |||||
| static void | |||||
| usage () | |||||
| { | |||||
| fprintf (stderr, "\n" | |||||
| "usage: jack_net_master \n" | |||||
| " [ -b buffer size (default = %d) ]\n" | |||||
| " [ -r sample rate (default = %d) ]\n" | |||||
| " [ -a hostname (default = %s) ]\n" | |||||
| " [ -p port (default = %d) ]\n", BUFFER_SIZE, SAMPLE_RATE, DEFAULT_MULTICAST_IP, DEFAULT_PORT); | |||||
| } | |||||
| int | |||||
| main (int argc, char *argv[]) | |||||
| { | |||||
| int buffer_size = BUFFER_SIZE; | |||||
| int sample_rate = SAMPLE_RATE; | |||||
| int port = DEFAULT_PORT; | |||||
| char* multicast_ip = DEFAULT_MULTICAST_IP; | |||||
| const char *options = "b:r:a:p:"; | |||||
| int option_index; | |||||
| int opt; | |||||
| struct option long_options[] = | |||||
| { | |||||
| {"buffer size", 1, 0, 'b'}, | |||||
| {"sample rate", 1, 0, 'r'}, | |||||
| {"hostname", 1, 0, 'a'}, | |||||
| {"port", 1, 0, 'p'}, | |||||
| {0, 0, 0, 0} | |||||
| }; | |||||
| while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { | |||||
| switch (opt) { | |||||
| case 'b': | |||||
| buffer_size = atoi(optarg); | |||||
| break; | |||||
| case 'r': | |||||
| sample_rate = atoi(optarg); | |||||
| break; | |||||
| case 'a': | |||||
| multicast_ip = strdup(optarg); | |||||
| break; | |||||
| case 'p': | |||||
| port = atoi(optarg); | |||||
| break; | |||||
| case 'h': | |||||
| usage(); | |||||
| return -1; | |||||
| } | |||||
| } | |||||
| int i; | |||||
| jack_master_t request = { buffer_size, sample_rate, "master" }; | |||||
| jack_slave_t result; | |||||
| float** audio_input_buffer; | |||||
| float** audio_output_buffer; | |||||
| int wait_usec = (int) ((((float)buffer_size) * 1000000) / ((float)sample_rate)); | |||||
| printf("Waiting for a slave...\n"); | |||||
| if ((net = jack_net_master_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_master", &request, &result)) == 0) { | |||||
| fprintf(stderr, "jack server not running?\n"); | |||||
| return 1; | |||||
| } | |||||
| /* install a signal handler to properly quits jack client */ | |||||
| #ifdef WIN32 | |||||
| signal(SIGINT, signal_handler); | |||||
| signal(SIGABRT, signal_handler); | |||||
| signal(SIGTERM, signal_handler); | |||||
| #else | |||||
| signal(SIGQUIT, signal_handler); | |||||
| signal(SIGTERM, signal_handler); | |||||
| signal(SIGHUP, signal_handler); | |||||
| signal(SIGINT, signal_handler); | |||||
| #endif | |||||
| // Allocate buffers | |||||
| audio_input_buffer = calloc(result.audio_input, sizeof(float*)); | |||||
| for (i = 0; i < result.audio_input; i++) { | |||||
| audio_input_buffer[i] = calloc(buffer_size, sizeof(float)); | |||||
| } | |||||
| audio_output_buffer = calloc(result.audio_output, sizeof(float*)); | |||||
| for (i = 0; i < result.audio_output; i++) { | |||||
| audio_output_buffer[i] = calloc(buffer_size, sizeof(float)); | |||||
| } | |||||
| // Run until interrupted | |||||
| while (1) { | |||||
| // Copy input to output | |||||
| for (i = 0; i < result.audio_input; i++) { | |||||
| memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); | |||||
| } | |||||
| jack_net_master_send(net, result.audio_output, audio_output_buffer, 0, NULL); | |||||
| jack_net_master_recv(net, result.audio_input, audio_input_buffer, 0, NULL); | |||||
| usleep(wait_usec); | |||||
| }; | |||||
| // Wait for application end | |||||
| jack_net_master_close(net); | |||||
| for (i = 0; i < result.audio_input; i++) { | |||||
| free(audio_input_buffer[i]); | |||||
| } | |||||
| free(audio_input_buffer); | |||||
| for (i = 0; i < result.audio_output; i++) { | |||||
| free(audio_output_buffer[i]); | |||||
| } | |||||
| free(audio_output_buffer); | |||||
| exit (0); | |||||
| } | |||||
| @@ -0,0 +1,160 @@ | |||||
| /* | |||||
| Copyright (C) 2009 Grame | |||||
| 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 <stdlib.h> | |||||
| #include <stdio.h> | |||||
| #include <errno.h> | |||||
| #ifndef WIN32 | |||||
| #include <unistd.h> | |||||
| #endif | |||||
| #include <math.h> | |||||
| #include <signal.h> | |||||
| #include <getopt.h> | |||||
| #include <string.h> | |||||
| #include <jack/net.h> | |||||
| jack_net_slave_t* net; | |||||
| static void signal_handler(int sig) | |||||
| { | |||||
| jack_net_slave_close(net); | |||||
| fprintf(stderr, "signal received, exiting ...\n"); | |||||
| exit(0); | |||||
| } | |||||
| static void | |||||
| usage () | |||||
| { | |||||
| fprintf (stderr, "\n" | |||||
| "usage: jack_net_slave \n" | |||||
| " [ -C capture channels (default = 2)]\n" | |||||
| " [ -P playback channels (default = 2) ]\n" | |||||
| " [ -a hostname (default = %s) ]\n" | |||||
| " [ -p port (default = %d)]\n", DEFAULT_MULTICAST_IP, DEFAULT_PORT); | |||||
| } | |||||
| static int net_process(jack_nframes_t buffer_size, | |||||
| int audio_input, | |||||
| float** audio_input_buffer, | |||||
| int midi_input, | |||||
| void** midi_input_buffer, | |||||
| int audio_output, | |||||
| float** audio_output_buffer, | |||||
| int midi_output, | |||||
| void** midi_output_buffer, | |||||
| void* data) | |||||
| { | |||||
| int i; | |||||
| // Copy input to output | |||||
| for (i = 0; i < audio_input; i++) { | |||||
| memcpy(audio_output_buffer[i], audio_input_buffer[i], buffer_size * sizeof(float)); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| int | |||||
| main (int argc, char *argv[]) | |||||
| { | |||||
| int audio_input = 2; | |||||
| int audio_output = 2; | |||||
| int port = DEFAULT_PORT; | |||||
| char* multicast_ip = DEFAULT_MULTICAST_IP; | |||||
| const char *options = "C:P:a:p:"; | |||||
| int option_index; | |||||
| int opt; | |||||
| struct option long_options[] = | |||||
| { | |||||
| {"audio input", 1, 0, 'C'}, | |||||
| {"audio output", 1, 0, 'P'}, | |||||
| {"hostname", 1, 0, 'a'}, | |||||
| {"port", 1, 0, 'p'}, | |||||
| {0, 0, 0, 0} | |||||
| }; | |||||
| while ((opt = getopt_long (argc, argv, options, long_options, &option_index)) != EOF) { | |||||
| switch (opt) { | |||||
| case 'C': | |||||
| audio_input = atoi(optarg); | |||||
| break; | |||||
| case 'P': | |||||
| audio_output = atoi(optarg); | |||||
| break; | |||||
| case 'a': | |||||
| multicast_ip = strdup(optarg); | |||||
| break; | |||||
| case 'p': | |||||
| port = atoi(optarg); | |||||
| break; | |||||
| case 'h': | |||||
| usage(); | |||||
| return -1; | |||||
| } | |||||
| } | |||||
| jack_slave_t request = { audio_input, audio_output, 0, 0, DEFAULT_MTU, -1, JackSlowMode }; | |||||
| jack_master_t result; | |||||
| printf("Waiting for a master...\n"); | |||||
| if ((net = jack_net_slave_open(DEFAULT_MULTICAST_IP, DEFAULT_PORT, "net_slave", &request, &result)) == 0) { | |||||
| fprintf(stderr, "jack server not running?\n"); | |||||
| return 1; | |||||
| } | |||||
| jack_set_net_slave_process_callback(net, net_process, NULL); | |||||
| if (jack_net_slave_activate(net) != 0) { | |||||
| fprintf(stderr, "Cannot sactivate client\n"); | |||||
| return 1; | |||||
| } | |||||
| /* install a signal handler to properly quits jack client */ | |||||
| #ifdef WIN32 | |||||
| signal(SIGINT, signal_handler); | |||||
| signal(SIGABRT, signal_handler); | |||||
| signal(SIGTERM, signal_handler); | |||||
| #else | |||||
| signal(SIGQUIT, signal_handler); | |||||
| signal(SIGTERM, signal_handler); | |||||
| signal(SIGHUP, signal_handler); | |||||
| signal(SIGINT, signal_handler); | |||||
| #endif | |||||
| /* run until interrupted */ | |||||
| while (1) { | |||||
| #ifdef WIN32 | |||||
| Sleep(1000); | |||||
| #else | |||||
| sleep(1); | |||||
| #endif | |||||
| }; | |||||
| // Wait for application end | |||||
| jack_net_slave_deactivate(net); | |||||
| jack_net_slave_close(net); | |||||
| exit (0); | |||||
| } | |||||
| @@ -21,6 +21,8 @@ example_programs = { | |||||
| 'jack_thru' : 'thru_client.c', | 'jack_thru' : 'thru_client.c', | ||||
| 'jack_cpu_load' : 'cpu_load.c', | 'jack_cpu_load' : 'cpu_load.c', | ||||
| 'jack_server_control' : 'server_control.cpp', | 'jack_server_control' : 'server_control.cpp', | ||||
| 'jack_net_slave' : 'netslave.c', | |||||
| 'jack_net_master' : 'netmaster.c', | |||||
| } | } | ||||
| example_libs = { | example_libs = { | ||||
| @@ -69,8 +71,13 @@ def build(bld): | |||||
| prog.env.append_value("LINKFLAGS", "-lm") | prog.env.append_value("LINKFLAGS", "-lm") | ||||
| if example_program == 'jack_server_control': | if example_program == 'jack_server_control': | ||||
| prog.uselib_local = 'serverlib' | prog.uselib_local = 'serverlib' | ||||
| elif example_program == 'jack_net_slave': | |||||
| prog.uselib_local = 'netlib' | |||||
| elif example_program == 'jack_net_master': | |||||
| prog.uselib_local = 'netlib' | |||||
| else: | else: | ||||
| prog.uselib_local = 'clientlib' | |||||
| prog.uselib_local = 'clientlib' | |||||
| prog.target = example_program | prog.target = example_program | ||||
| #if bld.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] | #if bld.env['BUILD_EXAMPLE_CLIENT_TRANSPORT'] | ||||