Пример #1
0
static int _list_ports(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj* const *objv) {
  if (argc != 2) return fw_error_str(interp, "jack-client list-ports");
  _t *dp = (_t *)clientData;
  Tcl_Obj *dict = Tcl_NewDictObj();
  const char **portv[] = {
    jack_get_ports (dp->fw.client, NULL, JACK_DEFAULT_AUDIO_TYPE, 0),
    jack_get_ports (dp->fw.client, NULL, JACK_DEFAULT_MIDI_TYPE, 0)
  };
  for (int p = 0; p < 2; p += 1)
    if (portv[p] != NULL) {
      for (int i = 0; portv[p][i] != NULL; i += 1) {
	jack_port_t *port = jack_port_by_name(dp->fw.client, portv[p][i]);
	if (port != NULL) {
	  Tcl_Obj *pdict = Tcl_NewDictObj();
	  int flags = jack_port_flags(port);
	  Tcl_DictObjPut(interp, pdict, Tcl_NewStringObj("direction", -1), flags & JackPortIsInput ? Tcl_NewStringObj("input", -1) : Tcl_NewStringObj("output", -1) );
	  Tcl_DictObjPut(interp, pdict, Tcl_NewStringObj("physical", -1), Tcl_NewIntObj(flags & JackPortIsPhysical ? 1 : 0));
	  Tcl_DictObjPut(interp, pdict, Tcl_NewStringObj("type", -1), p == 0 ? Tcl_NewStringObj("audio", -1) : Tcl_NewStringObj("midi", -1));
	  const char **connv = jack_port_get_all_connections(dp->fw.client, port);
	  Tcl_Obj *list = Tcl_NewListObj(0, NULL);
	  if (connv != NULL) {
	    for (int j = 0; connv[j] != NULL; j += 1)
	      Tcl_ListObjAppendElement(interp, list, Tcl_NewStringObj(connv[j], -1));
	    jack_free(connv);
	  }
	  Tcl_DictObjPut(interp, pdict, Tcl_NewStringObj("connections", -1), list);
	  Tcl_DictObjPut(interp, dict, Tcl_NewStringObj(portv[p][i], -1), pdict);
	}
      }
      jack_free(portv[p]);
    }
  Tcl_SetObjResult(interp, dict);
  return TCL_OK;
}
Пример #2
0
static int ja_connect_client(void)
{
        char **ports;
        int i;

        ports = (char **) jack_get_ports(client, NULL, NULL,
                                         JackPortIsPhysical | JackPortIsOutput);
        if (ports == NULL)
                return 1;

        for (i = 0; i < ja_in_channels && ports[i] != NULL; i++)
                jack_connect(client, ports[i], jack_port_name(input_ports[i]));
        jack_free(ports);

        ports = (char **) jack_get_ports(client, NULL, NULL,
                                         JackPortIsPhysical | JackPortIsInput);
        if (ports == NULL)
                return 1;

        for (i = 0; i < ja_out_channels && ports[i] != NULL; i++)
                jack_connect(client, jack_port_name(output_ports[i]), ports[i]);
        jack_free(ports);

        return 0;
}
Пример #3
0
    int JackSapaProxy::Setup(jack_client_t* client)
    {
        jack_log("JackSapaProxy::Setup");

        //refer to system ports and create sapaproxy ports
        unsigned int i = 0, j = 0;
        const char **ports_system_capture;
        const char **ports_system_playback;
        unsigned int ports_system_capture_cnt = 0;
        unsigned int ports_system_playback_cnt = 0;
        char port_name[JACK_PORT_NAME_SIZE] = {0,};
        ports_system_capture = jack_get_ports(client, "system:.*", NULL, JackPortIsPhysical | JackPortIsOutput);
        if (ports_system_capture != NULL) {
            for (i = 0; i < fCapturePorts && ports_system_capture[i]; i++) {
                sprintf(port_name, "__system_capture_%d", i + 1);
                fInputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
                sprintf(port_name, "capture_%d", i + 1);
                fOutputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
                ports_system_capture_cnt++;
            }
            jack_free(ports_system_capture);
        }

        ports_system_playback = jack_get_ports(client, "system:.*", NULL, JackPortIsPhysical | JackPortIsInput);
        if (ports_system_playback != NULL) {
            for (j = 0; j < fPlaybackPorts && ports_system_playback[j]; j++, i++) {
                sprintf(port_name, "playback_%d", j + 1);
                fInputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
                sprintf(port_name, "__system_playback_%d", j + 1);
                fOutputPorts[i] = jack_port_register(client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
                ports_system_playback_cnt++;
            }
            jack_free(ports_system_playback);
        }

        //store actual number of system ports
        fCapturePorts = ports_system_capture_cnt;
        fPlaybackPorts = ports_system_playback_cnt;

        jack_set_process_callback(client, Process, this);
        jack_activate(client);

        //conenct between sapaproxy and system ports
        for (unsigned int i = 0; i < ports_system_capture_cnt; i++) {
            sprintf(port_name, "system:capture_%d", i + 1);
            jack_connect(client, port_name, jack_port_name(fInputPorts[i]));
        }

        for (unsigned int i = 0; i < ports_system_playback_cnt; i++) {
            sprintf(port_name, "system:playback_%d", i + 1);
            jack_connect(client, jack_port_name(fOutputPorts[ports_system_capture_cnt + i]), port_name);
        }

        return 0;
    }
Пример #4
0
void AudioReader::stop() {
    if(!running)
        return;
    jack_client_close(client);
    delete[] buffer;
    delete[] sounds;
    jack_free(output_left);
    jack_free(output_right);
    jack_free(input_left);
    jack_free(input_right);
    free(cfg);
    running = false;
}
Пример #5
0
static jack_port_t *
update_connection(jack_port_t *remote_port, int connected,
                  jack_port_t *local_port, jack_port_t *current_port,
                  const char *target_name)
{
    if (connected) {
        if (current_port) {
            return current_port;
        }
        if (target_name) {
            char *aliases[2];
            if (! strcmp(target_name, jack_port_name(remote_port))) {
                return remote_port;
            }
            aliases[0] = alias1;
            aliases[1] = alias2;
            switch (jack_port_get_aliases(remote_port, aliases)) {
            case -1:
                /* Sigh ... */
                die("jack_port_get_aliases", "Failed to get port aliases");
            case 2:
                if (! strcmp(target_name, alias2)) {
                    return remote_port;
                }
                /* Fallthrough on purpose */
            case 1:
                if (! strcmp(target_name, alias1)) {
                    return remote_port;
                }
                /* Fallthrough on purpose */
            case 0:
                return NULL;
            }
            /* This shouldn't happen. */
            assert(0);
        }
        return remote_port;
    }
    if (! strcmp(jack_port_name(remote_port), jack_port_name(current_port))) {
        const char **port_names;
        if (target_name) {
            return NULL;
        }
        port_names = jack_port_get_connections(local_port);
        if (port_names == NULL) {
            return NULL;
        }

        /* If a connected port is disconnected and other ports are still
           connected, then we take the first port name in the array and use it
           as our remote port.  It's a dumb implementation. */
        current_port = jack_port_by_name(client, port_names[0]);
        jack_free(port_names);
        if (current_port == NULL) {
            /* Sigh */
            die("jack_port_by_name", "failed to get port by name");
        }
    }
    return current_port;
}
Пример #6
0
int main (int argc, char* argv[]) {
  jack_client_t* client;
  char const default_name[] = "connector";

  // this is moderately retarded
  aliases[0] = (char *) malloc (jack_port_name_size());
  aliases[1] = (char *) malloc (jack_port_name_size());

  client = jack_client_open(default_name, JackNullOption, NULL);

  while (1) {
    const char **portnames;
    const char **orig;
    orig = portnames = jack_get_ports(client, "", "", 0);

    desired_connection *desired = desired_connections;
    while (desired->from_port) {
      ensure_connected(client, orig, desired);
      desired++;
    }
    printf("\n");
    sleep(5);
    jack_free(orig);
  }
}
Пример #7
0
/* 0 on error */
static int autoconnect_jack_ports(out123_handle *ao, jack_handle_t* handle)
{
	const char **all_ports;
	unsigned int ch=0;
	int err,i;

	/* Get a list of all the jack ports*/
	all_ports = jack_get_ports (handle->client, NULL, NULL, JackPortIsInput);
	if(!all_ports)
	{
		if(!AOQUIET)
			error("connect_jack_ports(): jack_get_ports() returned NULL.");
		return 0;
	}
	/* Step through each port name*/
	for (i = 0; all_ports[i]; ++i)
	{
		const char* in = jack_port_name( handle->ports[ch] );
		const char* out = all_ports[i];

		if ((err = jack_connect(handle->client, in, out)) != 0 && err != EEXIST)
		{
			if(!AOQUIET)
				error1("connect_jack_ports(): failed to jack_connect() ports: %d",err);
			return 0;
		}

		/* Found enough ports ?*/
		if (++ch >= handle->channels) break;
	}
	jack_free(all_ports);
	return 1;
}
Пример #8
0
    void JackProxyDriver::ConnectPorts()
    {
        jack_log("JackProxyDriver::ConnectPorts");
        const char** ports = jack_get_ports(fClient, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsOutput);
        if (ports != NULL) {
            for (int i = 0; i < fCaptureChannels && ports[i]; i++) {
                jack_connect(fClient, ports[i], jack_port_name(fUpstreamPlaybackPorts[i]));
            }
            jack_free(ports);
        }

        ports = jack_get_ports(fClient, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical | JackPortIsInput);
        if (ports != NULL) {
            for (int i = 0; i < fPlaybackChannels && ports[i]; i++) {
                jack_connect(fClient, jack_port_name(fUpstreamCapturePorts[i]), ports[i]);
            }
            jack_free(ports);
        }
    }
Пример #9
0
 int JackProxyDriver::CountIO(const char* type, int flags)
 {
     int count = 0;
     const char** ports = jack_get_ports(fClient, NULL, type, flags);
     if (ports != NULL) {
         while (ports[count]) { count++; }
         jack_free(ports);
     }
     return count;
 }
Пример #10
0
void ensure_connected(jack_client_t *client, const char **ports, desired_connection *connection) {
  const char *from_port_name = find_port(client, ports, connection->from_port);
  const char *to_port_name = find_port(client, ports, connection->to_port);

  // make sure both ports exist
  if (from_port_name == NULL) {
    printf("X from port (%s:%s) cannot be found\n", connection->from_port->desired,
	   mtype_strings[connection->from_port->which]);
    return;
  }
  if (to_port_name == NULL) {
    printf("X to port (%s:%s) cannot be found\n", connection->to_port->desired,
	   mtype_strings[connection->to_port->which]);
    return;
  }

  jack_port_t *from_port, *to_port;
  from_port = jack_port_by_name(client, from_port_name);
  to_port = jack_port_by_name(client, to_port_name);

  // this should never prematurely return, in theory
  if (from_port == NULL || to_port == NULL) {
    return;
  }
  
  const char **connections, **orig_connections;
  orig_connections = connections = jack_port_get_all_connections(client, from_port);
  
  printf("! connections for %s\n", from_port_name);
  if (connections == NULL) {
    printf("X  --None\n");
  }
  int connected = 0;
  while (connections && *connections) {
    if (port_matcher(client, *connections, connection->to_port)) {
      printf("! -->%s\n", *connections);
      connected = 1;
      break;
    }
    printf("  >%s\n", *connections);
    *connections++;
  }
  if (connections != NULL) {
    jack_free(orig_connections);
  }

  if (!connected) {
    int rc;
    printf("! Connecting %s to %s\n", from_port_name, to_port_name);
    rc = jack_connect(client, from_port_name, to_port_name);
    printf("%s rc is %d\n", rc == 0 ? "!" : "X", rc);
  }
}
Пример #11
0
static void connect_jack_ports() {
  int i;
  int c=0;
  for (i = 0; i < AUDIO_CHANNELS; i++) {
    if (!jack_port[i]) continue;
    if (jack_connect(j_client, jack_port_name(j_output_port[i]), jack_port[i] )) {
      fprintf(stderr, "cannot connect port %s to %s\n", jack_port_name(j_output_port[i]), jack_port[i]);
    }
    c++;
  }

  if (c==0 && jack_ports && strlen(jack_ports)>0) {
    /* all of jack_port[] were NULL, try regexp */
    const char **found_ports = jack_get_ports(j_client, jack_ports, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput);
    if (found_ports) {
      for (i = 0; found_ports[i] && i < AUDIO_CHANNELS; ++i) {
	if (jack_connect(j_client, jack_port_name(j_output_port[i]), found_ports[i])) {
	  fprintf(stderr, "JACK: cannot connect port %s to %s\n", jack_port_name(j_output_port[i]), found_ports[i]);
	}
      }
      jack_free(found_ports);
    }
  }

  /* Midi Port */
  if (use_jack_midi && midi_port && strlen(midi_port)>0) {
    const char **found_ports = jack_get_ports(j_client, midi_port, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput);
    if (found_ports) {
      for (i = 0; found_ports[i]; ++i) {
	if (jack_connect(j_client, found_ports[i], jack_port_name(jack_midi_port))) {
	  fprintf(stderr, "JACK: cannot connect port %s to %s\n", found_ports[i], jack_port_name(jack_midi_port));
	}
      }
      jack_free(found_ports);
    }
  }
}
Пример #12
0
static void
cbjack_connect_ports (cubeb_stream * stream)
{
  const char **physical_ports = jack_get_ports (stream->context->jack_client,
      NULL, NULL, JackPortIsInput | JackPortIsPhysical);
  if (physical_ports == NULL) {
    return;
  }

  // Connect to all physical ports
  for (unsigned int c = 0; c < stream->params.channels && physical_ports[c]; c++) {
    const char *src_port = jack_port_name (stream->output_ports[c]);

    jack_connect (stream->context->jack_client, src_port, physical_ports[c]);
  }
  jack_free(physical_ports);
}
Пример #13
0
void jack_start() {
	jack_set_error_function(error);

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

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

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

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

	const char **ports;
	if((ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical | JackPortIsOutput)) == NULL)
	{
		fprintf(stderr, "cannot find any physical capture ports\n");
		exit(1);
	}
	if(jack_connect(client, ports[0], jack_port_name(input_port)))
		fprintf(stderr, "cannot connect to physical capture port\n");

	jack_free(ports);
	if((ports = jack_get_ports(client, NULL, "midi", JackPortIsInput)) == NULL)
	{
		fprintf(stderr, "cannot find any MIDI playback ports\n");
		exit(1);
	}
	if(jack_connect(client, jack_port_name(output_port), ports[0]))
		fprintf(stderr, "cannot connect to MIDI playback port\n");
}
Пример #14
0
GList *
get_jack_ports (gboolean midi, gboolean output)
{
  GList *list = NULL;

  // open a temporary connection to the JACK server
  jack_client_t *client = jack_client_open ("denemo", JackNoStartServer, NULL);

  if (!client)
    {
      return NULL;
    }

  char const *type = midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE;
  unsigned long flags = output ? JackPortIsOutput : JackPortIsInput;

  // get all input port names of the given type
  char const **ports = jack_get_ports (client, NULL, type, flags);

  if (!ports)
    {
      return NULL;
    }

  // copy all port names to our own list
  char const **p = ports;
  while (*p)
    {
      char *s = g_strdup (*p++);
      list = g_list_append (list, s);
    }

  jack_free (ports);
  jack_client_close (client);

  return list;
}
Пример #15
0
static int refresh_devices_bare(SoundIoPrivate *si) {
    SoundIo *soundio = &si->pub;
    SoundIoJack *sij = &si->backend_data.jack;

    if (sij->is_shutdown)
        return SoundIoErrorBackendDisconnected;


    SoundIoDevicesInfo *devices_info = allocate<SoundIoDevicesInfo>(1);
    if (!devices_info)
        return SoundIoErrorNoMem;

    devices_info->default_output_index = -1;
    devices_info->default_input_index = -1;
    const char **port_names = jack_get_ports(sij->client, nullptr, nullptr, 0);
    if (!port_names) {
        soundio_destroy_devices_info(devices_info);
        return SoundIoErrorNoMem;
    }

    SoundIoList<SoundIoJackClient> clients = {0};
    const char **port_name_ptr = port_names;
    for (; *port_name_ptr; port_name_ptr += 1) {
        const char *client_and_port_name = *port_name_ptr;
        int client_and_port_name_len = strlen(client_and_port_name);
        jack_port_t *jport = jack_port_by_name(sij->client, client_and_port_name);
        if (!jport) {
            // This refresh devices scan is already outdated. Just give up and
            // let refresh_devices be called again.
            jack_free(port_names);
            soundio_destroy_devices_info(devices_info);
            return SoundIoErrorInterrupted;
        }

        int flags = jack_port_flags(jport);
        const char *port_type = jack_port_type(jport);
        if (strcmp(port_type, JACK_DEFAULT_AUDIO_TYPE) != 0) {
            // we don't know how to support such a port
            continue;
        }

        SoundIoDeviceAim aim = (flags & JackPortIsInput) ?
            SoundIoDeviceAimOutput : SoundIoDeviceAimInput;
        bool is_physical = flags & JackPortIsPhysical;

        const char *client_name = nullptr;
        const char *port_name = nullptr;
        int client_name_len;
        int port_name_len;
        split_str(client_and_port_name, client_and_port_name_len, ':',
                &client_name, &client_name_len, &port_name, &port_name_len);
        if (!client_name || !port_name) {
            // device does not have colon, skip it
            continue;
        }
        SoundIoJackClient *client = find_or_create_client(&clients, aim, is_physical,
                client_name, client_name_len);
        if (!client) {
            jack_free(port_names);
            soundio_destroy_devices_info(devices_info);
            return SoundIoErrorNoMem;
        }
        if (client->port_count >= SOUNDIO_MAX_CHANNELS) {
            // we hit the channel limit, skip the leftovers
            continue;
        }
        SoundIoJackPort *port = &client->ports[client->port_count++];
        port->full_name = client_and_port_name;
        port->full_name_len = client_and_port_name_len;
        port->name = port_name;
        port->name_len = port_name_len;
        port->channel_id = soundio_parse_channel_id(port_name, port_name_len);

        jack_latency_callback_mode_t latency_mode = (aim == SoundIoDeviceAimOutput) ?
            JackPlaybackLatency : JackCaptureLatency;
        jack_port_get_latency_range(jport, latency_mode, &port->latency_range);
    }

    for (int i = 0; i < clients.length; i += 1) {
        SoundIoJackClient *client = &clients.at(i);
        if (client->port_count <= 0)
            continue;

        SoundIoDevicePrivate *dev = allocate<SoundIoDevicePrivate>(1);
        if (!dev) {
            jack_free(port_names);
            soundio_destroy_devices_info(devices_info);
            return SoundIoErrorNoMem;
        }
        SoundIoDevice *device = &dev->pub;
        SoundIoDeviceJack *dj = &dev->backend_data.jack;
        int description_len = client->name_len + 3 + 2 * client->port_count;
        for (int port_index = 0; port_index < client->port_count; port_index += 1) {
            SoundIoJackPort *port = &client->ports[port_index];

            description_len += port->name_len;
        }

        dev->destruct = destruct_device;

        device->ref_count = 1;
        device->soundio = soundio;
        device->is_raw = false;
        device->aim = client->aim;
        device->id = soundio_str_dupe(client->name, client->name_len);
        device->name = allocate<char>(description_len);
        device->current_format = SoundIoFormatFloat32NE;
        device->sample_rate_count = 1;
        device->sample_rates = &dev->prealloc_sample_rate_range;
        device->sample_rates[0].min = sij->sample_rate;
        device->sample_rates[0].max = sij->sample_rate;
        device->sample_rate_current = sij->sample_rate;

        device->software_latency_current = sij->period_size / (double) sij->sample_rate;
        device->software_latency_min = sij->period_size / (double) sij->sample_rate;
        device->software_latency_max = sij->period_size / (double) sij->sample_rate;

        dj->port_count = client->port_count;
        dj->ports = allocate<SoundIoDeviceJackPort>(dj->port_count);

        if (!device->id || !device->name || !dj->ports) {
            jack_free(port_names);
            soundio_device_unref(device);
            soundio_destroy_devices_info(devices_info);
            return SoundIoErrorNoMem;
        }

        for (int port_index = 0; port_index < client->port_count; port_index += 1) {
            SoundIoJackPort *port = &client->ports[port_index];
            SoundIoDeviceJackPort *djp = &dj->ports[port_index];
            djp->full_name = soundio_str_dupe(port->full_name, port->full_name_len);
            djp->full_name_len = port->full_name_len;
            djp->channel_id = port->channel_id;
            djp->latency_range = port->latency_range;

            if (!djp->full_name) {
                jack_free(port_names);
                soundio_device_unref(device);
                soundio_destroy_devices_info(devices_info);
                return SoundIoErrorNoMem;
            }
        }

        memcpy(device->name, client->name, client->name_len);
        memcpy(&device->name[client->name_len], ": ", 2);
        int index = client->name_len + 2;
        for (int port_index = 0; port_index < client->port_count; port_index += 1) {
            SoundIoJackPort *port = &client->ports[port_index];
            memcpy(&device->name[index], port->name, port->name_len);
            index += port->name_len;
            if (port_index + 1 < client->port_count) {
                memcpy(&device->name[index], ", ", 2);
                index += 2;
            }
        }

        device->current_layout.channel_count = client->port_count;
        bool any_invalid = false;
        for (int port_index = 0; port_index < client->port_count; port_index += 1) {
            SoundIoJackPort *port = &client->ports[port_index];
            device->current_layout.channels[port_index] = port->channel_id;
            any_invalid = any_invalid || (port->channel_id == SoundIoChannelIdInvalid);
        }
        if (any_invalid) {
            const struct SoundIoChannelLayout *layout = soundio_channel_layout_get_default(client->port_count);
            if (layout)
                device->current_layout = *layout;
        } else {
            soundio_channel_layout_detect_builtin(&device->current_layout);
        }

        device->layout_count = 1;
        device->layouts = &device->current_layout;
        device->format_count = 1;
        device->formats = &dev->prealloc_format;
        device->formats[0] = device->current_format;

        SoundIoList<SoundIoDevice *> *device_list;
        if (device->aim == SoundIoDeviceAimOutput) {
            device_list = &devices_info->output_devices;
            if (devices_info->default_output_index < 0 && client->is_physical)
                devices_info->default_output_index = device_list->length;
        } else {
            assert(device->aim == SoundIoDeviceAimInput);
            device_list = &devices_info->input_devices;
            if (devices_info->default_input_index < 0 && client->is_physical)
                devices_info->default_input_index = device_list->length;
        }

        if (device_list->append(device)) {
            soundio_device_unref(device);
            soundio_destroy_devices_info(devices_info);
            return SoundIoErrorNoMem;
        }

    }
    jack_free(port_names);

    soundio_destroy_devices_info(si->safe_devices_info);
    si->safe_devices_info = devices_info;

    return 0;
}
Пример #16
0
int
main (int argc, char *argv[])
{
    jack_client_t *client;
    jack_status_t status;
    char *server_name = NULL;
    int c;
    int option_index;
    jack_options_t options = JackNoStartServer;
    char *my_name = strrchr(argv[0], '/');
    jack_port_t *src_port = 0;
    jack_port_t *dst_port = 0;
    jack_port_t *port1 = 0;
    jack_port_t *port2 = 0;
    char portA[300];
    char portB[300];
    int use_uuid=0;
    int connecting, disconnecting;
    int port1_flags, port2_flags;
    int rc = 1;

    struct option long_options[] = {
        { "server", 1, 0, 's' },
        { "help", 0, 0, 'h' },
        { "version", 0, 0, 'v' },
        { "uuid", 0, 0, 'u' },
        { 0, 0, 0, 0 }
    };

    while ((c = getopt_long (argc, argv, "s:hvu", long_options, &option_index)) >= 0) {
        switch (c) {
        case 's':
            server_name = (char *) malloc (sizeof (char) * strlen(optarg));
            strcpy (server_name, optarg);
            options |= JackServerName;
            break;
        case 'u':
            use_uuid = 1;
            break;
        case 'h':
            show_usage (my_name);
            return 1;
            break;
        case 'v':
            show_version (my_name);
            return 1;
            break;
        default:
            show_usage (my_name);
            return 1;
            break;
        }
    }

    connecting = disconnecting = FALSE;
    if (my_name == 0) {
        my_name = argv[0];
    } else {
        my_name ++;
    }

    if (strstr(my_name, "disconnect")) {
        disconnecting = 1;
    } else if (strstr(my_name, "connect")) {
        connecting = 1;
    } else {
        fprintf(stderr, "ERROR! client should be called jack_connect or jack_disconnect. client is called %s\n", my_name);
        return 1;
    }

    if (argc < 3) {
        show_usage(my_name);
        return 1;
    }

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

    if ((client = jack_client_open (my_name, options, &status, server_name)) == 0) {
        fprintf (stderr, "jack server not running?\n");
        return 1;
    }

    /* find the two ports */

    if( use_uuid ) {
        char *tmpname;
        char *clientname;
        char *portname;
        tmpname = strdup( argv[argc-1] );
        portname = strchr( tmpname, ':' );
        portname[0] = '\0';
        portname+=1;
        clientname = jack_get_client_name_by_uuid( client, tmpname );
        if( clientname ) {

            snprintf( portA, sizeof(portA), "%s:%s", clientname, portname );
            jack_free( clientname );
        } else {
            snprintf( portA, sizeof(portA), "%s", argv[argc-1] );
        }
        free( tmpname );

        tmpname = strdup( argv[argc-2] );
        portname = strchr( tmpname, ':' );
        portname[0] = '\0';
        portname+=1;
        clientname = jack_get_client_name_by_uuid( client, tmpname );
        if( clientname ) {
            snprintf( portB, sizeof(portB), "%s:%s", clientname, portname );
            jack_free( clientname );
        } else {
            snprintf( portB, sizeof(portB), "%s", argv[argc-2] );
        }

        free( tmpname );

    } else {
        snprintf( portA, sizeof(portA), "%s", argv[argc-1] );
        snprintf( portB, sizeof(portB), "%s", argv[argc-2] );
    }
    if ((port1 = jack_port_by_name(client, portA)) == 0) {
        fprintf (stderr, "ERROR %s not a valid port\n", portA);
        goto exit;
    }
    if ((port2 = jack_port_by_name(client, portB)) == 0) {
        fprintf (stderr, "ERROR %s not a valid port\n", portB);
        goto exit;
    }

    port1_flags = jack_port_flags (port1);
    port2_flags = jack_port_flags (port2);

    if (port1_flags & JackPortIsInput) {
        if (port2_flags & JackPortIsOutput) {
            src_port = port2;
            dst_port = port1;
        }
    } else {
        if (port2_flags & JackPortIsInput) {
            src_port = port1;
            dst_port = port2;
        }
    }

    if (!src_port || !dst_port) {
        fprintf (stderr, "arguments must include 1 input port and 1 output port\n");
        goto exit;
    }

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

    if (connecting) {
        if (jack_connect(client, jack_port_name(src_port), jack_port_name(dst_port))) {
            goto exit;
        }
    }
    if (disconnecting) {
        if (jack_disconnect(client, jack_port_name(src_port), jack_port_name(dst_port))) {
            goto exit;
        }
    }

    /* everything was ok, so setting exitcode to 0 */
    rc = 0;

exit:
    jack_client_close (client);
    exit (rc);
}
Пример #17
0
static Data *create_data(const SoundPluginType *plugin_type, jack_client_t *client, int num_inputs, int num_outputs, const char **input_portnames, const char **output_portnames){
  Data *data = (Data*)V_calloc(1,sizeof(Data));
  data->client = client;
  data->input_ports=(jack_port_t**)V_calloc(num_outputs,sizeof(jack_port_t*));
  data->output_ports=(jack_port_t**)V_calloc(num_inputs,sizeof(jack_port_t*));

  int i;

  for(i=0;i<num_outputs;i++){
    static int n=0;
    char temp[500];

    if(input_portnames[i] != NULL)
      sprintf(temp, "%s", input_portnames[i]);
    else
      sprintf(temp, "in_%d",++n);
    
    if((data->input_ports[i] = jack_port_register(client,
                                                  V_strdup(temp),
                                                  JACK_DEFAULT_AUDIO_TYPE,
                                                  JackPortIsInput,
                                                  0
                                                  )
        )==NULL)
      GFX_Message(NULL, "Error. Could not register jack port.\n");
  }

  if(!strcmp(plugin_type->name,"System In")){
    int ch;
    const char **outportnames=jack_get_ports(client,NULL,NULL,JackPortIsPhysical|JackPortIsOutput);
    for (ch=0;outportnames && outportnames[ch]!=NULL && ch<num_outputs;ch++){
      if (
          data->input_ports[ch]!= NULL &&
	  jack_connect(
                       client,
		       outportnames[ch],
		       jack_port_name(data->input_ports[ch])
		       )
	  )
        GFX_Message(NULL, "Warning. Cannot connect to jack capture port %d: \"%s\".\n",ch,outportnames[ch]);
    }
    jack_free(outportnames);
  }

  for(i=0;i<num_inputs;i++){
    static int n=0;
    char temp[500];

    if(output_portnames[i] != NULL)
      sprintf(temp, "%s",output_portnames[i]);
    else
      sprintf(temp, "out_%d",++n);

    if((data->output_ports[i] = jack_port_register(
                                                   client,
                                                   V_strdup(temp),
                                                   JACK_DEFAULT_AUDIO_TYPE,
                                                   JackPortIsOutput,
                                                   0
                                                 )
        )==NULL)
      GFX_Message(NULL, "Error. Could not register jack port.\n");
  }

  if(!strcmp(plugin_type->name,"System Out") || !strcmp(plugin_type->name,"System Out 8")){
    int ch;
    const char **inportnames=jack_get_ports(client,NULL,NULL,JackPortIsPhysical|JackPortIsInput);
    for (ch=0;inportnames && inportnames[ch]!=NULL && ch<num_inputs;ch++){
      if (
          data->output_ports[ch] != NULL &&
	  jack_connect(
                       client,
		       jack_port_name(data->output_ports[ch]),
		       inportnames[ch]
		       )
	  )
        GFX_addMessage("Warning. Cannot connect to jack playback port %d: \"%s\".\n",ch,inportnames[ch]);
    }
    jack_free(inportnames);
  }


  return data;
}
bool JackAudioInterface::setPhysicalInputs(unsigned int* inputChannels)
{
    // get all jack ports that correspond to physical inputs
    if (!m_client) return false;
    const char** inputPorts = jack_get_ports(m_client, NULL, NULL, JackPortIsOutput | JackPortIsPhysical);

    // count the number of physical input ports
    const char** currentPort = inputPorts;
    unsigned int numPhysicalPortsIn = 0;
    while (*currentPort != NULL)
    {
        numPhysicalPortsIn++;
        qDebug("JackAudioInterface::SetPhysicalInputs() counted port %s", *currentPort);
        currentPort++;
    }
    qDebug("JackAudioInterface::SetPhysicalInputs() counted %d physical inputs", numPhysicalPortsIn);
    jack_free(inputPorts);
    
    if (m_channels > numPhysicalPortsIn)
    {
        return false; // requested more input ports than actually exist
    }
    
    // allocate array of input port pointers
    m_inputPorts = new jack_port_t*[m_channels];
    for (unsigned int ch = 0; ch < m_channels; ch++)
    {
        m_inputPorts[ch] = NULL;
    }
    
    // register JACK input ports and connect physical inputs to client inputs
    char portName[MAX_PORT_NAME];
    for (unsigned int i = 0; i < m_channels; i++)
    {
        // register input port
        snprintf(portName, MAX_PORT_NAME, "input_%d", i + 1);
        m_inputPorts[i] = jack_port_register(m_client, portName, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
        if (!m_inputPorts[i])
        {
            qDebug() << "JackAudioInterface::SetPhysicalInputs ERROR: couldn't register input port for channel " << i + 1 << endl;
            return false;
        }
        qDebug() << "JackAudioInterface::SetPhysicalInputs registered input port " << i << endl;
        
        // connect the specified physical input to the newly-created input port
        char systemIn[MAX_PORT_NAME];
        snprintf(systemIn, MAX_PORT_NAME, "system:capture_%d", inputChannels[i]);
        // TODO: handle case where system ports have non-standard names (is this possible?)?
        const char* inputPortName = jack_port_name(m_inputPorts[i]); // TODO: handle case where input port requested doesn't exist?
        int result = jack_connect(m_client, systemIn, inputPortName);
        if (result == EEXIST)
        {
            qWarning("JackAudioInterface::SetPhysicalInputs WARNING: %s and %s were already connected", systemIn, inputPortName);
            // TODO: decide how to handle this case
        }
        else if (result != 0)
        {
            qWarning("JackAudioInterface::SetPhysicalInputs ERROR: couldn't connect %s to %s", systemIn, inputPortName);

            return false;
        }
        else
        {
            qDebug("JackAudioInterface::SetPhysicalInputs connected %s to %s", systemIn, inputPortName);
        }
    }

    qDebug() << "JackAudioInterface::SetPhysicalInputs registered input ports" << endl;
    
    return true;
}
RString RageSoundDriver_JACK::ConnectPorts()
{
	vector<RString> portNames;
	split(PREFSMAN->m_iSoundDevice.Get(), ",", portNames, true);

	const char *port_out_l = NULL, *port_out_r = NULL;
	const char **ports = NULL;
	if( portNames.size() == 0 )
	{
		// The user has NOT specified any ports to connect to. Search 
		// for all physical sinks and use the first two.
		ports = jack_get_ports( client, NULL, NULL, JackPortIsInput | JackPortIsPhysical );
		if( ports == NULL )
			return "Couldn't get JACK ports";
		if( ports[0] == NULL )
		{
			jack_free( ports );
			return "No physical sinks!";
		}
		port_out_l = ports[0];

		if( ports[1] == NULL )
			// Only one physical sink. We're going mono!
			port_out_r = ports[0];
		else
			port_out_r = ports[1];
	}
	else
	{
		// The user has specified ports to connect to. Loop through
		// them to find two that are valid, then use them. If we find 
		// only one that is valid, connect both channels to it.
		// Use jack_port_by_name to ensure ports exist, then
		// jack_port_name to use their canonical name.  (I'm not sure 
		// if that second step is necessary, I've seen something about 
		// "aliases" in the docs.)
		FOREACH( RString, portNames, portName )
		{
			jack_port_t *out = jack_port_by_name( client, *portName );
			// Make sure the port is a sink.
			if( ! ( jack_port_flags( out ) & JackPortIsInput ) )
				continue;

			if( out != NULL )
			{
				if( port_out_l == NULL )
					port_out_l = jack_port_name( out );
				else
				{
					port_out_r = jack_port_name( out );
					break;
				}
			}
		}
		if( port_out_l == NULL )
			return "All specified sinks are invalid.";
		
		if( port_out_r == NULL )
			// Only found one valid sink. Going mono!
			port_out_r = port_out_l;
	}
Пример #20
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;
    }
}
Пример #21
0
void JACKInput::Init() {

	m_message_queue.Reset(RING_BUFFER_SIZE * m_channels * sizeof(float));

	m_jack_client = jack_client_open("SimpleScreenRecorder", JackNoStartServer, NULL);
	if(m_jack_client == NULL) {
		Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not connect to JACK!"));
		throw JACKException();
	}

	m_jack_ports.resize(m_channels, NULL);
	for(unsigned int i = 0; i < m_channels; ++i) {
		std::string port_name = "in_" + NumToString(i + 1);
		m_jack_ports[i] = jack_port_register(m_jack_client, port_name.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
		if(m_jack_ports[i] == NULL) {
			Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not create JACK port!"));
			throw JACKException();
		}
	}

	if(jack_set_process_callback(m_jack_client, ProcessCallback, this) != 0) {
		Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not set JACK process callback!"));
		throw JACKException();
	}
	if(jack_set_sample_rate_callback(m_jack_client, SampleRateCallback, this) != 0) {
		Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not set JACK sample rate callback!"));
		throw JACKException();
	}
	if(jack_set_xrun_callback(m_jack_client, XRunCallback, this) != 0) {
		Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not set JACK xrun callback!"));
		throw JACKException();
	}
	if(jack_set_port_connect_callback(m_jack_client, PortConnectCallback, this) != 0) {
		Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not set JACK port connect callback!"));
		throw JACKException();
	}

	if(jack_activate(m_jack_client) != 0) {
		Logger::LogError("[JACKInput::Init] " + Logger::tr("Error: Could not activate JACK client!"));
		throw JACKException();
	}

	for(unsigned int i = 0; i < m_channels; ++i) {
		std::string port_name_full = std::string(jack_get_client_name(m_jack_client)) + ":in_" + NumToString(i + 1);
		if(m_connect_system_capture) {
			std::string capture_name = "system:capture_" + NumToString(i + 1);
			Logger::LogInfo("[JACKInput::Init] " + Logger::tr("Connecting port %1 to %2.")
							.arg(QString::fromStdString(capture_name)).arg(QString::fromStdString(port_name_full)));
			jack_connect(m_jack_client, capture_name.c_str(), port_name_full.c_str());
		}
		if(m_connect_system_playback) {
			std::string playback_name = "system:playback_" + NumToString(i + 1);
			jack_port_t *port = jack_port_by_name(m_jack_client, playback_name.c_str());
			if(port != NULL) {
				const char **connected_ports = jack_port_get_all_connections(m_jack_client, port);
				if(connected_ports != NULL) {
					for(const char **p = connected_ports; *p != NULL; ++p) {
						Logger::LogInfo("[JACKInput::Init] " + Logger::tr("Connecting port %1 to %2.")
										.arg(*p).arg(QString::fromStdString(port_name_full)));
						jack_connect(m_jack_client, *p, port_name_full.c_str());
					}
					jack_free(connected_ports);
				}
			}
		}

	}

	// start input thread
	m_should_stop = false;
	m_error_occurred = false;
	m_thread = std::thread(&JACKInput::InputThread, this);

}
Пример #22
0
int pa__init(pa_module*m) {
    struct userdata *u = NULL;
    pa_sample_spec ss;
    pa_channel_map map;
    pa_modargs *ma = NULL;
    jack_status_t status;
    const char *server_name, *client_name;
    uint32_t channels = 0;
    bool do_connect = true;
    unsigned i;
    const char **ports = NULL, **p;
    pa_sink_new_data data;
    jack_latency_range_t r;
    size_t n;

    pa_assert(m);

    jack_set_error_function(jack_error_func);

    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
        pa_log("Failed to parse module arguments.");
        goto fail;
    }

    if (pa_modargs_get_value_boolean(ma, "connect", &do_connect) < 0) {
        pa_log("Failed to parse connect= argument.");
        goto fail;
    }

    server_name = pa_modargs_get_value(ma, "server_name", NULL);
    client_name = pa_modargs_get_value(ma, "client_name", "PulseAudio JACK Sink");

    m->userdata = u = pa_xnew0(struct userdata, 1);
    u->core = m->core;
    u->module = m;
    u->saved_frame_time_valid = false;
    u->rtpoll = pa_rtpoll_new();
    pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);

    /* The queue linking the JACK thread and our RT thread */
    u->jack_msgq = pa_asyncmsgq_new(0);

    /* The msgq from the JACK RT thread should have an even higher
     * priority than the normal message queues, to match the guarantee
     * all other drivers make: supplying the audio device with data is
     * the top priority -- and as long as that is possible we don't do
     * anything else */
    u->rtpoll_item = pa_rtpoll_item_new_asyncmsgq_read(u->rtpoll, PA_RTPOLL_EARLY-1, u->jack_msgq);

    if (!(u->client = jack_client_open(client_name, server_name ? JackServerName : JackNullOption, &status, server_name))) {
        pa_log("jack_client_open() failed.");
        goto fail;
    }

    ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsInput);

    channels = 0;
    if (ports)
        for (p = ports; *p; p++)
            channels++;

    if (!channels)
        channels = m->core->default_sample_spec.channels;

    if (pa_modargs_get_value_u32(ma, "channels", &channels) < 0 ||
        !pa_channels_valid(channels)) {
        pa_log("Failed to parse channels= argument.");
        goto fail;
    }

    if (channels == m->core->default_channel_map.channels)
        map = m->core->default_channel_map;
    else
        pa_channel_map_init_extend(&map, channels, PA_CHANNEL_MAP_ALSA);

    if (pa_modargs_get_channel_map(ma, NULL, &map) < 0 || map.channels != channels) {
        pa_log("Failed to parse channel_map= argument.");
        goto fail;
    }

    pa_log_info("Successfully connected as '%s'", jack_get_client_name(u->client));

    u->channels = ss.channels = (uint8_t) channels;
    ss.rate = jack_get_sample_rate(u->client);
    ss.format = PA_SAMPLE_FLOAT32NE;

    pa_assert(pa_sample_spec_valid(&ss));

    for (i = 0; i < ss.channels; i++) {
        if (!(u->port[i] = jack_port_register(u->client, pa_channel_position_to_string(map.map[i]), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput|JackPortIsTerminal, 0))) {
            pa_log("jack_port_register() failed.");
            goto fail;
        }
    }

    pa_sink_new_data_init(&data);
    data.driver = __FILE__;
    data.module = m;
    pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
    pa_sink_new_data_set_sample_spec(&data, &ss);
    pa_sink_new_data_set_channel_map(&data, &map);
    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "jack");
    if (server_name)
        pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, server_name);
    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Jack sink (%s)", jack_get_client_name(u->client));
    pa_proplist_sets(data.proplist, "jack.client_name", jack_get_client_name(u->client));

    if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) {
        pa_log("Invalid properties");
        pa_sink_new_data_done(&data);
        goto fail;
    }

    u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY);
    pa_sink_new_data_done(&data);

    if (!u->sink) {
        pa_log("Failed to create sink.");
        goto fail;
    }

    u->sink->parent.process_msg = sink_process_msg;
    u->sink->userdata = u;

    pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
    pa_sink_set_rtpoll(u->sink, u->rtpoll);
    pa_sink_set_max_request(u->sink, jack_get_buffer_size(u->client) * pa_frame_size(&u->sink->sample_spec));

    jack_set_process_callback(u->client, jack_process, u);
    jack_on_shutdown(u->client, jack_shutdown, u);
    jack_set_thread_init_callback(u->client, jack_init, u);
    jack_set_buffer_size_callback(u->client, jack_buffer_size, u);

    if (!(u->thread = pa_thread_new("jack-sink", thread_func, u))) {
        pa_log("Failed to create thread.");
        goto fail;
    }

    if (jack_activate(u->client)) {
        pa_log("jack_activate() failed");
        goto fail;
    }

    if (do_connect) {
        for (i = 0, p = ports; i < ss.channels; i++, p++) {

            if (!p || !*p) {
                pa_log("Not enough physical output ports, leaving unconnected.");
                break;
            }

            pa_log_info("Connecting %s to %s", jack_port_name(u->port[i]), *p);

            if (jack_connect(u->client, jack_port_name(u->port[i]), *p)) {
                pa_log("Failed to connect %s to %s, leaving unconnected.", jack_port_name(u->port[i]), *p);
                break;
            }
        }
    }

    jack_port_get_latency_range(u->port[0], JackPlaybackLatency, &r);
    n = r.max * pa_frame_size(&u->sink->sample_spec);
    pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(n, &u->sink->sample_spec));
    pa_sink_put(u->sink);

    if (ports)
        jack_free(ports);
    pa_modargs_free(ma);

    return 0;

