Example #1
0
int
midi_open(void)
{
    if (snd_seq_open(&alsaClient, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
        ghss_debug(GDB_ERROR, ": failed to open ALSA sequencer interface");
	return 0;
    }

    snd_seq_set_client_name(alsaClient, host_name);

    alsa_client_id = snd_seq_client_id(alsaClient);

    if ((alsa_port_id = snd_seq_create_simple_port
	 (alsaClient, "input",
	  SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {
        ghss_debug(GDB_ERROR, ": failed to create ALSA sequencer port");
	return 0;
    }

    alsaClient_npfd = snd_seq_poll_descriptors_count(alsaClient, POLLIN);
    alsaClient_pfd = (struct pollfd *)calloc(1, alsaClient_npfd * sizeof(struct pollfd));
    snd_seq_poll_descriptors(alsaClient, alsaClient_pfd, alsaClient_npfd, POLLIN);

    ghss_debug(GDB_ALWAYS, ": listening using ALSA MIDI");

    return 1;
}
Example #2
0
SeqDriver::SeqDriver(QList<MidiMap *> *p_midiMapList, QWidget *parent)
    : QWidget(parent), modified(false)
{
    int err;

    midiMapList = p_midiMapList; 
    portCount = 0;
    discardUnmatched = true;
    portUnmatched = 0;
    clientid = -1;
    
    err = snd_seq_open(&seq_handle, "hw", SND_SEQ_OPEN_DUPLEX, 0);
    if (err < 0) {
        qWarning("Error opening ALSA sequencer (%s).", snd_strerror(err));
        exit(1);
    }
    snd_seq_set_client_name(seq_handle, PACKAGE);
    clientid = snd_seq_client_id(seq_handle);
    portid_in = snd_seq_create_simple_port(seq_handle, "in",
                    SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
                    SND_SEQ_PORT_TYPE_APPLICATION);
    if (portid_in < 0) {
        qWarning("Error creating sequencer port (%s).",
                snd_strerror(portid_in));
        exit(1);
    }
}
Example #3
0
static
int alsa_seqmidi_attach(alsa_midi_t *m)
{
	alsa_seqmidi_t *self = (alsa_seqmidi_t*) m;
	int err;

	debug_log("midi: attach");

	if (self->seq)
		return -EALREADY;

	if ((err = snd_seq_open(&self->seq, "hw", SND_SEQ_OPEN_DUPLEX, 0)) < 0) {
		error_log("failed to open alsa seq");
		return err;
	}
	snd_seq_set_client_name(self->seq, self->alsa_name);
	self->port_id = snd_seq_create_simple_port(self->seq, "port",
		SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_WRITE
#ifndef JACK_MIDI_DEBUG
		|SND_SEQ_PORT_CAP_NO_EXPORT
#endif
		,SND_SEQ_PORT_TYPE_APPLICATION);
	self->client_id = snd_seq_client_id(self->seq);

  	self->queue = snd_seq_alloc_queue(self->seq);
  	snd_seq_start_queue(self->seq, self->queue, 0);

	stream_attach(self, PORT_INPUT);
	stream_attach(self, PORT_OUTPUT);

	snd_seq_nonblock(self->seq, 1);

	return 0;
}
Example #4
0
// Constructor.
qxgeditMidiDevice::qxgeditMidiDevice ( const QString& sClientName )
	: QObject(NULL)
{
	// Set pseudo-singleton reference.
	g_pMidiDevice = this;

	m_pAlsaSeq    = NULL;
	m_iAlsaClient = -1;
	m_iAlsaPort   = -1;

	m_pInputThread = NULL;

	// Open new ALSA sequencer client...
	if (snd_seq_open(&m_pAlsaSeq, "hw", SND_SEQ_OPEN_DUPLEX, 0) >= 0) {
		// Set client identification...
		QString sName = sClientName;
		snd_seq_set_client_name(m_pAlsaSeq, sName.toLatin1().constData());
		m_iAlsaClient = snd_seq_client_id(m_pAlsaSeq);
		// Create duplex port
		sName += " MIDI 1";
		m_iAlsaPort = snd_seq_create_simple_port(m_pAlsaSeq,
			sName.toLatin1().constData(),
			SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE |
			SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ,
			SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
		// Create and start our own MIDI input queue thread...
		m_pInputThread = new qxgeditMidiInputThread(this);
		m_pInputThread->start(QThread::TimeCriticalPriority);
	}
}
Example #5
0
void stop_midireceiver (JackVST *jvst)
{
	int err; 
	snd_seq_event_t event;
	snd_seq_t *seq2 = create_sequencer ("jfstquit", true);
	
	jvst->midiquit = 1;
	
	snd_seq_connect_to (seq2, 0, snd_seq_client_id (jvst->seq),0);
	snd_seq_ev_clear      (&event);
	snd_seq_ev_set_direct (&event);
	snd_seq_ev_set_subs   (&event);
	snd_seq_ev_set_source (&event, 0);
	snd_seq_ev_set_controller (&event,1,0x80,50);
	
	if ((err = snd_seq_event_output (seq2, &event)) < 0) {
		fst_error ("cannot send stop event to midi thread: %s\n",
			   snd_strerror (err));
	}

	snd_seq_drain_output (seq2);
	snd_seq_close (seq2);
	pthread_join (jvst->midi_thread,NULL);
	snd_seq_close (jvst->seq);
}
Example #6
0
int seq_open() {
  unsigned int caps;
  if (!seq_opened) {
    /* sequencer opening */
    if (snd_seq_open(&seq_handle, "hw", SND_SEQ_OPEN_OUTPUT, 0)) {
      fprintf(stderr, "Error opening ALSA sequencer.\n");
      return(-1);
    }
    /* our client id */
    my_client = snd_seq_client_id(seq_handle);
    /* set client info */
    snd_seq_set_client_name(seq_handle, DEFAULT_NAME);
    /* create port */
    caps = SND_SEQ_PORT_CAP_READ;
    if (seq_client == SND_SEQ_ADDRESS_SUBSCRIBERS)
      caps |= SND_SEQ_PORT_CAP_SUBS_READ;
    my_port = snd_seq_create_simple_port(seq_handle, DEFAULT_NAME, caps,SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
    if (my_port < 0) {
      fprintf(stderr, "can't create port\n");
      snd_seq_close(seq_handle);
      return 0;
    }
    /* subscribe to MIDI port */
    if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) {
      if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) {
        fprintf(stderr, "can't subscribe to MIDI port (%d:%d)\n", seq_client, seq_port);
        snd_seq_close(seq_handle);
        return 0;
      }
    }
  }
  seq_opened = 1;
  return 1;
}
Example #7
0
void JVlibForm::init_seq() {
  if (seq) return;
  int err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0);
  check_snd("open sequencer", err);
  err = snd_seq_set_client_name(seq, "midi_player");
  check_snd("set client name", err);
  int client = snd_seq_client_id(seq);    // client # is 128 by default
  check_snd("get client id", client);
}
Example #8
0
/* Returned structure pointer is allocated using malloc. */
struct polls *
midi_init_alsa(void)
{
  struct polls *polls;
  int npfd;
  int synth_port, ctrlr_port;
  int i;

  if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
    dprintf("Couldn't open ALSA sequencer: %s\n", snd_strerror(errno));
    return NULL;
  }
  snd_seq_set_client_name(seq, "Xtor");

  client = snd_seq_client_id(seq);
  if (client < 0) {
    dprintf("Can't get client_id: %d\n", client);
    return NULL;
  }
  dprintf("Client address %d\n", client);

  synth_port = snd_seq_create_simple_port(seq, "Xtor synth port",
                                          SND_SEQ_PORT_CAP_READ |
                                          SND_SEQ_PORT_CAP_WRITE |
                                          SND_SEQ_PORT_CAP_SUBS_READ |
                                          SND_SEQ_PORT_CAP_SUBS_WRITE,
                                          SND_SEQ_PORT_TYPE_APPLICATION);
  if (synth_port < 0) {
    dprintf("Couldn't create synth port: %s\n", snd_strerror(errno));
    return NULL;
  }
  ports[SYNTH_PORT] = synth_port;

  ctrlr_port = snd_seq_create_simple_port(seq, "Xtor controller port",
                                          SND_SEQ_PORT_CAP_READ |
                                          SND_SEQ_PORT_CAP_WRITE |
                                          SND_SEQ_PORT_CAP_SUBS_READ |
                                          SND_SEQ_PORT_CAP_SUBS_WRITE,
                                          SND_SEQ_PORT_TYPE_APPLICATION);
  if (ctrlr_port < 0) {
    dprintf("Couldn't create controller port: %s\n", snd_strerror(errno));
    return NULL;
  }
  ports[CTRLR_PORT] = ctrlr_port;

  /* Fetch poll descriptor(s) for MIDI input (normally only one) */
  npfd = snd_seq_poll_descriptors_count(seq, POLLIN);
  polls = (struct polls *) malloc(sizeof(struct polls) +
				  npfd * sizeof(struct pollfd));
  polls->npfd = npfd;
  snd_seq_poll_descriptors(seq, polls->pollfds, npfd, POLLIN);

  snd_seq_nonblock(seq, SND_SEQ_NONBLOCK);

  return polls;
}
Example #9
0
int ALSAMidiDriver::open() {
	std::string arg;
	unsigned int caps;

	if (isOpen)
		return -1;

	arg = getConfigSetting("alsa_port", ALSA_PORT);

	if (parse_addr(arg, &seq_client, &seq_port) < 0) {
		perr << "ALSAMidiDriver: Invalid port: " << arg << std::endl;
		return -1;
	}
	
	if (my_snd_seq_open(&seq_handle)) {
		perr << "ALSAMidiDriver: Can't open sequencer" << std::endl;
		return -1;
	}

	isOpen = true;
	
	my_client = snd_seq_client_id(seq_handle);
	snd_seq_set_client_name(seq_handle, "PENTAGRAM");
	snd_seq_set_client_group(seq_handle, "input");
	
	caps = SND_SEQ_PORT_CAP_READ;
	if (seq_client == SND_SEQ_ADDRESS_SUBSCRIBERS)
		caps = ~SND_SEQ_PORT_CAP_SUBS_READ;
	my_port =
		snd_seq_create_simple_port(seq_handle, "PENTAGRAM", caps,
								   SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);
	if (my_port < 0) {
		snd_seq_close(seq_handle);
		isOpen = false;
		perr << "ALSAMidiDriver: Can't create port" << std::endl;
		return -1;
	}

	if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) {
		/* subscribe to MIDI port */
		if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) {
			snd_seq_close(seq_handle);
			isOpen = false;
			perr << "ALSAMidiDriver: "
				 << "Can't subscribe to MIDI port (" << seq_client
				 << ":" << seq_port << ")" << std::endl;
			return -1;
		}
	}

	pout << "ALSA client initialised [" << seq_client << ":"
		 << seq_port << "]" << std::endl;

	return 0;
}
Example #10
0
mastermidibus::mastermidibus ()
 :
    m_alsa_seq          (nullptr),  // one pointer
    m_num_out_buses     (0),        // or c_max_busses, or what?
    m_num_in_buses      (0),        // or c_max_busses, or 1, or what?
    m_buses_out         (),         // array of c_max_busses midibus pointers
    m_buses_in          (),         // array of c_max_busses midibus pointers
    m_bus_announce      (nullptr),  // one pointer
    m_buses_out_active  (),         // array of c_max_busses booleans
    m_buses_in_active   (),         // array of c_max_busses booleans
    m_buses_out_init    (),         // array of c_max_busses booleans
    m_buses_in_init     (),         // array of c_max_busses booleans
    m_init_clock        (),         // array of c_max_busses clock_e values
    m_init_input        (),         // array of c_max_busses booleans
    m_queue             (0),
    m_ppqn              (0),
    m_bpm               (0),
    m_num_poll_descriptors (0),
    m_poll_descriptors  (nullptr),
    m_dumping_input     (false),
    m_seq               (nullptr),
    m_mutex             ()
{
    for (int i = 0; i < c_max_busses; ++i)        // why the global?
    {
        m_buses_in_active[i] = false;
        m_buses_out_active[i] = false;
        m_buses_in_init[i] = false;
        m_buses_out_init[i] = false;
        m_init_clock[i] = e_clock_off;
        m_init_input[i] = false;
    }

#ifdef HAVE_LIBASOUND
    /* open the sequencer client */

    int result  = snd_seq_open(&m_alsa_seq, "default",  SND_SEQ_OPEN_DUPLEX, 0);
    if (result  < 0)
    {
        errprint("snd_seq_open() error");
        exit(1);
    }
    snd_seq_set_client_name(m_alsa_seq, "seq24");   /* client's name  */
    m_queue = snd_seq_alloc_queue(m_alsa_seq);      /* client's queue */
#endif

#ifdef LASH_SUPPORT
    /*
     * Notify LASH of our client ID so that it can restore connections.
     */

    if (not_nullptr(global_lash_driver))
        global_lash_driver->set_alsa_client_id(snd_seq_client_id(m_alsa_seq));
#endif
}
Example #11
0
static PyObject *
alsaseq_id(PyObject *self, PyObject *args)
{
  int res = 0;
        
	if (!PyArg_ParseTuple(args, "" ))
		return NULL;
        res = snd_seq_client_id( seq_handle );

        return PyInt_FromLong( res );
}
    MidiInputDeviceAlsa::MidiInputDeviceAlsa(std::map<String,DeviceCreationParameter*> Parameters, void* pSampler) : MidiInputDevice(Parameters, pSampler), Thread(true, true, 1, -1) {
        if (snd_seq_open(&hAlsaSeq, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
            throw MidiInputException("Error opening ALSA sequencer");
        }
        this->hAlsaSeqClient = snd_seq_client_id(hAlsaSeq);
        snd_seq_set_client_name(hAlsaSeq, "LinuxSampler");
	AcquirePorts(((DeviceCreationParameterInt*)Parameters["PORTS"])->ValueAsInt());
	if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
		Listen();
	}
    }
