示例#1
0
文件: jack.c 项目: Joonie86/RetroArch
static size_t find_buffersize(jack_t *jd, int latency)
{
   jack_latency_range_t range;
   int i, buffer_frames, min_buffer_frames, jack_latency = 0;
   settings_t *settings = config_get_ptr();
   int frames = latency * settings->audio.out_rate / 1000;

   for (i = 0; i < 2; i++)
   {
      jack_port_get_latency_range(jd->ports[i], JackPlaybackLatency, &range);
      if ((int)range.max > jack_latency)
         jack_latency = range.max;
   }

   RARCH_LOG("JACK: Jack latency is %d frames.\n", jack_latency);

   buffer_frames = frames - jack_latency;
   min_buffer_frames = jack_get_buffer_size(jd->client) * 2;

   RARCH_LOG("JACK: Minimum buffer size is %d frames.\n", min_buffer_frames);

   if (buffer_frames < min_buffer_frames)
      buffer_frames = min_buffer_frames;

   return buffer_frames * sizeof(jack_default_audio_sample_t);
}
示例#2
0
文件: pyjack.c 项目: egasimus/pyjack
// Attempt to connect to the Jack server
static PyObject* attach(PyObject* self, PyObject* args)
{
    char* cname;
    if (! PyArg_ParseTuple(args, "s", &cname))
        return NULL;

    pyjack_client_t * client = self_or_global_client(self);
    if(client->pjc != NULL) {
        PyErr_SetString(JackUsageError, "A connection is already established.");
        return NULL;
    }

    jack_status_t status;
    client->pjc = jack_client_open(cname, JackNoStartServer, &status);
    if(client->pjc == NULL) {
        //TODO check status
        PyErr_SetString(JackNotConnectedError, "Failed to connect to Jack audio server.");
        return NULL;
    }

    jack_on_shutdown(client->pjc, pyjack_shutdown, client);
    signal(SIGHUP, pyjack_hangup); // TODO: This just works with global clients

    if(jack_set_process_callback(client->pjc, pyjack_process, client) != 0) {
        PyErr_SetString(JackError, "Failed to set jack process callback.");
        return NULL;
    }

    if(jack_set_buffer_size_callback(client->pjc, pyjack_buffer_size_changed, client) != 0) {
        PyErr_SetString(JackError, "Failed to set jack buffer size callback.");
        return NULL;
    }

    if(jack_set_sample_rate_callback(client->pjc, pyjack_sample_rate_changed, client) != 0) {
        PyErr_SetString(JackError, "Failed to set jack sample rate callback.");
        return NULL;
    }

    if(jack_set_port_registration_callback(client->pjc, pyjack_port_registration, client) != 0) {
        PyErr_SetString(JackError, "Failed to set jack port registration callback.");
        return NULL;
    }

    if(jack_set_graph_order_callback(client->pjc, pyjack_graph_order, client) != 0) {
        PyErr_SetString(JackError, "Failed to set jack graph order callback.");
        return NULL;
    }

    if(jack_set_xrun_callback(client->pjc, pyjack_xrun, client) != 0) {
        PyErr_SetString(JackError, "Failed to set jack xrun callback.");
        return NULL;
    }

    // Get buffer size
    client->buffer_size = jack_get_buffer_size(client->pjc);

    // Success!
    Py_INCREF(Py_None);
    return Py_None;
}
int JackSimpleClient::setUp (int argc, char *argv[])
{
	LOGD("setUp argc %d", argc);
	for(int i = 0;i< argc; i++){
		LOGD("setup argv %s", argv[i]);
	}

	// You have to use argv[0] as the jack client name like below.
	jackClient = jack_client_open (argv[0], JackNullOption, NULL, NULL);
	if (jackClient == NULL) {
		return APA_RETURN_ERROR;
	}

	bufferSize = jack_get_buffer_size(jackClient);

	// init the sine table
	for(int i=0; i<bufferSize; i++ )
	{
		sineTable[i] = (float) sin( ((double)i*8/(double)bufferSize) * 2. * 3.14159265 );
	}

	jack_set_process_callback (jackClient, processSine, this);

	outPort = jack_port_register (jackClient, "out",
					  JACK_DEFAULT_AUDIO_TYPE,
					  JackPortIsOutput, 0);
	if(outPort == NULL){
		return APA_RETURN_ERROR;
	}

	return APA_RETURN_SUCCESS;
}
示例#4
0
文件: bufsize.c 项目: HI-CARL/jack2
int main(int argc, char *argv[])
{
	int rc;

	parse_arguments(argc, argv);

	/* become a JACK client */
    if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) {
		fprintf(stderr, "JACK server not running?\n");
		exit(1);
	}

