/* * 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); } }
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()); }
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; }
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)); } } }
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
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 ); }
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; }
/************************************************************************** * 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; }
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; }
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"); }
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; }
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; }
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"); }
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; }
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++; } } } }
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; }
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); } } }
/* 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; }
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); } } }
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()); }
// 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; }
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]); }
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(); }
// 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); }
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 }
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; }
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 }
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 }
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 }