Example #1
0
static PyObject *
alsaseq_client(PyObject *self /* Not used */, PyObject *args)
{
  const char * client_name;

  if (!PyArg_ParseTuple(args, "siii", &client_name, &ninputports, &noutputports, &createqueue ) )
		return NULL;

  if ( ninputports > maximum_nports || noutputports > maximum_nports ) {
    printf( "Only %d ports of each are allowed.\n", maximum_nports );
    exit( 1 );
    }

  int portid, n;

  if (snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
    fprintf(stderr, "Error creating ALSA client.\n");
    exit(1);
  }
  snd_seq_set_client_name(seq_handle, client_name );

  if ( createqueue )
      queue_id = snd_seq_alloc_queue(seq_handle);
  else
      queue_id = SND_SEQ_QUEUE_DIRECT;

  for ( n=0; n < ninputports; n++ ) {
    if (( portid = snd_seq_create_simple_port(seq_handle, "Input port",
            SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
            SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
    fprintf(stderr, "Error creating input port %d.\n", n );
    exit(1);
    }
    if( createqueue ) {
      /* set timestamp info of port  */
      snd_seq_port_info_t *pinfo;
      snd_seq_port_info_alloca(&pinfo);
      snd_seq_get_port_info( seq_handle, portid, pinfo );
      snd_seq_port_info_set_timestamping(pinfo, 1);
      snd_seq_port_info_set_timestamp_queue(pinfo, queue_id );
      snd_seq_port_info_set_timestamp_real( pinfo, 1 );
      snd_seq_set_port_info( seq_handle, portid, pinfo );
    }
  }

  for ( n=0; n < noutputports; n++ ) {
    if (( portid = snd_seq_create_simple_port(seq_handle, "Output port",
            SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
            SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
      fprintf(stderr, "Error creating output port %d.\n", n );
      exit(1);
    }
  }
    firstoutputport = ninputports;
    lastoutputport  = noutputports + ninputports - 1;

    Py_INCREF(Py_None);
    return Py_None;
}
/** call-seq: timestamping = bool

Switch auto-timestamping on or off.  Note that the port needs a timestamp-queue
as well to actually activate it. This is not verified though. It will simply not
work. See RRTS::Driver::AlsaPortInfo_i#timestamp_queue=
*/
static VALUE
wrap_snd_seq_port_info_set_timestamping(VALUE v_port_info, VALUE v_bool)
{
  snd_seq_port_info_t *port_info;
  Data_Get_Struct(v_port_info, snd_seq_port_info_t, port_info);
  snd_seq_port_info_set_timestamping(port_info, BOOL2INT(v_bool));
  return Qnil;
}
Example #3
0
void event_decoder(snd_seq_t *handle, int argc, char *argv[])
{
	snd_seq_event_t *ev;
	snd_seq_port_info_t *pinfo;
	snd_seq_port_subscribe_t *sub;
	snd_seq_addr_t addr;
	int client, port, queue, max, err, v1, v2;
	char *ptr;
	struct pollfd *pfds;

	if ((client = snd_seq_client_id(handle))<0) {
		fprintf(stderr, "Cannot determine client number: %s\n", snd_strerror(client));
		return;
	}
	printf("Client ID = %i\n", client);
	if ((queue = snd_seq_alloc_queue(handle))<0) {
		fprintf(stderr, "Cannot allocate queue: %s\n", snd_strerror(queue));
		return;
	}
	printf("Queue ID = %i\n", queue);
	if ((err = snd_seq_nonblock(handle, 1))<0)
		fprintf(stderr, "Cannot set nonblock mode: %s\n", snd_strerror(err));
	snd_seq_port_info_alloca(&pinfo);
	snd_seq_port_info_set_name(pinfo, "Input");
	snd_seq_port_info_set_type(pinfo, SND_SEQ_PORT_TYPE_MIDI_GENERIC);
	snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_WRITE);

	/* Enable timestamping for events sent by external subscribers. */
	snd_seq_port_info_set_timestamping(pinfo, 1);
	snd_seq_port_info_set_timestamp_real(pinfo, 1);
	snd_seq_port_info_set_timestamp_queue(pinfo, queue);

	if ((err = snd_seq_create_port(handle, pinfo)) < 0) {
		fprintf(stderr, "Cannot create input port: %s\n", snd_strerror(err));
		return;
	}
	port = snd_seq_port_info_get_port(pinfo);
	event_decoder_start_timer(handle, queue, client, port);

	snd_seq_port_subscribe_alloca(&sub);
	addr.client = SND_SEQ_CLIENT_SYSTEM;
	addr.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE;
	snd_seq_port_subscribe_set_sender(sub, &addr);
	addr.client = client;
	addr.port = port;
	snd_seq_port_subscribe_set_dest(sub, &addr);
	snd_seq_port_subscribe_set_queue(sub, queue);
	snd_seq_port_subscribe_set_time_update(sub, 1);
	snd_seq_port_subscribe_set_time_real(sub, 1);
	if ((err = snd_seq_subscribe_port(handle, sub))<0) {
		fprintf(stderr, "Cannot subscribe announce port: %s\n", snd_strerror(err));
		return;
	}

	addr.client = SND_SEQ_CLIENT_SYSTEM;
	addr.port = SND_SEQ_PORT_SYSTEM_TIMER;
	snd_seq_port_subscribe_set_sender(sub, &addr);
	if ((err = snd_seq_subscribe_port(handle, sub))<0) {
		fprintf(stderr, "Cannot subscribe timer port: %s\n", snd_strerror(err));
		return;
	}

	for (max = 0; max < argc; max++) {
		ptr = argv[max];
		if (!ptr)
			continue;
		snd_seq_port_subscribe_set_time_real(sub, 0);
		if (tolower(*ptr) == 'r') {
			snd_seq_port_subscribe_set_time_real(sub, 1);
			ptr++;
		}
		if (sscanf(ptr, "%i.%i", &v1, &v2) != 2) {
			fprintf(stderr, "Wrong argument '%s'...\n", argv[max]);
			return;
		}
		addr.client = v1;
		addr.port = v2;
		snd_seq_port_subscribe_set_sender(sub, &addr);
		if ((err = snd_seq_subscribe_port(handle, sub))<0) {
			fprintf(stderr, "Cannot subscribe port %i from client %i: %s\n", v2, v1, snd_strerror(err));
			return;
		}
	}
	
	max = snd_seq_poll_descriptors_count(handle, POLLIN);
	pfds = alloca(sizeof(*pfds) * max);
	while (1) {
		snd_seq_poll_descriptors(handle, pfds, max, POLLIN);
		if (poll(pfds, max, -1) < 0)
			break;
		do {
			if ((err = snd_seq_event_input(handle, &ev))<0)
				break;
			if (!ev)
				continue;
			decode_event(ev);
			snd_seq_free_event(ev);
		} while (err > 0);
	}
}