#ifndef WIN32
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	jack_on_shutdown(client, jack_shutdown, 0);

	if (just_print_bufsize) {
		fprintf(stdout, "buffer size = %d  sample rate = %d\n", jack_get_buffer_size(client), jack_get_sample_rate(client));
		rc=0;
	}
	else
	{
		rc = jack_set_buffer_size(client, nframes);
		if (rc)
			fprintf(stderr, "jack_set_buffer_size(): %s\n", strerror(rc));
	}
	jack_client_close(client);

	return rc;
}
示例#5
0
    JackAudioProvider(Synth *synth, const std::string &name)
      : synth_(synth)
    {
      SampleBufferAllocator::reset();
      client_ = jack_client_open(name.c_str(), JackNoStartServer, 0);
      if (client_ == NULL) {
	throw JackClientOpenError();
      }
      std::cout << "connected to jackd as client `" << name << "`\n";
      sl::sampleRate(jack_get_sample_rate(client_));
      jack_set_sample_rate_callback(client_, jackSampleRateCallback, 0);
      sl::bufferSize(jack_get_buffer_size(client_));
      jack_set_buffer_size_callback(client_, jackBufferSizeCallback, 0);
      jack_set_process_callback(client_, jackProcessCallback, this);
      midiInPort_ = jack_port_register(client_, "midi_in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
      std::cout << "registered midi port: midi_in\n";
      char portName[64];
      for (int i=0; i<Synth::InputBuffer::nChannels; i++) {
	snprintf(portName, sizeof(portName), "in_%u", i+1);
	inputPorts_[i] = jack_port_register(client_, portName, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
        std::cout << "registered audio port: " << portName << "\n";
      }
      for (int i=0; i<Synth::OutputBuffer::nChannels; i++) {
	snprintf(portName, sizeof(portName), "out_%u", i+1);
	outputPorts_[i] = jack_port_register(client_, portName, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
        std::cout << "registered audio port: " << portName << "\n";
      }
      for (int i=0; i<128; i++) {
        midiCtrlMap_[i] = i;
      }
      for (int i=11; i<=19; i++) {
        midiCtrlMap_[i] = i-10;
      }
      midiCtrlMap_[1] = 129; // modwheel
    }
示例#6
0
static int start_jack(AVFormatContext *context, AVFormatParameters *params)
{
    JackData *self = context->priv_data;
    jack_status_t status;
    int i, test;
    double o, period;

    /* Register as a JACK client, using the context filename as client name. */
    self->client = jack_client_open(context->filename, JackNullOption, &status);
    if (!self->client) {
        av_log(context, AV_LOG_ERROR, "Unable to register as a JACK client\n");
        return AVERROR(EIO);
    }

    sem_init(&self->packet_count, 0, 0);

    self->sample_rate = jack_get_sample_rate(self->client);
    self->nports      = params->channels;
    self->ports       = av_malloc(self->nports * sizeof(*self->ports));
    self->buffer_size = jack_get_buffer_size(self->client);

    /* Register JACK ports */
    for (i = 0; i < self->nports; i++) {
        char str[16];
        snprintf(str, sizeof(str), "input_%d", i + 1);
        self->ports[i] = jack_port_register(self->client, str,
                                            JACK_DEFAULT_AUDIO_TYPE,
                                            JackPortIsInput, 0);
        if (!self->ports[i]) {
            av_log(context, AV_LOG_ERROR, "Unable to register port %s:%s\n",
                   context->filename, str);
            jack_client_close(self->client);
            return AVERROR(EIO);
        }
    }

    /* Register JACK callbacks */
    jack_set_process_callback(self->client, process_callback, self);
    jack_on_shutdown(self->client, shutdown_callback, self);
    jack_set_xrun_callback(self->client, xrun_callback, self);

    /* Create time filter */
    period            = (double) self->buffer_size / self->sample_rate;
    o                 = 2 * M_PI * 1.5 * period; /// bandwidth: 1.5Hz
    self->timefilter  = ff_timefilter_new (1.0 / self->sample_rate, sqrt(2 * o), o * o);

    /* Create FIFO buffers */
    self->filled_pkts = av_fifo_alloc(FIFO_PACKETS_NUM * sizeof(AVPacket));
    /* New packets FIFO with one extra packet for safety against underruns */
    self->new_pkts    = av_fifo_alloc((FIFO_PACKETS_NUM + 1) * sizeof(AVPacket));
    if ((test = supply_new_packets(self, context))) {
        jack_client_close(self->client);
        return test;
    }

    return 0;

}
示例#7
0
//=========================================================
void read_jack_properties()
{
	sample_rate=jack_get_sample_rate(client);
	//! new: assume JACK is always 32 bit float
	//bytes_per_sample only refers to data transmission 
	//param --16 will force to use 2 bytes
	//bytes_per_sample = sizeof(sample_t);
	period_size=jack_get_buffer_size(client);
}
示例#8
0
int
JACKstart(HOR *hor_)
{

   
  JackOUT=hor_; 

  jackclient = jack_client_open("Horgand",options,&status,NULL);;
  if (jackclient == NULL)
    {
      fprintf (stderr, "Cannot make a jack client, back to Alsa\n");
      return (2);
    };

  JackOUT->SAMPLE_RATE=DSAMPLE_RATE;
  fprintf (stderr, "Internal SampleRate   = %d\nJack Output SampleRate= %d\n",
           JackOUT->SAMPLE_RATE, jack_get_sample_rate (jackclient));
  if ((unsigned int) jack_get_sample_rate (jackclient) != (unsigned int) JackOUT->SAMPLE_RATE)
    fprintf (stderr, "Adjusting SAMPLE_RATE to jackd.\n");

  JackOUT->SAMPLE_RATE = jack_get_sample_rate(jackclient);
  JackOUT->PERIOD = jack_get_buffer_size (jackclient);
  JackOUT->Put_Period();
  
  jack_set_process_callback (jackclient, jackprocess, 0);

  outport_left = jack_port_register (jackclient, "out_1",
                                     JACK_DEFAULT_AUDIO_TYPE,
                                     JackPortIsOutput | JackPortIsTerminal,
                                     0);
  outport_right =
    jack_port_register (jackclient, "out_2", JACK_DEFAULT_AUDIO_TYPE,
                        JackPortIsOutput | JackPortIsTerminal, 0);


  jack_midi_in =  jack_port_register(jackclient, "in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
   


  if (jack_activate (jackclient))
    {
      fprintf (stderr, "Cannot activate jack client, back to Alsa\n");
      return (2);
    };

  jack_connect (jackclient, jack_port_name (outport_left),
                "alsa_pcm:playback_1");
  jack_connect (jackclient, jack_port_name (outport_right),
                "alsa_pcm:playback_2");


  pthread_mutex_init (&jmutex, NULL);
  
  return 3;

};
示例#9
0
文件: midiseq.c 项目: Andux/jack2
int main(int narg, char **args)
{
	int i;
	jack_nframes_t nframes;
	if((narg<6) || ((narg-3)%3 !=0))
	{
		usage();
		exit(1);
	}
	if((client = jack_client_open (args[1], JackNullOption, NULL)) == 0)
	{
		fprintf (stderr, "JACK server not running?\n");
		return 1;
	}
	jack_set_process_callback (client, process, 0);
	output_port = jack_port_register (client, "out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
	nframes = jack_get_buffer_size(client);
	loop_index = 0;
	num_notes = (narg - 3)/3;
	note_frqs = malloc(num_notes*sizeof(unsigned char));
	note_starts = malloc(num_notes*sizeof(jack_nframes_t));
	note_lengths = malloc(num_notes*sizeof(jack_nframes_t));
	loop_nsamp = atoi(args[2]);
	for(i=0; i<num_notes; i++)
	{
		note_starts[i] = atoi(args[3 + 3*i]);
		note_frqs[i] = atoi(args[4 + 3*i]);
		note_lengths[i] = atoi(args[5 + 3*i]);
	}

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

	/* install a signal handler to properly quits jack client */
#ifndef WIN32
	signal(SIGQUIT, signal_handler);
	signal(SIGHUP, signal_handler);
#endif
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	/* run until interrupted */
	while (1) {
#ifdef WIN32
		Sleep(1*1000);
#else
		sleep(1);
#endif
	};

    jack_client_close(client);
	exit (0);
}
示例#10
0
int rmdStartJackClient(JackData *jdata){
    float ring_buffer_size=0.0;
    int pid;
    char pidbuf[8];
    char rmd_client_name[32];

    //construct the jack client name
    //which is recordMyDesktop-pid
    //in order to allow multiple
    //instances of recordMyDesktop
    //to connetc to a Jack Server
    strcpy(rmd_client_name,"recordMyDesktop-");
    pid=getpid();
    snprintf( pidbuf, 8, "%d", pid );
    strcat(rmd_client_name,pidbuf);

    if ((jdata->client=(*jack_client_new)(rmd_client_name))==0){
        fprintf(stderr,"Could not create new client!\n"
                       "Make sure that Jack server is running!\n");
        return 15;
    }
//in contrast to ALSA and OSS, Jack dictates frequency
//and buffersize to the values it was launched with.
//Supposedly jack_set_buffer_size can set the buffersize
//but that causes some kind of halt and keeps giving me
//zero buffers.
//recordMyDesktop cannot handle buffer size changes.
//FIXME
//There is a callback for buffer size changes that I should use.
//It will provide clean exits, instead of ?segfaults? .
//Continuing though is not possible, with the current layout
//(it might be in some cases, but it will certainly be the cause
//of unpredicted problems). A clean exit is preferable
//and any recording up to that point will be encoded and saved.
    jdata->frequency=jack_get_sample_rate(jdata->client);
    jdata->buffersize=jack_get_buffer_size(jdata->client);
    ring_buffer_size=(jdata->ringbuffer_secs*
                      jdata->frequency*
                      sizeof(jack_default_audio_sample_t)*
                      jdata->nports);
    jdata->sound_buffer=
        (*jack_ringbuffer_create)((int)(ring_buffer_size+0.5));//round up
    jack_set_process_callback(jdata->client,rmdJackCapture,jdata);
    jack_on_shutdown(jdata->client,rmdJackShutdown,jdata);

    if (jack_activate(jdata->client)) {
        fprintf(stderr,"cannot activate client!\n");
        return 16;
    }
    if(rmdSetupPorts(jdata)){
        jack_client_close(jdata->client);
        return 17;
    }

    return 0;
}
示例#11
0
    void open_client(std::string const & server_name, std::string const & name, uint32_t input_port_count,
                     uint32_t output_port_count, uint32_t blocksize)
    {
        blocksize_ = blocksize;

        /* open client */
        client = server_name.empty() ? jack_client_open(name.c_str(), JackNoStartServer, &status)
                                     : jack_client_open(name.c_str(), jack_options_t(JackNoStartServer | JackServerName),
                                                        &status, server_name.c_str());
        boost::atomic_thread_fence(boost::memory_order_release); // ensure visibility on other threads

        if (status & JackServerFailed)
            throw std::runtime_error("Unable to connect to JACK server");

        if (status & JackNameNotUnique) {
            const char * client_name = jack_get_client_name(client);
            std::cout << "unique client name: " << client_name << std::endl;
        }

        /* initialize callbacks */
        jack_set_thread_init_callback (client, jack_thread_init_callback, this);
        jack_set_process_callback (client, jack_process_callback, this);
        jack_set_xrun_callback(client, jack_xrun_callback, this);
        jack_on_info_shutdown(client, (JackInfoShutdownCallback)jack_on_info_shutdown_callback, NULL);

        /* register ports */
        input_ports.clear();
        for (uint32_t i = 0; i != input_port_count; ++i) {
            std::string portname ("input_");
            portname += std::to_string(i+1);
            jack_port_t * port =
                jack_port_register(client, portname.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
            input_ports.push_back(port);
        }
        input_channels = input_port_count;
        super::input_samples.resize(input_port_count);

        output_ports.clear();
        for (uint32_t i = 0; i != output_port_count; ++i) {
            std::string portname ("output_");
            portname += std::to_string(i+1);
            jack_port_t * port =
                jack_port_register(client, portname.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
            output_ports.push_back(port);
        }
        output_channels = output_port_count;
        super::output_samples.resize(output_port_count);

        samplerate_ = jack_get_sample_rate(client);
        jack_frames = jack_get_buffer_size(client);

        if (jack_frames % blocksize_)
            throw std::runtime_error("Jack buffer size is not a multiple of blocksize");
    }
示例#12
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 ();
}
示例#13
0
// stage 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// JACK client initialization
int jack_init(){

    short i;
    char* client_name;
    jack_status_t status;

    client = jack_client_open (default_client_name, options, &status, default_server_name);

    if (client == NULL){
        return 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 );
    }

    char port_name[16];
    jack_ports = (jack_port_t**)calloc(n_channels, sizeof(jack_port_t*));

    if(amiserver){
        for(i=0;i<n_channels;i++){
                sprintf(port_name, "%s%d", default_in_port_basename, i+1);
                jack_ports[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
                if(jack_ports[i] == NULL){
                    fprintf ( stderr, "no more JACK ports available\n" );
                    return 1;
                }
        }
    }

    else{
        for(i=0;i<n_channels;i++){
            sprintf(port_name, "%s%d", default_out_port_basename, i+1);
            jack_ports[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
            if(jack_ports[i] == NULL){
                fprintf ( stderr, "no more JACK ports available\n" );
                return 1;
            }
        }
    }

    bufsize = jack_get_buffer_size(client);
    printf("JACK Client initialized\n");
    printf("JACK Buffer size = %d\n", bufsize);
    printf("Audio Channels %hd\n", n_channels);

    return 0;
}
示例#14
0
文件: pyjack.c 项目: egasimus/pyjack
// get_buffer_size
static PyObject* get_buffer_size(PyObject* self, PyObject* args)
{
    pyjack_client_t * client = self_or_global_client(self);

    if(client->pjc == NULL) {
        PyErr_SetString(JackNotConnectedError, "Jack connection has not yet been established.");
        return NULL;
    }

    int bs = jack_get_buffer_size(client->pjc);
    return Py_BuildValue("i", bs);
}
示例#15
0
JackLayer::JackLayer(const AudioPreference &p) :
    AudioLayer(p),
    captureClient_(nullptr),
    playbackClient_(nullptr),
    out_ports_(),
    in_ports_(),
    out_ringbuffers_(),
    in_ringbuffers_(),
    ringbuffer_thread_(),
    //workerAlive_(false),
    ringbuffer_thread_mutex_(),
    data_ready_(),
    playbackBuffer_(0, audioFormat_),
    playbackFloatBuffer_(),
    captureBuffer_(0, audioFormat_),
    captureFloatBuffer_(),
    hardwareBufferSize_(0),
    mainRingBuffer_(Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID))
{
    playbackClient_ = jack_client_open(PACKAGE_NAME,
            (jack_options_t) (JackNullOption | JackNoStartServer), NULL);
    if (!playbackClient_)
        throw std::runtime_error("Could not open JACK client");

    captureClient_ = jack_client_open(PACKAGE_NAME,
            (jack_options_t) (JackNullOption | JackNoStartServer), NULL);
    if (!captureClient_)
        throw std::runtime_error("Could not open JACK client");

    jack_set_process_callback(captureClient_, process_capture, this);
    jack_set_process_callback(playbackClient_, process_playback, this);

    createPorts(playbackClient_, out_ports_, true, out_ringbuffers_);
    createPorts(captureClient_, in_ports_, false, in_ringbuffers_);

    const auto playRate = jack_get_sample_rate(playbackClient_);
    const auto captureRate = jack_get_sample_rate(captureClient_);
    if (playRate != captureRate)
        RING_ERR("Mismatch between capture rate %u and playback rate %u", playRate, captureRate);

    hardwareBufferSize_ = jack_get_buffer_size(playbackClient_);

    auto update_buffer = [] (AudioBuffer &buf, size_t size, unsigned rate, unsigned nbChannels) {
        buf.setSampleRate(rate);
        buf.resize(size);
        buf.setChannelNum(nbChannels);
    };

    update_buffer(playbackBuffer_, hardwareBufferSize_, playRate, out_ports_.size());
    update_buffer(captureBuffer_, hardwareBufferSize_, captureRate, in_ports_.size());

    jack_on_shutdown(playbackClient_, onShutdown, this);
}
示例#16
0
bool JackClient::setup(volatile bool* p_runFlag, uint32_t nrOfFramesInRingBuffer)
{
    m_p_runFlag = p_runFlag;

    const char *server_name = NULL;
    jack_options_t options = JackNoStartServer;
    jack_status_t status;

    // create a jack client
    m_p_jackClient = jack_client_open(s_jackClientName.c_str(), options, &status, server_name);
    if (m_p_jackClient == NULL) {
        DEBUG_PRINT("jack_client_open() failed, status = 0x%2.0x",
                status);
        if (status & JackServerFailed) {
            DEBUG_PRINT("unable to connect to JACK server");
        }
        return false;
    }
    if (status & JackServerStarted) {
        DEBUG_PRINT("jack server up and running");
    }
    if (status & JackNameNotUnique) {
        char* client_name = jack_get_client_name(m_p_jackClient);
        DEBUG_PRINT("unique name `%s' assigned", client_name);
    }


    // create ringbuffer
    m_p_ringBuffer = jack_ringbuffer_create(sizeof(jack_default_audio_sample_t) * jack_get_buffer_size(m_p_jackClient) * nrOfFramesInRingBuffer);
    if (m_p_ringBuffer == NULL) {
        DEBUG_PRINT("failed to create ringbuffer");
        return false;
    }

    // setup callbacks
    int check;
    if ((check = jack_set_process_callback(m_p_jackClient, JackClient::processJackCallback, this))) {
        return false;
    }

    jack_on_shutdown(m_p_jackClient, JackClient::shutdownJackCallback, this);

    if ((check = jack_set_port_connect_callback(m_p_jackClient, JackClient::connectionJackCallback, this))) {
        return false;
    }

    if (!registerPorts()) {
        return false;
    }


    return true;
}
示例#17
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;
		}
	}

	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));

	// 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;
}
示例#18
0
int ja_initialize(SAMPLE srate, unsigned int input_channels,
                  unsigned int output_channels, unsigned int nframes,
                  const char* client_name)
{
        sigset_t sset;
        (void) srate;
        (void) nframes;

        ja_error_msg[0] = '\0';
        client = jack_client_open(client_name, JackNoStartServer, NULL);
        if (client == NULL) {
                ja_set_error_msg("jack_client_open failure");
                return 1;
        }
        ja_frames = jack_get_buffer_size(client);
        ja_sample_rate = (SAMPLE) jack_get_sample_rate(client);
        ja_in_channels = input_channels;
        ja_out_channels = output_channels;
        ja_buffer_bytes = ja_frames * JA_SAMPLE_SIZE;

        ja_inputs = (jack_default_audio_sample_t **)
                malloc(sizeof(jack_default_audio_sample_t *) * input_channels);
        RETURN_IF_NULLPTR(ja_inputs, "malloc failure");

        ja_outputs = (jack_default_audio_sample_t **)
                malloc(sizeof(jack_default_audio_sample_t *) * output_channels);
        RETURN_IF_NULLPTR(ja_outputs, "malloc failure");

        if (ja_register_ports() != 0)
                return 1;

        jack_set_process_thread(client, ja_process_thread, NULL);
        jack_on_shutdown(client, ja_shutdown, NULL);

        /* Unblock signals */
        sigemptyset(&sset);
        if (sigprocmask(SIG_SETMASK, &sset, NULL) < 0) {
                ja_error("Unblock signals error\n");
                return 1;
        }
        ja_lisp_busy = 1;

        return 0;
}
示例#19
0
文件: main.c 项目: pmyadlowsky/qmx
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;
	}
