Beispiel #1
0
    String open (const BigInteger& inputChannels, const BigInteger& outputChannels,
                 double /* sampleRate */, int /* bufferSizeSamples */)
    {
        jack_Log ("opening client");
        lastError = client.open (KV_JACK_NAME, 0);
        if (lastError.isNotEmpty())
        {
            jack_Log (lastError);
            return lastError;
        }

        DBG("num inputs: " << inputChannels.getHighestBit());
        DBG("num outputs: " << outputChannels.getHighestBit());


        jack_on_shutdown (client, JackDevice::shutdownCallback, this);
        jack_set_error_function (JackDevice::errorCallback);
        jack_set_port_connect_callback (client, JackDevice::portConnectCallback, this);
        jack_set_process_callback (client, JackDevice::processCallback, this);
        jack_set_thread_init_callback (client, JackDevice::threadInitCallback, this);
        jack_set_port_registration_callback (client, JackDevice::_portRegistration, this);

        client.registerPort ("audio_1", Jack::audioPort, JackPortIsOutput);
        client.registerPort ("audio_2", Jack::audioPort, JackPortIsOutput);

        return lastError;
    }
int main( int argc, char** argv )
{
    if( argc != 3 )
    {
        printf( "%s", "Usage arguments: -play somefile.wav\n" );
        
        return 1;
    }
    
    DEBUG( "InitDummy" );   

    jack_set_error_function( error );
    
    WavReader WavFile;
   
    WavFile.open( argv[2] );

    WavFile.read( );
    
    WavFile.close( );

    WavReader * WavFilePtr = &WavFile;

    SamplerClass Sampler( WavFilePtr );

    SamplerClass * SamplerPtr = &Sampler;

    SoundEngineClass * PolySampler = SamplerPtr;
    
    Sampler.setSampleIterator( SamplerPtr->getSoundFile()->begin() /*- 1000000*/ );
    
    PolySampler->OpenClient( client, "Wav Sampler" );

    PolySampler->setProcessCallback( SamplerPtr->Process, SamplerPtr );

    PolySampler->setSampleRateCallback( SamplerPtr->SampleRate, SamplerPtr );

    PolySampler->setLeftChannelOutputPort( "DAW_LEFT_CHANNEL" );

    PolySampler->setRightChannelOutputPort( "DAW_RIGHT_CHANNEL" );

    PolySampler->ActivateClient( );

    PolySampler->ConnectPorts( );

    INFO( "Bits per sample " << *WavFile.getBitsPerSample( ) );

    STATUS( "Now Playing - " << argv[2] );
	
	INFO( "WavFile Sample Rate is: " << *WavFile.getSampleRate() );	

    while( !SamplerPtr->isAtEnd() )
    {
        sleep( 1 );
    }
   
    return 0;

}
Beispiel #3
0
JackCpp::AudioIO::AudioIO(std::string name, unsigned int inPorts, unsigned int outPorts, bool startServer) 
	throw(std::runtime_error) : mCmdBuffer(256,true)
{
	jack_options_t jack_open_options = JackNullOption;

	if(startServer == false)
		jack_open_options = JackNoStartServer;

	mJackState = notActive;

	//set the error callback
	jack_set_error_function (error_callback);

	/* try to become a client of the JACK server */
	if ((mJackClient = jack_client_open (name.c_str(), jack_open_options, NULL)) == 0) {
		throw std::runtime_error("cannot create client jack server not running?");
	} 
#ifdef __APPLE__
	else {
		// because the mac version of jack is being totally LAME
		sleep(2);
	}
#endif 

	//set the shutdown callback
	jack_on_shutdown (mJackClient, shutdown_callback, this);

	//allocate ports
	if (inPorts > 0){
		for(unsigned int i = 0; i < inPorts; i++){
			std::string portname = "input";
			portname.append(ToString(i));
			mInputPorts.push_back(
					jack_port_register (mJackClient, portname.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0));
			mPortNames.push_back(portname);
		}
		//reserve the data for the jack callback buffers
		for(unsigned int i = 0; i < mInputPorts.size(); i++)
			mJackInBuf.push_back(NULL);
	} 
	if (outPorts > 0){
		for(unsigned int i = 0; i < outPorts; i++){
			std::string portname = "output";
			portname.append(ToString(i));
			mOutputPorts.push_back(
					jack_port_register (mJackClient, portname.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0));
			mPortNames.push_back(portname);
		}
		//reserve the data for the jack callback buffers
		for(unsigned int i = 0; i < mOutputPorts.size(); i++)
			mJackOutBuf.push_back(NULL);
	} 

	//set up the callback
	if(0 != jack_set_process_callback (mJackClient, JackCpp::AudioIO::jackProcessCallback, this))
		throw std::runtime_error("cannot register process callback");
}
void
gst_jack_audio_client_init (void)
{
  GST_DEBUG_CATEGORY_INIT (gst_jack_audio_client_debug, "jackclient", 0,
      "jackclient helpers");

  jack_set_error_function (jack_log_error);
  jack_set_info_function (jack_info_error);
}
Beispiel #5
0
jack_raw_output::jack_raw_output (const char* client,
                                  const char* server,
                                  int         rate,
                                  int         channels,
                                  callback_type cb)
    : detail::async_base_impl (cb)
    , _out_ports (channels)
    , _buffer_size (0)
{
    jack_set_error_function (log_jack_error);
    jack_set_info_function (log_jack_info);
    
    jack_options_t options = !server ? JackNullOption : JackServerName; 
    _client = jack_client_open (client, options, 0, server);
    if (!_client) throw jack_open_error ();

    auto grd_client = base::make_guard ([&] { jack_client_close (_client); });
    
    PSYNTH_JACK_CHECK (jack_set_process_callback (
                           _client, &jack_raw_output::_process_cb, this),
                       jack_param_error);
    PSYNTH_JACK_CHECK (jack_set_sample_rate_callback (
                           _client, &jack_raw_output::_sample_rate_cb, this),
                       jack_param_error);

    jack_on_shutdown (_client, &jack_raw_output::_shutdown_cb, this);
	
    _actual_rate = jack_get_sample_rate (_client);
    if (_actual_rate != rate)
        PSYNTH_LOG
            << base::log::warning
            << "Jackd sample rate and application sample rate mismatch."
            << "Better sound quality is achieved if both are the same.";


    _buffer_size = jack_get_buffer_size (_client);
    PSYNTH_LOG << base::log::info
               << "Jackd buffer size is: " << _buffer_size;
    
    for (size_t i = 0; i < _out_ports.size(); ++i)
    {
        std::string port_name = std::string ("out_") +
            boost::lexical_cast<std::string> (i);
        
        _out_ports [i] = jack_port_register (
            _client, port_name.c_str (), JACK_DEFAULT_AUDIO_TYPE,
            JackPortIsOutput, 0);
        
        if (_out_ports [i] == 0)
            throw jack_param_error ();
    }
    
    grd_client.dismiss ();
}
Beispiel #6
0
static SCM start_jack(void *data) {
	int i;
	char name[16];
	jack_status_t jstatus;
	jack_client = jack_client_open(client_name,
					JackServerName,
					&jstatus, server_name);
	if (jack_client == 0) {
		log_msg("JACK server not running?\n") ;
		cleanup();
		return SCM_UNSPECIFIED;
		}
	log_msg("JACK status: %04x\n", jstatus);
	if (jstatus & JackServerStarted)
		log_msg("\tserver started\n");
	if (jstatus & JackServerFailed)
		log_msg("\tcan't connect\n");
	if (jstatus & JackInitFailure)
		log_msg("\tcan't initialize client\n");
	client_name = (const char *)jack_get_client_name(jack_client);
	sampling_rate = jack_get_sample_rate(jack_client) ;
	period_frames = jack_get_buffer_size(jack_client);
	jack_set_error_function(jack_error);
	jack_set_info_function(jack_info);
	jack_set_xrun_callback(jack_client, jack_xrun, NULL);
	jack_set_process_callback(jack_client, mixmaster, NULL);
	jack_set_port_registration_callback(jack_client, check_ports, NULL);
	jack_on_shutdown(jack_client, jack_shutdown, 0);
	for (i = 0; i < QMX_CHANNELS; i++) {
		sprintf(name, "out%02d", i + 1);
		jack_cauldron[i] = jack_port_register(jack_client, name,
				JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
		}
	if (jack_activate(jack_client)) {
		log_msg("Cannot activate client.\n");
		cleanup();
		return SCM_UNSPECIFIED;
		}
	log_msg("JACK client activated: '%s'\n", client_name);
	return SCM_UNSPECIFIED;
	}
Beispiel #7
0
void jack_start() {
	jack_set_error_function(error);

	client = jack_client_open("MicToMIDI", JackNullOption, NULL);
	if (client == 0) {
		fprintf(stderr, "jack server not running?\n");
		exit(1);
	}

	jack_set_process_callback(client, process, 0);
	jack_set_sample_rate_callback(client, sample_rate, 0);
	jack_on_shutdown(client, jack_shutdown, 0);

	input_port = jack_port_register(client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
	output_port = jack_port_register(client, "output", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);

	if(jack_activate(client)) {
		fprintf(stderr, "cannot activate client");
		exit(1);
	}
	atexit(jack_stop);

	const char **ports;
	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)))
		fprintf(stderr, "cannot connect to physical capture port\n");

	jack_free(ports);
	if((ports = jack_get_ports(client, NULL, "midi", JackPortIsInput)) == NULL)
	{
		fprintf(stderr, "cannot find any MIDI playback ports\n");
		exit(1);
	}
	if(jack_connect(client, jack_port_name(output_port), ports[0]))
		fprintf(stderr, "cannot connect to MIDI playback port\n");
}
Beispiel #8
0
// initialization of data structure for incoming/outcoming packages
// and JACK client enabling
int process_init(){

    int i;

    n_packets = n_channels;

    packets = malloc((n_packets)*sizeof(jack_default_audio_sample_t*));
    for(i=0; i<n_packets; i++){
        packets[i] = calloc((bufsize + 1), sizeof(jack_default_audio_sample_t));
        packets[i][0] = (jack_default_audio_sample_t)(i + channels_offset);
    }

    jack_on_shutdown(client, jack_shutdown, 0);
    jack_set_error_function(jack_error_handler);

    if(amiserver){
        jack_set_process_callback(client, process_server, Remote);
    }
    else{
		received = calloc(n_channels, sizeof(short));
		silence = calloc(bufsize, sizeof(jack_default_audio_sample_t));
        jack_set_process_callback(client, process_client, 0);
    }

    if(jack_activate(client)){
        fprintf ( stderr, "cannot activate client" );
        return 1;
    }

    jack_active = 1;

    printf("JACK Client activated\n");

    return 0;

}
/* initialize JACK audio */
u8 j_init(void){
	jack_client_t *client;
	const intptr_t **ports;

	fprintf(stderr, "Trying jack....\n");

	// tell the JACK server to call error() whenever it
	//experiences an error.  Notice that this callback is
	// global to this process, not specific to each client.
	// 
	// This is set here so that it can catch errors in the
	// connection process
	jack_set_error_function(j_error);

	// try to become a client of the JACK server

	if((client = jack_client_new("pineappletracker")) == 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, j_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, j_shutdown, 0);

	// display the current sample rate. once the client is activated 
	// (see below), you should rely on your own sample rate
	// callback (see above) for this value.
	fprintf(stderr, "engine sample rate: %d\n", jack_get_sample_rate (client));

	sr=jack_get_sample_rate(client);

	output_port = jack_port_register(client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
	
	// tell the JACK server that we are ready to roll

	if(jack_activate(client)){
		fprintf (stderr, "cannot activate client");
		return 1;
	}

	// connect the ports
	if((ports = jack_get_ports(client, NULL, NULL,
					JackPortIsPhysical|JackPortIsInput)) == NULL){
		fprintf(stderr, "Cannot find any physical playback ports\n");
		return 1;
	}

	int i=0;
	while(ports[i]!=NULL){
		if(jack_connect(client, jack_port_name (output_port), ports[i]))
			fprintf(stderr, "cannot connect output ports\n");
		i++;
	}

	return 0;
}
Beispiel #10
0
int run(size_t port_count, const char** ports, const char* client_name,
	const char* file_path, jackoff_format_t* format, int bitrate,
	size_t channels, float buffer_duration, time_t recording_duration,
	jack_options_t options)
{
	jackoff_client_t* client;
	jackoff_encoder_t* encoder;
	jackoff_session_t* session;
	time_t stop_time = (time_t) 0;
	size_t i;
	long result;
	
	jack_set_error_function(handle_jack_error);
	jack_set_info_function(handle_jack_info);
	
	if (recording_duration) {
		stop_time = time(NULL) + recording_duration;
	}
	
	client = jackoff_create_client(client_name, options, channels, buffer_duration);
	
	if (jackoff_activate_client(client) != 0) {
		jackoff_destroy_client(client);
		jackoff_error("Failed to activate JACK client.");
	}
	
	signal(SIGTERM, handle_signal);
	signal(SIGINT, handle_signal);
	signal(SIGHUP, handle_signal);
	
	if (port_count == 0) {
		jackoff_auto_connect_client_ports(client);
	} else {
		for (i = 0; i < port_count; i++) {
			jackoff_connect_client_port(client, i, ports[i]);
		}
	}
	
	encoder = jackoff_create_encoder(client, format, bitrate);
	if (!encoder) {
		jackoff_destroy_client(client);
		return 1;
	}
	
	session = jackoff_open_session(client, encoder, file_path);
	if (!session) {
		jackoff_destroy_encoder(encoder);
		jackoff_destroy_client(client);
		return 2;
	}
	
	running = 1;
	jackoff_info("Recording.");
	while (running && (stop_time == 0 || time(NULL) < stop_time)) {
		if (client->ring_buffer_overflowed) {
			jackoff_warn("Ring buffer overflow; some audio was not written.");
			client->ring_buffer_overflowed = 0;
		}
		
		if (!client->status) {
			break;
		}
		
		result = jackoff_write_session(session);
		if (result == 0) {
			// Sleep for 1/4th the ring buffer duration.
			jackoff_debug("Sleeping for %.04fms.", (buffer_duration / 4));
			usleep(1000000 * (buffer_duration / 4));
		} else if (result == -1) {
			jackoff_close_session(session);
			jackoff_destroy_encoder(encoder);
			jackoff_destroy_client(client);
			jackoff_error("Encoding error. Shutting down.");
			return 3;
		}
	}
	
	jackoff_close_session(session);
	jackoff_destroy_encoder(encoder);
	jackoff_destroy_client(client);
	
	return 0;
}
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;
    pa_bool_t do_connect = TRUE;
    unsigned i;
    const char **ports = NULL, **p;
    pa_sink_new_data data;

    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;
    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 ||
        channels <= 0 ||
        channels > PA_CHANNELS_MAX) {
        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(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) {
                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;
            }
        }
    }

    pa_sink_put(u->sink);

    free(ports);
    pa_modargs_free(ma);

    return 0;