fail:
    if (ma)
        pa_modargs_free(ma);

    if (ports)
        jack_free(ports);

    pa__done(m);

    return -1;
}
Пример #23
0
static int start_jack(struct auplay_st *st)
{
	const char **ports;
	const char *client_name = "baresip";
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;
	unsigned ch;
	jack_nframes_t engine_srate;

	/* open a client connection to the JACK server */

	st->client = jack_client_open(client_name, options,
				      &status, server_name);
	if (st->client == NULL) {
		warning("jack: jack_client_open() failed, "
			"status = 0x%2.0x\n", status);

		if (status & JackServerFailed) {
			warning("jack: Unable to connect to JACK server\n");
		}
		return ENODEV;
	}
	if (status & JackServerStarted) {
		info("jack: JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(st->client);
		info("jack: unique name `%s' assigned\n", client_name);
	}

	jack_set_process_callback(st->client, process_handler, st);

	engine_srate = jack_get_sample_rate(st->client);
	st->nframes  = jack_get_buffer_size(st->client);

	info("jack: engine sample rate: %" PRIu32 " max_frames=%u\n",
	     engine_srate, st->nframes);

	/* currently the application must use the same sample-rate
	   as the jack server backend */
	if (engine_srate != st->prm.srate) {
		warning("jack: samplerate %uHz expected\n", engine_srate);
		return EINVAL;
	}

	/* create one port per channel */
	for (ch=0; ch<st->prm.ch; ch++) {

		char buf[32];
		re_snprintf(buf, sizeof(buf), "output_%u", ch+1);

		st->portv[ch] = jack_port_register (st->client, buf,
						    JACK_DEFAULT_AUDIO_TYPE,
						    JackPortIsOutput, 0);
		if ( st->portv[ch] == NULL) {
			warning("jack: no more JACK ports available\n");
			return ENODEV;
		}
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

	if (jack_activate (st->client)) {
		warning("jack: cannot activate client");
		return ENODEV;
	}

	/* Connect the ports.  You can't do this before the client is
	 * activated, because we can't make connections to clients
	 * that aren't running.  Note the confusing (but necessary)
	 * orientation of the driver backend ports: playback ports are
	 * "input" to the backend, and capture ports are "output" from
	 * it.
	 */

	ports = jack_get_ports (st->client, NULL, NULL,
				JackPortIsInput);
	if (ports == NULL) {
		warning("jack: no physical playback ports\n");
		return ENODEV;
	}

	for (ch=0; ch<st->prm.ch; ch++) {

		if (jack_connect (st->client, jack_port_name (st->portv[ch]),
				  ports[ch])) {
			warning("jack: cannot connect output ports\n");
		}
	}

	jack_free(ports);

	return 0;
}
Пример #24
0
Файл: tw.c Проект: Andux/jack2
int
main (int argc, char *argv[])
{
	const char **ports;
	const char *client_name;
	const char *server_name = NULL;
	jack_options_t options = JackNullOption;
	jack_status_t status;

	if (argc >= 2) {		/* client name specified? */
		client_name = argv[1];
		if (argc >= 3) {	/* server name specified? */
			server_name = argv[2];
			options |= JackServerName;
		}
	} else {			/* use basename of argv[0] */
		client_name = strrchr(argv[0], '/');
		if (client_name == 0) {
			client_name = argv[0];
		} else {
			client_name++;
		}
	}

	/* open a client connection to the JACK server */

	client = jack_client_open (client_name, options, &status, server_name);
	if (client == NULL) {
		fprintf (stderr, "jack_client_open() failed, "
			 "status = 0x%2.0x\n", status);
		if (status & JackServerFailed) {
			fprintf (stderr, "Unable to connect to JACK server\n");
		}
		exit (1);
	}
	if (status & JackServerStarted) {
		fprintf (stderr, "JACK server started\n");
	}
	if (status & JackNameNotUnique) {
		client_name = jack_get_client_name(client);
		fprintf (stderr, "unique name `%s' assigned\n", client_name);
	}

	/* tell the JACK server to call `process()' whenever
	   there is work to be done.
	*/
    if (jack_set_process_thread(client, jack_thread, client) < 0)
		exit(1);

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

	jack_on_shutdown (client, jack_shutdown, 0);

	/* display the current sample rate.
	 */

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

	/* create two ports */

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

	if ((input_port == NULL) || (output_port == NULL)) {
		fprintf(stderr, "no more JACK ports available\n");
		exit (1);
	}

	/* Tell the JACK server that we are ready to roll.  Our
	 * process() callback will start running now. */

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

	/* Connect the ports.  You can't do this before the client is
	 * activated, because we can't make connections to clients
	 * that aren't running.  Note the confusing (but necessary)
	 * orientation of the driver backend ports: playback ports are
	 * "input" to the backend, and capture ports are "output" from
	 * it.
	 */

	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsOutput);
	if (ports == NULL) {
		fprintf(stderr, "no physical capture ports\n");
		exit (1);
	}

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

	jack_free (ports);

	ports = jack_get_ports (client, NULL, NULL,
				JackPortIsPhysical|JackPortIsInput);
	if (ports == NULL) {
		fprintf(stderr, "no physical playback ports\n");
		exit (1);
	}

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

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

	/* keep running until the transport stops */

	while (client_state != Exit) {
		sleep (1);
	}

	jack_client_close (client);
	exit (0);
}
Пример #25
0
AudioDevJack::AudioDevJack(QObject *parent):
    AudioDev(parent)
{
    this->m_curChannels = 0;
    this->m_curSampleRate = 0;
    this->m_maxBufferSize = 0;
    this->m_isInput = false;
    this->m_client = NULL;

    this->m_descriptions = {
        {":jackinput:" , "JACK Audio Connection Kit Input" },
        {":jackoutput:", "JACK Audio Connection Kit Output"},
    };

    auto appName = QCoreApplication::applicationName()
                   + QString("_%1").arg(Ak::id());
    int maxNameSize = jack_client_name_size() - 1;

    if (appName.size() > maxNameSize)
        appName = appName.mid(0, maxNameSize);

    jack_status_t status;
    this->m_client = jack_client_open(appName.toStdString().c_str(),
                                      JackNullOption,
                                      &status);

    if (!this->m_client) {
        this->m_error = jackErrorCodes->value(status);
        Q_EMIT this->errorChanged(this->m_error);

        return;
    }

    // Setup callbacks

    jack_set_process_callback(this->m_client,
                              AudioDevJack::onProcessCallback,
                              this);
    jack_on_shutdown(this->m_client,
                     AudioDevJack::onShutdownCallback,
                     this);

    AkAudioCaps audioCaps;
    audioCaps.isValid() = true;
    audioCaps.format() = AkAudioCaps::SampleFormat_flt;
    audioCaps.bps() = AkAudioCaps::bitsPerSample(audioCaps.format());
    audioCaps.rate() = int(jack_get_sample_rate(this->m_client));
    audioCaps.layout() = AkAudioCaps::defaultChannelLayout(audioCaps.channels());
    audioCaps.align() = false;

    QMap<QString, JackPortFlags> portTypeMap = {
        {":jackinput:" , JackPortIsOutput},
        {":jackoutput:", JackPortIsInput }
    };

    // Query the number orr channels

    for (auto deviceId: portTypeMap.keys()) {
        auto ports = jack_get_ports(this->m_client,
                                    NULL,
                                    JACK_DEFAULT_AUDIO_TYPE,
                                    JackPortIsPhysical | portTypeMap[deviceId]);
        int channels = 0;

        for (auto portName = ports; portName && *portName; portName++, channels++)
            this->m_devicePorts[deviceId] << *portName;

        if (ports)
            jack_free(ports);

        if (channels > 0) {
            audioCaps.channels() = channels;
            this->m_caps[deviceId] = audioCaps;
        }
    }
}
Пример #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_execute_on(fb, NULL, "/external_tempo", "i", error, jii->external_tempo) &&
            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_rename_fn(jii->client, 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, "/rename_audio_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_audio_output *audioout = cbox_io_get_audio_output(io, NULL, &uuid);
        if (!audioout)
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Port '%s' not found", uuidstr);
            return FALSE;
        }
        if (0 != jack_port_rename_fn(jii->client, ((struct cbox_jack_audio_output *)audioout)->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(audioout->name);
        audioout->name = 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;
        }
        struct cbox_audio_output *audioout = cbox_io_get_audio_output(io, NULL, &uuid);
        if (audioout)
        {
            cbox_jack_audio_output_set_autoconnect((struct cbox_jack_audio_output *)audioout, 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_audio_output") && !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_audio_output *audioout = cbox_io_get_audio_output(io, NULL, &uuid);
        if (!audioout)
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Port '%s' not found", uuidstr);
            return FALSE;
        }
        jack_port_disconnect(jii->client, ((struct cbox_jack_audio_output *)audioout)->port);
        return TRUE;
    }
    else if (!strncmp(cmd->command, "/disconnect_midi_", 17) && !strcmp(cmd->arg_types, "s"))
    {
        bool is_both = !strcmp(cmd->command + 17, "port");
        bool is_in = is_both || !strcmp(cmd->command + 17, "input");
        bool is_out = is_both || !strcmp(cmd->command + 17, "output");
        if (is_in || is_out) {
            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 = is_in ? cbox_io_get_midi_input(io, NULL, &uuid) : NULL;
            struct cbox_midi_output *midiout = is_out ? cbox_io_get_midi_output(io, NULL, &uuid) : NULL;
            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;
        }
    }

    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 = NULL;
        if (!strchr(name, ':')) {
            // try UUID
            struct cbox_uuid uuid;
            if (!cbox_uuid_fromstring(&uuid, name, error))
                return FALSE;
            struct cbox_midi_output *midiout = cbox_io_get_midi_output(io, NULL, &uuid);
            if (midiout)
                port = ((struct cbox_jack_midi_output *)midiout)->port;
            else {
                struct cbox_midi_input *midiin = cbox_io_get_midi_input(io, NULL, &uuid);
                if (midiin)
                    port = ((struct cbox_jack_midi_input *)midiin)->port;
            }
        }
        else
            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 if (!strcmp(cmd->command, "/external_tempo") && !strcmp(cmd->arg_types, "i"))
    {
        jii->external_tempo = CBOX_ARG_I(cmd, 0);
        return TRUE;
    }

    //Metadata

    else if (!strcmp(cmd->command, "/set_property") && !strcmp(cmd->arg_types, "ssss"))
    //parameters: "client:port", key, value, type according to jack_property_t (empty or NULL for string)
    {
        const char *name = CBOX_ARG_S(cmd, 0);
        const char *key = CBOX_ARG_S(cmd, 1);
        const char *value = CBOX_ARG_S(cmd, 2);
        const char *type = CBOX_ARG_S(cmd, 3);

        jack_uuid_t subject;
        if (!cbox_jack_io_get_jack_uuid_from_name(jii, name, &subject, error)) //error message set inside
            return FALSE;

        if (jack_set_property(jii->client, subject, key, value, type)) // 0 on success
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Set property key:'%s' value: '%s' to port '%s' was not successful", key, value, name);
            return FALSE;
        }
        return TRUE;
    }
    else if (!strcmp(cmd->command, "/get_property") && !strcmp(cmd->arg_types, "ss"))
    //parameters: "client:port", key
    //returns python key, value and type as strings
    {
        const char *name = CBOX_ARG_S(cmd, 0);
        const char *key = CBOX_ARG_S(cmd, 1);

        jack_uuid_t subject;
        if (!cbox_jack_io_get_jack_uuid_from_name(jii, name, &subject, error)) //error message set inside
            return FALSE;

        char* value = NULL;
        char* type = NULL;

        if (jack_get_property(subject, key, &value, &type)) // 0 on success, -1 if the subject has no key property.
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Port '%s' does not have key '%s'", name, key);
            return FALSE;
        }

        char* returntype; //We need to call jack_free on type in any case so it can't be our own data.
        if (type == NULL)
             returntype = "";
        else
            returntype = type;

        if (!cbox_execute_on(fb, NULL, "/value", "ss", error, value, returntype)) //send return values to Python.
           return FALSE;

        jack_free(value);
        jack_free(type);
        return TRUE;
    }
    else if (!strcmp(cmd->command, "/get_properties") && !strcmp(cmd->arg_types, "s"))
    //parameters: "client:port"
    {
        const char *name = CBOX_ARG_S(cmd, 0);

        jack_uuid_t subject;
        if (!cbox_jack_io_get_jack_uuid_from_name(jii, name, &subject, error))  //error message set inside
            return FALSE;

        jack_description_t desc;
        if (!jack_get_properties(subject, &desc)) // 0 on success, -1 if no subject with any properties exists.
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Port '%s' with uuid '%lli' does not have any properties", name, (long long)subject);
            return FALSE;
        }

        const char *returntype;
        for (uint32_t i = 0; i<desc.property_cnt ; i++)
        {
            if (desc.properties[i].type == NULL)
                 returntype = "";
            else
                returntype = desc.properties[i].type;
            if (!cbox_execute_on(fb, NULL, "/properties", "sss", error, desc.properties[i].key, desc.properties[i].data, returntype))
                return FALSE;
        }
        jack_free_description(&desc, 0); //if non-zero desc will also be passed to free()
        return TRUE;
    }
    else if (!strcmp(cmd->command, "/get_all_properties") && !strcmp(cmd->arg_types, ""))
    {
        jack_description_t *descs;
        int counter;
        counter = jack_get_all_properties(&descs);
        const char *returntype;
        for (int j = 0; j < counter; j++)
        {
            jack_description_t *one_desc = &descs[j];
            for (uint32_t i = 0; i < one_desc->property_cnt ; i++)
            {
                if (one_desc->properties[i].type == NULL)
                    returntype = "";
                else
                    returntype = one_desc->properties[i].type;

                /*
                index = jack_uuid_to_index(one_desc->subject)
                portid = jack_port_by_id(jii->client, index);
                portname = jack_port_name(port);
                */
                if (!cbox_execute_on(fb, NULL, "/all_properties", "ssss",
                        error,
                        jack_port_name(jack_port_by_id(jii->client, jack_uuid_to_index(one_desc->subject))),
                        one_desc->properties[i].key,
                        one_desc->properties[i].data,
                        returntype))
                    return FALSE;
            }
            jack_free_description(one_desc, 0); //if non-zero one_desc will also be passed to free()
        }
        jack_free(descs);
        return TRUE;
    }


    else if (!strcmp(cmd->command, "/remove_property") && !strcmp(cmd->arg_types, "ss"))
    {
        const char *name = CBOX_ARG_S(cmd, 0);
        const char *key = CBOX_ARG_S(cmd, 1);

        jack_uuid_t subject;
        if (!cbox_jack_io_get_jack_uuid_from_name(jii, name, &subject, error)) //error message set inside
            return FALSE;

        if (jack_remove_property(jii->client, subject, key)) // 0 on success, -1 otherwise
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Could not remove port '%s' key '%s'", name, key);
            return FALSE;
        }
        return TRUE;
    }

    else if (!strcmp(cmd->command, "/remove_properties") && !strcmp(cmd->arg_types, "s"))
    {
        const char *name = CBOX_ARG_S(cmd, 0);

        jack_uuid_t subject;
        if (!cbox_jack_io_get_jack_uuid_from_name(jii, name, &subject, error)) //error message set inside
            return FALSE;

        if (jack_remove_properties(jii->client, subject) == -1) // number of removed properties returned, -1 on error
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Could not remove properties of port '%s'", name);
            return FALSE;
        }
        return TRUE;
    }


    else if (!strcmp(cmd->command, "/remove_all_properties") && !strcmp(cmd->arg_types, ""))
    {
        if (jack_remove_all_properties(jii->client)) // 0 on success, -1 otherwise
        {
            g_set_error(error, CBOX_MODULE_ERROR, CBOX_MODULE_ERROR_FAILED, "Remove all JACK properties was not successful");
            return FALSE;
        }
        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;
    }
}
Пример #27
0
static void autoconnect_by_spec(jack_client_t *client, const char *port, const char *orig_spec, int is_cbox_input, int is_midi, const jack_port_t *only_connect_port, struct cbox_command_target *fb)
{
    char *name, *copy_spec, *dpos;
    const char *use_name;
    
    copy_spec = g_strdup(orig_spec);
    name = copy_spec;
    do {
        dpos = strchr(name, ';');
        if (dpos)
            *dpos = '\0';
        
        use_name = name;
        if (use_name[0] == '#')
        {
            char *endptr = NULL;
            long portidx = strtol(use_name + 1, &endptr, 10) - 1;
            if (endptr == use_name + strlen(use_name))
            {
                const char **names = jack_get_ports(client, ".*", is_midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE, is_cbox_input ? JackPortIsOutput : JackPortIsInput);
                // Client killed by JACK
                if (!names)
                    return;
                int i;
                for (i = 0; i < portidx && names[i]; i++)
                    ;
                
                if (names[i])
                    autoconnect_port(client, port, names[i], is_cbox_input, only_connect_port, fb);
                else
                    g_message("Connect: unmatched port index %d", (int)portidx);
                
                jack_free(names);
            }
        }
        else if (use_name[0] == '~' || use_name[0] == '*')
        {
            const char **names = jack_get_ports(client, use_name + 1, is_midi ? JACK_DEFAULT_MIDI_TYPE : JACK_DEFAULT_AUDIO_TYPE, is_cbox_input ? JackPortIsOutput : JackPortIsInput);
            // Client killed by JACK
            if (!names)
                return;
            
            if (names && names[0])
            {
                if (use_name[0] == '*')
                {
                    int i;
                    for (i = 0; names[i]; i++)
                        autoconnect_port(client, port, names[i], is_cbox_input, only_connect_port, fb);
                }
                else
                    autoconnect_port(client, port, names[0], is_cbox_input, only_connect_port, fb);
            }
            else
                g_message("Connect: unmatched port regexp %s", use_name);
            jack_free(names);
        }
        else
            autoconnect_port(client, port, use_name, is_cbox_input, only_connect_port, fb);

        if (dpos)
            name = dpos + 1;
    } while(dpos);
    g_free(copy_spec);
}
Пример #28
0
int main(int argc, char *argv[])
{
	parse_arguments(argc, argv);
	jack_session_command_t *retval;
	int k,i,j;


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

	signal(SIGQUIT, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);
	signal(SIGINT, signal_handler);

	jack_on_shutdown(client, jack_shutdown, 0);

	jack_activate(client);


	retval = jack_session_notify( client, NULL, notify_type, save_path );
	for(i=0; retval[i].uuid; i++ ) {
		printf( "export SESSION_DIR=\"%s%s/\"\n", save_path, retval[i].client_name );
		printf( "%s &\n", retval[i].command );
		add_uuid_mapping(retval[i].uuid); 
	}

	printf( "sleep 10\n" );

	for(k=0; retval[k].uuid; k++ ) {

		char* port_regexp = alloca( jack_client_name_size()+3 );
		char* client_name = jack_get_client_name_by_uuid( client, retval[k].uuid );
		snprintf( port_regexp, jack_client_name_size()+3, "%s:.*", client_name );
		jack_free(client_name);
		const char **ports = jack_get_ports( client, port_regexp, NULL, 0 );
		if( !ports ) {
			continue;
		}
		for (i = 0; ports[i]; ++i) {
			const char **connections;
			if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) {
				for (j = 0; connections[j]; j++) {
					char *src = map_port_name_to_uuid_port( ports[i] ); 
					char *dst = map_port_name_to_uuid_port( connections[j] ); 
					printf( "jack_connect -u \"%s\" \"%s\"\n", src, dst );
				}
				jack_free (connections);
			} 
		}
		jack_free(ports);

	}
	jack_session_commands_free(retval);

	jack_client_close(client);

	return 0;
}
Пример #29
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;
}
Пример #30
0
Файл: jack.c Проект: BG2BKK/cmus
static int op_jack_init(void)
{
#ifdef HAVE_SAMPLERATE
	for (int i = 0; i < CHANNELS; i++) {
		src_state[i] = src_new(src_quality, 1, NULL);
		if (src_state[i] == NULL) {
			d_print("src_new failed");
			for (i = i - 1; i >= 0; i--) {
				src_delete(src_state[i]);
			}
			return -OP_ERROR_INTERNAL;
		}
	}
#endif
	jack_set_error_function(op_jack_error_cb);

	jack_options_t options = JackNullOption;
	if (fail) {
		/* since jackd failed, it will not be autostarted. Either jackd
		 * was killed intentionaly or it died by heartattack.
		 * Until it is restarted, init will happily fail again
		 * and again and again..
		 */
		options |= JackNoStartServer;
	}

	jack_status_t status;
	client = jack_client_open("cmus", options, &status, server_name);
	if (client == NULL) {
		d_print("jack_client_new failed\n");
		return -OP_ERROR_INTERNAL;
	}

	if (status & JackServerStarted) {
		d_print("jackd started\n");
	}

	jack_nframes_t jack_buffer_size = jack_get_buffer_size(client);
	jack_sample_rate = jack_get_sample_rate(client);
	op_jack_buffer_init(jack_buffer_size, NULL);

	jack_set_process_callback(client, op_jack_cb, NULL);
	jack_set_sample_rate_callback(client, op_jack_sample_rate_cb, NULL);
	jack_set_buffer_size_callback(client, op_jack_buffer_init, NULL);
	jack_on_shutdown(client, op_jack_shutdown_cb, NULL);

	for (int i = 0; i < CHANNELS; i++) {
		char port_name[20];
		snprintf(port_name, sizeof(port_name)-1, "output %d", i);

		output_ports[i] = jack_port_register(
			client,
			port_name,
			JACK_DEFAULT_AUDIO_TYPE,
			JackPortIsOutput,
			0
		);
		if (output_ports[i] == NULL) {
			d_print("no jack ports available\n");
			return -OP_ERROR_INTERNAL;
		}
	}

	if (jack_activate(client)) {
		d_print("jack_client_activate failed\n");
		return -OP_ERROR_INTERNAL;
	}

	const char **ports = jack_get_ports(client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
	if (ports == NULL) {
		d_print("cannot get playback ports\n");
		return -OP_ERROR_INTERNAL;
	}

	for (int i = 0; i < CHANNELS; i++) {
		if (ports[i] == NULL) {
			d_print("could not connect output %d. too few ports.\n", i);
			break;
		}
		if (jack_connect(client, jack_port_name(output_ports[i]), ports[i])) {
			d_print("connot connect port %s\n", ports[i]);
			jack_free(ports);
			return -OP_ERROR_INTERNAL;
		}
	}

	jack_free(ports);
	fail = 0;

	return OP_ERROR_SUCCESS;
}