示例#20
0
//-------------------------------------------------------------------------------------------------------
bool JackVST::Open()
{
	if (CheckClient()) {
	
		fInPorts = (jack_port_t**)malloc(sizeof(jack_port_t*)*MAX_PORTS);
		fOutPorts = (jack_port_t**)malloc(sizeof(jack_port_t*)*MAX_PORTS);

		fBufferSize = jack_get_buffer_size (fJackClient);
		fInPortsNum = fOutPortsNum = MAX_PORTS;
		
		// steph : are 32 buffers really needed??
		int numBuff = 4;

		for(int i = 0; i < fInPortsNum; i++) {
			char newName[256];
			sprintf(newName,"VSTreturn%d",fInstances+i+1);
			fInPorts[i] = jack_port_register(JackVST::fJackClient,newName,JACK_DEFAULT_AUDIO_TYPE,JackPortIsInput,0);
			printf("Port: %s created\n",newName);
			fRBufferIn[i] = (float*)malloc(sizeof(float)*fBufferSize*numBuff);
			if (RingBuffer_Init(&fRingBufferIn[i],fBufferSize*numBuff*sizeof(float),fRBufferIn[i])==-1) printf("error while creating ring buffer.\n");
		}

		for(int i = 0; i < fOutPortsNum; i++) {
			char newName[256];
			sprintf(newName,"VSTsend%d",fInstances+i+1);
			fOutPorts[i] = jack_port_register(JackVST::fJackClient,newName,JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput,0);
			printf("Port: %s created\n",newName);
			fRBufferOut[i] = (float*)malloc(sizeof(float)*fBufferSize*numBuff);
			if (RingBuffer_Init(&fRingBufferOut[i],fBufferSize*numBuff*sizeof(float),fRBufferOut[i])==-1) printf("error while creating ring buffer.\n");
		}
			
		fStatus = kIsOn;
		fInstances += MAX_PORTS;
		JackVST::fPlugInList.push_front(this);
		jack_activate(JackVST::fJackClient); 
		return true;
	}else{
		return false;
	}
}
示例#21
0
文件: jack.c 项目: EQ4/xjackfreak
int connect_to_jack(char *_str,int stereo)
	{
	if (debug) fprintf(stderr,"connect_to_jack(%s)",_str);
	if ((client=jack_client_open(_str,0,NULL)) == 0)
		{
		if (debug) fprintf (stderr, " [FAIL]\n");
		return 1;
		}
	else 	if (debug) fprintf(stderr," [OK]\n");
	jack_buf_size=jack_get_buffer_size(client);
	if (debug) fprintf(stderr,"jack buf_size=%lu\n",(unsigned long)jack_buf_size);
	jack_sample_rate=jack_get_sample_rate(client);
	if (debug) fprintf(stderr,"jack rate=%lu\n",(unsigned long)jack_sample_rate);
	if ((!jack_buf_size) || (!jack_sample_rate))
		{
		fprintf(stderr,"bad buf_size or sample rate!\n");
		exit(13);
		}
	if (stereo) jack_set_process_callback(client,output_mix_frame_stereo,0);
	else jack_set_process_callback(client,output_mix_frame_mono,0);
	jack_on_shutdown(client,jack_shutdown,0);

// zero out audio buffers
	memset(audio_inp,0,sizeof(audio_inp));
	memset(audio_out,0,sizeof(audio_out));
	memset(mmdata,0,sizeof(mmdata));

	audio_ird=(0-fft_size/2+MAX_SFRAG_SIZE)%MAX_SFRAG_SIZE;
	if (debug) printf("AUDIO LAG  IN:  audio_ird=%d = %d samples\n",audio_ird,fft_size/2);

	audio_ord=(0-fft_size/4+MAX_SFRAG_SIZE)%MAX_SFRAG_SIZE;
	if (debug) printf("AUDIO LAG OUT:  audio_ord=%d = %d samples\n",audio_ord,fft_size/4);

	audio_roff=fft_size/2;
	if (debug) printf("AUDIO LAG REC: audio_roff=%d samples\n",audio_roff);

	load_data_window(audio_data_window);
	return 0;
	}
    /**
     * Open and initialize connection to the JACK system.
     *
     * @param Parameters - optional parameters
     * @throws AudioOutputException  on error
     * @see AcquireChannels()
     */
    AudioOutputDeviceJack::AudioOutputDeviceJack(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters) {
        if (((DeviceCreationParameterString*)Parameters["NAME"])->ValueAsString().size() >= jack_client_name_size())
            throw Exception("JACK client name too long");

        if ((hJackClient = jack_client_new(((DeviceCreationParameterString*)Parameters["NAME"])->ValueAsString().c_str())) == 0)
            throw AudioOutputException("Seems Jack server not running.");

        existingJackDevices++;

        jack_set_process_callback(hJackClient, __libjack_process_callback, this);
        jack_on_shutdown(hJackClient, __libjack_shutdown_callback, this);
        if (jack_activate(hJackClient))
            throw AudioOutputException("Jack: Cannot activate Jack client.");

        uiMaxSamplesPerCycle = jack_get_buffer_size(hJackClient);

        // create audio channels
        AcquireChannels(((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt());

        // finally activate device if desired
        if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) Play();
    }
示例#23
0
int engine_jack_initialize(engine_t* engine){

  if (!engine->device_name){
    if (!(engine->device_name = strdup("soundtank"))){
      printf("memory error allocating string\n");
      return -1;
    }
  }

  /*try to become a client of the JACK server*/  
  if ((client = jack_client_new(engine->device_name)) == 0){
    printf ("jack engine error: couldn't make jack client, jack server not running?\n");
    return -1;
  }

  /*get sample rate*/
  engine->sample_rate = jack_get_sample_rate(client);

  /*get period size (TODO: JACK does not guarantee a static period
    size however the current Soundtank code can't handle a change in
    the period size and will crash)*/
  engine->period_size = jack_get_buffer_size(client);

  /*set callbacks used by jack server*/
  if (jack_set_process_callback(client, soundtank_jack_process_callback, 0) < 0){
    printf("jack engine error: could not set processing callback function\n");
    return -1;
  }

  jack_on_shutdown(client, soundtank_jack_shutdown_callback, 0);

  /*engine is ready to go, set state variable to indicate so*/
  engine->state = ENGINE_STATE_INACTIVE;

  return 0;
}
示例#24
0
static int 
_open(const char *path, const char *name, const char *id, void *data)
{
	bin_t *bin = data;
	prog_t *handle = (void *)bin - offsetof(prog_t, bin);
	(void)name;

	if(bin->path)
		free(bin->path);
	bin->path = strdup(path);

	// jack init
	if(_jack_init(handle, id))
	{
		bin->ui_driver.close(bin);
		return -1;
	}

	// synthpod init
	bin->app_driver.sample_rate = jack_get_sample_rate(handle->client);
	bin->app_driver.max_block_size = jack_get_buffer_size(handle->client);
	bin->app_driver.min_block_size = 1;
	bin->app_driver.seq_size = MAX(handle->seq_size,
		jack_port_type_get_buffer_size(handle->client, JACK_DEFAULT_MIDI_TYPE));
	
	// app init
	bin->app = sp_app_new(NULL, &bin->app_driver, bin);

	// jack activate
	atomic_init(&handle->kill, 0);
	jack_activate(handle->client); //TODO check

	sp_ui_bundle_load(bin->ui, bin->path, 1);

	return 0; // success
}
示例#25
0
int
main (int argc, char *argv[])
{
    /* Some startup related basics */
    char *client_name, *server_name = NULL, *peer_ip;
    int peer_port = 3000;
    jack_options_t options = JackNullOption;
    jack_status_t status;
#ifdef WIN32
    WSADATA wsa;
    int rc = WSAStartup(MAKEWORD(2, 0), &wsa);
#endif
    /* Torben's famous state variables, aka "the reporting API" ! */
    /* heh ? these are only the copies of them ;)                 */
    int statecopy_connected, statecopy_latency, statecopy_netxruns;
    jack_nframes_t net_period;
    /* Argument parsing stuff */
    extern char *optarg;
    extern int optind, optopt;
    int errflg = 0, c;

    if (argc < 3) {
        printUsage ();
        return 1;
    }

    client_name = (char *) malloc (sizeof (char) * 10);
    peer_ip = (char *) malloc (sizeof (char) * 10);
    sprintf(client_name, "netjack");
    sprintf(peer_ip, "localhost");

    while ((c = getopt (argc, argv, ":h:H:o:i:O:I:n:p:r:B:b:c:m:R:e:N:s:P:")) != -1) {
        switch (c) {
            case 'h':
                printUsage();
                exit (0);
                break;
            case 'H':
                free(peer_ip);
                peer_ip = (char *) malloc (sizeof (char) * strlen (optarg) + 1);
                strcpy (peer_ip, optarg);
                break;
            case 'o':
                playback_channels_audio = atoi (optarg);
                break;
            case 'i':
                capture_channels_audio = atoi (optarg);
                break;
            case 'O':
                playback_channels_midi = atoi (optarg);
                break;
            case 'I':
                capture_channels_midi = atoi (optarg);
                break;
            case 'n':
                latency = atoi (optarg);
                break;
            case 'p':
                peer_port = atoi (optarg);
                break;
            case 'r':
                reply_port = atoi (optarg);
                break;
            case 'B':
                bind_port = atoi (optarg);
                break;
            case 'f':
                factor = atoi (optarg);
                printf("This feature is deprecated and will be removed in future netjack versions. CELT offers a superiour way to conserve bandwidth");
                break;
            case 'b':
                bitdepth = atoi (optarg);
                break;
            case 'c':
#if HAVE_CELT
                bitdepth = 1000;
                factor = atoi (optarg);
#else
                printf( "not built with celt support\n" );
                exit(10);
#endif
                break;
            case 'P':
#if HAVE_OPUS
                bitdepth = 999;
                factor = atoi (optarg);
#else
                printf( "not built with opus support\n" );
                exit(10);
#endif
                break;
            case 'm':
                mtu = atoi (optarg);
                break;
            case 'R':
                redundancy = atoi (optarg);
                break;
            case 'e':
                dont_htonl_floats = 1;
                break;
            case 'N':
                free(client_name);
                client_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1);
                strcpy (client_name, optarg);
                break;
            case 's':
                server_name = (char *) malloc (sizeof (char) * strlen (optarg) + 1);
                strcpy (server_name, optarg);
                options |= JackServerName;
                break;
            case ':':
                fprintf (stderr, "Option -%c requires an operand\n", optopt);
                errflg++;
                break;
            case '?':
                fprintf (stderr, "Unrecognized option: -%c\n", optopt);
                errflg++;
        }
    }
    if (errflg) {
        printUsage ();
        exit (2);
    }

    capture_channels = capture_channels_audio + capture_channels_midi;
    playback_channels = playback_channels_audio + playback_channels_midi;

    outsockfd = socket (AF_INET, SOCK_DGRAM, 0);
    insockfd = socket (AF_INET, SOCK_DGRAM, 0);

    if ((outsockfd == -1) || (insockfd == -1)) {
        fprintf (stderr, "cant open sockets\n" );
        return 1;
    }

    init_sockaddr_in ((struct sockaddr_in *) &destaddr, peer_ip, peer_port);
    if (bind_port) {
        init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, bind_port);
        if( bind (outsockfd, &bindaddr, sizeof (bindaddr)) ) {
            fprintf (stderr, "bind failure\n" );
        }
    }
    if (reply_port) {
        init_sockaddr_in ((struct sockaddr_in *) &bindaddr, NULL, reply_port);
        if( bind (insockfd, &bindaddr, sizeof (bindaddr)) ) {
            fprintf (stderr, "bind failure\n" );
        }
    }

    /* try to become a client of the JACK server */
    client = jack_client_open (client_name, options, &status, server_name);
    if (client == NULL) {
        fprintf (stderr, "jack_client_open() failed, status = 0x%2.0x\n"
                 "Is the JACK server running ?\n", status);
        return 1;
    }

    /* Set up jack callbacks */
    jack_set_process_callback (client, process, 0);
    jack_set_sync_callback (client, sync_cb, 0);
    jack_set_freewheel_callback (client, freewheel_cb, 0);
    jack_on_shutdown (client, jack_shutdown, 0);

    alloc_ports (capture_channels_audio, playback_channels_audio, capture_channels_midi, playback_channels_midi);

    if( bitdepth == 1000 || bitdepth == 999)
        net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
    else
        net_period = ceilf((float) jack_get_buffer_size (client) / (float) factor);

    int rx_bufsize =  get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
    packcache = packet_cache_new (latency + 50, rx_bufsize, mtu);

    /* tell the JACK server that we are ready to roll */
    if (jack_activate (client)) {
        fprintf (stderr, "Cannot activate client");
        return 1;
    }

    /* Now sleep forever... and evaluate the state_ vars */

    signal( SIGTERM, sigterm_handler );
    signal( SIGINT, sigterm_handler );

    statecopy_connected = 2; // make it report unconnected on start.
    statecopy_latency = state_latency;
    statecopy_netxruns = state_netxruns;

    while ( !quit ) {
#ifdef WIN32
        Sleep (1000);
#else
        sleep(1);
#endif
        if (statecopy_connected != state_connected) {
            statecopy_connected = state_connected;
            if (statecopy_connected) {
                state_netxruns = 1; // We want to reset the netxrun count on each new connection
                printf ("Connected :-)\n");
            } else
                printf ("Not Connected\n");

            fflush(stdout);
        }

        if (statecopy_connected) {
            if (statecopy_netxruns != state_netxruns) {
                statecopy_netxruns = state_netxruns;
                printf ("%s: at frame %06d -> total netxruns %d  (%d%%) queue time= %d\n",
                        client_name,
                        state_currentframe,
                        statecopy_netxruns,
                        100 * statecopy_netxruns / state_currentframe,
                        state_recv_packet_queue_time);

                fflush(stdout);
            }
        } else {
            if (statecopy_latency != state_latency) {
                statecopy_latency = state_latency;
                if (statecopy_latency > 1)
                    printf ("current latency %d\n", statecopy_latency);
                fflush(stdout);
            }
        }
    }

    jack_client_close (client);
    packet_cache_free (packcache);
    exit (0);
}
示例#26
0
/**
 * The process callback for this JACK application.
 * It is called by JACK at the appropriate times.
 */
