コード例 #1
0
ファイル: midi_latency_test.c プロジェクト: Andux/jack2
int
main(int argc, char **argv)
{
    int jitter_plot[101];
    int latency_plot[101];
    int long_index = 0;
    struct option long_options[] = {
        {"help", 0, NULL, 'h'},
        {"message-size", 1, NULL, 'm'},
        {"samples", 1, NULL, 's'},
        {"timeout", 1, NULL, 't'}
    };
    size_t name_arg_count;
    size_t name_size;
    char *option_string = "hm:s:t:";
    int show_usage = 0;
    connections_established = 0;
    error_message = NULL;
    message_size = 3;
    program_name = argv[0];
    remote_in_port = 0;
    remote_out_port = 0;
    samples = 1024;
    timeout = 5;

    for (;;) {
        signed char c = getopt_long(argc, argv, option_string, long_options,
                             &long_index);
        switch (c) {
        case 'h':
            show_usage = 1;
            break;
        case 'm':
            message_size = parse_positive_number_arg(optarg, "message-size");
            break;
        case 's':
            samples = parse_positive_number_arg(optarg, "samples");
            break;
        case 't':
            timeout = parse_positive_number_arg(optarg, "timeout");
            break;
        default:
            {
                char *s = "'- '";
                s[2] = c;
                die(s, "invalid switch");
            }
        case -1:
            if (show_usage) {
                output_usage();
                exit(EXIT_SUCCESS);
            }
            goto parse_port_names;
        case 1:
            /* end of switch :) */
            ;
        }
    }
 parse_port_names:
    name_arg_count = argc - optind;
    switch (name_arg_count) {
    case 2:
        target_in_port_name = argv[optind + 1];
        target_out_port_name = argv[optind];
        break;
    case 0:
        target_in_port_name = 0;
        target_out_port_name = 0;
        break;
    default:
        output_usage();
        return EXIT_FAILURE;
    }
    name_size = jack_port_name_size();
    alias1 = malloc(name_size * sizeof(char));
    if (alias1 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto show_error;
    }
    alias2 = malloc(name_size * sizeof(char));
    if (alias2 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_alias1;
    }
    latency_values = malloc(sizeof(jack_nframes_t) * samples);
    if (latency_values == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_alias2;
    }
    latency_time_values = malloc(sizeof(jack_time_t) * samples);
    if (latency_time_values == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_latency_values;
    }
    message_1 = malloc(message_size * sizeof(jack_midi_data_t));
    if (message_1 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_latency_time_values;
    }
    message_2 = malloc(message_size * sizeof(jack_midi_data_t));
    if (message_2 == NULL) {
        error_message = strerror(errno);
        error_source = "malloc";
        goto free_message_1;
    }
    switch (message_size) {
    case 1:
        message_1[0] = 0xf6;
        message_2[0] = 0xfe;
        break;
    case 2:
        message_1[0] = 0xc0;
        message_1[1] = 0x00;
        message_2[0] = 0xd0;
        message_2[1] = 0x7f;
        break;
    case 3:
        message_1[0] = 0x80;
        message_1[1] = 0x00;
        message_1[2] = 0x00;
        message_2[0] = 0x90;
        message_2[1] = 0x7f;
        message_2[2] = 0x7f;
        break;
    default:
        message_1[0] = 0xf0;
        memset(message_1 + 1, 0,
               (message_size - 2) * sizeof(jack_midi_data_t));
        message_1[message_size - 1] = 0xf7;
        message_2[0] = 0xf0;
        memset(message_2 + 1, 0x7f,
               (message_size - 2) * sizeof(jack_midi_data_t));
        message_2[message_size - 1] = 0xf7;
    }
    client = jack_client_open(program_name, JackNullOption, NULL);
    if (client == NULL) {
        error_message = "failed to open JACK client";
        error_source = "jack_client_open";
        goto free_message_2;
    }
    in_port = jack_port_register(client, "in", JACK_DEFAULT_MIDI_TYPE,
                                 JackPortIsInput, 0);
    if (in_port == NULL) {
        error_message = "failed to register MIDI-in port";
        error_source = "jack_port_register";
        goto close_client;
    }
    out_port = jack_port_register(client, "out", JACK_DEFAULT_MIDI_TYPE,
                                  JackPortIsOutput, 0);
    if (out_port == NULL) {
        error_message = "failed to register MIDI-out port";
        error_source = "jack_port_register";
        goto unregister_in_port;
    }
    if (jack_set_process_callback(client, handle_process, NULL)) {
        error_message = "failed to set process callback";
        error_source = "jack_set_process_callback";
        goto unregister_out_port;
    }
    if (jack_set_xrun_callback(client, handle_xrun, NULL)) {
        error_message = "failed to set xrun callback";
        error_source = "jack_set_xrun_callback";
        goto unregister_out_port;
    }
    if (jack_set_port_connect_callback(client, handle_port_connection_change,
                                       NULL)) {
        error_message = "failed to set port connection callback";
        error_source = "jack_set_port_connect_callback";
        goto unregister_out_port;
    }
    jack_on_shutdown(client, handle_shutdown, NULL);
    jack_set_info_function(handle_info);
    process_state = 0;

    connect_semaphore = create_semaphore(0);
    if (connect_semaphore == NULL) {
        error_message = get_semaphore_error();
        error_source = "create_semaphore";
        goto unregister_out_port;
    }
    init_semaphore = create_semaphore(1);
    if (init_semaphore == NULL) {
        error_message = get_semaphore_error();
        error_source = "create_semaphore";
        goto destroy_connect_semaphore;;
    }
    process_semaphore = create_semaphore(2);
    if (process_semaphore == NULL) {
        error_message = get_semaphore_error();
        error_source = "create_semaphore";
        goto destroy_init_semaphore;
    }
    if (jack_activate(client)) {
        error_message = "could not activate client";
        error_source = "jack_activate";
        goto destroy_process_semaphore;
    }
    if (name_arg_count) {
        if (jack_connect(client, jack_port_name(out_port),
                         target_out_port_name)) {
            error_message = "could not connect MIDI out port";
            error_source = "jack_connect";
            goto deactivate_client;
        }
        if (jack_connect(client, target_in_port_name,
                         jack_port_name(in_port))) {
            error_message = "could not connect MIDI in port";
            error_source = "jack_connect";
            goto deactivate_client;
        }
    }
    if (! register_signal_handler(handle_signal)) {
        error_message = strerror(errno);
        error_source = "register_signal_handler";
        goto deactivate_client;
    }
    printf("Waiting for connections ...\n");
    if (wait_semaphore(connect_semaphore, 1) == -1) {
        error_message = get_semaphore_error();
        error_source = "wait_semaphore";
        goto deactivate_client;
    }
    if (connections_established) {
        printf("Waiting for test completion ...\n\n");
        if (wait_semaphore(process_semaphore, 1) == -1) {
            error_message = get_semaphore_error();
            error_source = "wait_semaphore";
            goto deactivate_client;
        }
    }
    if (! register_signal_handler(SIG_DFL)) {
        error_message = strerror(errno);
        error_source = "register_signal_handler";
        goto deactivate_client;
    }
    if (process_state == 2) {
        double average_latency = ((double) total_latency) / samples;
        double average_latency_time = total_latency_time / samples;
        size_t i;
        double latency_plot_offset =
            floor(((double) lowest_latency_time) / 100.0) / 10.0;
        double sample_rate = (double) jack_get_sample_rate(client);
        jack_nframes_t total_jitter = 0;
        jack_time_t total_jitter_time = 0;
        for (i = 0; i <= 100; i++) {
            jitter_plot[i] = 0;
            latency_plot[i] = 0;
        }
        for (i = 0; i < samples; i++) {
            double latency_time_value = (double) latency_time_values[i];
            double latency_plot_time =
                (latency_time_value / 1000.0) - latency_plot_offset;
            double jitter_time = ABS(average_latency_time -
                                     latency_time_value);
            if (latency_plot_time >= 10.0) {
                (latency_plot[100])++;
            } else {
                (latency_plot[(int) (latency_plot_time * 10.0)])++;
            }
            if (jitter_time >= 10000.0) {
                (jitter_plot[100])++;
            } else {
                (jitter_plot[(int) (jitter_time / 100.0)])++;
            }
            total_jitter += ABS(average_latency -
                                ((double) latency_values[i]));
            total_jitter_time += jitter_time;
        }
        printf("Reported out-port latency: %.2f-%.2f ms (%u-%u frames)\n"
               "Reported in-port latency: %.2f-%.2f ms (%u-%u frames)\n"
               "Average latency: %.2f ms (%.2f frames)\n"
               "Lowest latency: %.2f ms (%u frames)\n"
               "Highest latency: %.2f ms (%u frames)\n"
               "Peak MIDI jitter: %.2f ms (%u frames)\n"
               "Average MIDI jitter: %.2f ms (%.2f frames)\n",
               (out_latency_range.min / sample_rate) * 1000.0,
               (out_latency_range.max / sample_rate) * 1000.0,
               out_latency_range.min, out_latency_range.max,
               (in_latency_range.min / sample_rate) * 1000.0,
               (in_latency_range.max / sample_rate) * 1000.0,
               in_latency_range.min, in_latency_range.max,
               average_latency_time / 1000.0, average_latency,
               lowest_latency_time / 1000.0, lowest_latency,
               highest_latency_time / 1000.0, highest_latency,
               (highest_latency_time - lowest_latency_time) / 1000.0,
               highest_latency - lowest_latency,
               (total_jitter_time / 1000.0) / samples,
               ((double) total_jitter) / samples);
        printf("\nJitter Plot:\n");
        for (i = 0; i < 100; i++) {
            if (jitter_plot[i]) {
                printf("%.1f - %.1f ms: %d\n", ((float) i) / 10.0,
                       ((float) (i + 1)) / 10.0, jitter_plot[i]);
            }
        }
        if (jitter_plot[100]) {
            printf("     > 10 ms: %d\n", jitter_plot[100]);
        }
        printf("\nLatency Plot:\n");
        for (i = 0; i < 100; i++) {
            if (latency_plot[i]) {
                printf("%.1f - %.1f ms: %d\n",
                       latency_plot_offset + (((float) i) / 10.0),
                       latency_plot_offset + (((float) (i + 1)) / 10.0),
                       latency_plot[i]);
            }
        }
        if (latency_plot[100]) {
            printf("     > %.1f ms: %d\n", latency_plot_offset + 10.0,
                   latency_plot[100]);
        }
    }
 deactivate_client:
    jack_deactivate(client);
    printf("\nMessages sent: %d\nMessages received: %d\n", messages_sent,
           messages_received);
    if (unexpected_messages) {
        printf("Unexpected messages received: %d\n", unexpected_messages);
    }
    if (xrun_count) {
        printf("Xruns: %d\n", xrun_count);
    }
 destroy_process_semaphore:
    destroy_semaphore(process_semaphore, 2);
 destroy_init_semaphore:
    destroy_semaphore(init_semaphore, 1);
 destroy_connect_semaphore:
    destroy_semaphore(connect_semaphore, 0);
 unregister_out_port:
    jack_port_unregister(client, out_port);
 unregister_in_port:
    jack_port_unregister(client, in_port);
 close_client:
    jack_client_close(client);
 free_message_2:
    free(message_2);
 free_message_1:
    free(message_1);
 free_latency_time_values:
    free(latency_time_values);
 free_latency_values:
    free(latency_values);
 free_alias2:
    free(alias2);
 free_alias1:
    free(alias1);
    if (error_message != NULL) {
    show_error:
        output_error(error_source, error_message);
        exit(EXIT_FAILURE);
    }
    return EXIT_SUCCESS;
}
コード例 #2
0
ファイル: radio.c プロジェクト: attente/radio
int
main (int   argc,
      char *argv[])
{
  jack_client_t *client = jack_client_open (CLIENT_NAME,
                                            JackNullOption,
                                            NULL);

  state data;

  data.input_port = jack_port_register (client,
                                        INPUT_NAME,
                                        JACK_DEFAULT_AUDIO_TYPE,
                                        JackPortIsInput,
                                        0);

  data.output_port = jack_port_register (client,
                                         OUTPUT_NAME,
                                         JACK_DEFAULT_AUDIO_TYPE,
                                         JackPortIsOutput,
                                         0);

  data.sample_rate = jack_get_sample_rate (client);
  data.block_size  = jack_get_buffer_size (client);
  data.block_count = (int)(WINDOW_SIZE * data.sample_rate / data.block_size);
  data.block_index = 0;

  int buffer_size = data.block_count * data.block_size;

  data.sample_data  = calloc (2 * buffer_size - data.block_size, sizeof (jack_sample_t));
  data.window_data  = malloc (buffer_size * sizeof (double));
  data.input_data   = fftw_malloc (buffer_size * sizeof (double));
  data.output_data  = fftw_malloc ((buffer_size / 2 + 1) * sizeof (fftw_complex));
  data.modulus_data = malloc ((buffer_size / 2 + 1) * sizeof (double));

  int i;

  for (i = 0; i < buffer_size; i++)
    data.window_data[i] = window (buffer_size, i);

  data.fft_object = fftw_plan_dft_r2c_1d (buffer_size, data.input_data, data.output_data, FFTW_MEASURE | FFTW_DESTROY_INPUT);

  jack_set_process_callback (client, process, &data);

  jack_activate (client);

  while (pause ());

  fftw_destroy_plan (data.fft_object);

  free (data.sample_data);
  free (data.window_data);
  fftw_free (data.input_data);
  fftw_free (data.output_data);
  free (data.modulus_data);

  jack_port_unregister (client, data.input_port);
  jack_port_unregister (client, data.output_port);

  jack_deactivate   (client);
  jack_client_close (client);

  return 0;
}
コード例 #3
0
RString RageSoundDriver_JACK::Init()
{
	jack_status_t status;
	RString error;

	// Open JACK client and call it "StepMania" or whatever
	client = jack_client_open(PRODUCT_FAMILY, JackNoStartServer, &status);
	if (client == NULL)
		return "Couldn't connect to JACK server";

	sample_rate = jack_get_sample_rate(client);
	LOG->Trace("JACK connected at %u Hz", sample_rate);

	// Start this before callbacks
	StartDecodeThread();

	// Set callback for processing audio
	if (jack_set_process_callback(client, ProcessTrampoline, this))
	{
		error = "Couldn't set JACK process callback";
		goto out_close;
	}

	if (jack_set_sample_rate_callback(client, SampleRateTrampoline, this))
	{
		error = "Couldn't set JACK sample-rate callback";
		goto out_close;
	}

	// TODO Set a jack_on_shutdown callback as well?  Probably just stop
	// caring about sound altogether if that happens.

	// Create output ports
	port_l = jack_port_register(client, "out_l", JACK_DEFAULT_AUDIO_TYPE,
			JackPortIsOutput, 0);
	if (port_l == NULL)
	{
		error = "Couldn't create JACK port out_l";
		goto out_close;
	}

	port_r = jack_port_register(client, "out_r", JACK_DEFAULT_AUDIO_TYPE,
			JackPortIsOutput, 0);
	if (port_r == NULL)
	{
		error = "Couldn't create JACK port out_r";
		goto out_unreg_l;
	}

	// Go!
	if (jack_activate(client))
	{
		error = "Couldn't activate JACK client";
		goto out_unreg_r;
	}

	error = ConnectPorts();
	if (!error.empty())
		// Eh. Not fatal. JACK *is* running and we successfully created
		// our source ports, so it's unlkely any other driver will
		// function.
		LOG->Warn( "RageSoundDriver_JACK: Couldn't connect ports: %s", error.c_str() );

	// Success!
	LOG->Trace("JACK sound driver started successfully");
	return RString();


	// Not success!
out_unreg_r:
	jack_port_unregister(client, port_r);
out_unreg_l:
	jack_port_unregister(client, port_l);
out_close:
	jack_client_close(client);
	client = NULL;
	return error;
}
コード例 #4
0
ファイル: main.c プロジェクト: 50m30n3/SO-KL5
int main( int argc, char *argv[] )
{
	jack_client_t *jackClient;

	snd_seq_t *seqport;
	struct pollfd *pfd;
	int npfd;
	snd_seq_event_t *midievent;
	int channel, midiport;
	
	int note, length, i, j, minpos;
	double freq, avg, vol, scale, min;
	double *tempstring;

	puts( "SO-KL5 v.1.2 by 50m30n3 2009-2011" );

	if( argc > 1 )
		channel = atoi( argv[1] );
	else
		channel = 0;

	signal( SIGINT, sig_exit );
	signal( SIGTERM, sig_exit );


	puts( "Connecting to Jack Audio Server" );
	
	jackClient = jack_client_open( "SO-KL5", JackNoStartServer, NULL );
	if( jackClient == NULL )
	{
		fputs( "Cannot connect to Jack Server\n", stderr );
		return 1;
	}

	jack_on_shutdown( jackClient, jack_shutdown, 0 );

	outport = jack_port_register( jackClient, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 );

	jack_set_process_callback( jackClient, process, 0 );

	samplerate = jack_get_sample_rate( jackClient );


	puts( "Initializing synth parameters" );

	sustain = 0;
	cutoff = 64;
	resonance = 100;
	attack = 64;
	volume = 100;

	fcutoff = (cutoff+5.0)/400.0;
	sattack = (attack+5.0)/800.0;
	freso = (resonance/160.0)*(1.0-fcutoff);
	ssustain = 0.6+pow( sustain/127.0, 0.4)*0.4;

	for( note=0; note<NUMNOTES; note++ )
	{
		freq = 440.0*pow( 2.0, (note+BASENOTE-69) / 12.0 );
		stringcutoff[note] = 0.5 + pow( (double)note / (double)NUMNOTES, 0.5 ) * 0.45;
		length = round( (double)samplerate / freq );
		stringlength[note] = length;
		strings[note] = malloc( length * sizeof( double ) );
		if( strings[note] == NULL )
		{
			fputs( "Error allocating memory\n", stderr );
			return 1;
		}
		
		for( i=0; i<length; i++ )
		{
			strings[note][i] = 0.0;
		}
		stringpos[note] = 0;
		status[note] = 0;
	}

	freq = 440.0*pow( 2.0, (BASENOTE-69) / 12.0 );
	length = (double)samplerate / freq;
	tempstring = malloc( length * sizeof( double ) );
	if( tempstring == NULL )
	{
		fputs( "Error allocating memory\n", stderr );
		return 1;
	}

	lpval = lplast = 0.0;

	jack_activate( jackClient );


	printf( "Listening on MIDI channel %i\n", channel );

	if( snd_seq_open( &seqport, "default", SND_SEQ_OPEN_INPUT, 0 ) < 0 )
	{
		fputs( "Cannot connect to ALSA sequencer\n", stderr );
		return 1;
	}

	snd_seq_set_client_name( seqport, "SO-KL5" );

	midiport = snd_seq_create_simple_port( seqport, "input",
		SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
		SND_SEQ_PORT_TYPE_APPLICATION );

	if( midiport < 0 )
	{
		fputs( "Cannot create ALSA sequencer port\n", stderr );
		return 1;
	}

	npfd = snd_seq_poll_descriptors_count( seqport, POLLIN );
	pfd = (struct pollfd *)malloc( npfd * sizeof( struct pollfd ) );
	snd_seq_poll_descriptors( seqport, pfd, npfd, POLLIN );


	done = 0;

	while( ! done )
	{
		if( poll( pfd, npfd, 100000 ) > 0 )
		{
			do
			{
				snd_seq_event_input( seqport, &midievent );
				
				if( ( midievent->type == SND_SEQ_EVENT_NOTEON ) && ( midievent->data.note.channel == channel ) )
				{
					note = midievent->data.note.note;
					if( ( note >= BASENOTE ) && ( note < BASENOTE+NUMNOTES ) )
					{
						note -= BASENOTE;

						status[note] = 1;

						for( i=0; i<stringlength[note]; i++ )
						{
							tempstring[i] = ((double)rand()/(double)RAND_MAX)*2.0-1.0;
						}

						freq = stringcutoff[note] * 0.25 + midievent->data.note.velocity/127.0 * 0.2 + sattack + 0.1;

						for( j=0; j<30; j++ )
						{
							tempstring[0] = tempstring[0]*freq + tempstring[stringlength[note]-1]*(1.0-freq);
							for( i=1; i<stringlength[note]; i++ )
							{
								tempstring[i] = tempstring[i]*freq + tempstring[(i-1)%stringlength[note]]*(1.0-freq);
							}
						}

						avg = 0.0;

						for( i=0; i<stringlength[note]; i++ )
						{
							avg += tempstring[i];
						}

						avg /= stringlength[note];

						scale = 0.0;

						for( i=0; i<stringlength[note]; i++ )
						{
							tempstring[i] -= avg;
							if( fabs( tempstring[i] ) > scale )
								scale = fabs( tempstring[i] );
						}

						min = 10.0;
						minpos = 0;

						for( i=0; i<stringlength[note]; i++ )
						{
							tempstring[i] /= scale;
							if( fabs( tempstring[i] ) + fabs( tempstring[i] - tempstring[i-1] ) * 5.0 < min )
							{
								min = fabs( tempstring[i] ) + fabs( tempstring[i] - tempstring[i-1] ) * 5.0;
								minpos = i;
							}
						}

						vol = midievent->data.note.velocity/256.0;

						for( i=0; i<stringlength[note]; i++ )
						{
							strings[note][(stringpos[note]+i)%stringlength[note]] += tempstring[(i+minpos)%stringlength[note]]*vol;
						}
					}
				}
				else if( ( midievent->type == SND_SEQ_EVENT_NOTEOFF ) && ( midievent->data.note.channel == channel ) )
				{
					note = midievent->data.note.note;
					if( ( note >= BASENOTE ) && ( note < BASENOTE+NUMNOTES ) )
					{
						note -= BASENOTE;
						status[note] = 0;
					}
				}
				else if( ( midievent->type == SND_SEQ_EVENT_CONTROLLER ) && ( midievent->data.control.channel == channel ) )
				{
					if( midievent->data.control.param == 74 )
					{
						cutoff = midievent->data.control.value;
						fcutoff = (cutoff+5.0)/400.0;
						printf( "Cutoff: %i     \r", cutoff );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 71 )
					{
						resonance = midievent->data.control.value;
						freso = (resonance/140.0)*(1.0-fcutoff);
						printf( "Resonance: %i     \r", resonance );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 73 )
					{
						attack = midievent->data.control.value;
						sattack = (attack+5.0)/800.0;
						printf( "Attack: %i     \r", attack );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 7 )
					{
						volume = midievent->data.control.value;
						printf( "Volume: %i     \r", volume );
						fflush( stdout );
					}
					else if( ( midievent->data.control.param == 64 ) || ( midievent->data.control.param == 1 ) )
					{
						sustain = midievent->data.control.value;
						ssustain = 0.6+pow( sustain/127.0, 0.4)*0.4;
						printf( "Sustain: %i    \r", sustain );
						fflush( stdout );
					}
				}
				
				snd_seq_free_event( midievent );
			}
			while( snd_seq_event_input_pending( seqport, 0 ) > 0 );
		}
	}

	free( pfd );
	snd_seq_delete_port( seqport, midiport );
	snd_seq_close( seqport );
	
	jack_deactivate( jackClient );

	puts( "Freeing data" );
	for( note=0; note<NUMNOTES; note++ )
	{
		free( strings[note] );
	}
	free( tempstring );

	jack_port_unregister( jackClient, outport );
	jack_client_close( jackClient );

	return 0;
}
コード例 #5
0
ファイル: jackaudio.cpp プロジェクト: Archer90/MuseScore
void JackAudio::unregisterPort(int port)
      {
      jack_port_unregister(client, ports[port]);
      ports[port] = 0;
      }
