Пример #1
0
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;
}
Пример #2
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);
}
Пример #3
0
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;
}
Пример #4
0
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);
}
Пример #5
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);
}
Пример #6
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;
}