int
process (jack_nframes_t nframes, void *arg)
{
    jack_nframes_t net_period;
    int rx_bufsize, tx_bufsize;

    jack_default_audio_sample_t *buf;
    jack_port_t *port;
    JSList *node;
    int chn;
    int size, i;
    const char *porttype;
    int input_fd;

    jack_position_t local_trans_pos;

    uint32_t *packet_buf_tx, *packet_bufX;
    uint32_t *rx_packet_ptr;
    jack_time_t packet_recv_timestamp;

    if( bitdepth == 1000 || bitdepth == 999)
        net_period = (factor * jack_get_buffer_size(client) * 1024 / jack_get_sample_rate(client) / 8) & (~1) ;
    else
        net_period = (float) nframes / (float) factor;

    rx_bufsize =  get_sample_size (bitdepth) * capture_channels * net_period + sizeof (jacknet_packet_header);
    tx_bufsize =  get_sample_size (bitdepth) * playback_channels * net_period + sizeof (jacknet_packet_header);

    /* Allocate a buffer where both In and Out Buffer will fit */
    packet_buf_tx = alloca (tx_bufsize);

    jacknet_packet_header *pkthdr_tx = (jacknet_packet_header *) packet_buf_tx;

    /*
     * for latency==0 we need to send out the packet before we wait on the reply.
     * but this introduces a cycle of latency, when netsource is connected to itself.
     * so we send out before read only in zero latency mode.
     *
     */

    if( latency == 0 ) {
        /* reset packet_bufX... */
        packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);

        /* ---------- Send ---------- */
        render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
                                      packet_bufX, net_period, dont_htonl_floats);

        /* fill in packet hdr */
        pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos);
        pkthdr_tx->transport_frame = local_trans_pos.frame;
        pkthdr_tx->framecnt = framecnt;
        pkthdr_tx->latency = latency;
        pkthdr_tx->reply_port = reply_port;
        pkthdr_tx->sample_rate = jack_get_sample_rate (client);
        pkthdr_tx->period_size = nframes;

        /* playback for us is capture on the other side */
        pkthdr_tx->capture_channels_audio = playback_channels_audio;
        pkthdr_tx->playback_channels_audio = capture_channels_audio;
        pkthdr_tx->capture_channels_midi = playback_channels_midi;
        pkthdr_tx->playback_channels_midi = capture_channels_midi;
        pkthdr_tx->mtu = mtu;
        if( freewheeling != 0 )
            pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
        else
            pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness;
        //printf("goodness=%d\n", deadline_goodness );

        packet_header_hton (pkthdr_tx);
        if (cont_miss < 3 * latency + 5) {
            int r;
            for( r = 0; r < redundancy; r++ )
                netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
        } else if (cont_miss > 50 + 5 * latency) {
            state_connected = 0;
            packet_cache_reset_master_address( packcache );
            //printf ("Frame %d  \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
            cont_miss = 0;
        }
    }

    /*
     * ok... now the RECEIVE code.
     *
     */


    if( reply_port )
        input_fd = insockfd;
    else
        input_fd = outsockfd;

    // for latency == 0 we can poll.
    if( (latency == 0) || (freewheeling != 0)  ) {
        jack_time_t deadline = jack_get_time() + 1000000 * jack_get_buffer_size(client) / jack_get_sample_rate(client);
        // Now loop until we get the right packet.
        while(1) {
            jack_nframes_t got_frame;
            if ( ! netjack_poll_deadline( input_fd, deadline ) )
                break;

            packet_cache_drain_socket(packcache, input_fd);

            if (packet_cache_get_next_available_framecnt( packcache, framecnt - latency, &got_frame ))
                if( got_frame == (framecnt - latency) )
                    break;
        }
    } else {
        // normally:
        // only drain socket.
        packet_cache_drain_socket(packcache, input_fd);
    }

    size = packet_cache_retreive_packet_pointer( packcache, framecnt - latency, (char**)&rx_packet_ptr, rx_bufsize, &packet_recv_timestamp );
    /* First alternative : we received what we expected. Render the data
     * to the JACK ports so it can be played. */
    if (size == rx_bufsize) {
        uint32_t *packet_buf_rx = rx_packet_ptr;
        jacknet_packet_header *pkthdr_rx = (jacknet_packet_header *) packet_buf_rx;
        packet_bufX = packet_buf_rx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);
        // calculate how much time there would have been, if this packet was sent at the deadline.

        int recv_time_offset = (int) (jack_get_time() - packet_recv_timestamp);
        packet_header_ntoh (pkthdr_rx);
        deadline_goodness = recv_time_offset - (int)pkthdr_rx->latency;
        //printf( "deadline goodness = %d ---> off: %d\n", deadline_goodness, recv_time_offset );

        if (cont_miss) {
            //printf("Frame %d  \tRecovered from dropouts\n", framecnt);
            cont_miss = 0;
        }
        render_payload_to_jack_ports (bitdepth, packet_bufX, net_period,
                                      capture_ports, capture_srcs, nframes, dont_htonl_floats);

        state_currentframe = framecnt;
        state_recv_packet_queue_time = recv_time_offset;
        state_connected = 1;
        sync_state = pkthdr_rx->sync_state;
        packet_cache_release_packet( packcache, framecnt - latency );
    }
    /* Second alternative : we've received something that's not
     * as big as expected or we missed a packet. We render silence
     * to the ouput ports */
    else {
        jack_nframes_t latency_estimate;
        if( packet_cache_find_latency( packcache, framecnt, &latency_estimate ) )
            //if( (state_latency == 0) || (latency_estimate < state_latency) )
            state_latency = latency_estimate;

        // Set the counters up.
        state_currentframe = framecnt;
        //state_latency = framecnt - pkthdr->framecnt;
        state_netxruns += 1;

        //printf ("Frame %d  \tPacket missed or incomplete (expected: %d bytes, got: %d bytes)\n", framecnt, rx_bufsize, size);
        //printf ("Frame %d  \tPacket missed or incomplete\n", framecnt);
        cont_miss += 1;
        chn = 0;
        node = capture_ports;
        while (node != NULL) {
            port = (jack_port_t *) node->data;
            buf = jack_port_get_buffer (port, nframes);
            porttype = jack_port_type (port);
            if (strncmp (porttype, JACK_DEFAULT_AUDIO_TYPE, jack_port_type_size ()) == 0)
                for (i = 0; i < nframes; i++)
                    buf[i] = 0.0;
            else if (strncmp (porttype, JACK_DEFAULT_MIDI_TYPE, jack_port_type_size ()) == 0)
                jack_midi_clear_buffer (buf);
            node = jack_slist_next (node);
            chn++;
        }
    }
    if (latency != 0) {
        /* reset packet_bufX... */
        packet_bufX = packet_buf_tx + sizeof (jacknet_packet_header) / sizeof (jack_default_audio_sample_t);

        /* ---------- Send ---------- */
        render_jack_ports_to_payload (bitdepth, playback_ports, playback_srcs, nframes,
                                      packet_bufX, net_period, dont_htonl_floats);

        /* fill in packet hdr */
        pkthdr_tx->transport_state = jack_transport_query (client, &local_trans_pos);
        pkthdr_tx->transport_frame = local_trans_pos.frame;
        pkthdr_tx->framecnt = framecnt;
        pkthdr_tx->latency = latency;
        pkthdr_tx->reply_port = reply_port;
        pkthdr_tx->sample_rate = jack_get_sample_rate (client);
        pkthdr_tx->period_size = nframes;

        /* playback for us is capture on the other side */
        pkthdr_tx->capture_channels_audio = playback_channels_audio;
        pkthdr_tx->playback_channels_audio = capture_channels_audio;
        pkthdr_tx->capture_channels_midi = playback_channels_midi;
        pkthdr_tx->playback_channels_midi = capture_channels_midi;
        pkthdr_tx->mtu = mtu;
        if( freewheeling != 0 )
            pkthdr_tx->sync_state = (jack_nframes_t)MASTER_FREEWHEELS;
        else
            pkthdr_tx->sync_state = (jack_nframes_t)deadline_goodness;
        //printf("goodness=%d\n", deadline_goodness );

        packet_header_hton (pkthdr_tx);
        if (cont_miss < 3 * latency + 5) {
            int r;
            for( r = 0; r < redundancy; r++ )
                netjack_sendto (outsockfd, (char *) packet_buf_tx, tx_bufsize, 0, &destaddr, sizeof (destaddr), mtu);
        } else if (cont_miss > 50 + 5 * latency) {
            state_connected = 0;
            packet_cache_reset_master_address( packcache );
            //printf ("Frame %d  \tRealy too many packets missed (%d). Let's reset the counter\n", framecnt, cont_miss);
            cont_miss = 0;
        }
    }

    framecnt++;
    return 0;
}
示例#27
0
/**
 * This Function allocates all the I/O Ports which are added the lists.
 */
