/*
 * remove all (exported) connections
 */
static void remove_connection(snd_seq_t *seq, snd_seq_client_info_t *cinfo,
			      snd_seq_port_info_t *pinfo, int count)
{
	snd_seq_query_subscribe_t *query;

	snd_seq_query_subscribe_alloca(&query);
	snd_seq_query_subscribe_set_root(query, snd_seq_port_info_get_addr(pinfo));

	snd_seq_query_subscribe_set_type(query, SND_SEQ_QUERY_SUBS_READ);
	snd_seq_query_subscribe_set_index(query, 0);
	for (; snd_seq_query_port_subscribers(seq, query) >= 0;
	     snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1)) {
		snd_seq_port_info_t *port;
		snd_seq_port_subscribe_t *subs;
		const snd_seq_addr_t *sender = snd_seq_query_subscribe_get_root(query);
		const snd_seq_addr_t *dest = snd_seq_query_subscribe_get_addr(query);
		snd_seq_port_info_alloca(&port);
		if (snd_seq_get_any_port_info(seq, dest->client, dest->port, port) < 0)
			continue;
		if (!(snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_SUBS_WRITE))
			continue;
		if (snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_NO_EXPORT)
			continue;
		snd_seq_port_subscribe_alloca(&subs);
		snd_seq_port_subscribe_set_queue(subs, snd_seq_query_subscribe_get_queue(query));
		snd_seq_port_subscribe_set_sender(subs, sender);
		snd_seq_port_subscribe_set_dest(subs, dest);
		snd_seq_unsubscribe_port(seq, subs);
	}

	snd_seq_query_subscribe_set_type(query, SND_SEQ_QUERY_SUBS_WRITE);
	snd_seq_query_subscribe_set_index(query, 0);
	for (; snd_seq_query_port_subscribers(seq, query) >= 0;
	     snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1)) {
		snd_seq_port_info_t *port;
		snd_seq_port_subscribe_t *subs;
		const snd_seq_addr_t *dest = snd_seq_query_subscribe_get_root(query);
		const snd_seq_addr_t *sender = snd_seq_query_subscribe_get_addr(query);
		snd_seq_port_info_alloca(&port);
		if (snd_seq_get_any_port_info(seq, sender->client, sender->port, port) < 0)
			continue;
		if (!(snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_SUBS_READ))
			continue;
		if (snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_NO_EXPORT)
			continue;
		snd_seq_port_subscribe_alloca(&subs);
		snd_seq_port_subscribe_set_queue(subs, snd_seq_query_subscribe_get_queue(query));
		snd_seq_port_subscribe_set_sender(subs, sender);
		snd_seq_port_subscribe_set_dest(subs, dest);
		snd_seq_unsubscribe_port(seq, subs);
	}
}
Exemplo n.º 2
0
void DeviceManager::scanDevices()
{
    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_client_info_set_client(cinfo, -1);
    while (snd_seq_query_next_client(handle, cinfo) >= 0) {
        int client = snd_seq_client_info_get_client(cinfo);

        snd_seq_port_info_set_client(pinfo, client);
        snd_seq_port_info_set_port(pinfo, -1);

        while (snd_seq_query_next_port(handle, pinfo) >= 0) {
            Device *d = new Device(cinfo, pinfo);
            if(d->isValid()){
                snd_seq_connect_from(handle, 0, d->clientId, d->portId);
                list.push_back(d);
            }else{
                delete d;
            }
        }
    }

    D("Device list contain %d elements.", (int) list.size());

}
Exemplo n.º 3
0
AlsaDevices AlsaMusicPlugin::getAlsaDevices() const {
	AlsaDevices devices;
	snd_seq_t *seq_handle;
	if (my_snd_seq_open(&seq_handle) < 0)
		return devices; // can't open sequencer

	snd_seq_client_info_t *cinfo;
	snd_seq_client_info_alloca(&cinfo);
	snd_seq_port_info_t *pinfo;
	snd_seq_port_info_alloca(&pinfo);
	snd_seq_client_info_set_client(cinfo, -1);
	while (snd_seq_query_next_client(seq_handle, cinfo) >= 0) {
		bool found_valid_port = false;

		/* reset query info */
		snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
		snd_seq_port_info_set_port(pinfo, -1);
		while (!found_valid_port && snd_seq_query_next_port(seq_handle, pinfo) >= 0) {
			if (check_permission(pinfo)) {
				found_valid_port = true;

				const char *name = snd_seq_client_info_get_name(cinfo);
				// TODO: Can we figure out the appropriate music type?
				MusicType type = MT_GM;
				int client = snd_seq_client_info_get_client(cinfo);
				devices.push_back(AlsaDevice(name, type, client));
			}
		}
	}
	snd_seq_close(seq_handle);

	return devices;
}
Exemplo n.º 4
0
QMap<QString,QString> QMidi::outDeviceNames()
{
    QMap<QString,QString> ret;

#if defined(Q_OS_WIN)
    int numDevs = midiOutGetNumDevs();
    if(numDevs == 0) { return ret; }

    for(int i = 0;i<numDevs;i++) {
        MIDIOUTCAPS* devCaps = new MIDIOUTCAPS;
        midiOutGetDevCaps(i,devCaps,sizeof(*devCaps));
        ret.insert(QString::number(i),QString::fromWCharArray(devCaps->szPname));
        delete devCaps;
    }
#elif defined(Q_OS_LINUX)
    snd_seq_client_info_t *cinfo;
    snd_seq_port_info_t *pinfo;
    int client;
    int err;
    snd_seq_t *handle;

    err = snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0);
    if(err < 0)
    { /* Could not open sequencer!! use  snd_strerror(errno)  to get error. */ return ret; }

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

    while(snd_seq_query_next_client(handle, cinfo) >= 0) {
        client = snd_seq_client_info_get_client(cinfo);
        snd_seq_port_info_alloca(&pinfo);
        snd_seq_port_info_set_client(pinfo, client);

        snd_seq_port_info_set_port(pinfo, -1);
        while(snd_seq_query_next_port(handle, pinfo) >= 0) {
            int cap = (SND_SEQ_PORT_CAP_SUBS_WRITE|SND_SEQ_PORT_CAP_WRITE);
            if((snd_seq_port_info_get_capability(pinfo) & cap) == cap) {
                QString port = QString::number(snd_seq_port_info_get_client(pinfo));
                port += ":" + QString::number(snd_seq_port_info_get_port(pinfo));
                QString name = snd_seq_client_info_get_name(cinfo);
                ret.insert(port,name);
            }
        }
    }