コード例 #6
0
ファイル: plugin.c プロジェクト: vpinon/mlt
void
plugin_destroy (plugin_t * plugin)
{
    unsigned long i, j;
    int err;

    /* destroy holders */
    for (i = 0; i < plugin->copies; i++)
    {
        if (plugin->descriptor->deactivate)
            plugin->descriptor->deactivate (plugin->holders[i].instance);

        /*      if (plugin->descriptor->cleanup)
                plugin->descriptor->cleanup (plugin->holders[i].instance); */

        if (plugin->desc->control_port_count > 0)
        {
            for (j = 0; j < plugin->desc->control_port_count; j++)
            {
                lff_free (plugin->holders[i].ui_control_fifos + j);
            }
            g_free (plugin->holders[i].ui_control_fifos);
            g_free (plugin->holders[i].control_memory);
        }

        if (plugin->desc->status_port_count > 0)
        {
            g_free (plugin->holders[i].status_memory);
        }

        /* aux ports */
        if (plugin->jack_rack->procinfo->jack_client && plugin->desc->aux_channels > 0)
        {
            for (j = 0; j < plugin->desc->aux_channels; j++)
            {
                err = jack_port_unregister (plugin->jack_rack->procinfo->jack_client,
                                            plugin->holders[i].aux_ports[j]);

                if (err)
                    mlt_log_warning( NULL, "%s: could not unregister jack port\n", __FUNCTION__);
            }

            g_free (plugin->holders[i].aux_ports);
        }
    }

    g_free (plugin->holders);

    for (i = 0; i < plugin->jack_rack->channels; i++)
    {
        g_free (plugin->audio_output_memory[i]);
        lff_free (plugin->wet_dry_fifos + i);
    }

    g_free (plugin->audio_output_memory);
    g_free (plugin->wet_dry_fifos);
    g_free (plugin->wet_dry_values);

    err = dlclose (plugin->dl_handle);
    if (err)
    {
        mlt_log_warning( NULL, "%s: error closing shared object '%s': %s\n",
                         __FUNCTION__, plugin->desc->object_file, dlerror ());
    }

    g_free (plugin);
}
コード例 #7
0
ファイル: main.c プロジェクト: 50m30n3/SO-666
int main( int argc, char *argv[] )
{
	jack_client_t *jackClient;

	snd_seq_t *seqport;
	struct pollfd *pfd;
	int npfd;
	snd_seq_event_t *midievent;
	int channel, midiport;
	
	int note, length, i;
	double freq;

	puts( "SO-666 v.1.01 by 50m30n3 2009-2010" );

	if( argc > 1 )
		channel = atoi( argv[1] );
	else
		channel = 0;

	signal( SIGINT, sig_exit );
	signal( SIGTERM, sig_exit );


	puts( "Connecting to Jack Audio Server" );
	
	jackClient = jack_client_open( "SO-666", JackNoStartServer, NULL );
	if( jackClient == NULL )
	{
		fputs( "Cannot connect to Jack Server\n", stderr );
		return 1;
	}

	jack_on_shutdown( jackClient, jack_shutdown, 0 );

	outport = jack_port_register( jackClient, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0 );

	jack_set_process_callback( jackClient, process, 0 );

	samplerate = jack_get_sample_rate( jackClient );


	puts( "Initializing synth parameters" );

	feedback = 32;
	cutoff = 64;
	resonance = 64;
	volume = 100;

	fcutoff = pow( (cutoff+50.0)/200.0, 5.0 );
	freso = resonance/127.0;
	ffeedback = 0.01+pow( feedback/127.0, 4.0)*0.9;

	for( note=0; note<NUMNOTES; note++ )
	{
		freq = 440.0*pow( 2.0, (note+BASENOTE-69) / 12.0 );
		//stringcutoff[note] = ( freq * 16.0 ) / (double)samplerate;
		stringcutoff[note] = 0.9;
		length = (double)samplerate / freq;
		stringlength[note] = length;
		strings[note] = malloc( length * sizeof( double ) );
		if( strings[note] == NULL )
		{
			fputs( "Error allocating memory\n", stderr );
			return 1;
		}
		
		for( i=0; i<length; i++ )
		{
			strings[note][i] = 0.0;
		}
		stringpos[note] = 0;
		status[note] = 0;
	}

	lpval = lplast = 0.0;
	hpval = hplast = 0.0;

	jack_activate( jackClient );


	printf( "Listening on MIDI channel %i\n", channel );

	if( snd_seq_open( &seqport, "default", SND_SEQ_OPEN_INPUT, 0 ) < 0 )
	{
		fputs( "Cannot connect to ALSA sequencer\n", stderr );
		return 1;
	}

	snd_seq_set_client_name( seqport, "SO-666" );

	midiport = snd_seq_create_simple_port( seqport, "input",
		SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
		SND_SEQ_PORT_TYPE_APPLICATION );

	if( midiport < 0 )
	{
		fputs( "Cannot create ALSA sequencer port\n", stderr );
		return 1;
	}

	npfd = snd_seq_poll_descriptors_count( seqport, POLLIN );
	pfd = (struct pollfd *)malloc( npfd * sizeof( struct pollfd ) );
	snd_seq_poll_descriptors( seqport, pfd, npfd, POLLIN );


	done = 0;

	while( ! done )
	{
		if( poll( pfd, npfd, 100000 ) > 0 )
		{
			do
			{
				snd_seq_event_input( seqport, &midievent );
				
				if( ( midievent->type == SND_SEQ_EVENT_NOTEON ) && ( midievent->data.note.channel == channel ) )
				{
					note = midievent->data.note.note;
					if( ( note >= BASENOTE ) && ( note < BASENOTE+NUMNOTES ) )
					{
						note -= BASENOTE;

						status[note] = 1;
					}
				}
				else if( ( midievent->type == SND_SEQ_EVENT_NOTEOFF ) && ( midievent->data.note.channel == channel ) )
				{
					note = midievent->data.note.note;
					if( ( note >= BASENOTE ) && ( note < BASENOTE+NUMNOTES ) )
					{
						note -= BASENOTE;
						status[note] = 0;
					}
				}
				else if( ( midievent->type == SND_SEQ_EVENT_CONTROLLER ) && ( midievent->data.control.channel == channel ) )
				{
					if( midievent->data.control.param == 74 )
					{
						cutoff = midievent->data.control.value;
						fcutoff = pow( (cutoff+50.0)/200.0, 5.0 );
						printf( "Cutoff: %i     \r", cutoff );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 71 )
					{
						resonance = midievent->data.control.value;
						freso = resonance/127.0;
						printf( "Resonance: %i     \r", resonance );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 7 )
					{
						volume = midievent->data.control.value;
						printf( "Volume: %i     \r", volume );
						fflush( stdout );
					}
					else if( midievent->data.control.param == 1 )
					{
						feedback = midievent->data.control.value;
						ffeedback = 0.01+pow( feedback/127.0, 4.0)*0.9;
						printf( "Feedback: %i    \r", feedback );
						fflush( stdout );
					}
				}
				
				snd_seq_free_event( midievent );
			}
			while( snd_seq_event_input_pending( seqport, 0 ) > 0 );
		}
	}

	free( pfd );
	snd_seq_delete_port( seqport, midiport );
	snd_seq_close( seqport );
	
	jack_deactivate( jackClient );

	puts( "Freeing data" );
	for( note=0; note<NUMNOTES; note++ )
	{
		free( strings[note] );
	}

	jack_port_unregister( jackClient, outport );
	jack_client_close( jackClient );

	return 0;
}
コード例 #8
0
ファイル: mixer_strip.cpp プロジェクト: ycollet/qtjmix
void Mixer_Strip::set_nb_channel(int _nb_channel)
{
  int result = 0, i = 0;
  std::stringstream port_name;
  jack_port_t *tmp_port_out = NULL, *tmp_port_in = NULL;

  if (nb_channel==_nb_channel) return;

  nb_channel = _nb_channel;
  input_port.resize(nb_channel, NULL);
  output_port.resize(nb_channel, NULL);
  rms_level.resize(nb_channel, 0.0);
  max_level.resize(nb_channel, 0.0);

  if (nb_channel==1) 
    {
      type = mono;
      typeLabel->setText(tr("mono"));

      for(i=0; i<input_port.size(); i++)
	{
	  result = jack_port_unregister(client, input_port[i]);
	  if (result)
	    std::cerr << qPrintable(tr("QTJMix: problem while unregistering the input port of the mixer strip ")) << i << "." << std::endl;
	  
	  result = jack_port_unregister(client, output_port[i]);
	  if (result)
	    std::cerr << qPrintable(tr("QTJMix: problem while unregistering the output port of the mixer strip ")) << i << "." << std::endl;
	}
      
      input_port.resize(1, NULL);
      output_port.resize(1, NULL);
      
      // Create input port
      port_name.str("");
      port_name << "mixer_" << strip_id << "_m_in";
#ifdef ENABLE_JACK
      tmp_port_in = jack_port_register(client, port_name.str().c_str(),
				       JACK_DEFAULT_AUDIO_TYPE,
				       JackPortIsInput, 0);
#endif
      
      // Create output port
      port_name.str("");
      port_name << "mixer_" << strip_id << "_m_out";
#ifdef ENABLE_JACK
      tmp_port_out = jack_port_register(client, port_name.str().c_str(),
					JACK_DEFAULT_AUDIO_TYPE,
					JackPortIsOutput, 0);
#endif

#ifdef ENABLE_JACK
      if ((tmp_port_in == NULL) || (tmp_port_out == NULL))
	{
          std::cerr << qPrintable(tr("no more JACK ports available")) << std::endl;
	  exit (1);
        }
#endif
      
      set_input_port(0, tmp_port_in);
      set_output_port(0, tmp_port_out);
      rms_level.resize(1, 0.0);
      rms_level_n_1.resize(1, 0.0);
      max_level.resize(1, 0.0);
      max_level_n_1.resize(1, 0.0);
      panDial->setEnabled(false);
    }
  else
    {
      type = stereo;
      typeLabel->setText(tr("stereo"));

      for(i=0; i<input_port.size(); i++)
	{
	  result = jack_port_unregister(client, input_port[i]);
	  if (result)
	    std::cerr << qPrintable(tr("QTJMix: problem while unregistering the input port of the mixer strip ")) << i << "." << std::endl;
	  
	  result = jack_port_unregister(client, output_port[i]);
	  if (result)
	    std::cerr << qPrintable(tr("QTJMix: problem while unregistering the output port of the mixer strip ")) << i << "." << std::endl;
	}
      
      input_port.resize(2, NULL);
      output_port.resize(2, NULL);

      // Create left input port
      port_name.str("");
      port_name << "mixer_" << strip_id << "_l_in";
#ifdef ENABLE_JACK
      tmp_port_in = jack_port_register(client, port_name.str().c_str(),
				       JACK_DEFAULT_AUDIO_TYPE,
				       JackPortIsInput, 0);
#endif
      
      // Create left output port
      port_name.str("");
      port_name << "mixer_" << strip_id << "_l_out" << strip_id;
#ifdef ENABLE_JACK
      tmp_port_out = jack_port_register(client, port_name.str().c_str(),
					JACK_DEFAULT_AUDIO_TYPE,
					JackPortIsOutput, 0);
#endif

#ifdef ENABLE_JACK
      if ((tmp_port_in == NULL) || (tmp_port_out == NULL))
	{
          std::cerr << qPrintable(tr("no more JACK ports available")) << std::endl;
	  exit (1);
        }
#endif
      
      set_input_port(0, tmp_port_in);
      set_output_port(0, tmp_port_out);

      // Create right input port
      port_name.str("");
      port_name << "mixer_" << strip_id << "_r_in";
#ifdef ENABLE_JACK
      tmp_port_in = jack_port_register(client, port_name.str().c_str(),
				       JACK_DEFAULT_AUDIO_TYPE,
				       JackPortIsInput, 0);
#endif
      
      // Create right output port
      port_name.str("");
      port_name << "mixer_" << strip_id << "_r_out";
#ifdef ENABLE_JACK
      tmp_port_out = jack_port_register(client, port_name.str().c_str(),
					JACK_DEFAULT_AUDIO_TYPE,
					JackPortIsOutput, 0);
#endif

#ifdef ENABLE_JACK
      if ((tmp_port_in == NULL) || (tmp_port_out == NULL))
	{
          std::cerr << qPrintable(tr("no more JACK ports available")) << std::endl;
	  exit (1);
        }
#endif
      
      set_input_port(1, tmp_port_in);
      set_output_port(1, tmp_port_out);

      rms_level.resize(2, 0.0);
      rms_level_n_1.resize(2, 0.0);
      max_level.resize(2, 0.0);
      max_level_n_1.resize(2, 0.0);
      panDial->setEnabled(true);
    }
}
コード例 #9
0
ファイル: jackcard.c プロジェクト: luge/foolject
int jack_init(JackCard* obj)
{
  char* client_name;
  int error;

  if (!obj->jack_running) {
    obj->client = NULL;
    client_name = g_strdup_printf("linphone-%u", g_random_int());
    if ((obj->client = jack_client_new (client_name)) == NULL) {
      g_warning("cannot create jack client");
      g_free(client_name);
      return -1;
    }
    g_message("Found Jack Daemon");
    g_free(client_name);
    
    /* tell the JACK server to call `process()' whenever
       there is work to be done.
    */
    jack_set_process_callback (obj->client, process, obj);

    /* 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 (obj->client, jack_shutdown, obj);
    jack_set_sample_rate_callback (obj->client, samplerate, obj);
    obj->rate = jack_get_sample_rate (obj->client);
    if (obj->rate == 0) {
      g_warning ("rate is 0???");
      if (jack_client_close(obj->client) != 0)
	g_warning("could not close client");
      return -1;
    }
    obj->buffer_size = jack_get_buffer_size(obj->client);
    obj->jack_running = TRUE;
  }

  if (!obj->jack_active) {
    if (jack_activate (obj->client)) {
      g_warning("cannot activate jack client");
      return -1;
    } else obj->jack_active = TRUE;
  }

  if (obj->read.init) {
    if (!obj->read.port && (obj->read.port = jack_port_register (obj->client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))==NULL) {
      g_warning("error while trying to register input port");
      return -1;
    }
    if (!obj->read.phys_ports && (obj->read.phys_ports = jack_get_ports (obj->client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == NULL) {
      g_warning("Cannot find any physical capture ports\n");
      jack_port_unregister(obj->client, obj->read.port);
      obj->read.port = NULL;
      return -1;
    }
    if (!jack_port_connected(obj->read.port))
      if ((error = jack_connect (obj->client, obj->read.phys_ports[0], jack_port_name (obj->read.port))) != 0) {
	g_warning("cannot connect input ports: %s -> %s\n", jack_port_name (obj->read.port), obj->read.phys_ports[0]);
	if (error == EEXIST) g_warning("connection already made");
	else {
	  jack_port_unregister(obj->client, obj->read.port);
	  obj->read.port = NULL;
	  return -1;
	}
      }
    obj->read.init = FALSE;
  }

  if (obj->write.init) {
    if (!obj->write.port && (obj->write.port = jack_port_register (obj->client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0))==NULL) {
      g_warning("error while trying to register output port");
      return -1;
    }
    if (!obj->write.phys_ports && (obj->write.phys_ports = jack_get_ports (obj->client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) {
      g_warning("Cannot find any physical playback ports\n");
      jack_port_unregister(obj->client, obj->write.port);
      obj->write.port = NULL;
      return -1;
    }
    if (!jack_port_connected(obj->write.port)) {
      if ((error = jack_connect (obj->client, jack_port_name (obj->write.port), obj->write.phys_ports[0])) != 0) {
	g_warning("cannot connect output ports: %s -> %s\n", jack_port_name (obj->write.port), obj->write.phys_ports[0]);
	if (error == EEXIST) g_warning("connection already made");
	else {
	  jack_port_unregister(obj->client, obj->write.port);
	  obj->write.port = NULL;
	  return -1;
	}
      }
      if ((error = jack_connect (obj->client, jack_port_name (obj->write.port), obj->write.phys_ports[1])) != 0) {
	g_warning("cannot connect output ports: %s -> %s\n", jack_port_name (obj->write.port), obj->write.phys_ports[1]);
	if (error == EEXIST) g_warning("connection already made");
	else {
	  jack_port_unregister(obj->client, obj->write.port);
	  obj->write.port = NULL;
	  return -1;
	}
      }
    }
    obj->write.init = FALSE;
  }
  return 0;
}
コード例 #10
0
ファイル: jackplay.c プロジェクト: jeremysalwen/Ceres4
void *JackOpenPlay(struct FFTSound *fftsound){
  int lokke;
  static char *outnames[MAX_SAMPS_PER_FRAME]={"output1","output2","output3","output4","output5","output6","output7","output8"};

  struct Jackplay *jackplay;
  jackplay=calloc(1,sizeof(struct Jackplay));

  jackplay->fftsound=fftsound;
  jackplay->buffersize=BUFFERSIZE;

  //  fprintf(stderr,"Open jack play.\n");

#if 1
  if(globalclient==NULL){ // Hack to get around a bug in jack.
    if (CONFIG_getBool("jack_client_name_is_ceres_plus_pid")==true){
      sprintf(clientname,"ceres-%d",getpid());
    }else{
      sprintf(clientname,"ceres");
    }
    if ((jackplay->client=globalclient = jack_client_new (clientname)) == 0) {
      fprintf(stderr,"Failed. Jack server not running?\n");
      goto failed;
    }
    atexit(jackCleanUp);
  }

  jackplay->client=globalclient;
#else
  if ((jackplay->client=globalclient=jack_client_new ("ceres")) == 0) {
    fprintf(stderr,"Failed. Jack server not running?\n");
    goto failed;
  }
#endif


  if(fftsound->R!=jack_get_sample_rate(jackplay->client)){
    fprintf(
	    stderr,
	    "Warning, sample rate is %d, while jacks sample rate is %lu.\n",
	    fftsound->R,
	    jack_get_sample_rate(jackplay->client)
	    );
  }
  jack_set_process_callback (jackplay->client, jackprocess, jackplay);

  for(lokke=0;lokke<fftsound->samps_per_frame;lokke++){
    jackplay->jpc[lokke].output_port = 
      jack_port_register(
			 jackplay->client,
			 outnames[lokke],
			 JACK_DEFAULT_AUDIO_TYPE,
			 JackPortIsOutput,
			 0
			 );
  }
  if (jack_activate (jackplay->client)) {
    fprintf (stderr, "Error. Cannot activate jack client.\n");
    goto failed_activate;
  }

  for(lokke=0;lokke<fftsound->samps_per_frame;lokke++){
    if (
	jack_connect(
		     jackplay->client,
		     jack_port_name(jackplay->jpc[lokke].output_port),
		     outportnames[lokke]
		     )
	)
      {
	fprintf (stderr, "Error. Cannot connect jack output port %d: \"%s\".\n",lokke,outportnames[lokke]);
	goto failed_connect;
      }
  }
  return jackplay;

 failed_connect:
  for(lokke=0;lokke<jackplay->fftsound->samps_per_frame;lokke++){
    jack_disconnect(
		    jackplay->client,
		    jack_port_name(jackplay->jpc[lokke].output_port),
		    outportnames[lokke]
		    );
    
    jack_port_unregister(
			 jackplay->client,jackplay->jpc[lokke].output_port
			 );
    
  }

 failed_activate:
  jack_deactivate(jackplay->client);
  //  jack_client_close (jackplay->client);
 failed:
  free(jackplay);
  return NULL;
}