void
alloc_ports (int n_capture_audio, int n_playback_audio, int n_capture_midi, int n_playback_midi)
{

    int port_flags = JackPortIsOutput;
    int chn;
    jack_port_t *port;
    char buf[32];

    capture_ports = NULL;
    /* Allocate audio capture channels */
    for (chn = 0; chn < n_capture_audio; chn++) {
        snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
        port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
        if (!port) {
            printf( "jack_netsource: cannot register %s port\n", buf);
            break;
        }
        if (bitdepth == 1000) {
#if HAVE_CELT
#if HAVE_CELT_API_0_11
            CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL );
            capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create_custom( celt_mode, 1, NULL ) );
#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
            CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), jack_get_buffer_size(client), NULL );
            capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode, 1, NULL ) );
#else
            CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate( client ), 1, jack_get_buffer_size(client), NULL );
            capture_srcs = jack_slist_append(capture_srcs, celt_decoder_create( celt_mode ) );
#endif
#endif
        } else if (bitdepth == 999) {
#if HAVE_OPUS
            int err;
            OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate( client ), jack_get_buffer_size(client), &err);
            if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); }
            OpusCustomDecoder *decoder = opus_custom_decoder_create(opus_mode, 1, &err);
            if (err != OPUS_OK) { printf("OPUS DECODER FAILED\n"); }
            opus_custom_decoder_init(decoder, opus_mode, 1);
            capture_srcs = jack_slist_append(capture_srcs, decoder);