Example #13
0
/**
 * \brief simple disconnection
 * \param seq sequencer handle
 * \param myport the port id as sender
 * \param dest_client destination client id
 * \param dest_port destination port id
 * \return 0 on success or negative error code
 *
 * Remove connection from the given sender client:port
 * to the given destination port in the current client.
 *
 * \sa snd_seq_unsubscribe_port(), snd_seq_connect_to()
 */
int snd_seq_disconnect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port)
{
	snd_seq_port_subscribe_t subs;
	
	memset(&subs, 0, sizeof(subs));
	/*subs.sender.client = seq->client;*/
	subs.sender.client = snd_seq_client_id(seq);
	subs.sender.port = myport;
	subs.dest.client = dest_client;
	subs.dest.port = dest_port;

	return snd_seq_unsubscribe_port(seq, &subs);
}
Example #14
0
int lash_clinit(int argc, char** argv, jack_client_t *jack_client, snd_seq_t *alsa_handle)
{
    lash_jackname = jack_get_client_name(jack_client);
    lash_client = lash_init(lash_extract_args(&argc, &argv), lash_jackname, LASH_Config_File, LASH_PROTOCOL(2, 0));
    if (lash_enabled(lash_client)) 
    {
        lash_jack_client_name(lash_client, lash_jackname);
        lash_event_t *event = lash_event_new_with_type(LASH_Client_Name);
        lash_event_set_string(event, lash_jackname);
        lash_send_event(lash_client, event);
        lash_alsaid = alsa_handle;
        lash_alsa_client_id(lash_client, (unsigned char)snd_seq_client_id(alsa_handle));
        return 0;
    }
    return -1;
}
Example #15
0
void Alsa::openPort(unsigned int portNumber_)
{
    if ( _connected ) {
        this->closePort();
    }

    unsigned int nSrc = this->getPortCount();
    if (nSrc < 1) {
        std::cerr << "error: CxxMidi::Output::Alsa::openPort: no MIDI output sources found" << std::endl;
    }

    snd_seq_port_info_t *pinfo;
    snd_seq_port_info_alloca( &pinfo );
    std::ostringstream ost;
    if ( portInfo( _apiData->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber_ ) == 0 )
    {
        std::cerr << "error: CxxMidi::Output::Alsa::openPort: port " << portNumber_ << " is invalid" << std::endl;
    }

    snd_seq_addr_t sender, receiver;
    receiver.client = snd_seq_port_info_get_client( pinfo );
    receiver.port = snd_seq_port_info_get_port( pinfo );
    sender.client = snd_seq_client_id( _apiData->seq );

    if ( _apiData->vport < 0 ) {
        _apiData->vport = snd_seq_create_simple_port( _apiData->seq, "CxxMidi (RtMidi) output",
                                                      SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
                                                      SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION );
        if ( _apiData->vport < 0 ) {
            std::cerr << "error: CxxMidi::Output::Alsa::openPort: error creating output port" << std::endl;
        }
    }

    sender.port = _apiData->vport;

    // Make subscription
    snd_seq_port_subscribe_malloc( &_apiData->subscription );
    snd_seq_port_subscribe_set_sender(_apiData->subscription, &sender);
    snd_seq_port_subscribe_set_dest(_apiData->subscription, &receiver);
    snd_seq_port_subscribe_set_time_update(_apiData->subscription, 1);
    snd_seq_port_subscribe_set_time_real(_apiData->subscription, 1);
    if ( snd_seq_subscribe_port(_apiData->seq, _apiData->subscription) ) {
        std::cerr << "error: CxxMidi::Output::Alsa::openPort: error making port connection" << std::endl;
    }

    _connected = true;
}
Example #16
0
static PyObject *
alsaseq_id(PyObject *self, PyObject *args)
{
  int res = 0;
        
	if (!PyArg_ParseTuple(args, "" ))
		return NULL;

        if (!seq_handle) {
                PyErr_SetString(PyExc_RuntimeError, "Must initialize module with alsaseq.client() before using it");
                return NULL;
        }

        res = snd_seq_client_id( seq_handle );

        return PyInt_FromLong( res );
}
/* TODO Make sample rate, buffer, gain and polyphony set from CL interface*/
void connect2MidiThroughPort(snd_seq_t *seq_handle) {
        snd_seq_addr_t sender, dest;
        snd_seq_port_subscribe_t *subs;
        int myID;
        myID=snd_seq_client_id(seq_handle);
        fprintf(stderr,"MyID=%d",myID);  
        sender.client = 14;
        sender.port = 0;
        dest.client = myID;
        dest.port = 0;
        snd_seq_port_subscribe_alloca(&subs);
        snd_seq_port_subscribe_set_sender(subs, &sender);
        snd_seq_port_subscribe_set_dest(subs, &dest);
        snd_seq_port_subscribe_set_queue(subs, 1);
        snd_seq_port_subscribe_set_time_update(subs, 1);
        snd_seq_port_subscribe_set_time_real(subs, 1);
        snd_seq_subscribe_port(seq_handle, subs);
}
Example #18
0
static int set_seq_name(snd_seq_t *handle)
{
    int err;
    snd_seq_client_info_t info;
	
    memset(&info, 0, sizeof(info));
    info.client = snd_seq_client_id(handle);
    info.type = USER_CLIENT;
    snprintf(info.name, sizeof(info.name), "SoundTracker(%i)", getpid());
    err = snd_seq_set_client_info(handle, &info);
    if (err < 0) {
	fprintf(stderr, "Set client info error: %s\n", snd_strerror(err));
	return -1;
    }

    return 0;

} /* set_seq_name() */
Example #19
0
int send_note(int port, int on, int ch, int note, int vel)
{
	snd_seq_event_t ev;
	snd_seq_ev_clear(&ev);
	ev.dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS;
	ev.source.client = snd_seq_client_id(handle);
	ev.source.port = port;
	snd_seq_ev_set_direct(&ev);

	ev.type = on ? SND_SEQ_EVENT_NOTEON : SND_SEQ_EVENT_NOTEOFF;
	snd_seq_ev_set_fixed(&ev);
	ev.data.note.channel  = ch;
	ev.data.note.note     = note;
	ev.data.note.velocity = vel;

	snd_seq_event_output(handle, &ev);
	snd_seq_drain_output(handle);
	return 1;
}
Example #20
0
SeqContext::SeqContext()
{
	/*
	 * Create the sequencer context. Connected = 3 if all goes well
	 */	 
	connected = verbose = 0;

	handle = (snd_seq_t *)0;

	if (snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
		fprintf(stderr, "Could not open sequencer: %s", snd_strerror(errno));
		return;
		}
	
	connected++;

	if( (queue = snd_seq_alloc_queue(handle)) == 0 ) {
		fprintf(stderr, "Failure to allocate queue\n");
		return;		
	}
	if( (client = snd_seq_client_id(handle)) == 0 ) {
		fprintf(stderr, "Failure to get client address");
		return;		
	}
	
	connected++;

	destlist = new AddressList;
	source.client = client;
	source.port = 0;

	if( seq_new_port('e') < 0 ) {
		fprintf(stderr, "Could not open sequencer port: %s", snd_strerror(errno));
		return;
	}
	
	if( verbose ) {		
		fprintf(stderr, "Opened alsa sequencer for client %d and created queue\n", client );		
	}

	connected++;
}
Example #21
0
int init_alsa(ALSA_SEQ* seq, unsigned char verbose)
{
    if ( verbose) printf("Setting up alsa\n");

    seq->g_seq = open_client();
    if (seq->g_seq == NULL) {
        if ( verbose >= 0) printf("Error: open_client failed.\n");
        return 0;
    }

    int my_client_id = snd_seq_client_id(seq->g_seq);
    seq->g_port = my_new_port(seq->g_seq);
    if ( verbose) printf("client:port = %i:%i\n", my_client_id, seq->g_port);

    program_change(seq->g_seq, seq->g_port, 9, 0);
    int ret = 1;
    notedown_alsa((void*)seq, 9, 57, 55);

    if ( verbose) printf("Returning %i\n", ret);
    return ret;
}
Example #22
0
static PyObject *setup(PyObject *self, PyObject *args)
{
    if (!PyArg_ParseTuple(args, "i", &dest_client_id))
        return NULL;

    // open client
    err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0);
    if (err < 0)
        RAISE("couldnt open sequencer connection\n");

    // get client id
    my_client_id = snd_seq_client_id(seq);

    // create readable port for sending events
    readable_port = snd_seq_create_simple_port(
                                               seq, "my readable port",
                                               SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ,
                                               SND_SEQ_PORT_TYPE_MIDI_GENERIC);

    // create writable port for receiving events
    writable_port = snd_seq_create_simple_port(
                                               seq, "my writable port",
                                               SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
                                               SND_SEQ_PORT_TYPE_MIDI_GENERIC);

    // make subscription for sending events to device
    if (snd_seq_connect_to(seq, readable_port, dest_client_id, 0) < 0)
        RAISE("Unable to subscribe to MIDI port for writing.\n");

    // make subscription for capturing events from midi device
    if (snd_seq_connect_from(seq, writable_port, dest_client_id, 0) < 0)
        RAISE("Unable to subscribe to MIDI port for reading.\n");

    Py_INCREF(Py_None);
    return Py_None;
}
Example #23
0
/* fills the array with our buses */
mastermidibus::mastermidibus()
{
    /* temp return */
    int ret;
    
    /* set initial number buses */
    m_num_out_buses = 0;
    m_num_in_buses = 0;

    for( int i=0; i<c_maxBuses; ++i ){
        m_buses_in_active[i] = false;	
        m_buses_out_active[i] = false;
        m_buses_in_init[i] = false;	
        m_buses_out_init[i] = false;

        m_init_clock[i] = e_clock_off;
        m_init_input[i] = false;
    }
    
    /* open the sequencer client */
    ret = snd_seq_open(&m_alsa_seq, "default",  SND_SEQ_OPEN_DUPLEX, 0);
    
    if ( ret < 0 ){
	printf( "snd_seq_open() error\n");
	exit(1);
    }

    /* set our clients name */
    snd_seq_set_client_name(m_alsa_seq, "seq24");

    /* set up our clients queue */
    m_queue = snd_seq_alloc_queue( m_alsa_seq );

	/* notify lash of our client ID so it can restore connections */
	lash_driver->set_alsa_client_id(snd_seq_client_id(m_alsa_seq));
}
Example #24
0
static void stop_midireceiver(struct Data *data){
  int err; 
  snd_seq_event_t event;

  snd_seq_t *seq2=create_alsa_seq("alsagakkquit",true);

  data->toquit=true;
  snd_seq_connect_to(seq2,0,snd_seq_client_id(data->seq),0);
  snd_seq_ev_clear      (&event);
  snd_seq_ev_set_direct (&event);
  snd_seq_ev_set_subs   (&event);
  snd_seq_ev_set_source (&event, 0);
  snd_seq_ev_set_controller (&event,1,0x80,50);

  err = snd_seq_event_output (seq2, &event);
  if (err < 0){
    fprintf (stderr, "jackvst: %s: error sending midi event: %s\n",
	     __FUNCTION__, snd_strerror (err));
  }
  snd_seq_drain_output (seq2);
  snd_seq_close(seq2);
  pthread_join(data->midithread,NULL);
  snd_seq_close(data->seq);
}
Example #25
0
int
connect_to_alsa (struct a2j* self)
{
	int error;
	void * thread_status;

	self->port_add = jack_ringbuffer_create(2 * MAX_PORTS * sizeof(snd_seq_addr_t));
	if (self->port_add == NULL) {
		goto free_self;
	}

	self->port_del = jack_ringbuffer_create(2 * MAX_PORTS * sizeof(struct a2j_port *));
	if (self->port_del == NULL) {
		goto free_ringbuffer_add;
	}

	if (!a2j_stream_init(self)) {
		goto free_ringbuffer_outbound;
	}

	if ((error = snd_seq_open(&self->seq, "hw", SND_SEQ_OPEN_DUPLEX, 0)) < 0) {
		a2j_error("failed to open alsa seq");
		goto close_stream;
	}

	if ((error = snd_seq_set_client_name(self->seq, "midi_in")) < 0) {
		a2j_error("snd_seq_set_client_name() failed");
		goto close_seq_client;
	}

	if ((self->port_id = snd_seq_create_simple_port(
		self->seq,
		"port",
		SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_WRITE
#ifndef DEBUG
		|SND_SEQ_PORT_CAP_NO_EXPORT
#endif
		,SND_SEQ_PORT_TYPE_APPLICATION)) < 0) {

		a2j_error("snd_seq_create_simple_port() failed");
		goto close_seq_client;
	}

	if ((self->client_id = snd_seq_client_id(self->seq)) < 0) {
		a2j_error("snd_seq_client_id() failed");
		goto close_seq_client;
	}
	
	if ((self->queue = snd_seq_alloc_queue(self->seq)) < 0) {
		a2j_error("snd_seq_alloc_queue() failed");
		goto close_seq_client;
	}

	snd_seq_start_queue (self->seq, self->queue, 0); 

	a2j_stream_attach (&self->stream);

	if ((error = snd_seq_nonblock(self->seq, 1)) < 0) {
		a2j_error("snd_seq_nonblock() failed");
		goto close_seq_client;
	}

	snd_seq_drop_input (self->seq);

	a2j_add_ports(&self->stream);

	if (sem_init(&self->io_semaphore, 0, 0) < 0) {
		a2j_error("can't create IO semaphore");
		goto close_jack_client;
	}

	g_keep_alsa_walking = true;

	if (pthread_create(&self->alsa_io_thread, NULL, alsa_input_thread, self) < 0)
	{
		a2j_error("cannot start ALSA input thread");
		goto sem_destroy;
	}

	/* wake the poll loop in the alsa input thread so initial ports are fetched */
	if ((error = snd_seq_connect_from (self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE)) < 0) {
		a2j_error("snd_seq_connect_from() failed");
		goto join_io_thread;
	}

	return 0;

	g_keep_alsa_walking = false;  /* tell alsa threads to stop */
	snd_seq_disconnect_from(self->seq, self->port_id, SND_SEQ_CLIENT_SYSTEM, SND_SEQ_PORT_SYSTEM_ANNOUNCE);
  join_io_thread:
	pthread_join(self->alsa_io_thread, &thread_status);
  sem_destroy:
	sem_destroy(&self->io_semaphore);
  close_jack_client:
	if ((error = jack_client_close(self->jack_client)) < 0) {
		a2j_error("Cannot close jack client");
	}
  close_seq_client:
	snd_seq_close(self->seq);
  close_stream:
	a2j_stream_close(self);
  free_ringbuffer_outbound:
	jack_ringbuffer_free(self->outbound_events);
	jack_ringbuffer_free(self->port_del);
  free_ringbuffer_add:
	jack_ringbuffer_free(self->port_add);
  free_self:
	free(self);
	return -1;
}
Example #26
0
void
mastermidibus::init( )
{
    
    /* client info */
    snd_seq_client_info_t *cinfo;
    /* port info */
    snd_seq_port_info_t *pinfo;

    int client;

    snd_seq_client_info_alloca(&cinfo);
    snd_seq_client_info_set_client(cinfo, -1);

    //printf( "global_ports %d\n", global_manual_alsa_ports );
    
    if ( global_manual_alsa_ports )
    {

        int num_buses = 16;
        
        for( int i=0; i<num_buses; ++i )
        {

            m_buses_out[i] = 
                new midibus( snd_seq_client_id( m_alsa_seq ), m_alsa_seq, i+1, m_queue );

            m_buses_out[i]->init_out_sub();
            m_buses_out_active[i] = true;		
            m_buses_out_init[i] = true;
        }

        m_num_out_buses = num_buses;

        /* only one in */
        m_buses_in[0] = 
            new midibus( snd_seq_client_id( m_alsa_seq ),
                    m_alsa_seq,
                    m_num_in_buses, m_queue);

        m_buses_in[0]->init_in_sub();
        m_buses_in_active[0] = true;	
        m_buses_in_init[0] = true;
        m_num_in_buses = 1;


    }
    else 
    {
        /* while the next client one the sequencer is avaiable */
        while (snd_seq_query_next_client(m_alsa_seq, cinfo) >= 0){

            /* get client from cinfo */
            client = snd_seq_client_info_get_client(cinfo);

            /* fill pinfo */
            snd_seq_port_info_alloca(&pinfo);
            snd_seq_port_info_set_client(pinfo, client);
            snd_seq_port_info_set_port(pinfo, -1);

            /* while the next port is avail */
            while (snd_seq_query_next_port(m_alsa_seq, pinfo) >= 0 ){

                /* get its capability */
                int cap =  snd_seq_port_info_get_capability(pinfo);

                if ( snd_seq_client_id( m_alsa_seq ) != snd_seq_port_info_get_client(pinfo) &&
                        snd_seq_port_info_get_client(pinfo) != SND_SEQ_CLIENT_SYSTEM){

                    /* the outs */
                    if ( (cap & SND_SEQ_PORT_CAP_SUBS_WRITE) != 0 &&
                            snd_seq_client_id( m_alsa_seq ) != snd_seq_port_info_get_client(pinfo)){

                        m_buses_out[m_num_out_buses] = 
                            new midibus( snd_seq_client_id( m_alsa_seq ),
                                    snd_seq_port_info_get_client(pinfo),
                                    snd_seq_port_info_get_port(pinfo),
                                    m_alsa_seq,
                                    snd_seq_client_info_get_name(cinfo),
                                    snd_seq_port_info_get_name(pinfo),
                                    m_num_out_buses, m_queue );

                        if ( m_buses_out[m_num_out_buses]->init_out() ){
                            m_buses_out_active[m_num_out_buses] = true;		
                            m_buses_out_init[m_num_out_buses] = true;
                        } else {
                            m_buses_out_init[m_num_out_buses] = true;	
                        }

                        m_num_out_buses++;
                    }	

                    /* the ins */
                    if ( (cap & SND_SEQ_PORT_CAP_SUBS_READ) != 0 &&
                            snd_seq_client_id( m_alsa_seq ) != snd_seq_port_info_get_client(pinfo)){

                        m_buses_in[m_num_in_buses] = 
                            new midibus( snd_seq_client_id( m_alsa_seq ),
                                    snd_seq_port_info_get_client(pinfo),
                                    snd_seq_port_info_get_port(pinfo),
                                    m_alsa_seq,
                                    snd_seq_client_info_get_name(cinfo),
                                    snd_seq_port_info_get_name(pinfo),
                                    m_num_in_buses, m_queue);

                        //if ( m_buses_in[m_num_in_buses]->init_in() ){
                        m_buses_in_active[m_num_in_buses] = true;	
                        m_buses_in_init[m_num_in_buses] = true;
                        //} else {
                        //m_buses_in_init[m_num_in_buses] = true;	
                        //}
                        m_num_in_buses++;
                    }	
                }
            }

        } /* end loop for clients */
    }

    set_bpm( c_bpm );
    set_ppqn( c_ppqn );

    /* midi input */
    /* poll descriptors */

    /* get number of file descriptors */
    m_num_poll_descriptors = snd_seq_poll_descriptors_count(m_alsa_seq, POLLIN);

    /* allocate into */
    m_poll_descriptors = new pollfd[m_num_poll_descriptors];

    /* get descriptors */
    snd_seq_poll_descriptors(m_alsa_seq,  
            m_poll_descriptors, 
            m_num_poll_descriptors, 
            POLLIN);

    set_sequence_input( false, NULL );

    /* sizes */
    snd_seq_set_output_buffer_size(m_alsa_seq, c_midibus_output_size ); 
    snd_seq_set_input_buffer_size(m_alsa_seq, c_midibus_input_size ); 


    m_bus_announce = 
        new midibus( snd_seq_client_id( m_alsa_seq ),
                SND_SEQ_CLIENT_SYSTEM,
                SND_SEQ_PORT_SYSTEM_ANNOUNCE,
                m_alsa_seq,
                "system","annouce",
                0, m_queue);

    m_bus_announce->set_input(true);   


    for ( int i=0; i<m_num_out_buses; i++ )
        set_clock(i,m_init_clock[i]);

    for ( int i=0; i<m_num_in_buses; i++ )
        set_input(i,m_init_input[i]);

    
}
Example #27
0
void 
mastermidibus::port_start( int a_client, int a_port )
{
    lock();
    
 
    
    /* client info */
    snd_seq_client_info_t *cinfo;
    snd_seq_client_info_alloca(&cinfo);
    snd_seq_get_any_client_info( m_alsa_seq, a_client, cinfo );  
    
    /* port info */
    snd_seq_port_info_t *pinfo;
    
    /* fill pinfo */
    snd_seq_port_info_alloca(&pinfo);
    snd_seq_get_any_port_info( m_alsa_seq, a_client, a_port, pinfo );  
    
    
    /* get its capability */
    int cap =  snd_seq_port_info_get_capability(pinfo);
    
    if ( snd_seq_client_id( m_alsa_seq ) != snd_seq_port_info_get_client(pinfo)){
        
        /* the outs */
        if ( (cap & (SND_SEQ_PORT_CAP_SUBS_WRITE | SND_SEQ_PORT_CAP_WRITE ))
             == (SND_SEQ_PORT_CAP_SUBS_WRITE | SND_SEQ_PORT_CAP_WRITE )
             && snd_seq_client_id( m_alsa_seq ) != snd_seq_port_info_get_client(pinfo)){


            bool replacement = false;
            int bus_slot = m_num_out_buses;
            
            for( int i=0; i< m_num_out_buses; i++ ){
                
                if( m_buses_out[i]->get_client() == a_client  &&
                    m_buses_out[i]->get_port() == a_port &&
                    m_buses_out_active[i] == false ){
                    
                    replacement = true;
                    bus_slot = i;
                }
            }
            
            m_buses_out[bus_slot] = 
                new midibus( snd_seq_client_id( m_alsa_seq ),
                             snd_seq_port_info_get_client(pinfo),
                             snd_seq_port_info_get_port(pinfo),
                             m_alsa_seq,
                             snd_seq_client_info_get_name(cinfo),
                             snd_seq_port_info_get_name(pinfo),
                             m_num_out_buses, m_queue );
            
            m_buses_out[bus_slot]->init_out();
            m_buses_out_active[bus_slot] = true;
            m_buses_out_init[bus_slot] = true;
            
            if ( !replacement ){
                m_num_out_buses++;
            }
        }	
        
        /* the ins */
        if ( (cap & (SND_SEQ_PORT_CAP_SUBS_READ | SND_SEQ_PORT_CAP_READ ))
             == (SND_SEQ_PORT_CAP_SUBS_READ | SND_SEQ_PORT_CAP_READ )
             && snd_seq_client_id( m_alsa_seq ) != snd_seq_port_info_get_client(pinfo)){
            
            bool replacement = false;
            int bus_slot = m_num_in_buses;

          
            
            for( int i=0; i< m_num_in_buses; i++ ){
                
                if( m_buses_in[i]->get_client() == a_client  &&
                    m_buses_in[i]->get_port() == a_port &&
                    m_buses_in_active[i] == false ){
                    
                    replacement = true;
                    bus_slot = i;
                }
            }

            //printf( "in [%d] [%d]\n", replacement, bus_slot );
            
            m_buses_in[bus_slot] = 
                new midibus( snd_seq_client_id( m_alsa_seq ),
                             snd_seq_port_info_get_client(pinfo),
                             snd_seq_port_info_get_port(pinfo),
                             m_alsa_seq,
                             snd_seq_client_info_get_name(cinfo),
                             snd_seq_port_info_get_name(pinfo),
                             m_num_in_buses, m_queue);
            
            //m_buses_in[bus_slot]->init_in();
            m_buses_in_active[bus_slot] = true;
            m_buses_in_init[bus_slot] = true;

            if ( !replacement ){            
                m_num_in_buses++;
            }
        }	
    }
    
    /* end loop for clients */
    
    
    /* midi input */
    /* poll descriptors */

    /* get number of file descriptors */
    m_num_poll_descriptors = snd_seq_poll_descriptors_count(m_alsa_seq, POLLIN);

    /* allocate into */
    m_poll_descriptors = new pollfd[m_num_poll_descriptors];
    
    /* get descriptors */
    snd_seq_poll_descriptors(m_alsa_seq,  
			     m_poll_descriptors, 
			     m_num_poll_descriptors, 
			     POLLIN);
    
    unlock();
}
Example #28
0
int MidiDriver_ALSA::open() {
	if (_isOpen)
		return MERR_ALREADY_OPEN;
	_isOpen = true;

	if (my_snd_seq_open(&seq_handle) < 0) {
		error("Can't open sequencer");
		return -1;
	}

	my_client = snd_seq_client_id(seq_handle);
	if (snd_seq_set_client_name(seq_handle, "RESIDUALVM") < 0) {
		error("Can't set sequencer client name");
	}
	snd_seq_set_client_group(seq_handle, "input");

	// According to http://www.alsa-project.org/~tiwai/alsa-subs.html
	// you can set read or write capabilities to allow other clients to
	// read or write the port. I don't think we need that, unless maybe
	// to be able to record the sound, but I can't get that to work even
	// with those capabilities.

	my_port = snd_seq_create_simple_port(seq_handle, "RESIDUALVM port 0", 0,
	                                     SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION);

	if (my_port < 0) {
		snd_seq_close(seq_handle);
		error("Can't create port");
		return -1;
	}

	if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) {
		// Subscribe to MIDI port. Prefer one that doesn't already have
		// any connections, unless we've forced a port number already.
		if (seq_port == -1) {
			snd_seq_client_info_t *cinfo;
			snd_seq_port_info_t *pinfo;

			snd_seq_client_info_alloca(&cinfo);
			snd_seq_port_info_alloca(&pinfo);

			snd_seq_get_any_client_info(seq_handle, seq_client, cinfo);

			int first_port = -1;
			int found_port = -1;

			snd_seq_port_info_set_client(pinfo, seq_client);
			snd_seq_port_info_set_port(pinfo, -1);
			while (found_port == -1 && snd_seq_query_next_port(seq_handle, pinfo) >= 0) {
				if (check_permission(pinfo)) {
					if (first_port == -1)
						first_port = snd_seq_port_info_get_port(pinfo);
					if (found_port == -1 && snd_seq_port_info_get_write_use(pinfo) == 0)
						found_port = snd_seq_port_info_get_port(pinfo);
				}
			}

			if (found_port == -1) {
				// Should we abort here? For now, use the first
				// available port.
				seq_port = first_port;
				warning("MidiDriver_ALSA: All ports on client %d (%s) are already in use", seq_client, snd_seq_client_info_get_name(cinfo));
			} else {
				seq_port = found_port;
			}
		}

		if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) {
			error("Can't subscribe to MIDI port (%d:%d) see README for help", seq_client, seq_port);
		}
	}

	printf("Connected to Alsa sequencer client [%d:%d]\n", seq_client, seq_port);
	printf("ALSA client initialized [%d:0]\n", my_client);

	return 0;
}
mastermidibus::mastermidibus (int ppqn, int bpm)
 :
    m_alsa_seq          (nullptr),  // one pointer
    m_max_busses        (c_max_busses),
    m_num_out_buses     (0),        // or c_max_busses, or what?
    m_num_in_buses      (0),        // or c_max_busses, or 1, or what?
    m_buses_out         (),         // array of c_max_busses midibus pointers
    m_buses_in          (),         // array of c_max_busses midibus pointers
    m_bus_announce      (nullptr),  // one pointer
    m_buses_out_active  (),         // array of c_max_busses booleans
    m_buses_in_active   (),         // array of c_max_busses booleans
    m_buses_out_init    (),         // array of c_max_busses booleans
    m_buses_in_init     (),         // array of c_max_busses booleans
    m_init_clock        (),         // array of c_max_busses clock_e values
    m_init_input        (),         // array of c_max_busses booleans
    m_queue             (0),
    m_ppqn              (0),
    m_beats_per_minute  (bpm),      // beats per minute
    m_num_poll_descriptors (0),
    m_poll_descriptors  (nullptr),
    m_dumping_input     (false),
    m_vector_sequence   (),
    m_filter_by_channel (false),    // set below based on configuration
    m_seq               (nullptr),
    m_mutex             ()
{
    m_ppqn = choose_ppqn(ppqn);
    for (int i = 0; i < m_max_busses; ++i)
    {
        m_buses_in_active[i] =
            m_buses_out_active[i] =
            m_buses_in_init[i] =
            m_buses_out_init[i] =
            m_init_input[i] = false;

        m_init_clock[i] = e_clock_off;
    }

#ifdef SEQ64_HAVE_LIBASOUND

    /*
     * Open the sequencer client.  This line of code results in a loss of
     * 4 bytes somewhere in snd_seq_open(), as discovered via valgrind.
     */

    int result = snd_seq_open(&m_alsa_seq, "default",  SND_SEQ_OPEN_DUPLEX, 0);
    if (result < 0)
    {
        errprint("snd_seq_open() error");
        exit(1);
    }
    else
    {
        /*
         * Tried to reduce apparent memory leaks from libasound, but this call
         * changed nothing.
         *
         * (void) snd_config_update_free_global();
         */
    }

    /*
     * Set the client's name for ALSA.  It used to be "seq24".  Then set up our
     * ALSA client's queue.
     */

    snd_seq_set_client_name(m_alsa_seq, "sequencer64");
    m_queue = snd_seq_alloc_queue(m_alsa_seq);

#endif      // SEQ64_HAVE_LIBASOUND

#ifdef SEQ64_LASH_SUPPORT

    /*
     * Notify LASH of our client ID so that it can restore connections.
     */

    if (not_nullptr(lash_driver()))
        lash_driver()->set_alsa_client_id(snd_seq_client_id(m_alsa_seq));

#endif
}
void
mastermidibus::port_start (int client, int port)
{
#ifdef SEQ64_HAVE_LIBASOUND
    automutex locker(m_mutex);
    snd_seq_client_info_t * cinfo;                      /* client info        */
    snd_seq_client_info_alloca(&cinfo);
    snd_seq_get_any_client_info(m_alsa_seq, client, cinfo);
    snd_seq_port_info_t * pinfo;                        /* port info          */
    snd_seq_port_info_alloca(&pinfo);
    snd_seq_get_any_port_info(m_alsa_seq, client, port, pinfo);

    int cap = snd_seq_port_info_get_capability(pinfo);  /* get its capability */
    if (ALSA_CLIENT_CHECK(pinfo))
    {
        if (CAP_FULL_WRITE(cap) && ALSA_CLIENT_CHECK(pinfo)) /* outputs */
        {
            bool replacement = false;
            int bus_slot = m_num_out_buses;
            for (int i = 0; i < m_num_out_buses; ++i)
            {
                if
                (
                    m_buses_out[i]->get_client() == client  &&
                    m_buses_out[i]->get_port() == port &&
                    ! m_buses_out_active[i]
                )
                {
                    replacement = true;
                    bus_slot = i;
                }
            }
            if (not_nullptr(m_buses_out[bus_slot]))
            {
                delete m_buses_out[bus_slot];
                errprintf
                (
                    "mastermidibus::port_start(): m_buses_out[%d] not null\n",
                    bus_slot
                );
            }
            m_buses_out[bus_slot] = new midibus
            (
                snd_seq_client_id(m_alsa_seq),
                snd_seq_port_info_get_client(pinfo),
                snd_seq_port_info_get_port(pinfo),
                m_alsa_seq,
                snd_seq_client_info_get_name(cinfo),
                snd_seq_port_info_get_name(pinfo),
                m_num_out_buses,
                m_queue
            );
            m_buses_out[bus_slot]->init_out();
            m_buses_out_active[bus_slot] = true;
            m_buses_out_init[bus_slot] = true;
            if (! replacement)
                ++m_num_out_buses;
        }
        if (CAP_FULL_READ(cap) && ALSA_CLIENT_CHECK(pinfo)) /* inputs */
        {
            bool replacement = false;
            int bus_slot = m_num_in_buses;
            for (int i = 0; i < m_num_in_buses; ++i)
            {
                if
                (
                    m_buses_in[i]->get_client() == client  &&
                    m_buses_in[i]->get_port() == port && ! m_buses_in_active[i]
                )
                {
                    replacement = true;
                    bus_slot = i;
                }
            }
            if (not_nullptr(m_buses_in[bus_slot]))
            {
                delete m_buses_in[bus_slot];
                errprintf
                (
                    "mmbus::port_start(): m_buses_in[%d] not null\n", bus_slot
                );
            }
            m_buses_in[bus_slot] = new midibus
            (
                snd_seq_client_id(m_alsa_seq),
                snd_seq_port_info_get_client(pinfo),
                snd_seq_port_info_get_port(pinfo),
                m_alsa_seq,
                snd_seq_client_info_get_name(cinfo),
                snd_seq_port_info_get_name(pinfo),
                m_num_in_buses,
                m_queue
            );
            m_buses_in_active[bus_slot] = true;
            m_buses_in_init[bus_slot] = true;
            if (! replacement)
                m_num_in_buses++;
        }
    }                                           /* end loop for clients */

    /*
     * Get the number of MIDI input poll file descriptors.
     */

    m_num_poll_descriptors = snd_seq_poll_descriptors_count(m_alsa_seq, POLLIN);
    m_poll_descriptors = new pollfd[m_num_poll_descriptors]; /* allocate info */
    snd_seq_poll_descriptors                        /* get input descriptors */
    (
        m_alsa_seq, m_poll_descriptors, m_num_poll_descriptors, POLLIN
    );
#endif  // SEQ64_HAVE_LIBASOUND
}