int jack_initialize (jack_client_t *client, const char* load_init) { struct a2j* self = calloc(1, sizeof(struct a2j)); if (!self) { return -1; } self->jack_client = client; self->input = 1; self->ignore_hardware_ports = 0; self->finishing = 0; if (load_init) { char* args = strdup (load_init); char* token; char* ptr = args; char* savep; while (1) { if ((token = strtok_r (ptr, ", ", &savep)) == NULL) { break; } if (strncasecmp (token, "in", 2) == 0) { self->input = 1; } if (strncasecmp (token, "out", 2) == 0) { self->input = 0; } if (strncasecmp (token, "hw", 2) == 0) { self->ignore_hardware_ports = 0; } ptr = NULL; } free (args); } if (connect_to_alsa (self)) { free (self); return -1; } jack_set_process_callback (client, a2j_process, self); jack_set_freewheel_callback (client, a2j_freewheel, NULL); jack_on_shutdown (client, a2j_shutdown, NULL); jack_activate (client); return 0; }
void gojack_generic_callback_sync_destroy(struct gojack_generic_callback_sync *sync) { jack_set_freewheel_callback(sync->client, NULL, NULL); jack_set_buffer_size_callback(sync->client, NULL, NULL); jack_set_sample_rate_callback(sync->client, NULL, NULL); jack_set_client_registration_callback(sync->client, NULL, NULL); jack_set_port_registration_callback(sync->client, NULL, NULL); jack_set_port_connect_callback(sync->client, NULL, NULL); jack_set_port_rename_callback(sync->client, NULL, NULL); jack_set_graph_order_callback(sync->client, NULL, NULL); jack_set_xrun_callback(sync->client, NULL, NULL); jack_set_latency_callback(sync->client, NULL, NULL); cgo_callback_sync_destroy(sync->base); pthread_mutex_destroy(&sync->lock); free(sync); }
struct gojack_generic_callback_sync * gojack_generic_callback_sync_create(jack_client_t *client) { struct gojack_generic_callback_sync *sync = (struct gojack_generic_callback_sync *) malloc(sizeof(struct gojack_generic_callback_sync)); void *arg = (void *) sync; sync->base = cgo_callback_sync_create(); cgo_callback_sync_set_log_callback(sync->base, &handle_log, NULL); pthread_mutex_init(&sync->lock, NULL); sync->client = client; jack_set_freewheel_callback(client, &handle_freewheel, arg); jack_set_buffer_size_callback(client, &handle_buffer_size, arg); //jack_set_sample_rate_callback(client, &handle_sample_rate, arg); jack_set_client_registration_callback(client, &handle_client_registration, arg); jack_set_port_registration_callback(client, &handle_port_registration, arg); jack_set_port_connect_callback(client, &handle_port_connect, arg); jack_set_port_rename_callback(client, &handle_port_rename, arg); jack_set_graph_order_callback(client, &handle_graph_order, arg); jack_set_xrun_callback(client, &handle_xrun, arg); //jack_set_latency_callback(client, &handle_latency, arg); return sync; }
int main (int argc, char *argv[]) { /* Some startup related basics */ char *client_name, *server_name = NULL, *peer_ip; int peer_port = 3000; jack_options_t options = JackNullOption; jack_status_t status; #ifdef WIN32 WSADATA wsa; int rc = WSAStartup(MAKEWORD(2, 0), &wsa); #endif /* Torben's famous state variables, aka "the reporting API" ! */ /* heh ? these are only the copies of them ;) */ int statecopy_connected, statecopy_latency, statecopy_netxruns; jack_nframes_t net_period; /* Argument parsing stuff */ extern char *optarg; extern int optind, optopt; int errflg = 0, c; if (argc < 3) { printUsage (); return 1; } client_name = (char *) malloc (sizeof (char) * 10); peer_ip = (char *) malloc (sizeof (char) * 10); sprintf(client_name, "netjack"); sprintf(peer_ip, "localhost"); while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:P:")) != -1) { switch (c) { case 'h': printUsage(); exit (0); break; case 'H': free(peer_ip); peer_ip = (char *) malloc (sizeof (char) * strlen (optarg) + 1); strcpy (peer_ip, optarg); break; case 'o': playback_channels_audio = atoi (optarg); break; case 'i': capture_channels_audio = atoi (optarg); break; case 'O': playback_channels_midi = atoi (optarg); break; case 'I': capture_channels_midi = atoi (optarg); break; case 'n': latency = atoi (optarg); break; case 'p': peer_port = atoi (optarg); break; case 'r': reply_port = atoi (optarg); break; case 'B': bind_port = atoi (optarg); break; case 'f': factor = atoi (optarg); printf("This feature is deprecated and will be removed in future netjack versions. CELT offers a superiour way to conserve bandwidth"); break; case 'b': bitdepth = atoi (optarg); break; case 'c': #if HAVE_CELT bitdepth = 1000; factor = atoi (optarg); #else printf( "not built with celt support\n" ); exit(10); #endif break; case 'P': #if HAVE_OPUS bitdepth = 999; factor = atoi (optarg); #else printf( "not built with opus support\n" ); exit(10); #endif break; case 'm': mtu = atoi (optarg); break; case 'R': redundancy = atoi (optarg); break; case 'e': dont_htonl_floats = 1; break; case 'N': free(client_name); client_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1); strcpy (client_name, optarg); break; case 's': server_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1); strcpy (server_name, optarg); options |= JackServerName; break; case ':': fprintf (stderr, "Option -%c requires an operand\n", optopt); errflg++; break; case '?': fprintf (stderr, "Unrecognized option: -%c\n", optopt); errflg++; } } if (errflg) { printUsage (); exit (2); } capture_channels = capture_channels_audio + capture_channels_midi; playback_channels = playback_channels_audio + playback_channels_midi; outsockfd = socket (AF_INET, SOCK_DGRAM, 0); insockfd = socket (AF_INET, SOCK_DGRAM, 0); if ((outsockfd == -1) || (insockfd == -1)) { fprintf (stderr, "cant open sockets\n" ); return 1; } init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port); if (bind_port) { init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port); if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) { fprintf (stderr, "bind failure\n" ); } } if (reply_port) { init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port); if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) { fprintf (stderr, "bind failure\n" ); } } /* try to become a client of the JACK server */ client = jack_client_open (client_name, options, &status, server_name); if (client == NULL) { fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n" "Is the JACK server running ?\n", status); return 1; } /* Set up jack callbacks */ jack_set_process_callback (client, process, 0); jack_set_sync_callback (client, sync_cb, 0); jack_set_freewheel_callback (client, freewheel_cb, 0); jack_on_shutdown (client, jack_shutdown, 0); alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi); if( bitdepth == 1000 || bitdepth == 999) net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ; else net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor); int rx_bufsize = get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header); packcache = packet_cache_new (latency + 50, rx_bufsize, mtu); /* tell the JACK server that we are ready to roll */ if (jack_activate (client)) { fprintf (stderr, "Cannot activate client"); return 1; } /* Now sleep forever... and evaluate the state_ vars */ signal( SIGTERM, sigterm_handler ); signal( SIGINT, sigterm_handler ); statecopy_connected = 2; // make it report unconnected on start. statecopy_latency = state_latency; statecopy_netxruns = state_netxruns; while ( !quit ) { #ifdef WIN32 Sleep (1000); #else sleep(1); #endif if (statecopy_connected != state_connected) { statecopy_connected = state_connected; if (statecopy_connected) { state_netxruns = 1; // We want to reset the netxrun count on each new connection printf ("Connected :-)\n"); } else printf ("Not Connected\n"); fflush(stdout); } if (statecopy_connected) { if (statecopy_netxruns != state_netxruns) { statecopy_netxruns = state_netxruns; printf ("%s: at frame %06d -> total netxruns %d (%d%%) queue time= %d\n", client_name, state_currentframe, statecopy_netxruns, 100 * statecopy_netxruns / state_currentframe, state_recv_packet_queue_time); fflush(stdout); } } else { if (statecopy_latency != state_latency) { statecopy_latency = state_latency; if (statecopy_latency > 1) printf ("current latency %d\n", statecopy_latency); fflush(stdout); } } } jack_client_close (client); packet_cache_free (packcache); exit (0); }
int main (int argc, char *argv[]) { char jack_name[30] = "alsa_out"; char alsa_device[30] = "hw:0"; extern char *optarg; extern int optind, optopt; int errflg=0; int c; while ((c = getopt(argc, argv, "ivj:r:c:p:n:d:q:m:t:f:F:C:Q:s:")) != -1) { switch(c) { case 'j': strcpy(jack_name,optarg); break; case 'r': sample_rate = atoi(optarg); break; case 'c': num_channels = atoi(optarg); break; case 'p': period_size = atoi(optarg); break; case 'n': num_periods = atoi(optarg); break; case 'd': strcpy(alsa_device,optarg); break; case 't': target_delay = atoi(optarg); break; case 'q': samplerate_quality = atoi(optarg); break; case 'm': max_diff = atoi(optarg); break; case 'f': catch_factor = atoi(optarg); break; case 'F': catch_factor2 = atoi(optarg); break; case 'C': pclamp = (double) atoi(optarg); break; case 'Q': controlquant = (double) atoi(optarg); break; case 'v': verbose = 1; break; case 'i': instrument = 1; break; case 's': smooth_size = atoi(optarg); break; case ':': fprintf(stderr, "Option -%c requires an operand\n", optopt); errflg++; break; case '?': fprintf(stderr, "Unrecognized option: -%c\n", optopt); errflg++; } } if (errflg) { printUsage(); exit(2); } if( (samplerate_quality < 0) || (samplerate_quality > 4) ) { fprintf (stderr, "invalid samplerate quality\n"); return 1; } if ((client = jack_client_open (jack_name, 0, NULL)) == 0) { fprintf (stderr, "jack server not running?\n"); return 1; } /* tell the JACK server to call `process()' whenever there is work to be done. */ jack_set_process_callback (client, process, 0); /* tell the JACK server to call `freewheel()' whenever freewheel mode changes. */ jack_set_freewheel_callback (client, freewheel, 0); /* tell the JACK server to call `jack_shutdown()' if it ever shuts down, either entirely, or if it just decides to stop calling us. */ jack_on_shutdown (client, jack_shutdown, 0); if (jack_set_latency_callback) jack_set_latency_callback (client, latency_cb, 0); // get jack sample_rate jack_sample_rate = jack_get_sample_rate( client ); if( !sample_rate ) sample_rate = jack_sample_rate; static_resample_factor = (double) sample_rate / (double) jack_sample_rate; resample_lower_limit = static_resample_factor * 0.25; resample_upper_limit = static_resample_factor * 4.0; resample_mean = static_resample_factor; offset_array = malloc( sizeof(double) * smooth_size ); if( offset_array == NULL ) { fprintf( stderr, "no memory for offset_array !!!\n" ); exit(20); } window_array = malloc( sizeof(double) * smooth_size ); if( window_array == NULL ) { fprintf( stderr, "no memory for window_array !!!\n" ); exit(20); } int i; for( i=0; i<smooth_size; i++ ) { offset_array[i] = 0.0; window_array[i] = hann( (double) i / ((double) smooth_size - 1.0) ); } jack_buffer_size = jack_get_buffer_size( client ); // Setup target delay and max_diff for the normal user, who does not play with them... if( !target_delay ) target_delay = (num_periods*period_size / 2) - jack_buffer_size/2; if( !max_diff ) max_diff = target_delay; if( max_diff > target_delay ) { fprintf( stderr, "target_delay (%d) cant be smaller than max_diff(%d)\n", target_delay, max_diff ); exit(20); } if( (target_delay+max_diff) > (num_periods*period_size) ) { fprintf( stderr, "target_delay+max_diff (%d) cant be bigger than buffersize(%d)\n", target_delay+max_diff, num_periods*period_size ); exit(20); } // now open the alsa fd... alsa_handle = open_audiofd( alsa_device, 0, sample_rate, num_channels, period_size, num_periods); if( alsa_handle == 0 ) exit(20); printf( "selected sample format: %s\n", formats[format].name ); // alloc input ports, which are blasted out to alsa... alloc_ports( 0, num_channels ); outbuf = malloc( num_periods * period_size * formats[format].sample_size * num_channels ); resampbuf = malloc( num_periods * period_size * sizeof( float ) ); tmpbuf = malloc( 512 * formats[format].sample_size * num_channels ); if ((outbuf == NULL) || (resampbuf == NULL) || (tmpbuf == NULL)) { fprintf( stderr, "no memory for buffers.\n" ); exit(20); } /* tell the JACK server that we are ready to roll */ if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); return 1; } signal( SIGTERM, sigterm_handler ); signal( SIGINT, sigterm_handler ); if( verbose ) { while(!quit) { usleep(500000); if( output_new_delay ) { printf( "delay = %d\n", output_new_delay ); output_new_delay = 0; } printf( "res: %f, \tdiff = %f, \toffset = %f \n", output_resampling_factor, output_diff, output_offset ); } } else if( instrument ) { printf( "# n\tresamp\tdiff\toffseti\tintegral\n"); int n=0; while(!quit) { usleep(1000); printf( "%d\t%f\t%f\t%f\t%f\n", n++, output_resampling_factor, output_diff, output_offset, output_integral ); } } else { while(!quit) { usleep(500000); if( output_new_delay ) { printf( "delay = %d\n", output_new_delay ); output_new_delay = 0; } } } jack_deactivate( client ); jack_client_close (client); exit (0); }
static void openJackStreams(RtJackGlobals *p) { char buf[256]; int i, j, k; CSOUND *csound = p->csound; /* connect to JACK server */ p->client = jack_client_open(&(p->clientName[0]), JackNoStartServer, NULL); if (UNLIKELY(p->client == NULL)) rtJack_Error(csound, -1, Str("could not connect to JACK server")); csound->system_sr(csound, jack_get_sample_rate(p->client)); csound->Message(csound, "system sr: %f\n", csound->system_sr(csound,0)); /* check consistency of parameters */ if (UNLIKELY(p->nChannels < 1 || p->nChannels > 255)) rtJack_Error(csound, -1, Str("invalid number of channels")); if (UNLIKELY(p->sampleRate < 1000 || p->sampleRate > 768000)) rtJack_Error(csound, -1, Str("invalid sample rate")); if (UNLIKELY(p->sampleRate != (int) jack_get_sample_rate(p->client))) { snprintf(&(buf[0]), 256, Str("sample rate %d does not match " "JACK sample rate %d"), p->sampleRate, (int) jack_get_sample_rate(p->client)); rtJack_Error(p->csound, -1, &(buf[0])); } if (UNLIKELY(p->bufSize < 8 || p->bufSize > 32768)) rtJack_Error(csound, -1, Str("invalid period size (-b)")); if (p->nBuffers < 2) p->nBuffers = 2; if (UNLIKELY((unsigned int) (p->nBuffers * p->bufSize) > (unsigned int) 65536)) rtJack_Error(csound, -1, Str("invalid buffer size (-B)")); if (UNLIKELY(((p->nBuffers - 1) * p->bufSize) < (int) jack_get_buffer_size(p->client))) rtJack_Error(csound, -1, Str("buffer size (-B) is too small")); /* register ports */ rtJack_RegisterPorts(p); /* allocate ring buffers if not done yet */ if (p->bufs == NULL) rtJack_AllocateBuffers(p); /* initialise ring buffers */ p->csndBufCnt = 0; p->csndBufPos = 0; p->jackBufCnt = 0; p->jackBufPos = 0; for (i = 0; i < p->nBuffers; i++) { rtJack_TryLock(p->csound, &(p->bufs[i]->csndLock)); rtJack_Unlock(p->csound, &(p->bufs[i]->jackLock)); for (j = 0; j < p->nChannels; j++) { if (p->inputEnabled) { for (k = 0; k < p->bufSize; k++) p->bufs[i]->inBufs[j][k] = (jack_default_audio_sample_t) 0; } if (p->outputEnabled) { for (k = 0; k < p->bufSize; k++) p->bufs[i]->outBufs[j][k] = (jack_default_audio_sample_t) 0; } } } /* output port buffer pointer cache is invalid initially */ if (p->outputEnabled) p->outPortBufs[0] = (jack_default_audio_sample_t*) NULL; /* register callback functions */ if (UNLIKELY(jack_set_sample_rate_callback(p->client, sampleRateCallback, (void*) p) != 0)) rtJack_Error(csound, -1, Str("error setting sample rate callback")); if (UNLIKELY(jack_set_buffer_size_callback(p->client, bufferSizeCallback, (void*) p) != 0)) rtJack_Error(csound, -1, Str("error setting buffer size callback")); #ifdef LINUX if (UNLIKELY(jack_set_freewheel_callback(p->client, freeWheelCallback, (void*) p) != 0)) rtJack_Error(csound, -1, Str("error setting freewheel callback")); #endif if (UNLIKELY(jack_set_xrun_callback(p->client, xrunCallback, (void*) p) != 0)) rtJack_Error(csound, -1, Str("error setting xrun callback")); jack_on_shutdown(p->client, shutDownCallback, (void*) p); if (UNLIKELY(jack_set_process_callback(p->client, processCallback, (void*) p) != 0)) rtJack_Error(csound, -1, Str("error setting process callback")); /* activate client */ if (UNLIKELY(jack_activate(p->client) != 0)) rtJack_Error(csound, -1, Str("error activating JACK client")); /* connect ports if requested */ if (p->inputEnabled) { char dev[128], *dev_final, *sp; { int i,n = listDevices(csound,NULL,0); CS_AUDIODEVICE *devs = (CS_AUDIODEVICE *) malloc(n*sizeof(CS_AUDIODEVICE)); listDevices(csound,devs,0); for(i=0; i < n; i++) csound->Message(csound, " %d: %s (%s)\n", i, devs[i].device_id, devs[i].device_name); strncpy(dev, devs[0].device_name, 128); free(devs); } if(p->inDevName != NULL) { strncpy(dev, p->inDevName, 128); dev[127]='\0'; } //if (dev) { dev_final = dev; sp = strchr(dev_final, '\0'); if (!isalpha(dev_final[0])) dev_final++; for (i = 0; i < p->nChannels; i++) { snprintf(sp, 128-(dev-sp), "%d", i + 1); if (UNLIKELY(jack_connect(p->client, dev_final, jack_port_name(p->inPorts[i])) != 0)) { //rtJack_Error(csound, -1, Str("error connecting input ports")); csound->Warning(csound, Str("not autoconnecting input channel %d \n" "(needs manual connection)"), i+1); } } *sp = (char) 0; //} } if (p->outputEnabled) { char dev[128], *dev_final, *sp; { int i,n = listDevices(csound,NULL,1); CS_AUDIODEVICE *devs = (CS_AUDIODEVICE *) malloc(n*sizeof(CS_AUDIODEVICE)); listDevices(csound,devs,1); for(i=0; i < n; i++) csound->Message(csound, " %d: %s (%s)\n", i, devs[i].device_id, devs[i].device_name); strncpy(dev, devs[0].device_name, 128); free(devs); } if (p->outDevName != NULL) { strncpy(dev, p->outDevName, 128); dev[127]='\0'; } //if (dev) { this test is rubbish dev_final = dev; sp = strchr(dev_final, '\0'); if(!isalpha(dev_final[0])) dev_final++; for (i = 0; i < p->nChannels; i++) { snprintf(sp, 128-(dev-sp), "%d", i + 1); if (jack_connect(p->client, jack_port_name(p->outPorts[i]), dev_final) != 0) { //rtJack_Error(csound, -1, Str("error connecting output ports")); csound->Warning(csound, Str("not autoconnecting input channel %d \n" "(needs manual connection)"), i+1); } } *sp = (char) 0; } /* stream is now active */ p->jackState = 0; }