#endif
        } else {
#if HAVE_SAMPLERATE
            capture_srcs = jack_slist_append (capture_srcs, src_new (SRC_LINEAR, 1, NULL));
#endif
        }
        capture_ports = jack_slist_append (capture_ports, port);
    }

    /* Allocate midi capture channels */
    for (chn = n_capture_audio; chn < n_capture_midi + n_capture_audio; chn++) {
        snprintf (buf, sizeof (buf) - 1, "capture_%u", chn + 1);
        port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
        if (!port) {
            printf ("jack_netsource: cannot register %s port\n", buf);
            break;
        }
        capture_ports = jack_slist_append(capture_ports, port);
    }

    /* Allocate audio playback channels */
    port_flags = JackPortIsInput;
    playback_ports = NULL;
    for (chn = 0; chn < n_playback_audio; chn++) {
        snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
        port = jack_port_register (client, buf, JACK_DEFAULT_AUDIO_TYPE, port_flags, 0);
        if (!port) {
            printf ("jack_netsource: cannot register %s port\n", buf);
            break;
        }
        if( bitdepth == 1000 ) {
#if HAVE_CELT
#if HAVE_CELT_API_0_11
            CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL );
            playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create_custom( celt_mode, 1, NULL ) );
#elif HAVE_CELT_API_0_7 || HAVE_CELT_API_0_8
            CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), jack_get_buffer_size(client), NULL );
            playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode, 1, NULL ) );