fail:
    if (ma)
        pa_modargs_free(ma);

    free(ports);

    pa__done(m);

    return -1;
}
Beispiel #12
0
int
jack_open_audio(int inchans, int outchans, int rate, t_audiocallback callback)
{
    int j;
    char port_name[80] = "";
    char client_name[80] = "";

    int client_iterator = 0;
    int new_jack = 0;
    int srate;
    jack_status_t status;

#ifdef __APPLE__
    if (!jack_client_open)
    {
        error("Can't open Jack (it seems not to be installed on this Mac)");
        return 1;
    }
#endif

    jack_dio_error = 0;

    if ((inchans == 0) && (outchans == 0)) return 0;

    if (outchans > MAX_JACK_PORTS) {
        error("JACK: %d output ports not supported, setting to %d",
            outchans, MAX_JACK_PORTS);
        outchans = MAX_JACK_PORTS;
    }

    if (inchans > MAX_JACK_PORTS) {
        error("JACK: %d input ports not supported, setting to %d",
            inchans, MAX_JACK_PORTS);
        inchans = MAX_JACK_PORTS;
    }

    /* try to become a client of the JACK server.  (If no JACK server exists,
        jack_client_open() will start uone up by default.  It's not clear
        whether or not this is desirable; see long Pd list thread started by
        yvan volochine, June 2013) */
    if (!jack_client) {
        do {
          sprintf(client_name,"pure_data_%d",client_iterator);
          client_iterator++;
          jack_client = jack_client_open (client_name, JackNoStartServer,
            &status, NULL);
          if (status & JackServerFailed) {
            error("JACK: unable to connect to JACK server.  Is JACK running?");
            jack_client=NULL;
            break;
          }
        } while (status & JackNameNotUnique);

        if(status) {
          if (status & JackServerStarted) {
            verbose(1, "JACK: started server");
          } else {
            error("JACK: server returned status %d", status);
          }
        }
        verbose(1, "JACK: started server as '%s'", client_name);

        if (!jack_client) {
            /* jack spits out enough messages already, do not warn */
            sys_inchannels = sys_outchannels = 0;
            return 1;
        }

        sys_inchannels = inchans;
        sys_outchannels = outchans;
        if (jack_inbuf)
            free(jack_inbuf);
        if (sys_inchannels)
            jack_inbuf = calloc(sizeof(t_sample), sys_inchannels * BUF_JACK);
        if (jack_outbuf)
            free(jack_outbuf);
        if (sys_outchannels)
            jack_outbuf = calloc(sizeof(t_sample), sys_outchannels * BUF_JACK);

        jack_get_clients();

        /* set JACK callback functions */

        jack_callback = callback;
        jack_set_process_callback(jack_client,
            (callback? callbackprocess : pollprocess), 0);

        jack_set_error_function (pd_jack_error_callback);

#ifdef JACK_XRUN
        jack_set_xrun_callback (jack_client, jack_xrun, NULL);
#endif

        /* tell the JACK server to call `srate()' whenever
           the sample rate of the system changes.
        */

        jack_set_sample_rate_callback (jack_client, jack_srate, 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 (jack_client, jack_shutdown, 0);

        for (j=0; j<sys_inchannels; j++)
             input_port[j]=NULL;
        for (j=0; j<sys_outchannels; j++)
             output_port[j] = NULL;

        new_jack = 1;
    }

    /* display the current sample rate. once the client is activated
       (see below), you should rely on your own sample rate
       callback (see above) for this value.
    */

    srate = jack_get_sample_rate (jack_client);
    sys_dacsr = srate;

    /* create the ports */

    for (j = 0; j < inchans; j++)
    {
        sprintf(port_name, "input%d", j);
        if (!input_port[j]) input_port[j] = jack_port_register (jack_client,
            port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
        if (!input_port[j])
        {
          error("JACK: can only register %d input ports (of %d requested)",
            j, inchans);
          sys_inchannels = inchans = j;
          break;
        }
    }

    for (j = 0; j < outchans; j++)
    {
        sprintf(port_name, "output%d", j);
        if (!output_port[j]) output_port[j] = jack_port_register (jack_client,
            port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
        if (!output_port[j])
        {
          error("JACK: can only register %d output ports (of %d requested)",
            j, outchans);
          sys_outchannels = outchans = j;
          break;
        }
    }
    outport_count = outchans;

    /* tell the JACK server that we are ready to roll */

    if (new_jack)
    {
        if (jack_activate (jack_client)) {
            error("cannot activate client");
            sys_inchannels = sys_outchannels = 0;
            return 1;
        }

        for (j = 0; j < outchans; j++)
            memset(jack_outbuf + j * BUF_JACK, 0,
                BUF_JACK * sizeof(t_sample));

        if (jack_client_names[0])
            jack_connect_ports(jack_client_names[0]);

        pthread_mutex_init(&jack_mutex, NULL);
        pthread_cond_init(&jack_sem, NULL);
    }
    return 0;
}
Beispiel #13
0
mfp_context * 
mfp_jack_startup(char * client_name, int num_inputs, int num_outputs) 
{
    mfp_context * ctxt;
    jack_status_t status;
    jack_port_t * port;
    int i;

    char namebuf[16];

    ctxt = mfp_context_new(CTYPE_JACK);

    if ((ctxt->info.jack->client = jack_client_open(client_name, JackNullOption, &status, NULL)) == 0) {
        fprintf (stderr, "jack_client_open() failed.");
        return NULL;
    }
    
    /* callbacks */ 
    jack_set_process_callback(ctxt->info.jack->client, process_cb, ctxt);
    jack_set_graph_order_callback(ctxt->info.jack->client, reorder_cb, ctxt);

    /* no info logging to console */ 
    jack_set_info_function(info_cb);
    jack_set_error_function(info_cb);
    
    /* create application input and output ports */ 
    if (num_inputs > 0) {
        ctxt->info.jack->input_ports = g_array_new(TRUE, TRUE, sizeof(jack_port_t *));

        for(i=0; i<num_inputs; i++) {
            snprintf(namebuf, 16, "in_%d", i);
            port = jack_port_register (ctxt->info.jack->client, namebuf, JACK_DEFAULT_AUDIO_TYPE, 
                                       JackPortIsInput, i);
            g_array_append_val(ctxt->info.jack->input_ports, port);
        }
    }

    if (num_outputs > 0) {
        ctxt->info.jack->output_ports = g_array_new(TRUE, TRUE, sizeof(jack_port_t *));

        for(i=0; i<num_outputs; i++) {
            snprintf(namebuf, 16, "out_%d", i);
            port = jack_port_register (ctxt->info.jack->client, namebuf, JACK_DEFAULT_AUDIO_TYPE, 
                                       JackPortIsOutput, i);
            g_array_append_val(ctxt->info.jack->output_ports, port);
        }

    }
    
    /* find out sample rate */ 
    ctxt->samplerate = jack_get_sample_rate(ctxt->info.jack->client);
    ctxt->blocksize = jack_get_buffer_size(ctxt->info.jack->client);
    mfp_in_latency = 3000.0 * ctxt->blocksize / ctxt->samplerate; 
    mfp_out_latency = 3000.0 * ctxt->blocksize / ctxt->samplerate; 

    printf("jack_startup: samplerate=%d, blocksize=%d, in_latency=%.1f, out_latency = %.1f\n", 
            ctxt->samplerate, ctxt->blocksize, mfp_in_latency, mfp_out_latency); 

    /* tell the JACK server that we are ready to roll */
    if (jack_activate (ctxt->info.jack->client)) {
        fprintf (stderr, "cannot activate client");
        return NULL;
    }
    else {
        ctxt->activated = 1;
    }

    return ctxt;

}
Beispiel #14
0
int soundio_jack_init(struct SoundIoPrivate *si) {
    SoundIoJack *sij = &si->backend_data.jack;
    SoundIo *soundio = &si->pub;

    if (!global_msg_callback_flag.test_and_set()) {
        if (soundio->jack_error_callback)
            jack_set_error_function(soundio->jack_error_callback);
        if (soundio->jack_info_callback)
            jack_set_info_function(soundio->jack_info_callback);
        global_msg_callback_flag.clear();
    }

    sij->mutex = soundio_os_mutex_create();
    if (!sij->mutex) {
        destroy_jack(si);
        return SoundIoErrorNoMem;
    }

    sij->cond = soundio_os_cond_create();
    if (!sij->cond) {
        destroy_jack(si);
        return SoundIoErrorNoMem;
    }

    // We pass JackNoStartServer due to
    // https://github.com/jackaudio/jack2/issues/138
    jack_status_t status;
    sij->client = jack_client_open(soundio->app_name, JackNoStartServer, &status);
    if (!sij->client) {
        destroy_jack(si);
        assert(!(status & JackInvalidOption));
        if (status & JackShmFailure)
            return SoundIoErrorSystemResources;
        if (status & JackNoSuchClient)
            return SoundIoErrorNoSuchClient;

        return SoundIoErrorInitAudioBackend;
    }

    int err;
    if ((err = jack_set_buffer_size_callback(sij->client, buffer_size_callback, si))) {
        destroy_jack(si);
        return SoundIoErrorInitAudioBackend;
    }
    if ((err = jack_set_sample_rate_callback(sij->client, sample_rate_callback, si))) {
        destroy_jack(si);
        return SoundIoErrorInitAudioBackend;
    }
    if ((err = jack_set_port_registration_callback(sij->client, port_registration_callback, si))) {
        destroy_jack(si);
        return SoundIoErrorInitAudioBackend;
    }
    if ((err = jack_set_port_rename_callback(sij->client, port_rename_calllback, si))) {
        destroy_jack(si);
        return SoundIoErrorInitAudioBackend;
    }
    jack_on_shutdown(sij->client, shutdown_callback, si);

    sij->refresh_devices_flag.clear();
    sij->period_size = jack_get_buffer_size(sij->client);
    sij->sample_rate = jack_get_sample_rate(sij->client);

    if ((err = jack_activate(sij->client))) {
        destroy_jack(si);
        return SoundIoErrorInitAudioBackend;
    }

    if ((err = refresh_devices(si))) {
        destroy_jack(si);
        return err;
    }

    si->destroy = destroy_jack;
    si->flush_events = flush_events_jack;
    si->wait_events = wait_events_jack;
    si->wakeup = wakeup_jack;
    si->force_device_scan = force_device_scan_jack;

    si->outstream_open = outstream_open_jack;
    si->outstream_destroy = outstream_destroy_jack;
    si->outstream_start = outstream_start_jack;
    si->outstream_begin_write = outstream_begin_write_jack;
    si->outstream_end_write = outstream_end_write_jack;
    si->outstream_clear_buffer = outstream_clear_buffer_jack;
    si->outstream_pause = outstream_pause_jack;
    si->outstream_get_latency = outstream_get_latency_jack;

    si->instream_open = instream_open_jack;
    si->instream_destroy = instream_destroy_jack;
    si->instream_start = instream_start_jack;
    si->instream_begin_read = instream_begin_read_jack;
    si->instream_end_read = instream_end_read_jack;
    si->instream_pause = instream_pause_jack;
    si->instream_get_latency = instream_get_latency_jack;

    return 0;
}
Beispiel #15
0
ad_rec_t *
ad_open_dev(const char *dev, int32 sps)
{
    ad_rec_t *handle;
    const char **ports;

    if (dev == NULL) {
        dev = DEFAULT_DEVICE;
    }

    printf("JACK: Setting default device: %s\n", dev);

    if ((handle = (ad_rec_t *) calloc(1, sizeof(ad_rec_t))) == NULL) {
        fprintf(stderr, "calloc(%d) failed\n", (int)sizeof(ad_rec_t));
        abort();
    }
 
    /* Tell the JACK server to call error() whenever it
       experiences an error.  
    */
    jack_set_error_function (error);

    /* Try to become a client of the JACK server */
    if ((handle->client = jack_client_open ("jack_ad", (jack_options_t)0, NULL)) == 0) {
	fprintf (stderr, "jack server not running?\n");
	return NULL;
    }

    handle->rbuffer = jack_ringbuffer_create(BUFFER_SIZE);
    handle->sample_buffer = malloc(BUFFER_SIZE);

    if(handle->rbuffer == NULL) {
        fprintf (stderr, "Failed to create jack ringbuffer\n");
        return NULL;
    }

    /* Tell the JACK server to call `process()' whenever
       there is work to be done.
    */
    jack_set_process_callback (handle->client, process, handle);

    /* Tell the JACK server to call `srate()' whenever
       the sample rate of the system changes.
    */
    jack_set_sample_rate_callback (handle->client, srate, 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 (handle->client, jack_shutdown, 0);


    /* Create the input port */
    if((handle->input_port = jack_port_register (handle->client, "jack_ad_input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) {
	fprintf (stderr, "cannot register input port!\n");
	return NULL;
    }
   
    if((handle->output_port = jack_port_register (handle->client, "jack_ad_output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsOutput, 0)) == 0) {
        fprintf (stderr, "cannot register output port!\n");
        return NULL;
    }
 
    /* Tell the JACK server that we are ready to start */
    if (jack_activate (handle->client)) {
	fprintf (stderr, "cannot activate client");
	return NULL;
    }

    /* Connect the ports. Note: you can't do this before
       the client is activated, because we can't allow
       connections to be made to clients that aren't
       running.
    */

    if ((ports = jack_get_ports (handle->client, dev, NULL, JackPortIsOutput)) == NULL) {
	fprintf(stderr, "Cannot find any physical capture ports\n");
	return NULL;
    }

    if (jack_connect (handle->client, ports[0], jack_port_name (handle->input_port))) {
	fprintf (stderr, "cannot connect input ports\n");
	return NULL;
    }

    free (ports);

#ifdef MIC_SPEAKER_PASSTHROUGH_DEBUG
    int i;
    if ((ports = jack_get_ports (handle->client, "system:playback", NULL,
                               JackPortIsPhysical|JackPortIsInput)) == NULL) {
        fprintf(stderr, "Cannot find any physical playback ports\n");
        return NULL;
    }

    for (i = 0; ports[i] != NULL; i++) {
        if (jack_connect (handle->client, jack_port_name (handle->output_port), ports[i])) {
            fprintf (stderr, "cannot connect output ports\n");
        }
    }

    free (ports);
#endif

    handle->recording = 0;
    handle->sps = sps;
    handle->bps = sizeof(int16);

    /* Give the jack process callback time to run ? */
    sleep (1);

    return (ad_rec_t *) handle;
}
Beispiel #16
0
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;
}
Beispiel #17
0
int main(int argc, char** argv)
{
    jackctl_server_t * server_ctl;
    const JSList * server_parameters;
    const char* server_name = "default";
    jackctl_driver_t * master_driver_ctl;
    jackctl_driver_t * loopback_driver_ctl = NULL;
    int replace_registry = 0;
    const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:"
        "a:"
#ifdef __linux__
        "c:"
#endif
        ;

    struct option long_options[] = {
#ifdef __linux__
                                       { "clock-source", 1, 0, 'c' },
#endif
                                       { "loopback-driver", 1, 0, 'L' },
                                       { "audio-driver", 1, 0, 'd' },
                                       { "midi-driver", 1, 0, 'X' },
                                       { "internal-client", 1, 0, 'I' },
                                       { "verbose", 0, 0, 'v' },
                                       { "help", 0, 0, 'h' },
                                       { "port-max", 1, 0, 'p' },
                                       { "no-mlock", 0, 0, 'm' },
                                       { "name", 1, 0, 'n' },
                                       { "unlock", 0, 0, 'u' },
                                       { "realtime", 0, 0, 'R' },
                                       { "no-realtime", 0, 0, 'r' },
                                       { "replace-registry", 0, &replace_registry, 0 },
                                       { "loopback", 0, 0, 'L' },
                                       { "realtime-priority", 1, 0, 'P' },
                                       { "timeout", 1, 0, 't' },
                                       { "temporary", 0, 0, 'T' },
                                       { "version", 0, 0, 'V' },
                                       { "silent", 0, 0, 's' },
                                       { "sync", 0, 0, 'S' },
                                       { "autoconnect", 1, 0, 'a' },
                                       { 0, 0, 0, 0 }
                                   };

    int i,opt = 0;
    int option_index = 0;
    char* master_driver_name = NULL;
    char** master_driver_args = NULL;
    int master_driver_nargs = 1;
    int loopback = 0;
    bool show_version = false;
    jackctl_sigmask_t * sigmask;
    jackctl_parameter_t* param;
    union jackctl_parameter_value value;

    std::list<char*> internals_list;
    std::list<char*> slaves_list;
    std::list<char*>::iterator it;

    // Assume that we fail.
    int return_value = -1;
    bool notify_sent = false;

    copyright(stdout);
#if defined(JACK_DBUS) && defined(__linux__)
    server_ctl = jackctl_server_create(audio_acquire, audio_release);
#else
    server_ctl = jackctl_server_create(NULL, NULL);
#endif
    if (server_ctl == NULL) {
        fprintf(stderr, "Failed to create server object\n");
        return -1;
    }

    server_parameters = jackctl_server_get_parameters(server_ctl);

    opterr = 0;
    while (!master_driver_name &&
            (opt = getopt_long(argc, argv, options,
                               long_options, &option_index)) != EOF) {
        switch (opt) {

        #ifdef __linux__
            case 'c':
                param = jackctl_get_parameter(server_parameters, "clock-source");
                if (param != NULL) {
                    if (tolower (optarg[0]) == 'h') {
                        value.ui = JACK_TIMER_HPET;
                        jackctl_parameter_set_value(param, &value);
                    } else if (tolower (optarg[0]) == 'c') {
                        value.ui = JACK_TIMER_CYCLE_COUNTER;
                        jackctl_parameter_set_value(param, &value);
                    } else if (tolower (optarg[0]) == 's') {
                        value.ui = JACK_TIMER_SYSTEM_CLOCK;
                        jackctl_parameter_set_value(param, &value);
                    } else {
                        usage(stdout, NULL);
                        goto destroy_server;
                    }
                }
                break;
        #endif

            case 'a':
                param = jackctl_get_parameter(server_parameters, "self-connect-mode");
                if (param != NULL) {
                    bool value_valid = false;
                    for (uint32_t k=0; k<jackctl_parameter_get_enum_constraints_count( param ); k++ ) {
                        value = jackctl_parameter_get_enum_constraint_value( param, k );
                        if( value.c == optarg[0] )
                            value_valid = true;
                    }

                    if( value_valid ) {
                        value.c = optarg[0];
                        jackctl_parameter_set_value(param, &value);
                    } else {
                        usage(stdout, NULL);
                        goto destroy_server;
                    }
                }
                break;

            case 'd':
                master_driver_name = optarg;
                break;

            case 'L':
                loopback = atoi(optarg);
                break;

            case 'X':
                slaves_list.push_back(optarg);
                break;

            case 'I':
                internals_list.push_back(optarg);
                break;

            case 'p':
                param = jackctl_get_parameter(server_parameters, "port-max");
                if (param != NULL) {
                    value.ui = atoi(optarg);
                    jackctl_parameter_set_value(param, &value);
                }
                break;

            case 'v':
                param = jackctl_get_parameter(server_parameters, "verbose");
                if (param != NULL) {
                    value.b = true;
                    jackctl_parameter_set_value(param, &value);
                }
                break;

            case 's':
                jack_set_error_function(silent_jack_error_callback);
                break;

            case 'S':
                param = jackctl_get_parameter(server_parameters, "sync");
                if (param != NULL) {
                    value.b = true;
                    jackctl_parameter_set_value(param, &value);
                }
                break;

            case 'n':
                server_name = optarg;
                param = jackctl_get_parameter(server_parameters, "name");
                if (param != NULL) {
                    strncpy(value.str, optarg, JACK_PARAM_STRING_MAX);
                    jackctl_parameter_set_value(param, &value);
                }
                break;

            case 'P':
                param = jackctl_get_parameter(server_parameters, "realtime-priority");
                if (param != NULL) {
                    value.i = atoi(optarg);
                    jackctl_parameter_set_value(param, &value);
                }
                break;

            case 'r':
                param = jackctl_get_parameter(server_parameters, "realtime");
                if (param != NULL) {
                    value.b = false;
                    jackctl_parameter_set_value(param, &value);
                }
                break;

            case 'R':
                param = jackctl_get_parameter(server_parameters, "realtime");
                if (param != NULL) {
                    value.b = true;
                    jackctl_parameter_set_value(param, &value);
                }
                break;

            case 'T':
                param = jackctl_get_parameter(server_parameters, "temporary");
                if (param != NULL) {
                    value.b = true;
                    jackctl_parameter_set_value(param, &value);
                }
                break;

            case 't':
                param = jackctl_get_parameter(server_parameters, "client-timeout");
                if (param != NULL) {
                    value.i = atoi(optarg);
                    jackctl_parameter_set_value(param, &value);
                }
                break;

            case 'V':
                show_version = true;
                break;

            default:
                fprintf(stderr, "unknown option character %c\n", optopt);
                /*fallthru*/

            case 'h':
                usage(stdout, server_ctl);
                goto destroy_server;
        }
    }

    // Long option with no letter so treated separately
    param = jackctl_get_parameter(server_parameters, "replace-registry");
    if (param != NULL) {
        value.b = replace_registry;
        jackctl_parameter_set_value(param, &value);
    }

    if (show_version) {
        printf( "jackdmp version " VERSION
                " tmpdir " jack_server_dir
                " protocol %d"
                "\n", JACK_PROTOCOL_VERSION);
        return -1;
    }

    if (!master_driver_name) {
        usage(stderr, NULL);
        goto destroy_server;
    }

    // Master driver
    master_driver_ctl = jackctl_server_get_driver(server_ctl, master_driver_name);
    if (master_driver_ctl == NULL) {
        fprintf(stderr, "Unknown driver \"%s\"\n", master_driver_name);
        goto destroy_server;
    }

    if (jackctl_driver_get_type(master_driver_ctl) != JackMaster) {
        fprintf(stderr, "Driver \"%s\" is not a master \n", master_driver_name);
        goto destroy_server;
    }

    if (optind < argc) {
        master_driver_nargs = 1 + argc - optind;
    } else {
        master_driver_nargs = 1;
    }

    if (master_driver_nargs == 0) {
        fprintf(stderr, "No driver specified ... hmm. JACK won't do"
                " anything when run like this.\n");
        goto destroy_server;
    }

    master_driver_args = (char **) malloc(sizeof(char *) * master_driver_nargs);
    master_driver_args[0] = master_driver_name;

    for (i = 1; i < master_driver_nargs; i++) {
        master_driver_args[i] = argv[optind++];
    }

    if (jackctl_driver_params_parse(master_driver_ctl, master_driver_nargs, master_driver_args)) {
        goto destroy_server;
    }

    // Setup signals
    sigmask = jackctl_setup_signals(0);

    // Open server
    if (! jackctl_server_open(server_ctl, master_driver_ctl)) {
        fprintf(stderr, "Failed to open server\n");
        goto destroy_server;
    }

    // Slave drivers
    for (it = slaves_list.begin(); it != slaves_list.end(); it++) {
        jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it);
        if (slave_driver_ctl == NULL) {
            fprintf(stderr, "Unknown driver \"%s\"\n", *it);
            goto close_server;
        }
        if (jackctl_driver_get_type(slave_driver_ctl) != JackSlave) {
            fprintf(stderr, "Driver \"%s\" is not a slave \n", *it);
            goto close_server;
        }
        if (!jackctl_server_add_slave(server_ctl, slave_driver_ctl)) {
            fprintf(stderr, "Driver \"%s\" cannot be loaded\n", *it);
            goto close_server;
        }
    }

    // Loopback driver
    if (loopback > 0) {
        loopback_driver_ctl = jackctl_server_get_driver(server_ctl, "loopback");

        if (loopback_driver_ctl != NULL) {
            const JSList * loopback_parameters = jackctl_driver_get_parameters(loopback_driver_ctl);
            param = jackctl_get_parameter(loopback_parameters, "channels");
            if (param != NULL) {
                value.ui = loopback;
                jackctl_parameter_set_value(param, &value);
            }
            if (!jackctl_server_add_slave(server_ctl, loopback_driver_ctl)) {
                fprintf(stderr, "Driver \"loopback\" cannot be loaded\n");
                goto close_server;
            }
        } else {
            fprintf(stderr, "Driver \"loopback\" not found\n");
            goto close_server;
        }
    }

    // Start the server
    if (!jackctl_server_start(server_ctl)) {
        fprintf(stderr, "Failed to start server\n");
        goto close_server;
    }

    // Internal clients
    for (it = internals_list.begin(); it != internals_list.end(); it++) {
        jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it);
        if (internal_driver_ctl == NULL) {
            fprintf(stderr, "Unknown internal \"%s\"\n", *it);
            goto stop_server;
        }
        if (!jackctl_server_load_internal(server_ctl, internal_driver_ctl)) {
            fprintf(stderr, "Internal client \"%s\" cannot be loaded\n", *it);
            goto stop_server;
        }
    }

    notify_server_start(server_name);
    notify_sent = true;
    return_value = 0;

    // Waits for signal
    jackctl_wait_signals(sigmask);

 stop_server:
    if (!jackctl_server_stop(server_ctl)) {
        fprintf(stderr, "Cannot stop server...\n");
    }

 close_server:
    if (loopback > 0 && loopback_driver_ctl) {
        jackctl_server_remove_slave(server_ctl, loopback_driver_ctl);
    }
    // Slave drivers
    for (it = slaves_list.begin(); it != slaves_list.end(); it++) {
        jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it);
        if (slave_driver_ctl) {
            jackctl_server_remove_slave(server_ctl, slave_driver_ctl);
        }
    }

    // Internal clients
    for (it = internals_list.begin(); it != internals_list.end(); it++) {
        jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it);
        if (internal_driver_ctl) {
            jackctl_server_unload_internal(server_ctl, internal_driver_ctl);
        }
    }
    jackctl_server_close(server_ctl);

 destroy_server:
    jackctl_server_destroy(server_ctl);
    if (notify_sent) {
        notify_server_stop(server_name);
    }
    return return_value;
}
Beispiel #18
0
int
Server_jack_init(Server *self) {
    char client_name[32];
    char name[16];
    const char *server_name = "server";
    jack_options_t options = JackNullOption;
    jack_status_t status;
    int sampleRate = 0;
    int bufferSize = 0;
    int nchnls = 0;
    int total_nchnls = 0;
    int index = 0;
    int ret = 0;
    assert(self->audio_be_data == NULL);
    PyoJackBackendData *be_data = (PyoJackBackendData *) malloc(sizeof(PyoJackBackendData *));
    self->audio_be_data = (void *) be_data;
    be_data->jack_in_ports = (jack_port_t **) calloc(self->ichnls + self->input_offset, sizeof(jack_port_t *));
    be_data->jack_out_ports = (jack_port_t **) calloc(self->nchnls + self->output_offset, sizeof(jack_port_t *));
    strncpy(client_name,self->serverName, 32);
    be_data->jack_client = jack_client_open(client_name, options, &status, server_name);
    if (be_data->jack_client == NULL) {
        Server_error(self, "Jack error: Unable to create JACK client\n");
        if (status & JackServerFailed) {
            Server_debug(self, "Jack error: jack_client_open() failed, "
            "status = 0x%2.0x\n", status);
        }
        return -1;
    }
    if (status & JackServerStarted) {
        Server_warning(self, "JACK server started.\n");
    }
    if (strcmp(self->serverName, jack_get_client_name(be_data->jack_client)) ) {
        strcpy(self->serverName, jack_get_client_name(be_data->jack_client));
        Server_warning(self, "Jack name `%s' assigned\n", self->serverName);
    }

    sampleRate = jack_get_sample_rate (be_data->jack_client);
    if (sampleRate != self->samplingRate) {
        self->samplingRate = (double)sampleRate;
        Server_warning(self, "Sample rate set to Jack engine sample rate: %" PRIu32 "\n", sampleRate);
    }
    else {
        Server_debug(self, "Jack engine sample rate: %" PRIu32 "\n", sampleRate);
    }
    if (sampleRate <= 0) {
        Server_error(self, "Invalid Jack engine sample rate.");
        jack_client_close(be_data->jack_client);
        return -1;
    }
    bufferSize = jack_get_buffer_size(be_data->jack_client);
    if (bufferSize != self->bufferSize) {
        self->bufferSize = bufferSize;
        Server_warning(self, "Buffer size set to Jack engine buffer size: %" PRIu32 "\n", bufferSize);
    }
    else {
        Server_debug(self, "Jack engine buffer size: %" PRIu32 "\n", bufferSize);
    }

    nchnls = total_nchnls = self->ichnls + self->input_offset;
    while (nchnls-- > 0) {
        index = total_nchnls - nchnls - 1;
        ret = sprintf(name, "input_%i", index + 1);
        if (ret > 0) {
            be_data->jack_in_ports[index]
            = jack_port_register(be_data->jack_client, name,
                                 JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
        }

        if ((be_data->jack_in_ports[index] == NULL)) {
            Server_error(self, "Jack: no more JACK input ports available\n");
            return -1;
        }
    }

    nchnls = total_nchnls = self->nchnls + self->output_offset;
    while (nchnls-- > 0) {
        index = total_nchnls - nchnls - 1;
        ret = sprintf(name, "output_%i", index + 1);
        if (ret > 0) {
            be_data->jack_out_ports[index]
            = jack_port_register(be_data->jack_client, name,
                                 JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
        }
        if ((be_data->jack_out_ports[index] == NULL)) {
            Server_error(self, "Jack: no more JACK output ports available\n");
            return -1;
        }
    }
    jack_set_error_function(jack_error_cb);
    jack_set_sample_rate_callback(be_data->jack_client, jack_srate_cb, (void *) self);
    jack_on_shutdown(be_data->jack_client, jack_shutdown_cb, (void *) self);
    jack_set_buffer_size_callback(be_data->jack_client, jack_bufsize_cb, (void *) self);
    return 0;
}
Beispiel #19
0
int	       
main (int argc, char *argv[])

{
	jack_driver_desc_t * desc;
	int replace_registry = 0;
	int do_sanity_checks = 1;
	int show_version = 0;

#ifdef HAVE_ZITA_BRIDGE_DEPS
	const char *options = "A:d:P:uvshVrRZTFlI:t:mM:n:Np:c:X:C:";
#else
	const char *options = "A:d:P:uvshVrRZTFlI:t:mM:n:Np:c:X:C:";
#endif
	struct option long_options[] = 
	{ 
		/* keep ordered by single-letter option code */

#ifdef HAVE_ZITA_BRIDGE_DEPS
                { "alsa-add", 1, 0, 'A' },
#endif
		{ "clock-source", 1, 0, 'c' },
		{ "driver", 1, 0, 'd' },
		{ "help", 0, 0, 'h' },
		{ "tmpdir-location", 0, 0, 'l' },
		{ "internal-client", 0, 0, 'I' },
		{ "no-mlock", 0, 0, 'm' },
		{ "midi-bufsize", 1, 0, 'M' },
		{ "name", 1, 0, 'n' },
                { "no-sanity-checks", 0, 0, 'N' },
		{ "port-max", 1, 0, 'p' },
		{ "realtime-priority", 1, 0, 'P' },
		{ "no-realtime", 0, 0, 'r' },
		{ "realtime", 0, 0, 'R' },
		{ "replace-registry", 0, &replace_registry, 0 },
		{ "silent", 0, 0, 's' },
		{ "sync", 0, 0, 'S' },
		{ "timeout", 1, 0, 't' },
		{ "temporary", 0, 0, 'T' },
		{ "unlock", 0, 0, 'u' },
		{ "version", 0, 0, 'V' },
		{ "verbose", 0, 0, 'v' },
		{ "slave-driver", 1, 0, 'X' },
		{ "nozombies", 0, 0, 'Z' },
		{ "timeout-thres", 2, 0, 'C' },
		{ 0, 0, 0, 0 }
	};
	int opt = 0;
	int option_index = 0;
	int seen_driver = 0;
	char *driver_name = NULL;
	char **driver_args = NULL;
	JSList * driver_params;
	JSList * slave_drivers = NULL;
        JSList * load_list = NULL;
	size_t midi_buffer_size = 0;
	int driver_nargs = 1;
	int i;
	int rc;
#ifdef HAVE_ZITA_BRIDGE_DEPS
        const char* alsa_add_client_name_playback = "zalsa_out";
        const char* alsa_add_client_name_capture = "zalsa_in";
        char alsa_add_args[64];
        char* dirstr;
#endif
	setvbuf (stdout, NULL, _IOLBF, 0);

	maybe_use_capabilities ();

	opterr = 0;
	while (!seen_driver &&
	       (opt = getopt_long (argc, argv, options,
				   long_options, &option_index)) != EOF) {
		switch (opt) {

#ifdef HAVE_ZITA_BRIDGE_DEPS
                case 'A':
                        /* add a new internal client named after the ALSA device name
                           given as optarg, using the last character 'p' or 'c' to
                           indicate playback or capture. If there isn't one,
                           assume capture (common case: USB mics etc.)
                        */
                        if ((dirstr = strstr (optarg, "%p")) != NULL && dirstr == (optarg + strlen(optarg) - 2)) {
                                snprintf (alsa_add_args, sizeof (alsa_add_args), "%.*s_play:%s/-dhw:%.*s", 
                                          (int) strlen (optarg) - 2, optarg,
                                          alsa_add_client_name_playback,
                                          (int) strlen (optarg) - 2, optarg);
                                load_list = jack_slist_append(load_list, strdup (alsa_add_args));
                        } else if ((dirstr = strstr (optarg, "%c")) != NULL && dirstr == (optarg + strlen(optarg) - 2)) {
                                snprintf (alsa_add_args, sizeof (alsa_add_args), "%.*s_rec:%s/-dhw:%.*s", 
                                          (int) strlen (optarg) - 2, optarg,
                                          alsa_add_client_name_capture,
                                          (int) strlen (optarg) - 2, optarg);
                                load_list = jack_slist_append(load_list, strdup (alsa_add_args));
                        } else {
                                snprintf (alsa_add_args, sizeof (alsa_add_args), "%s_play:%s/-dhw:%s", 
                                          optarg,
                                          alsa_add_client_name_playback,
                                          optarg);
                                load_list = jack_slist_append(load_list, strdup (alsa_add_args));
                                snprintf (alsa_add_args, sizeof (alsa_add_args), "%s_rec:%s/-dhw:%s", 
                                          optarg,
                                          alsa_add_client_name_capture,
                                          optarg);
                                load_list = jack_slist_append(load_list, strdup (alsa_add_args));
                        }
                        break;
#endif

		case 'c':
			if (tolower (optarg[0]) == 'h') {
				clock_source = JACK_TIMER_HPET;
			} else if (tolower (optarg[0]) == 'c') {
				/* For backwards compatibility with scripts,
				 * allow the user to request the cycle clock
				 * on the command line, but use the system
				 * clock instead
				 */
				clock_source = JACK_TIMER_SYSTEM_CLOCK;
			} else if (tolower (optarg[0]) == 's') {
				clock_source = JACK_TIMER_SYSTEM_CLOCK;
			} else {
				usage (stderr);
				return -1;
			}
			break;

		case 'C':
			if (optarg)
				timeout_count_threshold = atoi (optarg);
			else
				timeout_count_threshold = 250;
			break;

		case 'd':
			seen_driver = optind + 1;
			driver_name = optarg;
			break;

		case 'D':
			frame_time_offset = JACK_MAX_FRAMES - atoi(optarg); 
			break;

		case 'l':
			/* special flag to allow libjack to determine jackd's idea of where tmpdir is */
			printf ("%s\n", jack_tmpdir);
			exit (0);

                case 'I':
			load_list = jack_slist_append(load_list, optarg);
                        break;

		case 'm':
			do_mlock = 0;
			break;

		case 'M':
			midi_buffer_size = (unsigned int) atol (optarg);
			break;

		case 'n':
			server_name = optarg;
			break;

		case 'N':
			do_sanity_checks = 0;
			break;

		case 'p':
			port_max = (unsigned int) atol (optarg);
			break;

		case 'P':
			realtime_priority = atoi (optarg);
			break;

		case 'r':
			realtime = 0;
			break;

		case 'R':
			/* this is now the default */
			realtime = 1;
			break;

		case 's':
			jack_set_error_function (silent_jack_error_callback);
			break;

                case 'S':
                        /* this option is for jack2 only (synchronous mode) */
                        break;

		case 'T':
			temporary = 1;
			break;

		case 't':
			client_timeout = atoi (optarg);
			break;

		case 'u':
			do_unlock = 1;
			break;

		case 'v':
			verbose = 1;
			break;

		case 'V':
			show_version = 1;
			break;

		case 'X':
			slave_drivers = jack_slist_append(slave_drivers, optarg);
			break;
		case 'Z':
			nozombies = 1;
			break;

		default:
			jack_error ("Unknown option character %c",
				    optopt);
			/*fallthru*/
		case 'h':
			usage (stdout);
			return -1;
		}
	}

	if (show_version) {
		printf ( "jackd version " VERSION 
				" tmpdir " DEFAULT_TMP_DIR 
				" protocol " PROTOCOL_VERSION
				"\n");
		return 0;
	}

	copyright (stdout);

	if (do_sanity_checks && (0 < sanitycheck (realtime, FALSE))) {
		return -1;
	}

	if (!seen_driver) {
		usage (stderr);
		exit (1);
	}

        /* DIRTY HACK needed to pick up -X supplied as part of ALSA driver args. This is legacy
           hack to make control apps like qjackctl based on the < 0.124 command line interface
           continue to work correctly.

           If -X seq was given as part of the driver args, load the ALSA MIDI slave driver.
        */
        
        for (i = seen_driver; i < argc; ++i) {
                if (strcmp (argv[i], "-X") == 0) {
                        if (argc >= i + 2) {
                                if (strcmp (argv[i+1], "seq") == 0) {
                                        slave_drivers = jack_slist_append (slave_drivers,"alsa_midi");
                                }
                        }
                        break;
                } else if (strcmp (argv[i], "-Xseq") == 0) {
                        slave_drivers = jack_slist_append (slave_drivers,"alsa_midi");
                        break;
                }
        }

	drivers = jack_drivers_load ();

	if (!drivers) {
		fprintf (stderr, "jackd: no drivers found; exiting\n");
		exit (1);
	}
	
	if (midi_buffer_size != 0) {
		jack_port_type_info_t* port_type = &jack_builtin_port_types[JACK_MIDI_PORT_TYPE];
		port_type->buffer_size = midi_buffer_size * jack_midi_internal_event_size ();
		port_type->buffer_scale_factor = -1;
		if (verbose) {
			fprintf (stderr, "Set MIDI buffer size to %u bytes\n", port_type->buffer_size);
		}
	}

	desc = jack_find_driver_descriptor (driver_name);
	if (!desc) {
		fprintf (stderr, "jackd: unknown driver '%s'\n", driver_name);
		exit (1);
	}

	if (optind < argc) {
		driver_nargs = 1 + argc - optind;
	} else {
		driver_nargs = 1;
	}

	if (driver_nargs == 0) {
		fprintf (stderr, "No driver specified ... hmm. JACK won't do"
			 " anything when run like this.\n");
		return -1;
	}

	driver_args = (char **) malloc (sizeof (char *) * driver_nargs);
	driver_args[0] = driver_name;
	
	for (i = 1; i < driver_nargs; i++) {
		driver_args[i] = argv[optind++];
	}

	if (jack_parse_driver_params (desc, driver_nargs,
				      driver_args, &driver_params)) {
		exit (0);
	}

	if (server_name == NULL)
		server_name = jack_default_server_name ();

	rc = jack_register_server (server_name, replace_registry);
	switch (rc) {
	case EEXIST:
		fprintf (stderr, "`%s' server already active\n", server_name);
		exit (1);
	case ENOSPC:
		fprintf (stderr, "too many servers already active\n");
		exit (2);
	case ENOMEM:
		fprintf (stderr, "no access to shm registry\n");
		exit (3);
	default:
		if (verbose)
			fprintf (stderr, "server `%s' registered\n",
				 server_name);
	}

	/* clean up shared memory and files from any previous
	 * instance of this server name */
	jack_cleanup_shm ();
	jack_cleanup_files (server_name);

	/* run the server engine until it terminates */
	jack_main (desc, driver_params, slave_drivers, load_list);

	/* clean up shared memory and files from this server instance */
	if (verbose)
		fprintf (stderr, "cleaning up shared memory\n");
	jack_cleanup_shm ();
	if (verbose)
		fprintf (stderr, "cleaning up files\n");
	jack_cleanup_files (server_name);
	if (verbose)
		fprintf (stderr, "unregistering server `%s'\n", server_name);
	jack_unregister_server (server_name);

	exit (0);
}
Beispiel #20
0
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;
}
Beispiel #21
0
void ja_silent_errors(int silent)
{
        jack_set_error_function(silent ?
                                ja_silent_error_callback
                                : ja_default_error_callback);
}