static int op_jack_init(void) { #ifdef HAVE_SAMPLERATE for (int i = 0; i < CHANNELS; i++) { src_state[i] = src_new(src_quality, 1, NULL); if (src_state[i] == NULL) { d_print("src_new failed"); for (i = i - 1; i >= 0; i--) { src_delete(src_state[i]); } return -OP_ERROR_INTERNAL; } } #endif jack_set_error_function(op_jack_error_cb); jack_options_t options = JackNullOption; if (fail) { /* since jackd failed, it will not be autostarted. Either jackd * was killed intentionaly or it died by heartattack. * Until it is restarted, init will happily fail again * and again and again.. */ options |= JackNoStartServer; } jack_status_t status; client = jack_client_open("cmus", options, &status, server_name); if (client == NULL) { d_print("jack_client_new failed\n"); return -OP_ERROR_INTERNAL; } if (status & JackServerStarted) { d_print("jackd started\n"); } jack_nframes_t jack_buffer_size = jack_get_buffer_size(client); jack_sample_rate = jack_get_sample_rate(client); op_jack_buffer_init(jack_buffer_size, NULL); jack_set_process_callback(client, op_jack_cb, NULL); jack_set_sample_rate_callback(client, op_jack_sample_rate_cb, NULL); jack_set_buffer_size_callback(client, op_jack_buffer_init, NULL); jack_on_shutdown(client, op_jack_shutdown_cb, NULL); for (int i = 0; i < CHANNELS; i++) { char port_name[20]; snprintf(port_name, sizeof(port_name)-1, "output %d", i); output_ports[i] = jack_port_register( client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); if (output_ports[i] == NULL) { d_print("no jack ports available\n"); return -OP_ERROR_INTERNAL; } } if (jack_activate(client)) { d_print("jack_client_activate failed\n"); return -OP_ERROR_INTERNAL; } const char **ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical | JackPortIsInput); if (ports == NULL) { d_print("cannot get playback ports\n"); return -OP_ERROR_INTERNAL; } for (int i = 0; i < CHANNELS; i++) { if (ports[i] == NULL) { d_print("could not connect output %d. too few ports.\n", i); break; } if (jack_connect(client, jack_port_name(output_ports[i]), ports[i])) { d_print("connot connect port %s\n", ports[i]); jack_free(ports); return -OP_ERROR_INTERNAL; } } jack_free(ports); fail = 0; return OP_ERROR_SUCCESS; }
bool SC_JackDriver::BufferSizeChanged(int numSamples) { Reset(jack_get_sample_rate(mClient), numSamples); return true; }
/* allocate a buffer and setup resources to process the audio samples of * the format as specified in @spec. * * We allocate N jack ports, one for each channel. If we are asked to * automatically make a connection with physical ports, we connect as many * ports as there are physical ports, leaving leftover ports unconnected. * * It is assumed that samplerate and number of channels are acceptable since our * getcaps method will always provide correct values. If unacceptable caps are * received for some reason, we fail here. */ static gboolean gst_jack_ring_buffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec) { GstJackAudioSrc *src; GstJackRingBuffer *abuf; const char **ports; gint sample_rate, buffer_size; gint i, channels, res; jack_client_t *client; src = GST_JACK_AUDIO_SRC (GST_OBJECT_PARENT (buf)); abuf = GST_JACK_RING_BUFFER_CAST (buf); GST_DEBUG_OBJECT (src, "acquire"); client = gst_jack_audio_client_get_client (src->client); /* sample rate must be that of the server */ sample_rate = jack_get_sample_rate (client); if (sample_rate != spec->rate) goto wrong_samplerate; channels = spec->channels; if (!gst_jack_audio_src_allocate_channels (src, channels)) goto out_of_ports; gst_jack_set_layout_on_caps (&spec->caps, channels); buffer_size = jack_get_buffer_size (client); /* the segment size in bytes, this is large enough to hold a buffer of 32bit floats * for all channels */ spec->segsize = buffer_size * sizeof (gfloat) * channels; spec->latency_time = gst_util_uint64_scale (spec->segsize, (GST_SECOND / GST_USECOND), spec->rate * spec->bytes_per_sample); /* segtotal based on buffer-time latency */ spec->segtotal = spec->buffer_time / spec->latency_time; if (spec->segtotal < 2) { spec->segtotal = 2; spec->buffer_time = spec->latency_time * spec->segtotal; } GST_DEBUG_OBJECT (src, "buffer time: %" G_GINT64_FORMAT " usec", spec->buffer_time); GST_DEBUG_OBJECT (src, "latency time: %" G_GINT64_FORMAT " usec", spec->latency_time); GST_DEBUG_OBJECT (src, "buffer_size %d, segsize %d, segtotal %d", buffer_size, spec->segsize, spec->segtotal); /* allocate the ringbuffer memory now */ buf->data = gst_buffer_new_and_alloc (spec->segtotal * spec->segsize); memset (GST_BUFFER_DATA (buf->data), 0, GST_BUFFER_SIZE (buf->data)); if ((res = gst_jack_audio_client_set_active (src->client, TRUE))) goto could_not_activate; /* if we need to automatically connect the ports, do so now. We must do this * after activating the client. */ if (src->connect == GST_JACK_CONNECT_AUTO || src->connect == GST_JACK_CONNECT_AUTO_FORCED) { /* find all the physical output ports. A physical output port is a port * associated with a hardware device. Someone needs connect to a physical * port in order to capture something. */ ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical | JackPortIsOutput); if (ports == NULL) { /* no ports? fine then we don't do anything except for posting a warning * message. */ GST_ELEMENT_WARNING (src, RESOURCE, NOT_FOUND, (NULL), ("No physical output ports found, leaving ports unconnected")); goto done; } for (i = 0; i < channels; i++) { /* stop when all output ports are exhausted */ if (ports[i] == NULL) { /* post a warning that we could not connect all ports */ GST_ELEMENT_WARNING (src, RESOURCE, NOT_FOUND, (NULL), ("No more physical ports, leaving some ports unconnected")); break; } GST_DEBUG_OBJECT (src, "try connecting to %s", jack_port_name (src->ports[i])); /* connect the physical port to a port */ res = jack_connect (client, ports[i], jack_port_name (src->ports[i])); if (res != 0 && res != EEXIST) goto cannot_connect; } free (ports); } done: abuf->sample_rate = sample_rate; abuf->buffer_size = buffer_size; abuf->channels = spec->channels; return TRUE; /* ERRORS */ wrong_samplerate: { GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL), ("Wrong samplerate, server is running at %d and we received %d", sample_rate, spec->rate)); return FALSE; } out_of_ports: { GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL), ("Cannot allocate more Jack ports")); return FALSE; } could_not_activate: { GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL), ("Could not activate client (%d:%s)", res, g_strerror (res))); return FALSE; } cannot_connect: { GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL), ("Could not connect input ports to physical ports (%d:%s)", res, g_strerror (res))); free (ports); return FALSE; } }
/* jack_init: * JACK init routine. */ static int jack_init(int input, int voices) { const char **ports; char tmp[128]; if (!jack_detect(input)) return -1; jack_bufsize = get_config_int("sound", "jack_buffer_size", jack_bufsize); if (jack_bufsize == -1) jack_bufsize = jack_get_buffer_size (jack_client); /* Those are already read in from the config file by Allegro. */ jack_16bit = (_sound_bits == 16 ? 1 : 0); jack_stereo = (_sound_stereo ? 1 : 0); /* Let Allegro mix in its native unsigned format. */ jack_signed = 0; jack_set_process_callback (jack_client, jack_process, NULL); output_left = jack_port_register (jack_client, jack_stereo ? "left" : "mono", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (jack_stereo) output_right = jack_port_register (jack_client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); jack_rate = jack_get_sample_rate (jack_client); jack_buffer = _AL_MALLOC_ATOMIC(jack_bufsize * (1 + jack_16bit) * (1 + jack_stereo)); if (!jack_buffer) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text( "Cannot allocate audio buffer")); jack_exit (input); return -1; } digi_jack.voices = voices; if (_mixer_init(jack_bufsize * (1 + jack_stereo), jack_rate, jack_stereo, jack_16bit, &digi_jack.voices)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text( "Cannot init software mixer")); jack_exit (input); return -1; } _mix_some_samples((uintptr_t) jack_buffer, 0, jack_signed); if (jack_activate (jack_client)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text( "Cannot activate Jack client")); jack_exit (input); return 1; } /* Try to connect the ports. Failure to connect is not critical, since with * JACK, users may connect/disconnect ports anytime, without Allegro caring. */ if ((ports = jack_get_ports (jack_client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) { TRACE (PREFIX_I "Cannot find any physical playback ports"); } if (ports) { if (ports[0]) { if (jack_connect (jack_client, jack_port_name (output_left), ports[0]) == 0) TRACE (PREFIX_I "Connected left playback port to %s", ports[0]); } if (jack_stereo && ports[1]) { if (jack_connect (jack_client, jack_port_name (output_right), ports[1]) == 0) TRACE (PREFIX_I "Connected right playback port to %s", ports[1]); } _AL_FREE (ports); } uszprintf(jack_desc, sizeof(jack_desc), get_config_text ("Jack, client '%s': %d bits, %s, %d bps, %s"), jack_client_name, jack_16bit ? 16 : 8, uconvert_ascii((jack_signed ? "signed" : "unsigned"), tmp), jack_rate, uconvert_ascii((jack_stereo ? "stereo" : "mono"), tmp)); return 0; }
int main( int argc, char **argv ) { const char **ports; const char *client_name; const char *server_name = NULL; jack_options_t options = JackNullOption; jack_status_t status; int i; char projectM_data[1024]; std::string config_file; config_file = read_config(); ConfigFile config(config_file); wvw = config.read<int>( "Window Width", 512 ); wvh = config.read<int>( "Window Height", 512 ); int fullscreen = 0; if (config.read("Fullscreen", true)) fullscreen = 1; else fullscreen = 0; #ifdef DEBUG int value; int rgb_size[3]; #endif const SDL_VideoInfo* info = NULL; int bpp = 0; /* Flags we will pass into SDL_SetVideoMode. */ int flags = 0; //JACK INIT //---------------------------------------------- if (argc >= 2) { /* client name specified? */ client_name = argv[1]; if (argc >= 3) { /* server name specified? */ server_name = argv[2]; // options |= JackServerName; } } else { /* use basename of argv[0] */ client_name = strrchr(argv[0], '/'); if (client_name == 0) { client_name = argv[0]; } else { client_name++; } } /* open a client connection to 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", status); if (status & JackServerFailed) { fprintf (stderr, "Unable to connect to JACK server\n"); } exit (1); } if (status & JackServerStarted) { fprintf (stderr, "JACK server started\n"); } if (status & JackNameNotUnique) { client_name = jack_get_client_name(client); fprintf (stderr, "unique name `%s' assigned\n", client_name); } /* 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 `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); /* display the current sample rate. */ printf ("engine sample rate: %d\n", jack_get_sample_rate (client)); /* create two ports */ input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); if (input_port == NULL) { fprintf(stderr, "no more JACK ports available\n"); exit (1); } /* Tell the JACK server that we are ready to roll. Our * process() callback will start running now. */ //END JACK INIT ---------------------------------- init_display(wvw,wvh,&fvw,&fvh,fullscreen); /** Setup some window stuff */ SDL_WM_SetCaption( PROJECTM_TITLE, NULL ); globalPM = new projectM(config_file); /** Initialise projectM */ //JACK BEGIN----------------------------- if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); exit (1); } /* Connect the ports. You can't do this before the client is * activated, because we can't make connections to clients * that aren't running. Note the confusing (but necessary) * orientation of the driver backend ports: playback ports are * "input" to the backend, and capture ports are "output" from * it. */ ports = jack_get_ports (client, NULL, NULL, JackPortIsOutput); if (ports == NULL) { fprintf(stderr, "no physical capture ports\n"); exit (1); } i=0; while (ports[i]!=NULL) { printf("Connecting to Jack port %s\n",ports[i]); if (jack_connect (client, ports[i], jack_port_name (input_port))) { fprintf (stderr, "cannot connect input ports\n"); } i++; } free (ports); //----------------------------------END /** Initialise the thread */ renderLoop(); return 1; }
int main(int argc, char *argv[]) { const char*filename = "jtest.caf"; const char*myname=argv[0]; observe_signals (); struct recorder d; ambix_matrix_t*matrix=NULL; int32_t order = -1; d.buffer_frames = 4096; d.minimal_frames = 32; d.channels = 2; d.timer_seconds = -1.0; d.timer_counter = 0; d.sample_format = AMBIX_SAMPLEFORMAT_FLOAT32; d.file_format = AMBIX_BASIC; int c; while((c = getopt(argc, argv, "hVx:X:O:b:fhm:n:t:")) != -1) { switch(c) { case 'x': d.e_channels = (int) strtol(optarg, NULL, 0); d.file_format = AMBIX_EXTENDED; break; case 'X': matrix=matrix_read(optarg, matrix); if(!matrix) { eprintf("%s: couldn't read matrix-file '%s'\n", myname, optarg); FAILURE; } d.file_format = AMBIX_EXTENDED; break; case 'O': order = (uint32_t) strtol(optarg, NULL, 0); break; case 'b': d.buffer_frames = (int) strtol(optarg, NULL, 0); break; #if 0 case 'f': d.file_format = (int) strtol(optarg, NULL, 0); break; #endif case 'V': version (myname); break; case 'h': usage (myname); break; case 'm': d.minimal_frames = (int) strtol(optarg, NULL, 0); break; case 't': d.timer_seconds = (float) strtod(optarg, NULL); break; default: eprintf("%s: illegal option, %c\n", myname, c); usage (myname); break; } } if(optind == argc - 1) { filename=argv[optind]; } else { eprintf("opening default file '%s'\n", filename); //usage (myname); } /* Allocate channel based data. */ if(matrix) { if(order<0) { d.a_channels = matrix->cols; } else { if(ambix_order2channels(order) != matrix->rows) { eprintf("%s: ambisonics order:%d cannot use [%dx%d] adaptor matrix.\n", myname, order, matrix->rows, matrix->cols); FAILURE; } d.a_channels = matrix->cols; } } else { if(order<0) order=1; d.a_channels=ambix_order2channels(order); } switch(d.file_format) { case AMBIX_BASIC: //d.a_channels; d.e_channels=0; break; case AMBIX_EXTENDED: //d.a_channels; //d.e_channels; break; case AMBIX_NONE: default: d.a_channels=0; //d.e_channels; } d.channels = d.a_channels+d.e_channels; if(d.channels < 1) { eprintf("%s: illegal number of channels: %d\n", myname, d.channels); FAILURE; } d.in = (float**)xmalloc(d.channels * sizeof(float *)); d.input_port = (jack_port_t**)xmalloc(d.channels * sizeof(jack_port_t *)); /* Connect to JACK. */ jack_client_t *client = jack_client_unique_("ambix-jrecord"); jack_set_error_function(jack_client_minimal_error_handler); jack_on_shutdown(client, jack_client_minimal_shutdown_handler, 0); jack_set_process_callback(client, process, &d); d.sample_rate = jack_get_sample_rate(client); /* Setup timer. */ if(d.timer_seconds < 0.0) { d.timer_frames = -1; } else { d.timer_frames = d.timer_seconds * d.sample_rate; } /* Create sound file. */ ambix_info_t sfinfo; memset(&sfinfo, 0, sizeof(sfinfo)); sfinfo.samplerate = (int) d.sample_rate; sfinfo.frames = 0; sfinfo.fileformat = d.file_format; sfinfo.ambichannels = d.a_channels; sfinfo.extrachannels = d.e_channels; d.sound_file = ambix_open(filename, AMBIX_WRITE, &sfinfo); if(matrix) { ambix_err_t aerr = ambix_set_adaptormatrix(d.sound_file, matrix); if(AMBIX_ERR_SUCCESS != aerr) { eprintf("setting [%dx%d] matrix returned %d.\n", matrix->rows, matrix->cols, aerr); FAILURE; } } /* Allocate buffers. */ d.buffer_samples = d.buffer_frames * d.channels; d.buffer_bytes = d.buffer_samples * sizeof(float); d.a_buffer = (float32_t*)xmalloc(d.buffer_frames * d.a_channels * sizeof(float32_t)); d.e_buffer = (float32_t*)xmalloc(d.buffer_frames * d.e_channels * sizeof(float32_t)); d.d_buffer = (float*)xmalloc(d.buffer_bytes); d.j_buffer = (float*)xmalloc(d.buffer_bytes); d.u_buffer = (float*)xmalloc(d.buffer_bytes); d.ring_buffer = jack_ringbuffer_create(d.buffer_bytes); /* Create communication pipe. */ xpipe(d.pipe); /* Start disk thread. */ pthread_create (&(d.disk_thread), NULL, disk_thread_procedure, &d); /* Create input ports and activate client. */ #if 0 jack_port_make_standard(client, d.input_port, d.channels, false); jack_client_activate(client); #else do { int i=0, a, e; const char*format=(sfinfo.fileformat == AMBIX_BASIC)?"ACN_%d":"ambisonics_%d"; const int a_offset=(sfinfo.fileformat == AMBIX_BASIC)?0:1; for(a=0; a<d.a_channels; a++) { d.input_port[i] = _jack_port_register(client, JackPortIsInput, format, a+a_offset); i++; } for(e=0; e<d.e_channels; e++) { d.input_port[i] = _jack_port_register(client, JackPortIsInput, "in_%d", e+1); i++; } } while(0); if(jack_activate(client)) { eprintf("jack_activate() failed\n"); FAILURE; } #endif /* Wait for disk thread to end, which it does when it reaches the end of the file or is interrupted. */ pthread_join(d.disk_thread, NULL); /* Close sound file, free ring buffer, close JACK connection, close pipe, free data buffers, indicate success. */ jack_client_close(client); ambix_close(d.sound_file); jack_ringbuffer_free(d.ring_buffer); close(d.pipe[0]); close(d.pipe[1]); free(d.a_buffer); free(d.e_buffer); free(d.d_buffer); free(d.j_buffer); free(d.u_buffer); free(d.in); free(d.input_port); if(matrix)ambix_matrix_destroy(matrix); return EXIT_SUCCESS; }
int cbox_jackio_get_sample_rate(struct cbox_io_impl *impl) { struct cbox_jack_io_impl *jii = (struct cbox_jack_io_impl *)impl; return jack_get_sample_rate(jii->client); }
bool DevJack::start(QString *err) { #ifdef JACK jack_options_t jackopts=JackNullOption; jack_status_t jackstat=JackFailure; int srcerr; // // Connect to JACK Instance // if(jack_server_name.isEmpty()) { jack_jack_client= jack_client_open(jack_client_name.toAscii(),jackopts,&jackstat); } else { jack_jack_client= jack_client_open(jack_client_name.toAscii(),jackopts,&jackstat, (const char *)jack_server_name.toAscii()); } if(jack_jack_client==NULL) { if((jackstat&JackInvalidOption)!=0) { *err=tr("invalid or unsupported JACK option"); } if((jackstat&JackServerError)!=0) { *err=tr("communication error with the JACK server"); } if((jackstat&JackNoSuchClient)!=0) { *err=tr("requested JACK client does not exist"); } if((jackstat&JackLoadFailure)!=0) { *err=tr("unable to load internal JACK client"); } if((jackstat&JackInitFailure)!=0) { *err=tr("unable to initialize JACK client"); } if((jackstat&JackShmFailure)!=0) { *err=tr("unable to access JACK shared memory"); } if((jackstat&JackVersionError)!=0) { *err=tr("JACK protocol version mismatch"); } if((jackstat&JackServerStarted)!=0) { *err=tr("JACK server started"); } if((jackstat&JackServerFailed)!=0) { fprintf (stderr, "unable to communication with JACK server\n"); *err=tr("unable to communicate with JACK server"); } if((jackstat&JackNameNotUnique)!=0) { *err=tr("JACK client name not unique"); } if((jackstat&JackFailure)!=0) { *err=tr("JACK general failure"); } *err=tr("no connection to JACK server"); printf("~DevJack::start() Ends FALSE 1\n"); return false; } jack_set_buffer_size_callback(jack_jack_client,JackBufferSizeChanged,this); jack_set_process_callback(jack_jack_client,JackProcess,this); // // Join the Graph // if(jack_activate(jack_jack_client)) { *err=tr("unable to join JACK graph"); printf("~DevJack::start() Ends FALSE 2\n"); return false; } jack_jack_sample_rate=jack_get_sample_rate(jack_jack_client); // // Register Ports // for(unsigned i=0;i<codec()->channels();i++) { QString name=QString().sprintf("output_%d",i+1); jack_jack_ports[i]= jack_port_register(jack_jack_client,name.toAscii(),JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput|JackPortIsTerminal,0); } Log(LOG_INFO,QString().sprintf("connected to JACK graph at %u samples/sec.", jack_jack_sample_rate)); // jack_meter_timer->start(AUDIO_METER_INTERVAL); // // Initialize SRC // jack_pll_setpoint_ratio= (double)jack_jack_sample_rate/(double)codec()->samplerate(); memset(&jack_data,0,sizeof(jack_data)); jack_data.src_ratio=jack_pll_setpoint_ratio; if((jack_src=src_new(SRC_LINEAR,codec()->channels(),&srcerr))==NULL) { fprintf(stderr,"SRC initialization error [%s]\n",src_strerror(srcerr)); exit(GLASS_EXIT_SRC_ERROR); } jack_play_position=0; jack_pll_setpoint_frames=0; jack_pll_offset=0.0; jack_play_position_timer->start(50); jack_meter_timer->start(AUDIO_METER_INTERVAL); return true; #endif // JACK return false; }
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; }
static int init(struct ao *ao) { struct priv *p = ao->priv; struct mp_chmap_sel sel = {0}; jack_options_t open_options; ao->format = AF_FORMAT_FLOATP; switch (p->stdlayout) { case 0: mp_chmap_sel_add_waveext(&sel); break; case 1: mp_chmap_sel_add_alsa_def(&sel); break; default: mp_chmap_sel_add_any(&sel); } if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels)) goto err_chmap; open_options = JackNullOption; if (!p->autostart) open_options |= JackNoStartServer; p->client = jack_client_open(p->cfg_client_name, open_options, NULL); if (!p->client) { MP_FATAL(ao, "cannot open server\n"); goto err_client_open; } if (create_ports(ao, ao->channels.num)) goto err_create_ports; jack_set_process_callback(p->client, process, ao); if (jack_activate(p->client)) { MP_FATAL(ao, "activate failed\n"); goto err_activate; } ao->samplerate = jack_get_sample_rate(p->client); if (p->connect) if (connect_to_outports(ao)) goto err_connect; jack_latency_range_t jack_latency_range; jack_port_get_latency_range(p->ports[0], JackPlaybackLatency, &jack_latency_range); p->jack_latency = (float)(jack_latency_range.max + jack_get_buffer_size(p->client)) / (float)ao->samplerate; if (!ao_chmap_sel_get_def(ao, &sel, &ao->channels, p->num_ports)) goto err_chmap_sel_get_def; return 0; err_chmap_sel_get_def: err_connect: jack_deactivate(p->client); err_activate: err_create_ports: jack_client_close(p->client); err_client_open: err_chmap: return -1; }
bool audioStreamer_JACK::init(const char* clientName, int nInputChannels, int nOutputChannels, SPLPROC proc) { njc = NULL; splproc = proc; if (client) { jack_client_close(client); client = NULL; } if ((client = jack_client_new(clientName)) == 0) { fprintf (stderr, "jack server not running?\n"); return false; // exit(20); } jack_set_process_callback (client, (JackProcessCallback) process_cb, this); jack_set_timebase_callback( client, 0, (JackTimebaseCallback) jack_timebase_cb, this ); if (_out) { delete[] _out; _out = NULL; } _out = new jack_port_t*[nOutputChannels]; if (_outports) { delete[] _outports; _outports = NULL; } _outports = new float*[nOutputChannels]; for (unsigned i=0; i<nOutputChannels; i++) { char name[10]; snprintf(name, sizeof(name), "out%d", i+1); _out[i] = jack_port_register (client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); } if (_in) { delete[] _in; _in = NULL; } _in = new jack_port_t*[nInputChannels]; if (_inports) { delete[] _inports; _inports = NULL; } _inports = new float*[nInputChannels]; for (unsigned i=0; i<nInputChannels; i++) { char name[10]; snprintf(name, sizeof(name), "in%d", i+1); _in[i] = jack_port_register (client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); } if (jack_activate (client)) { fprintf (stderr, "cannot activate client\n"); return false; //exit(20); } m_innch = nInputChannels; m_outnch = nOutputChannels; m_srate = jack_get_sample_rate( client ); m_bps = 32; return true; }
int so_main (int new_latency, int number_inputs, int number_outputs) { /* const char **ports; */ const char *client_name = "soft-rt-bridge"; const char *server_name = NULL; jack_options_t options = JackNullOption; jack_status_t status; latency = new_latency; jack_write_head = 1; lisp_read_head = 0; jack_read_head = 1; lisp_write_head = 0; n_input_ports = number_inputs; n_output_ports = number_outputs; underflow_flag = false; ready_flag = false; int j; for (j=0; j<n_input_ports; j++) { in_buffers[j] = malloc( latency * sizeof(jack_default_audio_sample_t)); if (in_buffers[j] == NULL) { fprintf (stderr, "no memory"); exit(1); } memset (in_buffers[j], 0, latency * sizeof(jack_default_audio_sample_t)); } for (j=0; j<n_output_ports; j++) { out_buffers[j] = malloc( latency * sizeof(jack_default_audio_sample_t)); if (out_buffers[j] == NULL) { fprintf (stderr, "no memory"); exit(1); } memset (out_buffers[j], 0, latency * sizeof(jack_default_audio_sample_t)); } /* open a client connection to 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", status); if (status & JackServerFailed) { fprintf (stderr, "Unable to connect to JACK server\n"); } exit (1); } if (status & JackServerStarted) { fprintf (stderr, "JACK server started\n"); } if (status & JackNameNotUnique) { client_name = jack_get_client_name(client); fprintf (stderr, "unique name `%s' assigned\n", client_name); } /* 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 `latency()' whenever the latency needs to be recalculated. */ /* if (jack_set_latency_callback) */ /* jack_set_latency_callback (client, latency_cb, 0); */ // FIXME the latency callback seems to generate some weird low-level // digital artefact that sounds frikkin nasty! /* 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); /* display the current sample rate. */ printf ("engine sample rate: %" PRIu32 "\n", jack_get_sample_rate (client)); /* create two ports */ char portname[256]; for (j=0; j<n_output_ports; j++) { sprintf(portname, "output %d", j); output_ports[j] = jack_port_register (client, portname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (output_ports[j] == NULL) { fprintf(stderr, "no more JACK ports available\n"); exit (1); } } for (j=0; j<n_input_ports; j++) { sprintf(portname, "input %d", j); input_ports[j] = jack_port_register (client, portname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); if (input_ports[j] == NULL) { fprintf(stderr, "no more JACK ports available\n"); exit (1); } } /* Tell the JACK server that we are ready to roll. Our * process() callback will start running now. */ if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); exit (1); } //maybe reconnect this plumbing when multiple ports are cooked... /* /\* Connect the ports. You can't do this before the client is */ /* * activated, because we can't make connections to clients */ /* * that aren't running. Note the confusing (but necessary) */ /* * orientation of the driver backend ports: playback ports are */ /* * "input" to the backend, and capture ports are "output" from */ /* * it. */ /* *\/ */ /* ports = jack_get_ports (client, NULL, NULL, */ /* JackPortIsPhysical|JackPortIsOutput); */ /* if (ports == NULL) { */ /* fprintf(stderr, "no physical capture ports\n"); */ /* exit (1); */ /* } */ /* if (jack_connect (client, ports[0], jack_port_name (input_port))) { */ /* fprintf (stderr, "cannot connect input ports\n"); */ /* } */ /* free (ports); */ /* ports = jack_get_ports (client, NULL, NULL, */ /* JackPortIsPhysical|JackPortIsInput); */ /* if (ports == NULL) { */ /* fprintf(stderr, "no physical playback ports\n"); */ /* exit (1); */ /* } */ /* if (jack_connect (client, jack_port_name (output_port), ports[0])) { */ /* fprintf (stderr, "cannot connect output ports\n"); */ /* } */ /* free (ports); */ /* keep running until stopped by the user */ while (underflow_flag == false) sleep (1); jack_deactivate (client); jack_client_close (client); /* exit (0); */ return 0; }
static int start_jack(struct auplay_st *st) { const char **ports; const char *client_name = "baresip"; const char *server_name = NULL; jack_options_t options = JackNullOption; jack_status_t status; unsigned ch; jack_nframes_t engine_srate; /* open a client connection to the JACK server */ st->client = jack_client_open(client_name, options, &status, server_name); if (st->client == NULL) { warning("jack: jack_client_open() failed, " "status = 0x%2.0x\n", status); if (status & JackServerFailed) { warning("jack: Unable to connect to JACK server\n"); } return ENODEV; } if (status & JackServerStarted) { info("jack: JACK server started\n"); } if (status & JackNameNotUnique) { client_name = jack_get_client_name(st->client); info("jack: unique name `%s' assigned\n", client_name); } jack_set_process_callback(st->client, process_handler, st); engine_srate = jack_get_sample_rate(st->client); st->nframes = jack_get_buffer_size(st->client); info("jack: engine sample rate: %" PRIu32 " max_frames=%u\n", engine_srate, st->nframes); /* currently the application must use the same sample-rate as the jack server backend */ if (engine_srate != st->prm.srate) { warning("jack: samplerate %uHz expected\n", engine_srate); return EINVAL; } /* create one port per channel */ for (ch=0; ch<st->prm.ch; ch++) { char buf[32]; re_snprintf(buf, sizeof(buf), "output_%u", ch+1); st->portv[ch] = jack_port_register (st->client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if ( st->portv[ch] == NULL) { warning("jack: no more JACK ports available\n"); return ENODEV; } } /* Tell the JACK server that we are ready to roll. Our * process() callback will start running now. */ if (jack_activate (st->client)) { warning("jack: cannot activate client"); return ENODEV; } /* Connect the ports. You can't do this before the client is * activated, because we can't make connections to clients * that aren't running. Note the confusing (but necessary) * orientation of the driver backend ports: playback ports are * "input" to the backend, and capture ports are "output" from * it. */ ports = jack_get_ports (st->client, NULL, NULL, JackPortIsInput); if (ports == NULL) { warning("jack: no physical playback ports\n"); return ENODEV; } for (ch=0; ch<st->prm.ch; ch++) { if (jack_connect (st->client, jack_port_name (st->portv[ch]), ports[ch])) { warning("jack: cannot connect output ports\n"); } } jack_free(ports); return 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; }
static int init(int rate, int channels, int format, int flags) { const char **matching_ports = NULL; char *port_name = NULL; char *client_name = NULL; int autostart = 0; const opt_t subopts[] = { {"port", OPT_ARG_MSTRZ, &port_name, NULL}, {"name", OPT_ARG_MSTRZ, &client_name, NULL}, {"estimate", OPT_ARG_BOOL, &estimate, NULL}, {"autostart", OPT_ARG_BOOL, &autostart, NULL}, {NULL} }; jack_options_t open_options = JackUseExactName; int port_flags = JackPortIsInput; int i; estimate = 1; if (subopt_parse(ao_subdevice, subopts) != 0) { print_help(); return 0; } if (channels > MAX_CHANS) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] Invalid number of channels: %i\n", channels); goto err_out; } if (!client_name) { client_name = malloc(40); sprintf(client_name, "MPlayer [%d]", getpid()); } if (!autostart) open_options |= JackNoStartServer; client = jack_client_open(client_name, open_options, NULL); if (!client) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] cannot open server\n"); goto err_out; } buffer = av_fifo_alloc(BUFFSIZE); jack_set_process_callback(client, outputaudio, 0); // list matching ports if (!port_name) port_flags |= JackPortIsPhysical; matching_ports = jack_get_ports(client, port_name, NULL, port_flags); if (!matching_ports || !matching_ports[0]) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] no physical ports available\n"); goto err_out; } i = 1; while (matching_ports[i]) i++; if (channels > i) channels = i; num_ports = channels; // create out output ports for (i = 0; i < num_ports; i++) { char pname[30]; snprintf(pname, 30, "out_%d", i); ports[i] = jack_port_register(client, pname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (!ports[i]) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] not enough ports available\n"); goto err_out; } } if (jack_activate(client)) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] activate failed\n"); goto err_out; } for (i = 0; i < num_ports; i++) { if (jack_connect(client, jack_port_name(ports[i]), matching_ports[i])) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] connecting failed\n"); goto err_out; } } rate = jack_get_sample_rate(client); jack_latency = (float)(jack_port_get_total_latency(client, ports[0]) + jack_get_buffer_size(client)) / (float)rate; callback_interval = 0; ao_data.channels = channels; ao_data.samplerate = rate; ao_data.format = AF_FORMAT_FLOAT_NE; ao_data.bps = channels * rate * sizeof(float); ao_data.buffersize = CHUNK_SIZE * NUM_CHUNKS; ao_data.outburst = CHUNK_SIZE; free(matching_ports); free(port_name); free(client_name); return 1; err_out: free(matching_ports); free(port_name); free(client_name); if (client) jack_client_close(client); av_fifo_free(buffer); buffer = NULL; return 0; }
/*------------------------------------------------------------------------------ * Open the audio source *----------------------------------------------------------------------------*/ bool JackDspSource :: open ( void ) throw ( Exception ) { char client_name[255]; size_t rb_size; unsigned int c; if ( isOpen() ) { return false; } // Register client with Jack if ( jack_client_name != NULL ) { snprintf(client_name, 255, "%s", jack_client_name); } else { snprintf(client_name, 255, "darkice-%d", getpid()); } if ((client = jack_client_new(client_name)) == NULL) { throw Exception( __FILE__, __LINE__, "JACK server not running?"); } Reporter::reportEvent( 1, "Registering as JACK client", client_name); // Check the sample rate is correct if (jack_get_sample_rate( client ) != (jack_nframes_t)getSampleRate()) { throw Exception( __FILE__, __LINE__, "JACK server sample rate is different than " "sample rate in darkice config file"); } // Register ports with Jack if (getChannel() == 1) { if (!(ports[0] = jack_port_register(client, "mono", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))) { throw Exception( __FILE__, __LINE__, "Cannot register input port", "mono"); } } else if (getChannel() == 2) { if (!(ports[0] = jack_port_register(client, "left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))) { throw Exception( __FILE__, __LINE__, "Cannot register input port", "left"); } if (!(ports[1] = jack_port_register(client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0))) { throw Exception( __FILE__, __LINE__, "Cannot register input port", "right"); } } else { throw Exception( __FILE__, __LINE__, "Invalid number of channels", getChannel()); } // Create a ring buffer for each channel rb_size = 2 * jack_get_sample_rate(client) * sizeof (jack_default_audio_sample_t); for (c=0; c<getChannel(); c++) { rb[c] = jack_ringbuffer_create(rb_size); if (!rb[c]) { throw Exception( __FILE__, __LINE__, "Failed to create ringbuffer for", "channel", c); } } // Set the callbacks jack_on_shutdown(client, JackDspSource::shutdown_callback, (void*)this); if (jack_set_process_callback(client, JackDspSource::process_callback, (void*)this)) { throw Exception( __FILE__, __LINE__, "Failed to set process callback"); } // Activate client if (jack_activate(client)) { throw Exception( __FILE__, __LINE__, "Can't activate client"); } // Attempt to automatically connect up our input ports to something ? if (auto_connect) { do_auto_connect(); } return true; }
/* JackProxyDriver is wrapped in a JackWaitCallbackDriver decorator that behaves as a "dummy driver, until Initialize method returns. */ bool JackProxyDriver::Initialize() { jack_log("JackProxyDriver::Initialize"); // save existing local connections if needed if (fAutoSave) { SaveConnections(0); } // new loading, but existing client, restart the driver if (fClient) { jack_info("JackProxyDriver restarting..."); jack_client_close(fClient); } FreePorts(); // display some additional infos jack_info("JackProxyDriver started in %s mode.", (fEngineControl->fSyncMode) ? "sync" : "async"); do { jack_status_t status; char *old = NULL; if (fPromiscuous) { // as we are fiddling with the environment variable content, save it const char* tmp = getenv("JACK_PROMISCUOUS_SERVER"); if (tmp) { old = strdup(tmp); } // temporary enable promiscuous mode if (setenv("JACK_PROMISCUOUS_SERVER", fPromiscuous, 1) < 0) { free(old); jack_error("Error allocating memory."); return false; } } jack_info("JackProxyDriver connecting to %s", fUpstream); fClient = jack_client_open(fClientName, static_cast<jack_options_t>(JackNoStartServer|JackServerName), &status, fUpstream); if (fPromiscuous) { // restore previous environment variable content if (old) { if (setenv("JACK_PROMISCUOUS_SERVER", old, 1) < 0) { free(old); jack_error("Error allocating memory."); return false; } free(old); } else { unsetenv("JACK_PROMISCUOUS_SERVER"); } } // the connection failed, try again later if (!fClient) { JackSleep(1000000); } } while (!fClient); jack_info("JackProxyDriver connected to %s", fUpstream); // we are connected, let's register some callbacks jack_on_shutdown(fClient, shutdown_callback, this); if (jack_set_process_callback(fClient, process_callback, this) != 0) { jack_error("Cannot set process callback."); return false; } if (jack_set_buffer_size_callback(fClient, bufsize_callback, this) != 0) { jack_error("Cannot set buffer size callback."); return false; } if (jack_set_sample_rate_callback(fClient, srate_callback, this) != 0) { jack_error("Cannot set sample rate callback."); return false; } if (jack_set_port_connect_callback(fClient, connect_callback, this) != 0) { jack_error("Cannot set port connect callback."); return false; } // detect upstream physical playback ports if needed if (fDetectPlaybackChannels) { fPlaybackChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput); } // detect upstream physical capture ports if needed if (fDetectCaptureChannels) { fCaptureChannels = CountIO(JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput); } if (AllocPorts() != 0) { jack_error("Can't allocate ports."); return false; } bufsize_callback(jack_get_buffer_size(fClient)); srate_callback(jack_get_sample_rate(fClient)); // restore local connections if needed if (fAutoSave) { LoadConnections(0); } // everything is ready, start upstream processing if (jack_activate(fClient) != 0) { jack_error("Cannot activate jack client."); return false; } // connect upstream ports if needed if (fAutoConnect) { ConnectPorts(); } return true; }
ExternalMetro::ExternalMetro(int freq, double max_amp, int dur_arg, int bpm, const char* client_name) { sample_t scale; int i, attack_length, decay_length; int attack_percent = 1, decay_percent = 10; const char *bpm_string = "bpm"; jack_options_t options = JackNullOption; jack_status_t status; offset = 0; /* Initial Jack setup, get sample rate */ if ((client = jack_client_open (client_name, options, &status)) == 0) { fprintf (stderr, "jack server not running?\n"); throw -1; } jack_set_process_callback (client, process_audio, this); jack_on_shutdown (client, shutdown, this); output_port = jack_port_register (client, bpm_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); input_port = jack_port_register (client, "metro_in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); sr = jack_get_sample_rate (client); /* setup wave table parameters */ wave_length = 60 * sr / bpm; tone_length = sr * dur_arg / 1000; attack_length = tone_length * attack_percent / 100; decay_length = tone_length * decay_percent / 100; scale = 2 * PI * freq / sr; if (tone_length >= wave_length) { /* fprintf (stderr, "invalid duration (tone length = %" PRIu32 ", wave length = %" PRIu32 "\n", tone_length, wave_length); */ return ; } if (attack_length + decay_length > (int)tone_length) { fprintf (stderr, "invalid attack/decay\n"); return ; } /* Build the wave table */ wave = (sample_t *) malloc (wave_length * sizeof(sample_t)); amp = (double *) malloc (tone_length * sizeof(double)); for (i = 0; i < attack_length; i++) { amp[i] = max_amp * i / ((double) attack_length); } for (i = attack_length; i < (int) tone_length - decay_length; i++) { amp[i] = max_amp; } for (i = (int)tone_length - decay_length; i < (int)tone_length; i++) { amp[i] = - max_amp * (i - (double) tone_length) / ((double) decay_length); } for (i = 0; i < (int) tone_length; i++) { wave[i] = amp[i] * sin (scale * i); } for (i = tone_length; i < (int) wave_length; i++) { wave[i] = 0; } if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); } }
gboolean cbox_io_init_jack(struct cbox_io *io, struct cbox_open_params *const params, struct cbox_command_target *fb, GError **error) { const char *client_name = cbox_config_get_string_with_default("io", "client_name", "cbox"); jack_client_t *client = NULL; jack_status_t status = 0; client = jack_client_open(client_name, JackNoStartServer, &status); if (client == NULL) { if (!cbox_hwcfg_setup_jack()) { g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot set up JACK server configuration based on current hardware"); return FALSE; } status = 0; client = jack_client_open(client_name, 0, &status); } if (client == NULL) { g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create JACK instance"); return FALSE; } // XXXKF would use a callback instead io->io_env.buffer_size = jack_get_buffer_size(client); io->cb = NULL; io->io_env.input_count = cbox_config_get_int("io", "inputs", 0); io->input_buffers = malloc(sizeof(float *) * io->io_env.input_count); io->io_env.output_count = cbox_config_get_int("io", "outputs", 2); io->output_buffers = malloc(sizeof(float *) * io->io_env.output_count); struct cbox_jack_io_impl *jii = malloc(sizeof(struct cbox_jack_io_impl)); io->impl = &jii->ioi; jii->enable_common_midi_input = cbox_config_get_int("io", "enable_common_midi_input", 1); jii->debug_transport = cbox_config_get_int("debug", "jack_transport", 0); jii->last_transport_state = JackTransportStopped; jii->external_tempo = FALSE; cbox_command_target_init(&io->cmd_target, cbox_jack_io_process_cmd, jii); jii->ioi.pio = io; jii->ioi.getsampleratefunc = cbox_jackio_get_sample_rate; jii->ioi.startfunc = cbox_jackio_start; jii->ioi.stopfunc = cbox_jackio_stop; jii->ioi.getstatusfunc = cbox_jackio_get_status; jii->ioi.pollfunc = cbox_jackio_poll_ports; jii->ioi.cyclefunc = cbox_jackio_cycle; jii->ioi.getmidifunc = cbox_jackio_get_midi_data; jii->ioi.createmidiinfunc = cbox_jackio_create_midi_in; jii->ioi.destroymidiinfunc = cbox_jackio_destroy_midi_in; jii->ioi.createmidioutfunc = cbox_jackio_create_midi_out; jii->ioi.destroymidioutfunc = cbox_jackio_destroy_midi_out; jii->ioi.updatemidiinroutingfunc = cbox_jackio_update_midi_in_routing; jii->ioi.createaudiooutfunc = cbox_jackio_create_audio_out; jii->ioi.destroyaudiooutfunc = cbox_jackio_destroy_audio_out; jii->ioi.controltransportfunc = cbox_jackio_control_transport; jii->ioi.getsynccompletedfunc = cbox_jackio_get_sync_completed; jii->ioi.destroyfunc = cbox_jackio_destroy; jii->client_name = g_strdup(jack_get_client_name(client)); jii->client = client; jii->rb_autoconnect = jack_ringbuffer_create(sizeof(jack_port_t *) * 128); jii->error_str = NULL; io->io_env.srate = jack_get_sample_rate(client); jii->inputs = malloc(sizeof(jack_port_t *) * io->io_env.input_count); jii->outputs = malloc(sizeof(jack_port_t *) * io->io_env.output_count); for (uint32_t i = 0; i < io->io_env.input_count; i++) jii->inputs[i] = NULL; for (uint32_t i = 0; i < io->io_env.output_count; i++) jii->outputs[i] = NULL; for (uint32_t i = 0; i < io->io_env.input_count; i++) { gchar *name = g_strdup_printf("in_%d", 1 + i); jii->inputs[i] = jack_port_register(jii->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); if (!jii->inputs[i]) { g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create input port %d (%s)", i, name); g_free(name); goto cleanup; } g_free(name); } for (uint32_t i = 0; i < io->io_env.output_count; i++) { gchar *name = g_strdup_printf("out_%d", 1 + i); jii->outputs[i] = jack_port_register(jii->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (!jii->outputs[i]) { g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create output port %d (%s)", i, name); g_free(name); goto cleanup; } g_free(name); } if (jii->enable_common_midi_input) { jii->midi = jack_port_register(jii->client, "midi", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); if (!jii->midi) { g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot create MIDI port"); return FALSE; } } else jii->midi = NULL; if (fb) cbox_execute_on(fb, NULL, "/io/jack_client_name", "s", NULL, jii->client_name); cbox_io_poll_ports(io, fb); return TRUE; cleanup: if (jii->inputs) { for (uint32_t i = 0; i < io->io_env.input_count; i++) free(jii->inputs[i]); free(jii->inputs); } if (jii->outputs) { for (uint32_t i = 0; i < io->io_env.output_count; i++) free(jii->outputs[i]); free(jii->outputs); } cbox_io_destroy_all_midi_ports(io); if (jii->client_name) free(jii->client_name); jack_client_close(jii->client); free(jii); io->impl = NULL; return FALSE; };
int pa__init(pa_module*m) { struct userdata *u = NULL; pa_sample_spec ss; pa_channel_map map; pa_modargs *ma = NULL; jack_status_t status; const char *server_name, *client_name; uint32_t channels = 0; bool do_connect = true; unsigned i; const char **ports = NULL, **p; pa_sink_new_data data; jack_latency_range_t r; size_t n; pa_assert(m); jack_set_error_function(jack_error_func); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); goto fail; } if (pa_modargs_get_value_boolean(ma, "connect", &do_connect) < 0) { pa_log("Failed to parse connect= argument."); goto fail; } server_name = pa_modargs_get_value(ma, "server_name", NULL); client_name = pa_modargs_get_value(ma, "client_name", "PulseAudio JACK Sink"); m->userdata = u = pa_xnew0(struct userdata, 1); u->core = m->core; u->module = m; u->saved_frame_time_valid = false; u->rtpoll = pa_rtpoll_new(); pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); /* The queue linking the JACK thread and our RT thread */ u->jack_msgq = pa_asyncmsgq_new(0); /* The msgq from the JACK RT thread should have an even higher * priority than the normal message queues, to match the guarantee * all other drivers make: supplying the audio device with data is * the top priority -- and as long as that is possible we don't do * anything else */ u->rtpoll_item = pa_rtpoll_item_new_asyncmsgq_read(u->rtpoll, PA_RTPOLL_EARLY-1, u->jack_msgq); if (!(u->client = jack_client_open(client_name, server_name ? JackServerName : JackNullOption, &status, server_name))) { pa_log("jack_client_open() failed."); goto fail; } ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsInput); channels = 0; if (ports) for (p = ports; *p; p++) channels++; if (!channels) channels = m->core->default_sample_spec.channels; if (pa_modargs_get_value_u32(ma, "channels", &channels) < 0 || !pa_channels_valid(channels)) { pa_log("Failed to parse channels= argument."); goto fail; } if (channels == m->core->default_channel_map.channels) map = m->core->default_channel_map; else pa_channel_map_init_extend(&map, channels, PA_CHANNEL_MAP_ALSA); if (pa_modargs_get_channel_map(ma, NULL, &map) < 0 || map.channels != channels) { pa_log("Failed to parse channel_map= argument."); goto fail; } pa_log_info("Successfully connected as '%s'", jack_get_client_name(u->client)); u->channels = ss.channels = (uint8_t) channels; ss.rate = jack_get_sample_rate(u->client); ss.format = PA_SAMPLE_FLOAT32NE; pa_assert(pa_sample_spec_valid(&ss)); for (i = 0; i < ss.channels; i++) { if (!(u->port[i] = jack_port_register(u->client, pa_channel_position_to_string(map.map[i]), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput|JackPortIsTerminal, 0))) { pa_log("jack_port_register() failed."); goto fail; } } pa_sink_new_data_init(&data); data.driver = __FILE__; data.module = m; pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME)); pa_sink_new_data_set_sample_spec(&data, &ss); pa_sink_new_data_set_channel_map(&data, &map); pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "jack"); if (server_name) pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, server_name); pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Jack sink (%s)", jack_get_client_name(u->client)); pa_proplist_sets(data.proplist, "jack.client_name", jack_get_client_name(u->client)); if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) { pa_log("Invalid properties"); pa_sink_new_data_done(&data); goto fail; } u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY); pa_sink_new_data_done(&data); if (!u->sink) { pa_log("Failed to create sink."); goto fail; } u->sink->parent.process_msg = sink_process_msg; u->sink->userdata = u; pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_rtpoll(u->sink, u->rtpoll); pa_sink_set_max_request(u->sink, jack_get_buffer_size(u->client) * pa_frame_size(&u->sink->sample_spec)); jack_set_process_callback(u->client, jack_process, u); jack_on_shutdown(u->client, jack_shutdown, u); jack_set_thread_init_callback(u->client, jack_init, u); jack_set_buffer_size_callback(u->client, jack_buffer_size, u); if (!(u->thread = pa_thread_new("jack-sink", thread_func, u))) { pa_log("Failed to create thread."); goto fail; } if (jack_activate(u->client)) { pa_log("jack_activate() failed"); goto fail; } if (do_connect) { for (i = 0, p = ports; i < ss.channels; i++, p++) { if (!p || !*p) { pa_log("Not enough physical output ports, leaving unconnected."); break; } pa_log_info("Connecting %s to %s", jack_port_name(u->port[i]), *p); if (jack_connect(u->client, jack_port_name(u->port[i]), *p)) { pa_log("Failed to connect %s to %s, leaving unconnected.", jack_port_name(u->port[i]), *p); break; } } } jack_port_get_latency_range(u->port[0], JackPlaybackLatency, &r); n = r.max * pa_frame_size(&u->sink->sample_spec); pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(n, &u->sink->sample_spec)); pa_sink_put(u->sink); if (ports) jack_free(ports); pa_modargs_free(ma); return 0; fail: if (ma) pa_modargs_free(ma); if (ports) jack_free(ports); pa__done(m); return -1; }
void * start_jack_client(void *ptr) { const char *client_name = "filter"; const char *server_name = NULL; jack_options_t options = (JackNoStartServer|JackUseExactName|JackSessionID); jack_status_t status; /* open a client connection to 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", status); if (status & JackServerFailed) { fprintf (stderr, "Unable to connect to JACK server\n"); } exit (1); } if (status & JackServerStarted) { fprintf (stderr, "JACK server started\n"); } if (status & JackNameNotUnique) { client_name = jack_get_client_name(client); fprintf (stderr, "unique name `%s' assigned\n", client_name); } /* 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 `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); /* display the current sample rate. */ printf ("engine sample rate: %" PRIu32 "\n", jack_get_sample_rate (client)); /* create two ports */ input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); output_port = jack_port_register (client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if ((input_port == NULL) || (output_port == NULL)) { fprintf(stderr, "no more JACK ports available\n"); exit (1); } /* create and initialize the control list */ ctrls = malloc(sizeof(control_list)); /* set with default values */ ctrls->ftype = LPF; ctrls->dBgain = 0; // dB value ctrls->fc = 100; //Hz value ctrls->fs = (smp_type)jack_get_sample_rate(client); ctrls->bw = 0.25; //bandwidth (ocataves) /* Compute default biquad lpf */ filter = compute_biquad(ctrls->ftype, ctrls->dBgain, ctrls->fc, ctrls->fs, ctrls->bw); printf("initial coefficients:\n"); printf("b0=%f, b1=%f, b2=%f, a1=%f, a2=%f \n", filter->b0, filter->b1, filter->b2, filter->a1, filter->a2); /* Tell the JACK server that we are ready to roll. Our * process() callback will start running now. */ if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); exit (1); } /* Connect the ports. You can't do this before the client is * activated, because we can't make connections to clients * that aren't running. Note the confusing (but necessary) * orientation of the driver backend ports: playback ports are * "input" to the backend, and capture ports are "output" from * it. */ /********************************************************** Automatic Port Connections! -> Not usually recommended! *********************************************************** const char **ports; ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput); if (ports == NULL) { fprintf(stderr, "no physical capture ports\n"); exit (1); } if (jack_connect (client, ports[0], jack_port_name (input_port))) { fprintf (stderr, "cannot connect input ports\n"); } free (ports); ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput); if (ports == NULL) { fprintf(stderr, "no physical playback ports\n"); exit (1); } if (jack_connect (client, jack_port_name (output_port), ports[0])) { fprintf (stderr, "cannot connect output ports\n"); } free (ports); */ /* keep running until stopped by the user */ sleep (-1); /* this is never reached, but if the program had some other way to exit besides being killed, they would be important to call. */ jack_client_close (client); exit (0); }
int main (int argc, char *argv[]) { const char **ports; const char *client_name = "simple"; const char *server_name = NULL; jack_options_t options = JackNullOption; jack_status_t status; /* open a client connection to 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", status); if (status & JackServerFailed) { fprintf (stderr, "Unable to connect to JACK server\n"); } exit (1); } if (status & JackServerStarted) { fprintf (stderr, "JACK server started\n"); } if (status & JackNameNotUnique) { client_name = jack_get_client_name(client); fprintf (stderr, "unique name `%s' assigned\n", client_name); } /* 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 `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); /* display the current sample rate. */ printf ("engine sample rate: %" PRIu32 "\n", jack_get_sample_rate (client)); /* create two ports */ input_port = jack_port_register (client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); output_port = jack_port_register (client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if ((input_port == NULL) || (output_port == NULL)) { fprintf(stderr, "no more JACK ports available\n"); exit (1); } /* Tell the JACK server that we are ready to roll. Our * process() callback will start running now. */ if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); exit (1); } /* Connect the ports. You can't do this before the client is * activated, because we can't make connections to clients * that aren't running. Note the confusing (but necessary) * orientation of the driver backend ports: playback ports are * "input" to the backend, and capture ports are "output" from * it. */ ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput); if (ports == NULL) { fprintf(stderr, "no physical capture ports\n"); exit (1); } if (jack_connect (client, ports[0], jack_port_name (input_port))) { fprintf (stderr, "cannot connect input ports\n"); } free (ports); ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput); if (ports == NULL) { fprintf(stderr, "no physical playback ports\n"); exit (1); } if (jack_connect (client, jack_port_name (output_port), ports[0])) { fprintf (stderr, "cannot connect output ports\n"); } free (ports); /* keep running until stopped by the user */ sleep (-1); /* this is never reached but if the program had some other way to exit besides being killed, they would be important to call. */ jack_client_close (client); exit (0); }
int main (int argc, char *argv[]) { fprintf(stderr, "tmrd v%s\n", VERSION); parseArgs(argc, argv); attach_sig_handler(); jack_client_t *client; const char **ports; /* init jack */ if ((client = jack_client_new ("smp")) == 0) { fprintf (stderr, "jack server not running?\n"); return 1; } jack_set_process_callback (client, process, 0); jack_on_shutdown (client, jack_shutdown, 0); sample_rate = jack_get_sample_rate (client); printf ("engine sample rate: %u\n", sample_rate); /* create a delay buffer for each channel */ buffer = (jack_default_audio_sample_t**)malloc(2*sizeof(jack_default_audio_sample_t**)); /* div by 10 since time is in tenths of secs */ buf_frames = max_delay_time*sample_rate/10; buffer[0] = (jack_default_audio_sample_t*)malloc(buf_frames*sizeof(jack_default_audio_sample_t)); buffer[1] = (jack_default_audio_sample_t*)malloc(buf_frames*sizeof(jack_default_audio_sample_t)); memset(buffer[0], 0, buf_frames*sizeof(jack_default_audio_sample_t)); memset(buffer[1], 0, buf_frames*sizeof(jack_default_audio_sample_t)); printf("buffer frames: %d\n", buf_frames); /* create two input ports and two output ports */ input_port = (jack_port_t**)malloc(2*sizeof(jack_port_t**)); output_port = (jack_port_t**)malloc(2*sizeof(jack_port_t**)); input_port[0] = jack_port_register (client, "input0", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); input_port[1] = jack_port_register (client, "input1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); output_port[0] = jack_port_register (client, "output0", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); output_port[1] = jack_port_register (client, "output1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); /* start jack */ if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); return 1; } if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == NULL) { fprintf(stderr, "Cannot find any physical capture ports\n"); exit(1); } if (jack_connect (client, ports[0], jack_port_name (input_port[0]))) fprintf (stderr, "cannot connect input ports\n"); if (jack_connect (client, ports[1], jack_port_name (input_port[1]))) fprintf (stderr, "cannot connect input ports\n"); free (ports); if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) { fprintf(stderr, "Cannot find any physical playback ports\n"); exit(1); } if (jack_connect (client, jack_port_name (output_port[0]), ports[0])) fprintf (stderr, "cannot connect output ports\n"); if (jack_connect (client, jack_port_name (output_port[1]), ports[1])) fprintf (stderr, "cannot connect output ports\n"); free (ports); run_ui(); /* start the ui, listen for keyboard input */ jack_client_close (client); 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); }
bool SC_JackDriver::DriverSetup(int* outNumSamples, double* outSampleRate) { char* clientName = 0; char* serverName = 0; if (mWorld->hw->mInDeviceName && (strlen(mWorld->hw->mInDeviceName) > 0)) { // parse string <serverName>:<clientName> SC_StringParser sp(mWorld->hw->mInDeviceName, ':'); if (!sp.AtEnd()) serverName = strdup(sp.NextToken()); if (!sp.AtEnd()) clientName = strdup(sp.NextToken()); if (clientName == 0) { // no semicolon found clientName = serverName; serverName = 0; } else if (strlen(clientName) == 0) { free(clientName); clientName = 0; } } #ifdef SC_USE_JACK_CLIENT_NEW // old style client startup for Jack <0.100 -- AG if (clientName) { mClient = jack_client_new(clientName); } else { clientName = strdup("SuperCollider"); mClient = jack_client_new(clientName); if (mClient == 0) { char uniqueName[64]; sprintf(uniqueName, "SuperCollider-%d", getpid()); clientName = strdup(uniqueName); mClient = jack_client_new(uniqueName); } } if (mClient) scprintf("%s: client name is '%s'\n", kJackDriverIdent, clientName); if (serverName) free(serverName); if (clientName) free(clientName); if (mClient == 0) return false; #else mClient = jack_client_open( clientName ? clientName : kJackDefaultClientName, serverName ? JackServerName : JackNullOption, NULL, serverName); if (serverName) free(serverName); if (clientName) free(clientName); if (mClient == 0) return false; scprintf("%s: client name is '%s'\n", kJackDriverIdent, jack_get_client_name(mClient)); #endif // create jack I/O ports mInputList = new SC_JackPortList(mClient, mWorld->mNumInputs, JackPortIsInput); mOutputList = new SC_JackPortList(mClient, mWorld->mNumOutputs, JackPortIsOutput); // register callbacks jack_set_process_callback(mClient, sc_jack_process_cb, this); jack_set_buffer_size_callback(mClient, sc_jack_bufsize_cb, this); jack_set_sample_rate_callback(mClient, sc_jack_srate_cb, this); jack_set_graph_order_callback(mClient, sc_jack_graph_order_cb, this); jack_set_xrun_callback(mClient, sc_jack_xrun_cb, this); jack_on_shutdown(mClient, sc_jack_shutdown_cb, mWorld); *outNumSamples = (int)jack_get_buffer_size(mClient); *outSampleRate = (double)jack_get_sample_rate(mClient); return true; }
static int init(int rate, const struct mp_chmap *channels, int format, int flags) { const char **matching_ports = NULL; char *port_name = NULL; char *client_name = NULL; int autostart = 0; int connect = 1; const opt_t subopts[] = { {"port", OPT_ARG_MSTRZ, &port_name, NULL}, {"name", OPT_ARG_MSTRZ, &client_name, NULL}, {"estimate", OPT_ARG_BOOL, &estimate, NULL}, {"autostart", OPT_ARG_BOOL, &autostart, NULL}, {"connect", OPT_ARG_BOOL, &connect, NULL}, {NULL} }; jack_options_t open_options = JackUseExactName; int port_flags = JackPortIsInput; int i; estimate = 1; if (subopt_parse(ao_subdevice, subopts) != 0) { print_help(); return 0; } struct mp_chmap_sel sel = {0}; mp_chmap_sel_add_waveext(&sel); if (!ao_chmap_sel_adjust(&ao_data, &sel, &ao_data.channels)) goto err_out; if (!client_name) { client_name = malloc(40); sprintf(client_name, "mpv [%d]", getpid()); } if (!autostart) open_options |= JackNoStartServer; client = jack_client_open(client_name, open_options, NULL); if (!client) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] cannot open server\n"); goto err_out; } buffer = av_fifo_alloc(BUFFSIZE); jack_set_process_callback(client, outputaudio, 0); // list matching ports if connections should be made if (connect) { if (!port_name) port_flags |= JackPortIsPhysical; matching_ports = jack_get_ports(client, port_name, NULL, port_flags); if (!matching_ports || !matching_ports[0]) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] no physical ports available\n"); goto err_out; } i = 1; num_ports = ao_data.channels.num; while (matching_ports[i]) i++; if (num_ports > i) num_ports = i; } // create out output ports for (i = 0; i < num_ports; i++) { char pname[30]; snprintf(pname, 30, "out_%d", i); ports[i] = jack_port_register(client, pname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (!ports[i]) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] not enough ports available\n"); goto err_out; } } if (jack_activate(client)) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] activate failed\n"); goto err_out; } for (i = 0; i < num_ports; i++) { if (jack_connect(client, jack_port_name(ports[i]), matching_ports[i])) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] connecting failed\n"); goto err_out; } } rate = jack_get_sample_rate(client); jack_latency_range_t jack_latency_range; jack_port_get_latency_range(ports[0], JackPlaybackLatency, &jack_latency_range); jack_latency = (float)(jack_latency_range.max + jack_get_buffer_size(client)) / (float)rate; callback_interval = 0; if (!ao_chmap_sel_get_def(&ao_data, &sel, &ao_data.channels, num_ports)) goto err_out; ao_data.samplerate = rate; ao_data.format = AF_FORMAT_FLOAT_NE; ao_data.bps = ao_data.channels.num * rate * sizeof(float); ao_data.buffersize = CHUNK_SIZE * NUM_CHUNKS; ao_data.outburst = CHUNK_SIZE; free(matching_ports); free(port_name); free(client_name); return 1; err_out: free(matching_ports); free(port_name); free(client_name); if (client) jack_client_close(client); av_fifo_free(buffer); buffer = NULL; return 0; }
uint32_t JackAudioSystem::sample_rate() { if( !_client ) return 0; return jack_get_sample_rate(_client); }
void synthv1_jack::open ( const char *client_id ) { // init param ports for (uint32_t i = 0; i < synthv1::NUM_PARAMS; ++i) { const synthv1::ParamIndex index = synthv1::ParamIndex(i); m_params[i] = synthv1_param::paramDefaultValue(index); synthv1::setParamPort(index, &m_params[i]); } // open client m_client = ::jack_client_open(client_id, JackNullOption, NULL); if (m_client == NULL) return; // set sample rate synthv1::setSampleRate(float(jack_get_sample_rate(m_client))); // synthv1::reset(); // register audio ports & buffers uint16_t nchannels = synthv1::channels(); m_audio_ins = new jack_port_t * [nchannels]; m_audio_outs = new jack_port_t * [nchannels]; m_ins = new float * [nchannels]; m_outs = new float * [nchannels]; char port_name[32]; for (uint16_t k = 0; k < nchannels; ++k) { ::snprintf(port_name, sizeof(port_name), "in_%d", k + 1); m_audio_ins[k] = ::jack_port_register(m_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); m_ins[k] = NULL; ::snprintf(port_name, sizeof(port_name), "out_%d", k + 1); m_audio_outs[k] = ::jack_port_register(m_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); m_outs[k] = NULL; } // register midi port #ifdef CONFIG_JACK_MIDI m_midi_in = ::jack_port_register(m_client, "in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); #endif #ifdef CONFIG_ALSA_MIDI m_alsa_seq = NULL; // m_alsa_client = -1; m_alsa_port = -1; m_alsa_decoder = NULL; m_alsa_buffer = NULL; m_alsa_thread = NULL; // open alsa sequencer client... if (snd_seq_open(&m_alsa_seq, "hw", SND_SEQ_OPEN_INPUT, 0) >= 0) { snd_seq_set_client_name(m_alsa_seq, client_id); // m_alsa_client = snd_seq_client_id(m_alsa_seq); m_alsa_port = snd_seq_create_simple_port(m_alsa_seq, "in", SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); snd_midi_event_new(1024, &m_alsa_decoder); m_alsa_buffer = ::jack_ringbuffer_create( 1024 * (sizeof(jack_midi_event_t) + 4)); m_alsa_thread = new synthv1_alsa_thread(this); m_alsa_thread->start(QThread::TimeCriticalPriority); } #endif // CONFIG_ALSA_MIDI // setup any local buffers synthv1::setBufferSize(::jack_get_buffer_size(m_client)); // set process callbacks... ::jack_set_process_callback(m_client, synthv1_jack_process, this); #ifdef CONFIG_JACK_SESSION // JACK session event callback... if (::jack_set_session_callback) { ::jack_set_session_callback(m_client, synthv1_jack_session_event, this); } #endif }
/*static*/ int jack_init (cubeb ** context, char const * context_name) { int r; if(context == NULL) { return CUBEB_ERROR; } *context = NULL; cubeb *ctx = (cubeb*)calloc(1, sizeof(*ctx)); if(ctx == NULL) { return CUBEB_ERROR; } r = pthread_mutex_init(&ctx->mutex, NULL); if(r != 0) { cbjack_destroy(ctx); return CUBEB_ERROR; } ctx->ops = &cbjack_ops; const char* jack_client_name = "cubeb"; if(context_name) jack_client_name = context_name; ctx->jack_client = jack_client_open (jack_client_name, JackNoStartServer, NULL); if (ctx->jack_client == NULL) { cbjack_destroy(ctx); return CUBEB_ERROR; } ctx->jack_sample_rate = jack_get_sample_rate(ctx->jack_client); jack_set_process_callback (ctx->jack_client, cbjack_process, ctx); if (jack_activate (ctx->jack_client)) { cbjack_destroy(ctx); return CUBEB_ERROR; } for(int s = 0; s < MAX_STREAMS; s++) { for (int c = 0; c < MAX_CHANNELS; c++) { ctx->streams[s].ringbuffer[c] = jack_ringbuffer_create(FIFO_SIZE); if(!ctx->streams[s].ringbuffer[c]) { cbjack_destroy(ctx); return CUBEB_ERROR; } } } ctx->active = true; int ret = pthread_create (&ctx->stream_refill_thread, NULL, stream_refill_thread, (void *)ctx); if(ret != 0) { ctx->stream_refill_thread = 0; cbjack_destroy(ctx); return CUBEB_ERROR; } *context = ctx; return CUBEB_OK; }
int main(int argc, char **argv) { char opts[NELEM(long_opts) * 3 + 1]; char *cp; int c; struct option *op; /* Build up the short option string */ cp = opts; for (op = long_opts; op < &long_opts[NELEM(long_opts)]; op++) { *cp++ = op->val; if (op->has_arg) *cp++ = ':'; } /* Deal with the options */ for (;;) { c = getopt_long(argc, argv, opts, long_opts, NULL); if (c == -1) break; switch(c) { case 'v': main_showversion(); exit(0); case 'd': be_jack_client = 0; break; case 's': be_server = 1; break; default: main_showusage(); exit(1); } } if (optind >= argc) { printf("No input files!\n"); main_showusage(); exit( 1); } if (optind < argc-1) { printf("Too many input files!\n"); main_showusage(); exit( 1); } if (!jpmidi_init()) { fprintf( stderr, "Failed to initialize jpmidi, errno = %d\n", errno); exit( errno); } dump_init(); jack_nframes_t jack_sample_rate = 44100; if (be_jack_client) { if (jackclient_new( "jpmidi")) return 1; jack_sample_rate = jack_get_sample_rate(jackclient_get_client()); } else printf("Not connecting to jack, assuming sample rate of %d\n", jack_sample_rate); root = jpmidi_loadfile(argv[optind], jack_sample_rate); printf("loaded %s\n", root->filename); if (be_jack_client && jackclient_activate()) return 1; /* launch either command line or server mode */ if (be_server) { tcpserver(TCPPORT); } else { cmdline(); } if (be_jack_client && jackclient_deactivate()) return 1; if (be_jack_client && jackclient_close()) return 1; return 0; }