#else
            CELTMode *celt_mode = celt_mode_create( jack_get_sample_rate (client), 1, jack_get_buffer_size(client), NULL );
            playback_srcs = jack_slist_append(playback_srcs, celt_encoder_create( celt_mode ) );
#endif
#endif
        } else if( bitdepth == 999 ) {
#if HAVE_OPUS
            const int kbps = factor;
            printf("new opus encoder %d kbps\n", kbps);
            int err;
            OpusCustomMode *opus_mode = opus_custom_mode_create(jack_get_sample_rate (client), jack_get_buffer_size(client), &err ); // XXX free me
            if (err != OPUS_OK) { printf("OPUS MODE FAILED\n"); }
            OpusCustomEncoder *oe = opus_custom_encoder_create( opus_mode, 1, &err );
            if (err != OPUS_OK) { printf("OPUS ENCODER FAILED\n"); }
            opus_custom_encoder_ctl(oe, OPUS_SET_BITRATE(kbps*1024)); // bits per second
            opus_custom_encoder_ctl(oe, OPUS_SET_COMPLEXITY(10));
            opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC));
            opus_custom_encoder_ctl(oe, OPUS_SET_SIGNAL(OPUS_APPLICATION_RESTRICTED_LOWDELAY));
            opus_custom_encoder_init(oe, opus_mode, 1);
            playback_srcs = jack_slist_append(playback_srcs, oe);