#elif defined(Q_OS_HAIKU)
	bool OK = true;
	int32 id = 0;
	while(OK) {
		BMidiConsumer* c = BMidiRoster::NextConsumer(&id);
		if(c != NULL) {
			ret.insert(QString::number(id),QString::fromUtf8(c->Name()));
			c->Release();
		} else {
			OK = false;
		}
	}
#endif

    return ret;
}
static void list_ports(void)
{
	snd_seq_client_info_t *cinfo;
	snd_seq_port_info_t *pinfo;

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

	puts(" Port    Client name                      Port name");

	snd_seq_client_info_set_client(cinfo, -1);
	while (snd_seq_query_next_client(seq, cinfo) >= 0) {
		int client = snd_seq_client_info_get_client(cinfo);

		snd_seq_port_info_set_client(pinfo, client);
		snd_seq_port_info_set_port(pinfo, -1);
		while (snd_seq_query_next_port(seq, pinfo) >= 0) {
			/* we need both READ and SUBS_READ */
			if ((snd_seq_port_info_get_capability(pinfo)
			     & (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ))
			    != (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ))
				continue;
			printf("%3d:%-3d  %-32.32s %s\n",
			       snd_seq_port_info_get_client(pinfo),
			       snd_seq_port_info_get_port(pinfo),
			       snd_seq_client_info_get_name(cinfo),
			       snd_seq_port_info_get_name(pinfo));
		}
	}
}
Exemplo n.º 6
0
void JVlibForm::connect_port() {
    if (seq && strlen(SEQ_dev)) {
        //  create_source_port
        snd_seq_port_info_t *pinfo;
        snd_seq_port_info_alloca(&pinfo);
        // the first created port is 0 anyway, but let's make sure ...
        snd_seq_port_info_set_port(pinfo, 0);
        snd_seq_port_info_set_port_specified(pinfo, 1);
        snd_seq_port_info_set_name(pinfo, "midi_player");
        snd_seq_port_info_set_capability(pinfo, 0);
        snd_seq_port_info_set_type(pinfo,
               SND_SEQ_PORT_TYPE_MIDI_GENERIC |
               SND_SEQ_PORT_TYPE_APPLICATION);
        int err = snd_seq_create_port(seq, pinfo);
        check_snd("create port", err);
	
        ports = (snd_seq_addr_t *)realloc(ports, sizeof(snd_seq_addr_t));
        err = snd_seq_parse_address(seq, &ports[0], SEQ_dev);
        if (err < 0) {
            QMessageBox::critical(this, "MIDI Player", QString("Invalid port%1\n%2") .arg(SEQ_dev) .arg(snd_strerror(err)));
            return;
        }
        err = snd_seq_connect_to(seq, 0, ports[0].client, ports[0].port);
        if (err < 0 && err!= -16)
            QMessageBox::critical(this, "MIDI Player", QString("%4 Cannot connect to port %1:%2 - %3") .arg(ports[0].client) .arg(ports[0].port) .arg(strerror(errno)) .arg(err));
    }
}   // end connect_port
Exemplo n.º 7
0
size_t Alsa::getPortCount()
{
    snd_seq_port_info_t *pinfo;
    snd_seq_port_info_alloca( &pinfo );

    return portInfo(_apiData->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, -1 );
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
/**************************************************************************
 * ALSA_MidiInit				[internal]
 *
 * Initializes the MIDI devices information variables
 */
LONG ALSA_MidiInit(void)
{
#ifdef HAVE_ALSA
    static	BOOL	bInitDone = FALSE;
    snd_seq_client_info_t *cinfo;
    snd_seq_port_info_t *pinfo;

    if (bInitDone)
	return TRUE;

    TRACE("Initializing the MIDI variables.\n");
    bInitDone = TRUE;

    /* try to open device */
    if (midiOpenSeq(0) == -1) {
	return TRUE;
    }

#if 0 /* Debug purpose */
    snd_lib_error_set_handler(error_handler);
#endif
    
    snd_seq_client_info_alloca(&cinfo);
    snd_seq_port_info_alloca(&pinfo);

    /* First, search for all internal midi devices */
    snd_seq_client_info_set_client(cinfo, -1);
    while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) {
        snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
	snd_seq_port_info_set_port(pinfo, -1);
	while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {
            int cap = snd_seq_port_info_get_capability(pinfo);
	    int type = snd_seq_port_info_get_type(pinfo);
	    if (type != SND_SEQ_PORT_TYPE_MIDI_GENERIC)
	        ALSA_AddMidiPort(cinfo, pinfo, cap, type);
	}
    }

    /* Second, search for all external ports */
    snd_seq_client_info_set_client(cinfo, -1);
    while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) {
        snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
	snd_seq_port_info_set_port(pinfo, -1);
	while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {
            int cap = snd_seq_port_info_get_capability(pinfo);
	    int type = snd_seq_port_info_get_type(pinfo);
	    if (type == SND_SEQ_PORT_TYPE_MIDI_GENERIC)
	        ALSA_AddMidiPort(cinfo, pinfo, cap, type);
	}
    }

    /* close file and exit */
    midiCloseSeq();

    TRACE("End\n");
