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; }
/************************************************************************** * 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; }
//============================================================================== static AlsaPort iterateMidiClient (const AlsaClient::Ptr& seq, snd_seq_client_info_t* clientInfo, const bool forInput, StringArray& deviceNamesFound, const int deviceIndexToOpen) { AlsaPort port; snd_seq_t* seqHandle = seq->get(); snd_seq_port_info_t* portInfo = nullptr; if (snd_seq_port_info_malloc (&portInfo) == 0) { int numPorts = snd_seq_client_info_get_num_ports (clientInfo); const int client = snd_seq_client_info_get_client (clientInfo); snd_seq_port_info_set_client (portInfo, client); snd_seq_port_info_set_port (portInfo, -1); while (--numPorts >= 0) { if (snd_seq_query_next_port (seqHandle, portInfo) == 0 && (snd_seq_port_info_get_capability (portInfo) & (forInput ? SND_SEQ_PORT_CAP_READ : SND_SEQ_PORT_CAP_WRITE)) != 0) { deviceNamesFound.add (snd_seq_client_info_get_name (clientInfo)); if (deviceNamesFound.size() == deviceIndexToOpen + 1) { const int sourcePort = snd_seq_port_info_get_port (portInfo); const int sourceClient = snd_seq_client_info_get_client (clientInfo); if (sourcePort != -1) { const String name (forInput ? JUCE_ALSA_MIDI_INPUT_NAME : JUCE_ALSA_MIDI_OUTPUT_NAME); seq->setName (name); port.createPort (seq, name, forInput); port.connectWith (sourceClient, sourcePort); } } } } snd_seq_port_info_free (portInfo); } return port; }
void a2j_port_fill_name (struct a2j_port * port_ptr, int dir, snd_seq_client_info_t * client_info_ptr, const snd_seq_port_info_t * port_info_ptr, bool make_unique) { char *c; if (make_unique) { snprintf (port_ptr->name, sizeof(port_ptr->name), "%s [%d] %s %s", snd_seq_client_info_get_name(client_info_ptr), snd_seq_client_info_get_client(client_info_ptr), snd_seq_port_info_get_name(port_info_ptr), (dir == A2J_PORT_CAPTURE ? "in" : "out")); } else { snprintf (port_ptr->name, sizeof(port_ptr->name), "%s %s %s", snd_seq_client_info_get_name(client_info_ptr), snd_seq_port_info_get_name(port_info_ptr), (dir == A2J_PORT_CAPTURE ? "in" : "out")); } // replace all offending characters with ' ' for (c = port_ptr->name; *c; ++c) { if (!JACK_IS_VALID_PORT_NAME_CHAR(*c)) { *c = ' '; } } }
void MidiEnumeratorPrivate::initAlsa() { qDebug() << Q_FUNC_INFO; if (snd_seq_open(&m_alsa, "default", SND_SEQ_OPEN_DUPLEX, 0) != 0) { qWarning() << "Unable to open ALSA interface!"; m_alsa = NULL; return; } /* Set current client information */ snd_seq_client_info_t* client = NULL; snd_seq_client_info_alloca(&client); snd_seq_set_client_name(m_alsa, "qlcplus"); snd_seq_get_client_info(m_alsa, client); /* Create an application-level port */ m_address = new snd_seq_addr_t; m_address->port = snd_seq_create_simple_port(m_alsa, "__QLC__", SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ | SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC); m_address->client = snd_seq_client_info_get_client(client); /* Create input thread */ m_inputThread = new AlsaMidiInputThread(m_alsa, m_address, this); }
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)); } } }
static void print_port(snd_seq_t *seq, snd_seq_client_info_t *cinfo, snd_seq_port_info_t *pinfo, int count) { if (! count) { int card = -1, pid = -1; printf(_("client %d: '%s' [type=%s"), snd_seq_client_info_get_client(cinfo), snd_seq_client_info_get_name(cinfo), (snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? _("user") : _("kernel"))); #ifdef HAVE_SEQ_CLIENT_INFO_GET_CARD card = snd_seq_client_info_get_card(cinfo); #endif if (card != -1) printf(",card=%d", card); #ifdef HAVE_SEQ_CLIENT_INFO_GET_PID pid = snd_seq_client_info_get_pid(cinfo); #endif if (pid != -1) printf(",pid=%d", pid); printf("]\n"); } printf(" %3d '%-16s'\n", snd_seq_port_info_get_port(pinfo), snd_seq_port_info_get_name(pinfo)); }
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; }
// This function is used to count or get the pinfo structure for a given port number. size_t Alsa::portInfo( snd_seq_t *seq, snd_seq_port_info_t *pinfo, unsigned int type, int portNumber ) { snd_seq_client_info_t *cinfo; int client; size_t count = 0; snd_seq_client_info_alloca( &cinfo ); snd_seq_client_info_set_client( cinfo, -1 ); while ( snd_seq_query_next_client( seq, cinfo ) >= 0 ) { client = snd_seq_client_info_get_client( cinfo ); if ( client == 0 ) continue; // Reset query info 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 ) { unsigned int atyp = snd_seq_port_info_get_type( pinfo ); if ( ( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC ) == 0 ) continue; unsigned int caps = snd_seq_port_info_get_capability( pinfo ); if ( ( caps & type ) != type ) continue; if ( (int)count == portNumber ) return 1; ++count; } } // If a negative portNumber was used, return the port count. if ( portNumber < 0 ) return count; return 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()); }
void MIDIOut::initALSA() { snd_seq_client_info_t* client = NULL; /* Destroy the old handle */ if (m_alsa != NULL) snd_seq_close(m_alsa); m_alsa = NULL; /* Destroy the plugin's own address */ if (m_address != NULL) delete m_address; m_address = NULL; /* Open the sequencer interface */ if (snd_seq_open(&m_alsa, "default", SND_SEQ_OPEN_DUPLEX, 0) != 0) { qWarning() << "Unable to open ALSA interface!"; m_alsa = NULL; return; } /* Set current client information */ snd_seq_client_info_alloca(&client); snd_seq_set_client_name(m_alsa, name().toAscii()); snd_seq_get_client_info(m_alsa, client); /* Create an application-level port */ m_address = new snd_seq_addr_t; m_address->port = snd_seq_create_simple_port(m_alsa, "__QLC__output", SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC); m_address->client = snd_seq_client_info_get_client(client); }
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; }
int ALSAMidiIn::getalsaid() { if(midi_handle) { snd_seq_client_info_t *seq_info; snd_seq_client_info_malloc(&seq_info); snd_seq_get_client_info(midi_handle, seq_info); int id = snd_seq_client_info_get_client(seq_info); snd_seq_client_info_free(seq_info); return id; } return -1; }
/* * Class: org_tritonus_lowlevel_alsa_AlsaSeqClientInfo * Method: getClient * Signature: ()I */ JNIEXPORT jint JNICALL Java_org_tritonus_lowlevel_alsa_AlsaSeqClientInfo_getClient (JNIEnv* env, jobject obj) { snd_seq_client_info_t* handle; int nReturn; if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaSeqClientInfo_getClient(): begin\n"); } handle = getHandle(env, obj); nReturn = snd_seq_client_info_get_client(handle); if (debug_flag) { fprintf(debug_file, "Java_org_tritonus_lowlevel_alsa_AlsaSeqClientInfo_getClient(): end\n"); } return nReturn; }
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 print_port(snd_seq_t *seq, snd_seq_client_info_t *cinfo, snd_seq_port_info_t *pinfo, int count) { if (! count) { printf(_("client %d: '%s' [type=%s]\n"), snd_seq_client_info_get_client(cinfo), snd_seq_client_info_get_name(cinfo), (snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? _("user") : _("kernel"))); } printf(" %3d '%-16s'\n", snd_seq_port_info_get_port(pinfo), snd_seq_port_info_get_name(pinfo)); }
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; }
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++; } } } }
/* 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 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 }
bool midi_init() { snd_seq_addr_t sender, receiver; snd_seq_port_info_t *pinfo; snd_seq_client_info_t *cinfo; bool found = false; if (snd_seq_open(&s_midi, "default", SND_SEQ_OPEN_OUTPUT, 0) < 0) { Error("Failed to initialize MIDI\n"); s_midi = NULL; return false; } snd_seq_set_client_name(s_midi, s_midiCaption); /* Create a port to work on */ s_midiPort = snd_seq_create_simple_port(s_midi, s_midiCaption, SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC); if (s_midiPort < 0) { Error("Failed to initialize MIDI\n"); snd_seq_close(s_midi); s_midi = NULL; return false; } /* Try to find a MIDI out */ snd_seq_port_info_alloca(&pinfo); snd_seq_client_info_alloca(&cinfo); snd_seq_client_info_set_client(cinfo, -1); /* Walk all clients and ports, and see if one matches our demands */ while (snd_seq_query_next_client(s_midi, cinfo) >= 0 && !found) { int client; client = snd_seq_client_info_get_client(cinfo); if (client == 0) continue; snd_seq_port_info_set_client(pinfo, client); snd_seq_port_info_set_port(pinfo, -1); while (snd_seq_query_next_port(s_midi, pinfo) >= 0) { if ((snd_seq_port_info_get_capability(pinfo) & (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)) != (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)) continue; /* Most linux installations come with a Midi Through Port. * This is 'hardware' support that mostly ends up on your serial, which * you most likely do not have connected. So we skip it by default. */ if (strncmp("Midi Through Port", snd_seq_port_info_get_name(pinfo), 17) == 0) continue; found = true; break; } } if (!found) { Error("No valid MIDI output ports.\n Please install and start Timidity++ like: timidity -iA\n"); snd_seq_delete_port(s_midi, s_midiPort); snd_seq_close(s_midi); s_midi = NULL; return false; } /* Subscribe ourself to the port */ receiver.client = snd_seq_port_info_get_client(pinfo); receiver.port = snd_seq_port_info_get_port(pinfo); sender.client = snd_seq_client_id(s_midi); sender.port = s_midiPort; snd_seq_port_subscribe_malloc(&s_midiSubscription); snd_seq_port_subscribe_set_sender(s_midiSubscription, &sender); snd_seq_port_subscribe_set_dest(s_midiSubscription, &receiver); snd_seq_port_subscribe_set_time_update(s_midiSubscription, 1); snd_seq_port_subscribe_set_time_real(s_midiSubscription, 1); if (snd_seq_subscribe_port(s_midi, s_midiSubscription) < 0) { Error("Failed to subscript to MIDI output\n"); snd_seq_delete_port(s_midi, s_midiPort); snd_seq_close(s_midi); s_midi = NULL; return false; } /* Start the MIDI decoder */ if (snd_midi_event_new(4, &s_midiCoder) < 0) { Error("Failed to initialize MIDI decoder\n"); snd_seq_delete_port(s_midi, s_midiPort); snd_seq_close(s_midi); s_midi = NULL; return false; } snd_midi_event_init(s_midiCoder); return true; }
// 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]); }
// 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 main(int argc, char **argv) { int i; int listen_port = -1; char *client_name = "net2alsamidi"; char *connect_client = NULL; int connect_port = -1; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--port") == 0) { if (++i == argc) usage(argv[0]); listen_port = atoi(argv[i]); } else if (strcmp(argv[i], "--name") == 0) { if (++i == argc) usage(argv[0]); client_name = argv[i]; } else if (strcmp(argv[i], "--connect") == 0) { if (++i == argc) usage(argv[0]); connect_client = argv[i]; if (++i == argc) usage(argv[0]); connect_port = atoi(argv[i]); } else { usage(argv[0]); } } if (listen_port > 0) { snd_seq_t *seq; int port; if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_OUTPUT, 0) < 0) { fprintf(stderr, "Cannot open the ALSA sequencer.\n"); exit(1); } snd_seq_set_client_name(seq, client_name); port = snd_seq_create_simple_port(seq, "from NetMIDI client", SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); if ((connect_client != NULL) && (connect_port >= 0)) { int connect_client_id = -1; { snd_seq_client_info_t *client_info; snd_seq_client_info_malloc(&client_info); while (snd_seq_query_next_client(seq, client_info) == 0) { if (strcmp(snd_seq_client_info_get_name(client_info), connect_client) == 0) { connect_client_id = snd_seq_client_info_get_client(client_info); break; } } snd_seq_client_info_free(client_info); } if (connect_client_id < 0) connect_client_id = atoi(connect_client); snd_seq_connect_to(seq, port, connect_client_id, connect_port); } { int server_socket; struct sockaddr_in server_address; if ((server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port); exit(1); } server_address.sin_family = AF_INET; server_address.sin_port = htons(listen_port); server_address.sin_addr.s_addr = INADDR_ANY; if (bind(server_socket, (struct sockaddr *)(&server_address), sizeof(server_address)) < 0) { fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port); exit(1); } if (listen(server_socket, 1) < 0) { fprintf(stderr, "Cannot start a NetMIDI server on port %d.\n", listen_port); exit(1); } while (1) { int socket_to_client; if ((socket_to_client = accept(server_socket, NULL, NULL)) >= 0) { snd_midi_event_t *midi_event_parser; snd_seq_event_t *event; unsigned char buffer[BUFFER_SIZE]; int bytes_read; { char one = 1; setsockopt(socket_to_client, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)); } snd_midi_event_new(BUFFER_SIZE, &midi_event_parser); while ((bytes_read = recv(socket_to_client, buffer, BUFFER_SIZE, 0)) > 0) { for (i = 0; i < bytes_read; i++) { if (snd_midi_event_encode_byte(midi_event_parser, buffer[i], event) == 1) { snd_seq_event_output_direct(seq, event); } } } snd_midi_event_free(midi_event_parser); close(socket_to_client); } } close(server_socket); } snd_seq_delete_simple_port(seq, port); snd_seq_close(seq); } else { usage(argv[0]); } return 0; }
void sys_alsa_do_open_midi(int nmidiin, int *midiinvec, int nmidiout, int *midioutvec) { char portname[50]; int err = 0; int client; int i; snd_seq_client_info_t *alsainfo; alsa_nmidiin = 0; alsa_nmidiout = 0; if (nmidiout == 0 && nmidiin == 0) return; if(nmidiin>MAXMIDIINDEV ) { post("midi input ports reduced to maximum %d", MAXMIDIINDEV); nmidiin=MAXMIDIINDEV; } if(nmidiout>MAXMIDIOUTDEV) { post("midi output ports reduced to maximum %d", MAXMIDIOUTDEV); nmidiout=MAXMIDIOUTDEV; } if (nmidiin>0 && nmidiout>0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_DUPLEX,0); else if (nmidiin > 0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0); else if (nmidiout > 0) err = snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_OUTPUT,0); if (err!=0) { sys_setalarm(1000000); post("couldn't open alsa sequencer"); return; } for (i=0;i<nmidiin;i++) { int port; sprintf(portname,"Pure Data Midi-In %d",i+1); port = snd_seq_create_simple_port(midi_handle,portname, SND_SEQ_PORT_CAP_WRITE |SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION); alsa_midiinfd[i] = port; if (port < 0) goto error; } for (i=0;i<nmidiout;i++) { int port; sprintf(portname,"Pure Data Midi-Out %d",i+1); port = snd_seq_create_simple_port(midi_handle,portname, SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_APPLICATION); alsa_midioutfd[i] = port; if (port < 0) goto error; } snd_seq_client_info_malloc(&alsainfo); snd_seq_get_client_info(midi_handle,alsainfo); snd_seq_client_info_set_name(alsainfo,"Pure Data"); client = snd_seq_client_info_get_client(alsainfo); snd_seq_set_client_info(midi_handle,alsainfo); snd_seq_client_info_free(alsainfo); post("Opened Alsa Client %d in:%d out:%d",client,nmidiin,nmidiout); sys_setalarm(0); snd_midi_event_new(ALSA_MAX_EVENT_SIZE,&midiev); alsa_nmidiout = nmidiout; alsa_nmidiin = nmidiin; return; error: sys_setalarm(1000000); post("couldn't open alsa MIDI output device"); return; }
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()); }
void MidiAlsaSeq::updatePortList() { QStringList readablePorts; QStringList writablePorts; // get input- and output-ports snd_seq_client_info_t * cinfo; snd_seq_port_info_t * pinfo; snd_seq_client_info_malloc( &cinfo ); snd_seq_port_info_malloc( &pinfo ); snd_seq_client_info_set_client( cinfo, -1 ); m_seqMutex.lock(); while( snd_seq_query_next_client( m_seqHandle, 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( m_seqHandle, 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 ) ) { readablePorts.push_back( __portName( cinfo, pinfo ) ); } if( ( snd_seq_port_info_get_capability( pinfo ) & ( SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE ) ) == ( SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE ) ) { writablePorts.push_back( __portName( cinfo, pinfo ) ); } } } m_seqMutex.unlock(); snd_seq_client_info_free( cinfo ); snd_seq_port_info_free( pinfo ); if( m_readablePorts != readablePorts ) { m_readablePorts = readablePorts; emit readablePortsChanged(); } if( m_writablePorts != writablePorts ) { m_writablePorts = writablePorts; emit writablePortsChanged(); } }