#endif
        } else {
#if HAVE_SAMPLERATE
            playback_srcs = jack_slist_append (playback_srcs, src_new (SRC_LINEAR, 1, NULL));
#endif
        }
        playback_ports = jack_slist_append (playback_ports, port);
    }

    /* Allocate midi playback channels */
    for (chn = n_playback_audio; chn < n_playback_midi + n_playback_audio; chn++) {
        snprintf (buf, sizeof (buf) - 1, "playback_%u", chn + 1);
        port = jack_port_register (client, buf, JACK_DEFAULT_MIDI_TYPE, port_flags, 0);
        if (!port) {
            printf ("jack_netsource: cannot register %s port\n", buf);
            break;
        }
        playback_ports = jack_slist_append (playback_ports, port);
    }
}
示例#28
0
/* 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;

  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;

  GST_DEBUG_OBJECT (src, "segsize %d, segtotal %d", 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) {
    /* 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]));
      g_print ("connecting to %s\n", 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;
  }
}
示例#29
0
static int init(struct ao *ao)
{
    struct priv *p = ao->priv;
    const char **matching_ports = NULL;
    char *port_name = p->cfg_port && p->cfg_port[0] ? p->cfg_port : NULL;
    jack_options_t open_options = JackNullOption;
    int port_flags = JackPortIsInput;
    int i;

    struct mp_chmap_sel sel = {0};

    if (p->stdlayout == 0) {
        mp_chmap_sel_add_waveext(&sel);
    } else if (p->stdlayout == 1) {
        mp_chmap_sel_add_alsa_def(&sel);
    } else {
        mp_chmap_sel_add_any(&sel);
    }

    if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
        goto err_out;

    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_out;
    }
    jack_set_process_callback(p->client, outputaudio, ao);

    // list matching ports if connections should be made
    if (p->connect) {
        if (!port_name)
            port_flags |= JackPortIsPhysical;
        matching_ports = jack_get_ports(p->client, port_name, NULL, port_flags);
        if (!matching_ports || !matching_ports[0]) {
            MP_FATAL(ao, "no physical ports available\n");
            goto err_out;
        }
        i = 1;
        p->num_ports = ao->channels.num;
        while (matching_ports[i])
            i++;
        if (p->num_ports > i)
            p->num_ports = i;
    }

    // create out output ports
    for (i = 0; i < p->num_ports; i++) {
        char pname[30];
        snprintf(pname, 30, "out_%d", i);
        p->ports[i] =
            jack_port_register(p->client, pname, JACK_DEFAULT_AUDIO_TYPE,
                               JackPortIsOutput, 0);
        if (!p->ports[i]) {
            MP_FATAL(ao, "not enough ports available\n");
            goto err_out;
        }
    }
    if (jack_activate(p->client)) {
        MP_FATAL(ao, "activate failed\n");
        goto err_out;
    }
    for (i = 0; i < p->num_ports; i++) {
        if (jack_connect(p->client, jack_port_name(p->ports[i]),
                         matching_ports[i]))
        {
            MP_FATAL(ao, "connecting failed\n");
            goto err_out;
        }
    }
    ao->samplerate = jack_get_sample_rate(p->client);
    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;
    p->callback_interval = 0;

    if (!ao_chmap_sel_get_def(ao, &sel, &ao->channels, p->num_ports))
        goto err_out;

    ao->format = AF_FORMAT_FLOAT_NE;
    int unitsize = ao->channels.num * sizeof(float);
    p->outburst = (CHUNK_SIZE + unitsize - 1) / unitsize * unitsize;
    p->ring = mp_ring_new(p, NUM_CHUNKS * p->outburst);
    free(matching_ports);
    return 0;

err_out:
    free(matching_ports);
    if (p->client)
        jack_client_close(p->client);
    return -1;
}
示例#30
0
/*****************************************************************************
 * Open: create a JACK client
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    char psz_name[32];
    audio_output_t *p_aout = (audio_output_t *)p_this;
    struct aout_sys_t *p_sys = NULL;
    int status = VLC_SUCCESS;
    unsigned int i;
    int i_error;

    /* Allocate structure */
    p_sys = calloc( 1, sizeof( aout_sys_t ) );
    if( p_sys == NULL )
    {
        status = VLC_ENOMEM;
        goto error_out;
    }
    p_aout->sys = p_sys;
    p_sys->latency = 0;

    /* Connect to the JACK server */
    snprintf( psz_name, sizeof(psz_name), "vlc_%d", getpid());
    psz_name[sizeof(psz_name) - 1] = '\0';
    p_sys->p_jack_client = jack_client_open( psz_name,
                                             JackNullOption | JackNoStartServer,
                                             NULL );
    if( p_sys->p_jack_client == NULL )
    {
        msg_Err( p_aout, "failed to connect to JACK server" );
        status = VLC_EGENERIC;
        goto error_out;
    }

    /* Set the process callback */
    jack_set_process_callback( p_sys->p_jack_client, Process, p_aout );
    jack_set_graph_order_callback ( p_sys->p_jack_client, GraphChange, p_aout );

    p_aout->pf_play = aout_PacketPlay;
    p_aout->pf_pause = aout_PacketPause;
    p_aout->pf_flush = aout_PacketFlush;
    aout_PacketInit( p_aout, &p_sys->packet,
                     jack_get_buffer_size( p_sys->p_jack_client ) );
    aout_VolumeSoftInit( p_aout );

    /* JACK only supports fl32 format */
    p_aout->format.i_format = VLC_CODEC_FL32;
    // TODO add buffer size callback
    p_aout->format.i_rate = jack_get_sample_rate( p_sys->p_jack_client );

    p_sys->i_channels = aout_FormatNbChannels( &p_aout->format );

    p_sys->p_jack_ports = malloc( p_sys->i_channels *
                                  sizeof(jack_port_t *) );
    if( p_sys->p_jack_ports == NULL )
    {
        status = VLC_ENOMEM;
        goto error_out;
    }

    p_sys->p_jack_buffers = malloc( p_sys->i_channels *
                                    sizeof(jack_sample_t *) );
    if( p_sys->p_jack_buffers == NULL )
    {
        status = VLC_ENOMEM;
        goto error_out;
    }

    /* Create the output ports */
    for( i = 0; i < p_sys->i_channels; i++ )
    {
        snprintf( psz_name, sizeof(psz_name), "out_%d", i + 1);
        psz_name[sizeof(psz_name) - 1] = '\0';
        p_sys->p_jack_ports[i] = jack_port_register( p_sys->p_jack_client,
                psz_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );

        if( p_sys->p_jack_ports[i] == NULL )
        {
            msg_Err( p_aout, "failed to register a JACK port" );
            status = VLC_EGENERIC;
            goto error_out;
        }
    }

    /* Tell the JACK server we are ready */
    i_error = jack_activate( p_sys->p_jack_client );
    if( i_error )
    {
        msg_Err( p_aout, "failed to activate JACK client (error %d)", i_error );
        status = VLC_EGENERIC;
        goto error_out;
    }

    /* Auto connect ports if we were asked to */
    if( var_InheritBool( p_aout, AUTO_CONNECT_OPTION ) )
    {
        unsigned int i_in_ports;
        char *psz_regex = var_InheritString( p_aout, CONNECT_REGEX_OPTION );
        const char **pp_in_ports = jack_get_ports( p_sys->p_jack_client,
                                                   psz_regex, NULL,
                                                   JackPortIsInput );
        free( psz_regex );
        /* Count the number of returned ports */
        i_in_ports = 0;
        while( pp_in_ports && pp_in_ports[i_in_ports] )
        {
            i_in_ports++;
        }

        /* Tie the output ports to JACK input ports */
        for( i = 0; i_in_ports > 0 && i < p_sys->i_channels; i++ )
        {
            const char* psz_in = pp_in_ports[i % i_in_ports];
            const char* psz_out = jack_port_name( p_sys->p_jack_ports[i] );

            i_error = jack_connect( p_sys->p_jack_client, psz_out, psz_in );
            if( i_error )
            {
                msg_Err( p_aout, "failed to connect port %s to port %s (error %d)",
                         psz_out, psz_in, i_error );
            }
            else
            {
                msg_Dbg( p_aout, "connecting port %s to port %s",
                         psz_out, psz_in );
            }
        }
        free( pp_in_ports );
    }

    msg_Dbg( p_aout, "JACK audio output initialized (%d channels, rate=%d)",
             p_sys->i_channels, p_aout->format.i_rate );

error_out:
    /* Clean up, if an error occurred */
    if( status != VLC_SUCCESS && p_sys != NULL)
    {
        if( p_sys->p_jack_client )
        {
            jack_deactivate( p_sys->p_jack_client );
            jack_client_close( p_sys->p_jack_client );
            aout_PacketDestroy( p_aout );
        }
        free( p_sys->p_jack_ports );
        free( p_sys->p_jack_buffers );
        free( p_sys );
    }
    return status;
}