/* * 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); } }
bool midibus::deinit_in( ) { /* temp return */ int ret; snd_seq_port_subscribe_t *subs; snd_seq_port_subscribe_alloca(&subs); snd_seq_addr_t sender, dest; /* the destinatino port is actually our local port */ sender.client = m_dest_addr_client; sender.port = m_dest_addr_port; dest.client = m_local_addr_client; dest.port = m_local_addr_port; /* set in and out ports */ snd_seq_port_subscribe_set_sender(subs, &sender); snd_seq_port_subscribe_set_dest(subs, &dest); /* use the master queue, and get ticks */ snd_seq_port_subscribe_set_queue(subs, m_queue); snd_seq_port_subscribe_set_time_update(subs, 1); /* subscribe */ ret = snd_seq_unsubscribe_port(m_seq, subs); if ( ret < 0 ){ printf( "snd_seq_unsubscribe_port(%d:%d) error\n", m_dest_addr_client, m_dest_addr_port); return false; } return true; }
bool midibus::deinit_in () { #ifdef SEQ64_HAVE_LIBASOUND snd_seq_port_subscribe_t * subs; snd_seq_port_subscribe_alloca(&subs); snd_seq_addr_t sender; /* output */ sender.client = m_dest_addr_client; sender.port = m_dest_addr_port; snd_seq_port_subscribe_set_sender(subs, &sender); snd_seq_addr_t dest; /* input */ dest.client = m_local_addr_client; dest.port = m_local_addr_port; snd_seq_port_subscribe_set_dest(subs, &dest); snd_seq_port_subscribe_set_queue(subs, m_queue); /* master queue */ snd_seq_port_subscribe_set_time_update(subs, 1); /* get ticks */ int result = snd_seq_unsubscribe_port(m_seq, subs); /* subscribe */ if (result < 0) { fprintf ( stderr, "snd_seq_unsubscribe_port(%d:%d) error\n", m_dest_addr_client, m_dest_addr_port ); return false; } #endif // SEQ64_HAVE_LIBASOUND return true; }
static int a2j_alsa_connect_from (alsa_midi_driver_t * driver, int client, int port) { snd_seq_port_subscribe_t* sub; snd_seq_addr_t seq_addr; int err; snd_seq_port_subscribe_alloca (&sub); seq_addr.client = client; seq_addr.port = port; snd_seq_port_subscribe_set_sender (sub, &seq_addr); seq_addr.client = driver->client_id; seq_addr.port = driver->port_id; snd_seq_port_subscribe_set_dest (sub, &seq_addr); snd_seq_port_subscribe_set_time_update (sub, 1); snd_seq_port_subscribe_set_queue (sub, driver->queue); snd_seq_port_subscribe_set_time_real (sub, 1); if ((err = snd_seq_subscribe_port (driver->seq, sub))) { a2j_error ("can't subscribe to %d:%d - %s", client, port, snd_strerror(err)); } return err; }
bool midibus::init_in () { #ifdef HAVE_LIBASOUND int result = snd_seq_create_simple_port /* create ports */ ( m_seq, "seq24 in", SND_SEQ_PORT_CAP_NO_EXPORT | SND_SEQ_PORT_CAP_WRITE, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION ); m_local_addr_port = result; if (result < 0) { errprint("snd_seq_create_simple_port(read) error"); return false; } snd_seq_port_subscribe_t * subs; snd_seq_port_subscribe_alloca(&subs); snd_seq_addr_t sender; snd_seq_addr_t dest; /* the destination port is actually our local port */ sender.client = m_dest_addr_client; sender.port = m_dest_addr_port; dest.client = m_local_addr_client; dest.port = m_local_addr_port; /* set in and out ports */ snd_seq_port_subscribe_set_sender(subs, &sender); snd_seq_port_subscribe_set_dest(subs, &dest); /* use the master queue, and get ticks */ snd_seq_port_subscribe_set_queue(subs, m_queue); snd_seq_port_subscribe_set_time_update(subs, 1); /* subscribe */ result = snd_seq_subscribe_port(m_seq, subs); if (result < 0) { fprintf ( stderr, "snd_seq_connect_from(%d:%d) error\n", m_dest_addr_client, m_dest_addr_port ); return false; } #endif // HAVE_LIBASOUND return true; }
/* TODO Make sample rate, buffer, gain and polyphony set from CL interface*/ void connect2MidiThroughPort(snd_seq_t *seq_handle) { snd_seq_addr_t sender, dest; snd_seq_port_subscribe_t *subs; int myID; myID=snd_seq_client_id(seq_handle); fprintf(stderr,"MyID=%d",myID); sender.client = 14; sender.port = 0; dest.client = myID; dest.port = 0; snd_seq_port_subscribe_alloca(&subs); snd_seq_port_subscribe_set_sender(subs, &sender); snd_seq_port_subscribe_set_dest(subs, &dest); snd_seq_port_subscribe_set_queue(subs, 1); snd_seq_port_subscribe_set_time_update(subs, 1); snd_seq_port_subscribe_set_time_real(subs, 1); snd_seq_subscribe_port(seq_handle, subs); }
/** * Connects this Alsa midi input device with an Alsa MIDI source. * * @param Client - Alsa sequencer client and port ID of a MIDI source * (e.g. "64:0") * @throws MidiInputException if connection cannot be established */ void MidiInputDeviceAlsa::MidiInputPortAlsa::ConnectToAlsaMidiSource(const char* MidiSource) { snd_seq_addr_t sender, dest; snd_seq_port_subscribe_t* subs; int hExtClient, hExtPort; sscanf(MidiSource, "%d:%d", &hExtClient, &hExtPort); sender.client = (char) hExtClient; sender.port = (char) hExtPort; dest.client = (char) pDevice->hAlsaSeqClient; dest.port = (char) portNumber; snd_seq_port_subscribe_malloc(&subs); snd_seq_port_subscribe_set_sender(subs, &sender); snd_seq_port_subscribe_set_dest(subs, &dest); snd_seq_port_subscribe_set_queue(subs, 1); snd_seq_port_subscribe_set_time_update(subs, 1); snd_seq_port_subscribe_set_time_real(subs, 1); if (snd_seq_subscribe_port(pDevice->hAlsaSeq, subs) < 0) { snd_seq_port_subscribe_free(subs); throw MidiInputException(String("Unable to connect to Alsa seq client \'") + MidiSource + "\' (" + snd_strerror(errno) + ")"); } subscriptions.push_back(subs); }
static int alsa_connect_from(alsa_seqmidi_t *self, int client, int port) { snd_seq_port_subscribe_t* sub; snd_seq_addr_t seq_addr; int err; snd_seq_port_subscribe_alloca(&sub); seq_addr.client = client; seq_addr.port = port; snd_seq_port_subscribe_set_sender(sub, &seq_addr); seq_addr.client = self->client_id; seq_addr.port = self->port_id; snd_seq_port_subscribe_set_dest(sub, &seq_addr); snd_seq_port_subscribe_set_time_update(sub, 1); snd_seq_port_subscribe_set_queue(sub, self->queue); snd_seq_port_subscribe_set_time_real(sub, 1); if ((err=snd_seq_subscribe_port(self->seq, sub))) error_log("can't subscribe to %d:%d - %s", client, port, snd_strerror(err)); return err; }
int main(int argc, char **argv) { int c; snd_seq_t *seq; int queue = 0, convert_time = 0, convert_real = 0, exclusive = 0; int command = SUBSCRIBE; int list_perm = 0; int client; int list_subs = 0; snd_seq_port_subscribe_t *subs; snd_seq_addr_t sender, dest; #ifdef ENABLE_NLS setlocale(LC_ALL, ""); textdomain(PACKAGE); #endif while ((c = getopt_long(argc, argv, "dior:t:elx", long_option, NULL)) != -1) { switch (c) { case 'd': command = UNSUBSCRIBE; break; case 'i': command = LIST; list_perm |= LIST_INPUT; break; case 'o': command = LIST; list_perm |= LIST_OUTPUT; break; case 'e': exclusive = 1; break; case 'r': queue = atoi(optarg); convert_time = 1; convert_real = 1; break; case 't': queue = atoi(optarg); convert_time = 1; convert_real = 0; break; case 'l': list_subs = 1; break; case 'x': command = REMOVE_ALL; break; default: usage(); exit(1); } } if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0) { fprintf(stderr, _("can't open sequencer\n")); return 1; } snd_lib_error_set_handler(error_handler); switch (command) { case LIST: do_search_port(seq, list_perm, list_subs ? print_port_and_subs : print_port); snd_seq_close(seq); return 0; case REMOVE_ALL: remove_all_connections(seq); snd_seq_close(seq); return 0; } /* connection or disconnection */ if (optind + 2 > argc) { snd_seq_close(seq); usage(); exit(1); } if ((client = snd_seq_client_id(seq)) < 0) { snd_seq_close(seq); fprintf(stderr, _("can't get client id\n")); return 1; } /* set client info */ if (snd_seq_set_client_name(seq, "ALSA Connector") < 0) { snd_seq_close(seq); fprintf(stderr, _("can't set client info\n")); return 1; } /* set subscription */ if (snd_seq_parse_address(seq, &sender, argv[optind]) < 0) { snd_seq_close(seq); fprintf(stderr, _("invalid sender address %s\n"), argv[optind]); return 1; } if (snd_seq_parse_address(seq, &dest, argv[optind + 1]) < 0) { snd_seq_close(seq); fprintf(stderr, _("invalid destination address %s\n"), argv[optind + 1]); return 1; } snd_seq_port_subscribe_alloca(&subs); snd_seq_port_subscribe_set_sender(subs, &sender); snd_seq_port_subscribe_set_dest(subs, &dest); snd_seq_port_subscribe_set_queue(subs, queue); snd_seq_port_subscribe_set_exclusive(subs, exclusive); snd_seq_port_subscribe_set_time_update(subs, convert_time); snd_seq_port_subscribe_set_time_real(subs, convert_real); if (command == UNSUBSCRIBE) { if (snd_seq_get_port_subscription(seq, subs) < 0) { snd_seq_close(seq); fprintf(stderr, _("No subscription is found\n")); return 1; } if (snd_seq_unsubscribe_port(seq, subs) < 0) { snd_seq_close(seq); fprintf(stderr, _("Disconnection failed (%s)\n"), snd_strerror(errno)); return 1; } } else { if (snd_seq_get_port_subscription(seq, subs) == 0) { snd_seq_close(seq); fprintf(stderr, _("Connection is already subscribed\n")); return 1; } if (snd_seq_subscribe_port(seq, subs) < 0) { snd_seq_close(seq); fprintf(stderr, _("Connection failed (%s)\n"), snd_strerror(errno)); return 1; } } snd_seq_close(seq); return 0; }
void event_decoder(snd_seq_t *handle, int argc, char *argv[]) { snd_seq_event_t *ev; snd_seq_port_info_t *pinfo; snd_seq_port_subscribe_t *sub; snd_seq_addr_t addr; int client, port, queue, max, err, v1, v2; char *ptr; struct pollfd *pfds; if ((client = snd_seq_client_id(handle))<0) { fprintf(stderr, "Cannot determine client number: %s\n", snd_strerror(client)); return; } printf("Client ID = %i\n", client); if ((queue = snd_seq_alloc_queue(handle))<0) { fprintf(stderr, "Cannot allocate queue: %s\n", snd_strerror(queue)); return; } printf("Queue ID = %i\n", queue); if ((err = snd_seq_nonblock(handle, 1))<0) fprintf(stderr, "Cannot set nonblock mode: %s\n", snd_strerror(err)); snd_seq_port_info_alloca(&pinfo); snd_seq_port_info_set_name(pinfo, "Input"); snd_seq_port_info_set_type(pinfo, SND_SEQ_PORT_TYPE_MIDI_GENERIC); snd_seq_port_info_set_capability(pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_WRITE); /* Enable timestamping for events sent by external subscribers. */ snd_seq_port_info_set_timestamping(pinfo, 1); snd_seq_port_info_set_timestamp_real(pinfo, 1); snd_seq_port_info_set_timestamp_queue(pinfo, queue); if ((err = snd_seq_create_port(handle, pinfo)) < 0) { fprintf(stderr, "Cannot create input port: %s\n", snd_strerror(err)); return; } port = snd_seq_port_info_get_port(pinfo); event_decoder_start_timer(handle, queue, client, port); snd_seq_port_subscribe_alloca(&sub); addr.client = SND_SEQ_CLIENT_SYSTEM; addr.port = SND_SEQ_PORT_SYSTEM_ANNOUNCE; snd_seq_port_subscribe_set_sender(sub, &addr); addr.client = client; addr.port = port; snd_seq_port_subscribe_set_dest(sub, &addr); snd_seq_port_subscribe_set_queue(sub, queue); snd_seq_port_subscribe_set_time_update(sub, 1); snd_seq_port_subscribe_set_time_real(sub, 1); if ((err = snd_seq_subscribe_port(handle, sub))<0) { fprintf(stderr, "Cannot subscribe announce port: %s\n", snd_strerror(err)); return; } addr.client = SND_SEQ_CLIENT_SYSTEM; addr.port = SND_SEQ_PORT_SYSTEM_TIMER; snd_seq_port_subscribe_set_sender(sub, &addr); if ((err = snd_seq_subscribe_port(handle, sub))<0) { fprintf(stderr, "Cannot subscribe timer port: %s\n", snd_strerror(err)); return; } for (max = 0; max < argc; max++) { ptr = argv[max]; if (!ptr) continue; snd_seq_port_subscribe_set_time_real(sub, 0); if (tolower(*ptr) == 'r') { snd_seq_port_subscribe_set_time_real(sub, 1); ptr++; } if (sscanf(ptr, "%i.%i", &v1, &v2) != 2) { fprintf(stderr, "Wrong argument '%s'...\n", argv[max]); return; } addr.client = v1; addr.port = v2; snd_seq_port_subscribe_set_sender(sub, &addr); if ((err = snd_seq_subscribe_port(handle, sub))<0) { fprintf(stderr, "Cannot subscribe port %i from client %i: %s\n", v2, v1, snd_strerror(err)); return; } } max = snd_seq_poll_descriptors_count(handle, POLLIN); pfds = alloca(sizeof(*pfds) * max); while (1) { snd_seq_poll_descriptors(handle, pfds, max, POLLIN); if (poll(pfds, max, -1) < 0) break; do { if ((err = snd_seq_event_input(handle, &ev))<0) break; if (!ev) continue; decode_event(ev); snd_seq_free_event(ev); } while (err > 0); } }