#endif
    return TRUE;
}
Exemplo n.º 10
0
void* alsa_input_thread(void * arg)
{
	struct a2j * self = arg;
	int npfd;
	struct pollfd * pfd;
	snd_seq_addr_t addr;
	snd_seq_client_info_t * client_info;
	snd_seq_port_info_t * port_info;
	bool initial;
	snd_seq_event_t * event;
	int ret;

	npfd = snd_seq_poll_descriptors_count(self->seq, POLLIN);
	pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd));
	snd_seq_poll_descriptors(self->seq, pfd, npfd, POLLIN);

	initial = true;
	while (g_keep_alsa_walking) {
		if ((ret = poll(pfd, npfd, 1000)) > 0) {

			while (snd_seq_event_input (self->seq, &event) > 0) {
				if (initial) {
					snd_seq_client_info_alloca(&client_info);
					snd_seq_port_info_alloca(&port_info);
					snd_seq_client_info_set_client(client_info, -1);
					while (snd_seq_query_next_client(self->seq, client_info) >= 0) {
						addr.client = snd_seq_client_info_get_client(client_info);
						if (addr.client == SND_SEQ_CLIENT_SYSTEM || addr.client == self->client_id) {
							continue;
						}
						snd_seq_port_info_set_client(port_info, addr.client);
						snd_seq_port_info_set_port(port_info, -1);
						while (snd_seq_query_next_port(self->seq, port_info) >= 0) {
							addr.port = snd_seq_port_info_get_port(port_info);
							a2j_update_port(self, addr, port_info);
						}
					}

					initial = false;
				}

				if (event->source.client == SND_SEQ_CLIENT_SYSTEM) {
					a2j_port_event(self, event);
				} else {
					a2j_input_event(self, event);
				}

				snd_seq_free_event (event);
			}
		}
	}

	return (void*) 0;
}
Exemplo n.º 11
0
void MIDIDevice::extractName()
{
    MIDIInput* plugin = static_cast<MIDIInput*> (parent());
    if (plugin == NULL || plugin->alsa() == NULL || m_address == NULL)
        return;

    snd_seq_port_info_t* portInfo = NULL;
    snd_seq_port_info_alloca(&portInfo);
    int r = snd_seq_get_any_port_info(plugin->alsa(), m_address->client,
                                      m_address->port, portInfo);
    if (r == 0)
        m_name = QString(snd_seq_port_info_get_name(portInfo));
    else
        m_name = QString("ERROR");
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
QStringList qxgeditMidiDevice::deviceList ( bool bReadable ) const
{
	QStringList list;

	if (m_pAlsaSeq == NULL)
		return list;

	unsigned int uiPortFlags;
	if (bReadable)
		uiPortFlags = SND_SEQ_PORT_CAP_READ  | SND_SEQ_PORT_CAP_SUBS_READ;
	else
		uiPortFlags = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;

	snd_seq_client_info_t *pClientInfo;
	snd_seq_port_info_t   *pPortInfo;

	snd_seq_client_info_alloca(&pClientInfo);
	snd_seq_port_info_alloca(&pPortInfo);
	snd_seq_client_info_set_client(pClientInfo, -1);

	while (snd_seq_query_next_client(m_pAlsaSeq, pClientInfo) >= 0) {
		int iAlsaClient = snd_seq_client_info_get_client(pClientInfo);
		if (iAlsaClient > 0 && iAlsaClient != m_iAlsaClient) {
			snd_seq_port_info_set_client(pPortInfo, iAlsaClient);
			snd_seq_port_info_set_port(pPortInfo, -1);
			while (snd_seq_query_next_port(m_pAlsaSeq, pPortInfo) >= 0) {
				unsigned int uiPortCapability
					= snd_seq_port_info_get_capability(pPortInfo);
				if (((uiPortCapability & uiPortFlags) == uiPortFlags) &&
					((uiPortCapability & SND_SEQ_PORT_CAP_NO_EXPORT) == 0)) {
					int iAlsaPort = snd_seq_port_info_get_port(pPortInfo);
					QString sItem = QString::number(iAlsaClient) + ':';
					sItem += snd_seq_client_info_get_name(pClientInfo);
					sItem += c_pszItemSep;
					sItem += QString::number(iAlsaPort) + ':';
					sItem += snd_seq_port_info_get_name(pPortInfo);
					list.append(sItem);
				}
			}
		}
	}

	return list;
}
Exemplo n.º 14
0
void MIDIDevice::extractName()
{
    snd_seq_port_info_t* portInfo = NULL;
    MIDIOut* plugin;
    int r;

    plugin = static_cast<MIDIOut*> (parent());
    Q_ASSERT(plugin != NULL);
    Q_ASSERT(plugin->alsa() != NULL);
    Q_ASSERT(m_address != NULL);

    snd_seq_port_info_alloca(&portInfo);
    r = snd_seq_get_any_port_info(plugin->alsa(), m_address->client,
                                  m_address->port, portInfo);
    if (r == 0)
        m_name = QString(snd_seq_port_info_get_name(portInfo));
    else
        m_name = tr("Unknown");
}
Exemplo n.º 15
0
std::string Alsa::getPortName(unsigned int portNumber_ )
{
    snd_seq_client_info_t *cinfo;
    snd_seq_port_info_t *pinfo;
    snd_seq_client_info_alloca( &cinfo );
    snd_seq_port_info_alloca( &pinfo );

    std::string stringName;
    if ( portInfo( _apiData->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber_ ) ) {
        int cnum = snd_seq_port_info_get_client(pinfo);
        snd_seq_get_any_client_info( _apiData->seq, cnum, cinfo );
        std::ostringstream os;
        os << snd_seq_client_info_get_name(cinfo);
        os << ":";
        os << snd_seq_port_info_get_port(pinfo);
        stringName = os.str();
        return stringName;
    }

    std::cerr << "error: CxxMidi::Output::Alsa::getPortName: error looking for port name" << std::endl;
    return stringName;
}
Exemplo n.º 16
0
static void do_search_port(snd_seq_t *seq, int perm, action_func_t do_action)
{
	snd_seq_client_info_t *cinfo;
	snd_seq_port_info_t *pinfo;
	int count;

	snd_seq_client_info_alloca(&cinfo);
	snd_seq_port_info_alloca(&pinfo);
	snd_seq_client_info_set_client(cinfo, -1);
	while (snd_seq_query_next_client(seq, cinfo) >= 0) {
		/* reset query info */
		snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
		snd_seq_port_info_set_port(pinfo, -1);
		count = 0;
		while (snd_seq_query_next_port(seq, pinfo) >= 0) {
			if (check_permission(pinfo, perm)) {
				do_action(seq, cinfo, pinfo, count);
				count++;
			}
		}
	}
}
Exemplo n.º 17
0
    std::vector<String> MidiInputDeviceAlsa::MidiInputPortAlsa::ParameterAlsaSeqBindings::PossibilitiesAsString() {
        std::vector<String> res;
        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_client_info_set_client(cinfo, -1);
        while (snd_seq_query_next_client(pPort->pDevice->hAlsaSeq, cinfo) >= 0) {
            snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
            snd_seq_port_info_set_port(pinfo, -1);
            while (snd_seq_query_next_port(pPort->pDevice->hAlsaSeq, pinfo) >= 0) {
                if (perm_ok(pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ)) {
                        String seq_id = ToString(snd_seq_client_info_get_client(cinfo)) + ":" +
                                        ToString(snd_seq_port_info_get_port(pinfo));
                        res.push_back(seq_id);
                }
            }
        }

        return res;
    }
Exemplo n.º 18
0
static
void update_ports(alsa_seqmidi_t *self)
{
	snd_seq_addr_t addr;
	snd_seq_port_info_t *info;
	int size;

	snd_seq_port_info_alloca(&info);

	while ((size = jack_ringbuffer_read(self->port_add, (char*)&addr, sizeof(addr)))) {

		int err;

		assert (size == sizeof(addr));
		assert (addr.client != self->client_id);
		if ((err=snd_seq_get_any_port_info(self->seq, addr.client, addr.port, info))>=0) {
			update_port(self, addr, info);
		} else {
			//port_setdead(self->stream[PORT_INPUT].ports, addr);
			//port_setdead(self->stream[PORT_OUTPUT].ports, addr);
		}
	}
}
Exemplo n.º 19
0
/*
  discover the sequencer devices currently available
*/
static int alsa_sequencer_list(ClientData clientData, Tcl_Interp *interp) {
  snd_seq_client_info_t *cinfo;
  snd_seq_port_info_t *pinfo;
  Tcl_Obj *result = Tcl_NewListObj(0, NULL);
  if (init_seq(clientData, interp) != TCL_OK) {
    return TCL_ERROR;
  }
  snd_seq_client_info_alloca(&cinfo);
  snd_seq_port_info_alloca(&pinfo);

  snd_seq_client_info_set_client(cinfo, -1);
  while (snd_seq_query_next_client(seq, cinfo) >= 0) {
    int client = snd_seq_client_info_get_client(cinfo);
    snd_seq_port_info_set_client(pinfo, client);
    snd_seq_port_info_set_port(pinfo, -1);
    while (snd_seq_query_next_port(seq, pinfo) >= 0) {
      /* we need both READ and SUBS_READ */
      int capability = snd_seq_port_info_get_capability(pinfo);
      char *readable = ((capability &
			 (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ)) ==
			(SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ)) ? "r" : "";
      char *writable = ((capability &
			 (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)) ==
			(SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)) ? "w" : "";
      Tcl_Obj *element = Tcl_ObjPrintf("%3d:%-3d  %-32.32s %s %s%s",
				       snd_seq_port_info_get_client(pinfo),
				       snd_seq_port_info_get_port(pinfo),
				       snd_seq_client_info_get_name(cinfo),
				       snd_seq_port_info_get_name(pinfo),
				       readable, writable);
      Tcl_ListObjAppendElement(interp, result, element);
    }
  }
  Tcl_SetObjResult(interp, result);
  return TCL_OK;
}
Exemplo n.º 20
0
static
void add_existing_ports(alsa_seqmidi_t *self)
{
	snd_seq_addr_t addr;
	snd_seq_client_info_t *client_info;
	snd_seq_port_info_t *port_info;

	snd_seq_client_info_alloca(&client_info);
	snd_seq_port_info_alloca(&port_info);
	snd_seq_client_info_set_client(client_info, -1);
	while (snd_seq_query_next_client(self->seq, client_info) >= 0)
	{
		addr.client = snd_seq_client_info_get_client(client_info);
		if (addr.client == SND_SEQ_CLIENT_SYSTEM || addr.client == self->client_id)
			continue;
		snd_seq_port_info_set_client(port_info, addr.client);
		snd_seq_port_info_set_port(port_info, -1);
		while (snd_seq_query_next_port(self->seq, port_info) >= 0)
		{
			addr.port = snd_seq_port_info_get_port(port_info);
			update_port(self, addr, port_info);
		}
	}
}
Exemplo n.º 21
0
void MIDIOut::rescanDevices()
{
	snd_seq_client_info_t* clientInfo = NULL;
	snd_seq_port_info_t* portInfo = NULL;

	/* Don't do anything if the ALSA sequencer interface is not open */
	if (m_alsa == NULL)
		return;

	/* Copy all device pointers to a destroy list */
	QList <MIDIDevice*> destroyList(m_devices);

	/* Allocate these from stack */
	snd_seq_client_info_alloca(&clientInfo);
	snd_seq_port_info_alloca(&portInfo);

	/* Find out what kinds of clients and ports there are */
	snd_seq_client_info_set_client(clientInfo, 0); // TODO: -1 ?????
	while (snd_seq_query_next_client(m_alsa, clientInfo) == 0)
	{
		int client;

		/* Get the client ID */
		client = snd_seq_client_info_get_client(clientInfo);

		/* Ignore our own client */
		if (m_address->client == client)
			continue;

		/* Go thru all available ports in the client */
		snd_seq_port_info_set_client(portInfo, client);
		snd_seq_port_info_set_port(portInfo, -1);
		while (snd_seq_query_next_port(m_alsa, portInfo) == 0)
		{
			const snd_seq_addr_t* address;
			MIDIDevice* dev;

			address = snd_seq_port_info_get_addr(portInfo);
			if (address == NULL)
				continue;

			dev = device(address);
			if (dev == NULL)
			{
				/* New address. Create a new device for it. */
				dev = new MIDIDevice(this, address);
				Q_ASSERT(dev != NULL);

				/* Don't show QLC's internal ALSA ports */
				if (dev->name().contains("__QLC__") == false)
					addDevice(dev);
				else
					delete dev;
			}
			else
			{
				/* This device is still alive. Do not destroy
				   it at the end of this function. */
				destroyList.removeAll(dev);
			}
		}
	}

	/* All devices that were not found during rescan are clearly no longer
	   in our presence and must be destroyed. */
	while (destroyList.isEmpty() == false)
		removeDevice(destroyList.takeFirst());
}
Exemplo n.º 22
0
// Client:port refreshner.
int qjackctlAlsaClientList::updateClientPorts (void)
{
	qjackctlMainForm *pMainForm = qjackctlMainForm::getInstance();
	if (pMainForm == NULL)
		return 0;

	snd_seq_t *pAlsaSeq = pMainForm->alsaSeq();
	if (pAlsaSeq == NULL)
		return 0;

	int iDirtyCount = 0;

	markClientPorts(0);

#ifdef CONFIG_ALSA_SEQ

	unsigned int uiAlsaFlags;
	if (isReadable())
		uiAlsaFlags = SND_SEQ_PORT_CAP_READ  | SND_SEQ_PORT_CAP_SUBS_READ;
	else
		uiAlsaFlags = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;

	snd_seq_client_info_t *pClientInfo;
	snd_seq_port_info_t   *pPortInfo;

	snd_seq_client_info_alloca(&pClientInfo);
	snd_seq_port_info_alloca(&pPortInfo);
	snd_seq_client_info_set_client(pClientInfo, -1);

	while (snd_seq_query_next_client(pAlsaSeq, pClientInfo) >= 0) {

		int iAlsaClient = snd_seq_client_info_get_client(pClientInfo);
		if (iAlsaClient > 0) {
			qjackctlAlsaClient *pClient = findClient(iAlsaClient);
			snd_seq_port_info_set_client(pPortInfo, iAlsaClient);
			snd_seq_port_info_set_port(pPortInfo, -1);
			while (snd_seq_query_next_port(pAlsaSeq, pPortInfo) >= 0) {
				unsigned int uiPortCapability
					= snd_seq_port_info_get_capability(pPortInfo);
				if (((uiPortCapability & uiAlsaFlags) == uiAlsaFlags) &&
					((uiPortCapability & SND_SEQ_PORT_CAP_NO_EXPORT) == 0)) {
					QString sClientName = QString::number(iAlsaClient) + ':';
					sClientName += QString::fromUtf8(
						snd_seq_client_info_get_name(pClientInfo));
					qjackctlAlsaPort *pPort = 0;
					int iAlsaPort = snd_seq_port_info_get_port(pPortInfo);
					if (pClient == 0) {
						pClient = new qjackctlAlsaClient(this,
							sClientName, iAlsaClient);
						iDirtyCount++;
					} else {
						pPort = pClient->findPort(iAlsaPort);
						if (sClientName != pClient->clientName()) {
							pClient->setClientName(sClientName);
							iDirtyCount++;
						}
					}
					if (pClient) {
						QString sPortName = QString::number(iAlsaPort) + ':';
						sPortName += QString::fromUtf8(
							snd_seq_port_info_get_name(pPortInfo));
						if (pPort == 0) {
							pPort = new qjackctlAlsaPort(pClient,
								sPortName, iAlsaPort);
							iDirtyCount++;
						} else if (sPortName != pPort->portName()) {
							pPort->setPortName(sPortName);
							iDirtyCount++;
						}
					}
					if (pPort)
						pPort->markClientPort(1);
				}
			}
		}
	}

#endif	// CONFIG_ALSA_SEQ

	iDirtyCount += cleanClientPorts(0);

	return iDirtyCount;
}
Exemplo n.º 23
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]);

    
}
Exemplo n.º 24
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();
}
Exemplo n.º 25
0
// MIDI Input(readable) / Output(writable) device connects.
bool qxgeditMidiDevice::connectDeviceList (
	bool bReadable, const QStringList& list ) const
{
	if (m_pAlsaSeq == NULL)
		return false;

	if (list.isEmpty())
		return false;

	snd_seq_addr_t seq_addr;
	snd_seq_port_subscribe_t *pPortSubs;

	snd_seq_port_subscribe_alloca(&pPortSubs);

	snd_seq_client_info_t *pClientInfo;
	snd_seq_port_info_t   *pPortInfo;

	snd_seq_client_info_alloca(&pClientInfo);
	snd_seq_port_info_alloca(&pPortInfo);

	unsigned int uiPortFlags;
	if (bReadable)
		uiPortFlags = SND_SEQ_PORT_CAP_READ  | SND_SEQ_PORT_CAP_SUBS_READ;
	else
		uiPortFlags = SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;

	int iConnects = 0;
	while (snd_seq_query_next_client(m_pAlsaSeq, pClientInfo) >= 0) {
		int iAlsaClient = snd_seq_client_info_get_client(pClientInfo);
		if (iAlsaClient > 0 && iAlsaClient != m_iAlsaClient) {
			QString sClientName = snd_seq_client_info_get_name(pClientInfo);
			snd_seq_port_info_set_client(pPortInfo, iAlsaClient);
			snd_seq_port_info_set_port(pPortInfo, -1);
			while (snd_seq_query_next_port(m_pAlsaSeq, pPortInfo) >= 0) {
				unsigned int uiPortCapability
					= snd_seq_port_info_get_capability(pPortInfo);
				if (((uiPortCapability & uiPortFlags) == uiPortFlags) &&
					((uiPortCapability & SND_SEQ_PORT_CAP_NO_EXPORT) == 0)) {
					int iAlsaPort = snd_seq_port_info_get_port(pPortInfo);
					QString sPortName = snd_seq_port_info_get_name(pPortInfo);
					QStringListIterator iter(list);
					while (iter.hasNext()) {
						const QString& sItem = iter.next();
						const QString& sClientItem
							= sItem.section(c_pszItemSep, 0, 0);
						const QString& sPortItem
							= sItem.section(c_pszItemSep, 1, 1);
						if (sClientName != sClientItem.section(':', 1, 1))
							continue;
						if (sPortName != sPortItem  .section(':', 1, 1))
							continue;
						if (bReadable) {
							seq_addr.client = iAlsaClient;
							seq_addr.port   = iAlsaPort;
							snd_seq_port_subscribe_set_sender(pPortSubs, &seq_addr);
							seq_addr.client = m_iAlsaClient;
							seq_addr.port   = m_iAlsaPort;
							snd_seq_port_subscribe_set_dest(pPortSubs, &seq_addr);
						} else {
							seq_addr.client = m_iAlsaClient;
							seq_addr.port   = m_iAlsaPort;
							snd_seq_port_subscribe_set_sender(pPortSubs, &seq_addr);
							seq_addr.client = iAlsaClient;
							seq_addr.port   = iAlsaPort;
							snd_seq_port_subscribe_set_dest(pPortSubs, &seq_addr);
						}
						if (snd_seq_subscribe_port(m_pAlsaSeq, pPortSubs) == 0)
							iConnects++;
					}
				}
			}
		}
	}

	return (iConnects > 0);
}
Exemplo n.º 26
0
void
mastermidibus::init()
{
#ifdef HAVE_LIBASOUND
    snd_seq_client_info_t * cinfo;          /* client info */
    snd_seq_port_info_t * pinfo;            /* port info   */
    snd_seq_client_info_alloca(&cinfo);
    snd_seq_client_info_set_client(cinfo, -1);
    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;
        m_num_in_buses = 1;                 /* only one in, or 0? */
        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;
    }
    else
    {
        /* While the next client for the sequencer is available */

        while (snd_seq_query_next_client(m_alsa_seq, cinfo) >= 0)
        {
            int client = snd_seq_client_info_get_client(cinfo);
            snd_seq_port_info_alloca(&pinfo);           /* will fill pinfo */
            snd_seq_port_info_set_client(pinfo, client);
            snd_seq_port_info_set_port(pinfo, -1);
            while (snd_seq_query_next_port(m_alsa_seq, pinfo) >= 0)
            {
                /* While the next port is available, 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
                )
                {
                    if                              /* the outputs */
                    (
                        (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++;
                    }
                    if                              /* the inputs */
                    (
                        (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
                        );
                        m_buses_in_active[m_num_in_buses] = true;
                        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);

    /*
     * 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 into */
    snd_seq_poll_descriptors                    /* get input poll descriptors */
    (
        m_alsa_seq, m_poll_descriptors, m_num_poll_descriptors, POLLIN
    );
    set_sequence_input(false, nullptr);

    /* Set the input and output buffer 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]);

#endif  // HAVE_LIBASOUND
}
Exemplo n.º 27
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;
}
Exemplo n.º 28
0
void
mastermidibus::port_start (int a_client, int a_port)
{
#ifdef 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, a_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, a_client, a_port, pinfo);

    int cap = snd_seq_port_info_get_capability(pinfo);  /* get its capability */
    if (snd_seq_client_id(m_alsa_seq) != snd_seq_port_info_get_client(pinfo))
    {
        if                                              /* the outputs */
        (
            (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++;
        }
        if                                          /* the inputs */
        (
            (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;
                }
            }
            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  // HAVE_LIBASOUND
}
Exemplo n.º 29
0
void
mastermidibus::init (int ppqn)
{
#ifdef SEQ64_HAVE_LIBASOUND
    snd_seq_client_info_t * cinfo;          /* client info */
    snd_seq_port_info_t * pinfo;            /* port info   */
    snd_seq_client_info_alloca(&cinfo);
    snd_seq_client_info_set_client(cinfo, -1);
    if (rc().manual_alsa_ports())
    {
        /*
         * Output busses
         */

        int num_buses = SEQ64_ALSA_OUTPUT_BUSS_MAX;
        for (int i = 0; i < num_buses; ++i)
        {
            if (not_nullptr(m_buses_out[i]))
            {
                delete m_buses_out[i];
                errprintf("mmbus::init() manual: m_buses_out[%d] not null\n", 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] = m_buses_out_init[i] = true;
        }
        m_num_out_buses = num_buses;
        if (not_nullptr(m_buses_in[0]))
        {
            delete m_buses_in[0];
            errprint("mmbus::init() manual: m_buses_[0] not null");
        }

        /*
         * Input buss.  Only the first element is set up.  The rest are used
         * only for non-manual ALSA ports in the else-class below.
         */

        m_num_in_buses = 1;
        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] = m_buses_in_init[0] = true;
    }
    else
    {
        /*
         * While the next client for the sequencer is available, get the client
         * from cinfo.  Fill pinfo.
         */

        while (snd_seq_query_next_client(m_alsa_seq, cinfo) >= 0)
        {
            int client = snd_seq_client_info_get_client(cinfo);
            snd_seq_port_info_alloca(&pinfo);           /* will fill pinfo */
            snd_seq_port_info_set_client(pinfo, client);
            snd_seq_port_info_set_port(pinfo, -1);
            while (snd_seq_query_next_port(m_alsa_seq, pinfo) >= 0)
            {
                /*
                 * While the next port is available, get its capability.
                 */

                int cap = snd_seq_port_info_get_capability(pinfo);
                if
                (
                    ALSA_CLIENT_CHECK(pinfo) &&
                    snd_seq_port_info_get_client(pinfo) != SND_SEQ_CLIENT_SYSTEM
                )
                {
                    /*
                     * Output busses:
                     *
                     * Why are we doing the ALSA client check again here?
                     * Because it could be altered in the if-clause above.
                     */

                    if (CAP_WRITE(cap) && ALSA_CLIENT_CHECK(pinfo))
                    {
                        if (not_nullptr(m_buses_out[m_num_out_buses]))
                        {
                            delete m_buses_out[m_num_out_buses];
                            errprintf
                            (
                                "mmbus::init(): m_buses_out[%d] not null\n",
                                m_num_out_buses
                            );
                        }
                        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;
                    }

                    /*
                     * Input busses
                     */

                    if (CAP_READ(cap) && ALSA_CLIENT_CHECK(pinfo)) /* inputs */
                    {
                        if (not_nullptr(m_buses_in[m_num_in_buses]))
                        {
                            delete m_buses_in[m_num_in_buses];
                            errprintf
                            (
                                "mmbus::init(): m_buses_in[%d] not null\n",
                                m_num_in_buses
                            );
                        }
                        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
                        );
                        m_buses_in_active[m_num_in_buses] =
                            m_buses_in_init[m_num_in_buses] = true;

                        ++m_num_in_buses;
                    }
                }
            }
        }                                       /* end loop for clients */
    }
    set_beats_per_minute(m_beats_per_minute);
    set_ppqn(ppqn);

    /*
     * Get the number of MIDI input poll file descriptors.  Allocate the
     * poll-descriptors array.  Then get the input poll-descriptors into the
     * array
     */

    m_num_poll_descriptors = snd_seq_poll_descriptors_count(m_alsa_seq, POLLIN);
    m_poll_descriptors = new pollfd[m_num_poll_descriptors];
    snd_seq_poll_descriptors
    (
        m_alsa_seq, m_poll_descriptors, m_num_poll_descriptors, POLLIN
    );
    set_sequence_input(false, nullptr);

    /* Set the input and output buffer 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", "announce",   // was "annouce" ca 2016-04-03
        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]);

#endif  // SEQ64_HAVE_LIBASOUND
}
Exemplo n.º 30
0
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
}