int ALSAMidiDriver::open() { std::string arg; unsigned int caps; if (isOpen) return -1; arg = getConfigSetting("alsa_port", ALSA_PORT); if (parse_addr(arg, &seq_client, &seq_port) < 0) { perr << "ALSAMidiDriver: Invalid port: " << arg << std::endl; return -1; } if (my_snd_seq_open(&seq_handle)) { perr << "ALSAMidiDriver: Can't open sequencer" << std::endl; return -1; } isOpen = true; my_client = snd_seq_client_id(seq_handle); snd_seq_set_client_name(seq_handle, "PENTAGRAM"); snd_seq_set_client_group(seq_handle, "input"); caps = SND_SEQ_PORT_CAP_READ; if (seq_client == SND_SEQ_ADDRESS_SUBSCRIBERS) caps = ~SND_SEQ_PORT_CAP_SUBS_READ; my_port = snd_seq_create_simple_port(seq_handle, "PENTAGRAM", caps, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); if (my_port < 0) { snd_seq_close(seq_handle); isOpen = false; perr << "ALSAMidiDriver: Can't create port" << std::endl; return -1; } if (seq_client != SND_SEQ_ADDRESS_SUBSCRIBERS) { /* subscribe to MIDI port */ if (snd_seq_connect_to(seq_handle, my_port, seq_client, seq_port) < 0) { snd_seq_close(seq_handle); isOpen = false; perr << "ALSAMidiDriver: " << "Can't subscribe to MIDI port (" << seq_client << ":" << seq_port << ")" << std::endl; return -1; } } pout << "ALSA client initialised [" << seq_client << ":" << seq_port << "]" << std::endl; return 0; }
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; }