Example #1
0
void
setup_ports (int sources, char *source_names[], jack_thread_info_t *info)
{
	unsigned int i;
	size_t in_size;

	/* Allocate data structures that depend on the number of ports. */
	nports = sources;
	ports = (jack_port_t **) malloc (sizeof (jack_port_t *) * nports);
	in_size =  nports * sizeof (jack_default_audio_sample_t *);
	in = (jack_default_audio_sample_t **) malloc (in_size);
	rb = jack_ringbuffer_create(nports * sample_size * info->rb_size);

	//	printf("sample size [%u]\n", sample_size);

	/* When JACK is running realtime, jack_activate() will have
	 * called mlockall() to lock our pages into memory.  But, we
	 * still need to touch any newly allocated pages before
	 * process() starts using them.  Otherwise, a page fault could
	 * create a delay that would force JACK to shut us down. */
	memset(in, 0, in_size);
	memset(rb->buf, 0, rb->size);

	for (i = 0; i < nports; i++) {
		char name[64];

		sprintf (name, "input%d", i+1);

		if ((ports[i] = jack_port_register (info->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) {
			fprintf (stderr, "cannot register input port \"%s\"!\n", name);
			jack_client_close (info->client);
			exit (1);
		}
	}

	for (i = 0; i < nports; i++) {
		if (jack_connect (info->client, source_names[i], jack_port_name (ports[i]))) {
			fprintf (stderr, "cannot connect input port %s to %s\n", jack_port_name (ports[i]), source_names[i]);
			jack_client_close (info->client);
			exit (1);
		} 
	}

	info->can_process = 1;		/* process() can start, now */
}
Example #2
0
/* connect to jack ports named in the NULL-terminated wishlist */
static int real_connect_jack_ports(out123_handle *ao
,	jack_handle_t* handle, const char** wishlist)
{
	const char **wish = wishlist;
	int ch, err;
	int ch_wrap = 0, wish_wrap = 0;

	if(!wish)
		return 0;
	if(wish != NULL && *wish == NULL)
		return 1; /* success, nothing connected as wanted */
	ch=0;
	/* Connect things as long as there are sources or sinks left. */
	while(!wish_wrap || !ch_wrap)
	{
		const char* in = jack_port_name(handle->ports[ch]);

		if((err = jack_connect(handle->client, in, *wish)) != 0 && err != EEXIST)
		{
			if(!AOQUIET)
				error4( "connect_jack_ports(): failed to jack_connect() ch%i (%s) to %s: %d"
				,	ch, in ? in : "<nil>", *wish, err );
			return 0;
		}
		/*
			Increment channel and wishlist, both possibly wrapping around, to
			ensure we connected all channels to some output port and provided
			some input to all ports in the wishlist. Both cases of less channels
			than output ports (splitting) and more channels	than output ports
			(downmix) are sensible.
		*/
		if(++ch == handle->channels)
		{
			ch = 0;
			++ch_wrap;
		}
		if(!*(++wish))
		{
			wish = wishlist;
			++wish_wrap;
		}
	}

	return 1;
}
int
connect_to_output_port (const char * port)
{
   int ret = jack_port_disconnect(jack_client, input_port);
   if (ret)
   {
      g_warning("Cannot disconnect MIDI port.");
      return -3;
   }
   ret = jack_connect(jack_client, port, jack_port_name(input_port));
   if (ret)
   {
      g_warning("Cannot connect to %s.", port);
      return -4;
   }
   g_warning("Connected to %s.", port);
   return 0;
}
Example #4
0
/////////////////////////////////////////////////////////////////////////////////////////////
// Output means output of SSM, so this connects plugin inputs to a jack destination
void JackClient::ConnectOutput(int n, const std::string &JackPort) {
    if(!IsAttached()) return;
    std::cerr << "JackClient::ConnectOutput: connecting source [" << m_OutputPortMap[n]->Name << "] \
        to dest [" << JackPort << "]" << std::endl;

    if(m_OutputPortMap[n]->ConnectedTo != "") {
        if(jack_disconnect(m_Client, jack_port_name(m_OutputPortMap[n]->Port), m_OutputPortMap[n]->ConnectedTo.c_str()))
            error("JackClient::ConnectOutput: cannot disconnect output port [%s] to [%s]",
                  m_OutputPortMap[n]->ConnectedTo.c_str(),
                  m_OutputPortMap[n]->Name.c_str());
    }

    m_OutputPortMap[n]->ConnectedTo = JackPort;
    if(jack_connect(m_Client, jack_port_name(m_OutputPortMap[n]->Port), JackPort.c_str()))
        error("JackClient::ConnectOutput: cannot connect output port [%s] to [%s]",
              m_OutputPortMap[n]->Name.c_str(), JackPort.c_str());
    m_OutputPortMap[n]->Connected = true;
}
 void AudioOutputDeviceJack::AudioChannelJack::ParameterJackBindings::OnSetValue(std::vector<String> vS) {
     String src_name = ((DeviceCreationParameterString*)pChannel->pDevice->Parameters["NAME"])->ValueAsString() + ":" +
                       ((DeviceRuntimeParameterString*)pChannel->Parameters["NAME"])->ValueAsString();
     // disconnect all current bindings first
     for (int i = 0; i < Bindings.size(); i++) {
         String dst_name = Bindings[i];
         int res = jack_disconnect(pChannel->pDevice->hJackClient, src_name.c_str(), dst_name.c_str());
     }
     // connect new bindings
     for (int i = 0; i < vS.size(); i++) {
         String dst_name = vS[i];
         int res = jack_connect(pChannel->pDevice->hJackClient, src_name.c_str(), dst_name.c_str());
         if (res == EEXIST) throw AudioOutputException("Jack: Connection to port '" + dst_name + "' already established");
         else if (res)      throw AudioOutputException("Jack: Cannot connect port '" + src_name + "' to port '" + dst_name + "'");
     }
     // remember bindings
     Bindings = vS;
 }
Example #6
0
void RtMidiOutJack :: openPort( unsigned int portNumber, const std::string portName )
{
  JackMidiData *data = static_cast<JackMidiData *> (apiData_);

  // Creating new port
  if ( data->port == NULL )
    data->port = jack_port_register( data->client, portName.c_str(),
      JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 );

  if ( data->port == NULL ) {
    errorString_ = "RtMidiOut::openVirtualPort: JACK error creating virtual port";
    error( RtError::DRIVER_ERROR );
  }

  // Connecting to the output
  std::string name = getPortName( portNumber );
  jack_connect( data->client, jack_port_name( data->port ), name.c_str() );
}
Example #7
0
static void
process_info_connect_port (process_info_t * procinfo,
                           ui_t * ui,
                           gshort in,
                           unsigned long port_index,
                           const char * port_name)
{
  const char ** jack_ports;
  unsigned long jack_port_index;
  int err;
  char * full_port_name;
  
  jack_ports = jack_get_ports (procinfo->jack_client, NULL, NULL,
                               JackPortIsPhysical | (in ? JackPortIsOutput : JackPortIsInput));
  
  if (!jack_ports)
    return;
  
  for (jack_port_index = 0;
       jack_ports[jack_port_index] && jack_port_index <= port_index;
       jack_port_index++)
    {
      if (jack_port_index != port_index)
        continue;
        
      full_port_name = g_strdup_printf ("%s:%s", jack_client_name, port_name);

      _update_status ( _("Connecting port '%s' with '%s'"), full_port_name, jack_ports[jack_port_index] );

      err = jack_connect (procinfo->jack_client,
                          in ? jack_ports[jack_port_index] : full_port_name,
                          in ? full_port_name : jack_ports[jack_port_index]);

      if (err)
        fprintf (stderr, _("%s: error connecting ports '%s' and '%s'\n"),
                 __FUNCTION__, full_port_name, jack_ports[jack_port_index]);
      else
	      _update_status ( _("Connected port '%s' with '%s'"), full_port_name, jack_ports[jack_port_index] );

      free (full_port_name);
    }
  
  free (jack_ports);
}
Example #8
0
int 
jack_port_connect_named ( jack_client_t *client , 
			  const char *src , const char *dst )
{
  int err = jack_connect ( client , src , dst ) ;
  if ( err ) {
    eprintf ( "jack_connect() failed: '%s' -> '%s'\n" , src , dst ) ;
    switch ( err ) {
    case EEXIST:
      eprintf ( "jack_connect() failed: connection exists\n" ) ;
      break ;
    default:
      eprintf ( "jack_connect() failed: unknown reason\n" ) ;
/*       FAILURE ; */
      break ;
    }
  }
  return err ;
}
Example #9
0
void JackCpp::AudioIO::connectFrom(unsigned int index, std::string sourcePortName)
	throw(std::range_error, std::runtime_error)
{
	int connect_ret;
	if (mJackState != active)
		throw std::runtime_error("client must be active before connecting ports");
	if(index < mInputPorts.size()){
		connect_ret = jack_connect(mJackClient, sourcePortName.c_str(), jack_port_name(mInputPorts[index]));
		if(connect_ret != 0 && connect_ret != EEXIST){
			std::string ret_string("cannot connect source: ");
			ret_string.append(sourcePortName);
			ret_string.append(" to dest: ");
			ret_string.append(jack_port_name(mInputPorts[index]));
			ret_string.append(" does source exist?");
			throw std::range_error(ret_string);
		}
	} else
		throw std::range_error("inport index out of range");
}
Example #10
0
void setup_ports (int nports, char *source_names[], jack_thread_info_t *info) {
	unsigned int i;
	const size_t in_size =  nports * sizeof(jack_default_audio_sample_t *);

	info->peak = (float*) malloc(sizeof(float) * nports);
	info->pcur = (float*) malloc(sizeof(float) * nports);
	info->pmax = (float*) malloc(sizeof(float) * nports);
	info->ptme = (int*) malloc(sizeof(int  ) * nports);

	/* Allocate data structures that depend on the number of ports. */
	ports = (jack_port_t **) malloc(sizeof(jack_port_t *) * nports);
	in = (jack_default_audio_sample_t **) malloc(in_size);
	memset(in, 0, in_size);

	for (i = 0; i < nports; i++) {
		char name[64];
		info->peak[i]=0.0;
		info->pcur[i]=0.0;
		info->ptme[i]=0;

		sprintf(name, "input%d", i+1);

		if ((ports[i] = jack_port_register(info->client, name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0)) == 0) {
			fprintf(stderr, "cannot register input port \"%s\"!\n", name);
			jack_client_close(info->client);
			cleanup(info);
			exit(1);
		}
	}

	for (i = 0; i < nports; i++) {
		if (jack_connect(info->client, source_names[i], jack_port_name(ports[i]))) {
			fprintf(stderr, "cannot connect input port %s to %s\n", jack_port_name(ports[i]), source_names[i]);
#if 0 /* not fatal - connect manually */
			jack_client_close(info->client);
			exit(1);
#endif
		}
	}

	/* process() can start, now */
	info->can_process = 1;
}
Example #11
0
static void JACKconnect(GError** error) {
	dbg(1, "...");

	j_client = jack_client_open("samplecat", (jack_options_t) 0, NULL);

	if(!j_client) {
		*error = g_error_new_literal(g_quark_from_static_string(AUDITIONER_DOMAIN), 1, "could not connect to JACK");
		return;
	}

	jack_on_shutdown(j_client, jack_shutdown_callback, NULL);
	jack_set_process_callback(j_client, jack_audio_callback, NULL);

#ifdef JACK_MIDI
	jack_midi_port = jack_port_register(j_client, "Midi in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput , 0);
	if (jack_midi_port == NULL) {
		 dbg(0, "can't register jack-midi-port\n");
	}

	midi_thread_run = 1;
	pthread_create(&midi_thread_id, NULL, jack_midi_thread, NULL);
	sched_yield();
#endif

	jack_activate(j_client);
	if(_debug_) printf("jack activated\n");

#ifdef JACK_MIDI
	char *jack_midiconnect = play->config.jack_midiconnect;
	if(!jack_midiconnect || strlen(jack_midiconnect) < 1) {
		jack_midiconnect = NULL;
	} else if(!strncmp(jack_midiconnect, "DISABLE", 7)) {
		jack_midiconnect = NULL;
	}
	if(jack_midiconnect) {
		dbg(1, "MIDI autoconnect '%s' -> '%s'", jack_midiconnect, jack_port_name(jack_midi_port));
		if(jack_connect(j_client, jack_midiconnect, jack_port_name(jack_midi_port))) {
			dbg(0, "Auto-connect jack midi port failed.");
		}
	}
#endif
}
Example #12
0
void jack_raw_output::connect_ports ()
{
    const char** ports;

    ports = jack_get_ports (_client, 0, 0, JackPortIsPhysical | JackPortIsInput);
    if (!ports)
    {
	PSYNTH_LOG << base::log::warning << "There are no phisical output ports.";
	return;
    }

    PSYNTH_ON_BLOCK_EXIT ([&] { ::free (ports); });

    std::size_t i = 0;
    for (; i < _out_ports.size() && ports [i]; ++i)
	jack_connect (_client, jack_port_name (_out_ports [i]), ports [i]);

    if (i < _out_ports.size ())
        PSYNTH_LOG << base::log::warning << "Not enough phisical output ports.";
}
Example #13
0
    int connect_all_outputs(const char * client_name)
    {
        const char **ports = jack_get_ports (client, client_name, NULL, JackPortIsInput);

        if (!ports)
            return -1;

        std::size_t i = 0;
        while (ports[i]) {
            if (i == output_ports.size())
                break;

            int err = jack_connect(client, jack_port_name(output_ports[i]), ports[i]);
            if (err)
                return err;
            ++i;
        }

        free(ports);
        return 0;
    }
void JackSequencerController::play() {
    if( m_sequencer != NULL ) {
        // do stuff
        if( jack_activate( m_client ) ) {
		std::cout << "Could not activate client." << std::endl;
		return;
	}

	const char ** ports;
	if( ( ports = jack_get_ports( m_client, NULL, NULL, JackPortIsPhysical | JackPortIsInput ) ) == NULL ) {
		std::cout << "cannot get playback ports" << std::endl;
		return;
	}

	int i = 0;
	while( ports[i] != NULL ) {
		if( !jack_connect( m_client, jack_port_name( m_port ), ports[i] ) ) break;
	}
	
	free( ports );
    }
}
Example #15
0
void reconfigure_send_ch_count(struct state_jack *s, int ch_count)
{
        const char **ports;
        int i;

        s->out_channel_count = s->out_channel_count_req = ch_count;

        if ((ports = jack_get_ports (s->client, s->out_port_pattern, NULL, JackPortIsInput)) == NULL) {
                fprintf(stderr, "Cannot find any ports matching pattern '%s'\n", s->out_port_pattern);
                s->out_channel_count = 0;
                return;
        }
        for (i = 0; i < s->record.ch_count; ++i) {
                jack_disconnect(s->client, jack_port_name (s->output_port[i]), ports[i]);
                free(s->play_buffer[i]);
        }

        i = 0;
        while (ports[i]) ++i;

        if(i < s->out_channel_count) {
                fprintf(stderr, "Not enought output ports found matching pattern '%s': "
                                "%d requested, %d found\n", s->out_port_pattern, s->record.ch_count, i);
                fprintf(stderr, "Reducing port count to %d\n", i);
                s->out_channel_count = i;
        }
         
        for(i = 0; i < s->out_channel_count; ++i) {
                fprintf(stderr, "%s\n\n\n", ports[i]);
                if (jack_connect (s->client, jack_port_name (s->output_port[i]), ports[i])) {
                        fprintf (stderr, "cannot connect output ports\n");
                }
                s->play_buffer[i] = malloc(BUFF_SIZE);
        }
        
        fprintf(stderr, "[JACK] Sending %d output audio streams (ports).\n", s->out_channel_count);
 
        free (ports);
}
Example #16
0
// connect_port
static PyObject* port_connect(PyObject* self, PyObject* args)
{
    char* src_name;
    char* dst_name;

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

    if (! PyArg_ParseTuple(args, "ss", &src_name, &dst_name))
        return NULL;

    jack_port_t * src = jack_port_by_name(client->pjc, src_name);
    if (!src) {
        PyErr_SetString(JackUsageError, "Non existing source port.");
        return NULL;
        }
    jack_port_t * dst = jack_port_by_name(client->pjc, dst_name);
    if (!dst) {
        PyErr_SetString(JackUsageError, "Non existing destination port.");
        return NULL;
        }
    if(! client->active) {
        if(jack_port_is_mine(client->pjc, src) || jack_port_is_mine(client->pjc, dst)) {
            PyErr_SetString(JackUsageError, "Jack client must be activated to connect own ports.");
            return NULL;
        }
    }
    int error = jack_connect(client->pjc, src_name, dst_name);
    if (error !=0 && error != EEXIST) {
        PyErr_SetString(JackError, "Failed to connect ports.");
        return NULL;
    }

    Py_INCREF(Py_None);
    return Py_None;
}
Example #17
0
File: ao_jack.c Project: Nikoli/mpv
static int
connect_to_outports(struct ao *ao)
{
    struct priv *p = ao->priv;

    char *port_name = (p->cfg_port && p->cfg_port[0]) ? p->cfg_port : NULL;
    const char **matching_ports = NULL;
    int port_flags = JackPortIsInput;
    int i;

    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 ports to connect to\n");
        goto err_get_ports;
    }

    for (i = 0; i < p->num_ports && matching_ports[i]; i++) {
        if (jack_connect(p->client, jack_port_name(p->ports[i]),
                         matching_ports[i]))
        {
            MP_FATAL(ao, "connecting failed\n");
            goto err_connect;
        }
    }

    free(matching_ports);
    return 0;

err_connect:
    free(matching_ports);
err_get_ports:
    return -1;
}
Example #18
0
int
main (int argc, char *argv[])
{
	jack_client_t* client = NULL;
    /* try to become a client of the JACK server */
	if ((client = jack_client_open ("zombie", JackNullOption, NULL)) == 0) {
		fprintf (stderr, "jack server not running?\n");
		goto error;
	}
    
    jack_set_process_callback (client, process, NULL);
    jack_on_shutdown(client, shutdown, NULL);
    output_port = jack_port_register (client, "port1", 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");
		goto error;
	}
    
    jack_connect(client, jack_port_name(output_port), "coreaudio:Built-in Audio:in2");
    
    while (running) {
        sleep(1);
        printf ("run\n");
    }

    jack_deactivate (client);
	jack_client_close (client);
	return 0;
    
error:
    if (client) 
        jack_client_close (client);
    return 1;
}
Example #19
0
 int connect_input(size_t channel, const char * portname)
 {
     if (channel >= input_ports.size())
         return -1;
     return jack_connect(client, portname, jack_port_name(input_ports[channel]));
 }
/* 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;
  }
}
Example #21
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;
}
Example #22
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;
}
// return 0: ok
// return 1: cannot activate client
// return 2: cannot connect output port
int JackAudioDriver::connect()
{
	INFOLOG( "connect" );

	// The `jack_activate' function is defined in the jack/jack.h
	// header files and tells the JACK server that the program is
	// ready to start processing audio. It returns 0 on success
	// and a non-zero error code otherwise.
	if ( jack_activate( m_pClient ) ) {
		Hydrogen::get_instance()->raiseError( Hydrogen::JACK_CANNOT_ACTIVATE_CLIENT );
		return 1;
	}


	bool connect_output_ports = m_bConnectOutFlag;

	memset( track_output_ports_L, 0, sizeof(track_output_ports_L) );
	memset( track_output_ports_R, 0, sizeof(track_output_ports_R) );

#ifdef H2CORE_HAVE_LASH
	if ( Preferences::get_instance()->useLash() ){
		LashClient* lashClient = LashClient::get_instance();
		if (lashClient && lashClient->isConnected()){
			// INFOLOG( "[LASH] Sending JACK client name to LASH server" );
			lashClient->sendJackClientName();

			if (!lashClient->isNewProject()){
				connect_output_ports = false;
			}
		}
	}
#endif

	if ( connect_output_ports ) {
		// Connect the ports.
		// The `jack_connect' function is defined in the
		// jack/jack.h file. It establishes a connection between
		// two ports. When a connection exists, data written
		// to the source port will be available to be read at
		// the destination port. Returns 0 on success, exits
		// if the connection is already made, and returns a
		// non-zero error code otherwise.
		// Syntax: jack_connect( jack_client_t jack_client,
		//                       const char *source_port )
		//                       const char *destination_port
		// )
		// The `jack_port_name' function is also defined in
		// the jack/jack.h header returns the full name of a
		// provided port of type jack_port_t.
		if ( jack_connect( m_pClient, jack_port_name( output_port_1 ),
				   output_port_name_1.toLocal8Bit() ) == 0 &&
		     jack_connect( m_pClient, jack_port_name( output_port_2 ),
				   output_port_name_2.toLocal8Bit() ) == 0 ) {
			return 0;
		}

		INFOLOG( "Could not connect to the saved output ports. Connect to the first pair of input ports instead." );
		// The `jack_get_ports' is defined in the jack/jack.h
		// header file and performs a lookup of ports of the
		// JACK server based on their e.g. flags. It returns a
		// NULL-terminated array of ports that match the
		// specified arguments. The caller is responsible for
		// calling jack_free() any non-NULL returned
		// value.
		const char ** portnames = jack_get_ports( m_pClient, NULL, NULL, JackPortIsInput );
		if ( !portnames || !portnames[0] || !portnames[1] ) {
			ERRORLOG( "Couldn't locate two Jack input ports" );
			Hydrogen::get_instance()->raiseError( Hydrogen::JACK_CANNOT_CONNECT_OUTPUT_PORT );
			return 2;
		}
		if ( jack_connect( m_pClient, jack_port_name( output_port_1 ),
				   portnames[0] ) != 0 ||
		     jack_connect( m_pClient, jack_port_name( output_port_2 ),
				   portnames[1] ) != 0 ) {
			ERRORLOG( "Couldn't connect to first pair of Jack input ports" );
			Hydrogen::get_instance()->raiseError( Hydrogen::JACK_CANNOT_CONNECT_OUTPUT_PORT );
			return 2;
		}
		free( portnames );
	}

	return 0;
}
Example #24
0
static void *ja_init(const char *device, unsigned rate, unsigned latency)
{
   jack_t *jd = (jack_t*)calloc(1, sizeof(jack_t));
   if (!jd)
      return NULL;

   pthread_cond_init(&jd->cond, NULL);
   pthread_mutex_init(&jd->cond_lock, NULL);
   
   const char **jports = NULL;
   char *dest_ports[2];
   size_t bufsize = 0;
   int parsed = 0;

   jd->client = jack_client_open("RetroArch", JackNullOption, NULL);
   if (jd->client == NULL)
      goto error;

   g_settings.audio.out_rate = jack_get_sample_rate(jd->client);

   jack_set_process_callback(jd->client, process_cb, jd);
   jack_on_shutdown(jd->client, shutdown_cb, jd);

   jd->ports[0] = jack_port_register(jd->client, "left", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
   jd->ports[1] = jack_port_register(jd->client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
   if (jd->ports[0] == NULL || jd->ports[1] == NULL)
   {
      RARCH_ERR("Failed to register ports.\n");
      goto error;
   }
   
   jports = jack_get_ports(jd->client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
   if (jports == NULL)
   {
      RARCH_ERR("Failed to get ports.\n");
      goto error;
   }

   bufsize = find_buffersize(jd, latency);
   jd->buffer_size = bufsize;

   RARCH_LOG("JACK: Internal buffer size: %d frames.\n", (int)(bufsize / sizeof(jack_default_audio_sample_t)));
   for (int i = 0; i < 2; i++)
   {
      jd->buffer[i] = jack_ringbuffer_create(bufsize);
      if (jd->buffer[i] == NULL)
      {
         RARCH_ERR("Failed to create buffers.\n");
         goto error;
      }
   }

   parsed = parse_ports(dest_ports, jports);

   if (jack_activate(jd->client) < 0)
   {
      RARCH_ERR("Failed to activate Jack...\n");
      goto error;
   }

   for (int i = 0; i < 2; i++)
   {
      if (jack_connect(jd->client, jack_port_name(jd->ports[i]), dest_ports[i]))
      {
         RARCH_ERR("Failed to connect to Jack port.\n");
         goto error;
      }
   }

   for (int i = 0; i < parsed; i++)
      free(dest_ports[i]);
  
   jack_free(jports);
   return jd;

error:
   if (jports != NULL)
      jack_free(jports);
   return NULL;
}
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;
}
Example #26
0
static gboolean cbox_jack_io_process_cmd(struct cbox_command_target *ct, struct cbox_command_target *fb, struct cbox_osc_command *cmd, GError **error)
{
    struct cbox_jack_io_impl *jii = (struct cbox_jack_io_impl *)ct->user_data;
    struct cbox_io *io = jii->ioi.pio;
    gboolean handled = FALSE;
    if (!strcmp(cmd->command, "/status") && !strcmp(cmd->arg_types, ""))
    {
        if (!cbox_check_fb_channel(fb, cmd->command, error))
            return FALSE;
        return cbox_execute_on(fb, NULL, "/client_type", "s", error, "JACK") &&
            cbox_execute_on(fb, NULL, "/client_name", "s", error, jii->client_name) &&
            cbox_io_process_cmd(io, fb, cmd, error, &handled);
    }
    else if (!strcmp(cmd->command, "/rename_midi_port") && !strcmp(cmd->arg_types, "ss"))
    {
        const char *uuidstr = CBOX_ARG_S(cmd, 0);
        const char *new_name = CBOX_ARG_S(cmd, 1);
        struct cbox_uuid uuid;
        if (!cbox_uuid_fromstring(&uuid, uuidstr, error))
            return FALSE;
        struct cbox_midi_input *midiin = cbox_io_get_midi_input(io, NULL, &uuid);
        struct cbox_midi_output *midiout = cbox_io_get_midi_output(io, NULL, &uuid);
        if (!midiout && !midiin)
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Port '%s' not found", uuidstr);
            return FALSE;
        }
        jack_port_t *port = midiout ? ((struct cbox_jack_midi_output *)midiout)->port 
            : ((struct cbox_jack_midi_input *)midiin)->port;
        char **pname = midiout ? &midiout->name : &midiin->name;
        if (0 != jack_port_set_name(port, new_name))
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot set port name to '%s'", new_name);
            return FALSE;
        }
        g_free(*pname);
        *pname = g_strdup(new_name);
        return TRUE;
    }
    else if (!strcmp(cmd->command, "/autoconnect") && !strcmp(cmd->arg_types, "ss"))
    {
        const char *uuidstr = CBOX_ARG_S(cmd, 0);
        const char *spec = CBOX_ARG_S(cmd, 1);
        struct cbox_uuid uuid;
        if (!cbox_uuid_fromstring(&uuid, uuidstr, error))
            return FALSE;
        struct cbox_midi_output *midiout = cbox_io_get_midi_output(io, NULL, &uuid);
        if (midiout)
        {
            cbox_jack_midi_output_set_autoconnect((struct cbox_jack_midi_output *)midiout, spec);
            return TRUE;
        }
        struct cbox_midi_input *midiin = cbox_io_get_midi_input(io, NULL, &uuid);
        if (midiin)
        {
            cbox_jack_midi_input_set_autoconnect((struct cbox_jack_midi_input *)midiin, spec);
            return TRUE;
        }
        g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Port '%s' not found", uuidstr);
        return FALSE;
    }
    else if (!strcmp(cmd->command, "/disconnect_midi_port") && !strcmp(cmd->arg_types, "s"))
    {
        const char *uuidstr = CBOX_ARG_S(cmd, 0);
        struct cbox_uuid uuid;
        if (!cbox_uuid_fromstring(&uuid, uuidstr, error))
            return FALSE;
        struct cbox_midi_input *midiin = cbox_io_get_midi_input(io, NULL, &uuid);
        struct cbox_midi_output *midiout = cbox_io_get_midi_output(io, NULL, &uuid);
        if (!midiout && !midiin)
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Port '%s' not found", uuidstr);
            return FALSE;
        }
        jack_port_t *port = midiout ? ((struct cbox_jack_midi_output *)midiout)->port 
            : ((struct cbox_jack_midi_input *)midiin)->port; 
        jack_port_disconnect(jii->client, port);
        return TRUE;
    }
    else if (!strcmp(cmd->command, "/port_connect") && !strcmp(cmd->arg_types, "ss"))
    {
        const char *port_from = CBOX_ARG_S(cmd, 0);
        const char *port_to = CBOX_ARG_S(cmd, 1);
        int res = jack_connect(jii->client, port_from, port_to);
        if (res == EEXIST)
            res = 0;
        if (res)
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot connect port '%s' to '%s'", port_from, port_to);
        return res == 0;
    }
    else if (!strcmp(cmd->command, "/port_disconnect") && !strcmp(cmd->arg_types, "ss"))
    {
        const char *port_from = CBOX_ARG_S(cmd, 0);
        const char *port_to = CBOX_ARG_S(cmd, 1);
        int res = jack_disconnect(jii->client, port_from, port_to);
        if (res)
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Cannot disconnect port '%s' from '%s'", port_from, port_to);
        return res == 0;
    }
    else if (!strcmp(cmd->command, "/get_connected_ports") && !strcmp(cmd->arg_types, "s"))
    {
        if (!cbox_check_fb_channel(fb, cmd->command, error))
            return FALSE;
        const char *name = CBOX_ARG_S(cmd, 0);
        jack_port_t *port = jack_port_by_name(jii->client, name);
        if (!port)
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Port '%s' not found", name);
            return FALSE;
        }
        const char** ports = jack_port_get_all_connections(jii->client, port);
        for (int i = 0; ports && ports[i]; i++)
        {
            if (!cbox_execute_on(fb, NULL, "/port", "s", error, ports[i]))
                return FALSE;
        }
        jack_free(ports);
        return TRUE;
    }
    else if (!strcmp(cmd->command, "/get_ports") && !strcmp(cmd->arg_types, "ssi"))
    {
        if (!cbox_check_fb_channel(fb, cmd->command, error))
            return FALSE;
        const char *mask = CBOX_ARG_S(cmd, 0);
        const char *type = CBOX_ARG_S(cmd, 1);
        uint32_t flags = CBOX_ARG_I(cmd, 2);
        const char** ports = jack_get_ports(jii->client, mask, type, flags);
        for (int i = 0; ports && ports[i]; i++)
        {
            if (!cbox_execute_on(fb, NULL, "/port", "s", error, ports[i]))
                return FALSE;
        }
        jack_free(ports);
        return TRUE;
    }
    else
    {
        gboolean result = cbox_io_process_cmd(io, fb, cmd, error, &handled);
        if (!handled)
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Unknown combination of target path and argument: '%s', '%s'", cmd->command, cmd->arg_types);
        return result;
    }
}
Example #27
0
extern jack_client_t *jack_start(t_callback callback, bool autoconnect) {
  const char *client_name = "dirt";
  const char *server_name = NULL;
  jack_options_t options = JackNullOption;
  jack_status_t status;
  int i;
  char portname[16];

  /* open a client connection to the JACK server */
  
  client = jack_client_open(client_name, options, &status, server_name);
  if (client == NULL) {
    fprintf(stderr, "jack_client_open() failed, "
             "status = 0x%2.0x\n", status);
    if (status & JackServerFailed) {
      fprintf(stderr, "Unable to connect to JACK server\n");
    }
    exit(1);
  }
  if (status & JackServerStarted) {
    fprintf(stderr, "JACK server started\n");
  }
  if (status & JackNameNotUnique) {
    client_name = jack_get_client_name(client);
    fprintf(stderr, "unique name `%s' assigned\n", client_name);
  }
  
  jack_set_process_callback(client, process, (void *) callback);
  
  jack_on_shutdown(client, jack_shutdown, 0);

  printf("engine sample rate: %" PRIu32 "\n",
          jack_get_sample_rate(client));

#ifdef INPUT
  strcpy(portname, "input");
  input_port = jack_port_register(client, portname,
                                  JACK_DEFAULT_AUDIO_TYPE,
                                  JackPortIsInput, 0);

  if (input_port == NULL) {
    fprintf(stderr, "no JACK input ports available\n");
    exit(1);
  }
#endif

  output_ports = malloc((g_num_channels + 1) * sizeof(jack_port_t*));
  if (!output_ports) {
    fprintf(stderr, "no memory to allocate `output_ports'\n");
    exit(1);
  }

  for (i = 0; i < g_num_channels; ++i) {
    sprintf(portname, "output_%d", i);
    output_ports[i] = jack_port_register(client, portname,
                                         JACK_DEFAULT_AUDIO_TYPE,
                                         JackPortIsOutput, 0);
    if (output_ports[i] == NULL) {
      fprintf(stderr, "no more JACK ports available\n");
      if (output_ports) free(output_ports);
      exit(1);
    }
  }
  
  output_ports[g_num_channels] = NULL;
  
  if (jack_activate(client)) {
    fprintf(stderr, "cannot activate client");
    if (output_ports) free(output_ports);
    exit(1);
  }

  if (autoconnect) {
    const char **ports;
    ports = jack_get_ports(client, NULL, NULL,
                           JackPortIsPhysical|JackPortIsInput);
    if (!ports) {
      fprintf(stderr, "cannot find any physical capture ports\n");
    } else {
      for (i = 0; i < g_num_channels; ++i) {
        if (ports[i] == NULL) {
          break;
        }
        //sprintf(portname, "output_%d", i);
        if (jack_connect(client, jack_port_name(output_ports[i]), ports[i])) {
          fprintf(stderr, "cannot connect output ports\n");
        }
      }
      free(ports);
    }

#ifdef INPUT
    ports = jack_get_ports(client, NULL, NULL,
                           JackPortIsPhysical|JackPortIsOutput);
    //strcpy(portname, "input");
    if (!ports) {
      fprintf(stderr, "cannot find any physical capture ports\n");
    } else {
      if (jack_connect(client, ports[0], jack_port_name(input_port))) {
        fprintf(stderr, "cannot connect input port\n");
      }
      free(ports);
    }
#endif
  }

  return(client);
}
Example #28
0
 int connect_output(size_t channel, const char * portname)
 {
     if (channel >= output_ports.size())
         return -1;
     return jack_connect(client, jack_port_name(output_ports[channel]), portname);
 }
Example #29
0
void
AudioJACKTarget::sourceModelReplaced()
{
    m_mutex.lock();

    m_source->setTarget(this, m_bufferSize);
    m_source->setTargetSampleRate(m_sampleRate);

    size_t channels = m_source->getSourceChannelCount();

    // Because we offer pan, we always want at least 2 channels
    if (channels < 2) channels = 2;

    if (channels == m_outputs.size() || !m_client) {
	m_mutex.unlock();
	return;
    }

    const char **ports =
	jack_get_ports(m_client, NULL, NULL,
		       JackPortIsPhysical | JackPortIsInput);
    size_t physicalPortCount = 0;
    while (ports[physicalPortCount]) ++physicalPortCount;

#ifdef DEBUG_AUDIO_JACK_TARGET    
    std::cerr << "AudioJACKTarget::sourceModelReplaced: have " << channels << " channels and " << physicalPortCount << " physical ports" << std::endl;
#endif

    while (m_outputs.size() < channels) {
	
	char name[20];
	jack_port_t *port;

	sprintf(name, "out %d", int(m_outputs.size() + 1));

	port = jack_port_register(m_client,
				  name,
				  JACK_DEFAULT_AUDIO_TYPE,
				  JackPortIsOutput,
				  0);

	if (!port) {
	    std::cerr
		<< "ERROR: AudioJACKTarget: Failed to create JACK output port "
		<< m_outputs.size() << std::endl;
	} else {
	    m_source->setTargetPlayLatency(jack_port_get_latency(port));
	}

	if (m_outputs.size() < physicalPortCount) {
	    jack_connect(m_client, jack_port_name(port), ports[m_outputs.size()]);
	}

	m_outputs.push_back(port);
    }

    while (m_outputs.size() > channels) {
	std::vector<jack_port_t *>::iterator itr = m_outputs.end();
	--itr;
	jack_port_t *port = *itr;
	if (port) jack_port_unregister(m_client, port);
	m_outputs.erase(itr);
    }

    m_mutex.unlock();
}
Example #30
0
int
main (int argc, char *argv[])
{
	const char **ports;
	float fs;		// The sample rate
	float peak;
	unsigned long peak_sample;
	unsigned int i;
	float duration = 0.0f;
	unsigned int c_format = 0;
        int longopt_index = 0;
	int c;
        extern int optind, opterr;
        int show_usage = 0;
        char *optstring = "d:f:h";
        struct option long_options[] = {
                { "help", 1, 0, 'h' },
                { "duration", 1, 0, 'd' },
                { "format", 1, 0, 'f' },
                { 0, 0, 0, 0 }
        };

        while ((c = getopt_long (argc, argv, optstring, long_options, &longopt_index)) != -1) {
                switch (c) {
		case 1:
			// end of opts, but don't care
			break;
                case 'h':
                        show_usage++;
                        break;
		case 'd':
			duration = (float)atof(optarg);
			break;
		case 'f':
			if (*optarg == 'c' || *optarg == 'C') {
				c_format = 1;
			}
			break;
		default:
			show_usage++;
			break;
		}
	}
	if (show_usage || duration <= 0.0f) {
		fprintf(stderr, "usage: jack_impulse_grab -d duration [-f (C|gnuplot)]\n");
		exit(1);
	}

	/* try to become a client of the JACK server */

	if ((client = jack_client_open("impulse_grabber", JackNullOption, NULL)) == 0) {
		fprintf (stderr, "JACK server not running?\n");
		return 1;
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/

	jack_set_process_callback (client, process, 0);

	/* tell the JACK server to call `jack_shutdown()' if
	   it ever shuts down, either entirely, or if it
	   just decides to stop calling us.
	*/

	jack_on_shutdown (client, jack_shutdown, 0);

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

	fs = jack_get_sample_rate(client);
	response_duration = (unsigned long) (fs * duration);
	response = malloc(response_duration * sizeof(float));
	fprintf(stderr,
		"Grabbing %f seconds (%lu samples) of impulse response\n",
		duration, response_duration);

	/* create two ports */

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

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

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

	/* connect the ports. Note: you can't do this before
	   the client is activated (this may change in the future).
	*/

	if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput)) == NULL) {
		fprintf(stderr, "Cannot find any physical capture ports");
		exit(1);
	}

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

	free (ports);

	if ((ports = jack_get_ports (client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) {
		fprintf(stderr, "Cannot find any physical playback ports");
		exit(1);
	}

	if (jack_connect (client, jack_port_name (output_port), ports[0])) {
		fprintf (stderr, "cannot connect output ports\n");
	}

	free (ports);

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

	/* Wait for grab to finish */
	while (!grab_finished) {
		sleep (1);
	}
	jack_client_close (client);

	peak = response[0];
	peak_sample = 0;
	if (c_format) {
		printf("impulse[%lu] = {", response_duration);
		for (i=0; i<response_duration; i++) {
			if (i % 4 != 0) {
				printf(" ");
			} else {
				printf("\n\t");
			}
			printf("\"%+1.10f\"", response[i]);
			if (i < response_duration - 1) {
				printf(",");
			}
			if (fabs(response[i]) > peak) {
				peak = fabs(response[i]);
				peak_sample = i;
			}
		}
		printf("\n};\n");
	} else {
		for (i=0; i<response_duration; i++) {
			printf("%1.12f\n", response[i]);
			if (fabs(response[i]) > peak) {
				peak = fabs(response[i]);
				peak_sample = i;
			}
		}
	}
	fprintf(stderr, "Peak value was %f at sample %lu\n", peak, peak_sample);

	exit (0);
}