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; }
Common::Error AlsaMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle dev) const { bool found = false; int seq_client, seq_port; const char *var = NULL; // TODO: Upgrade from old alsa_port setting. This probably isn't the // right place to do that, though. if (ConfMan.hasKey("alsa_port")) { warning("AlsaMusicPlugin: Found old 'alsa_port' setting, which will be ignored"); } // The SCUMMVM_PORT environment variable can still be used to override // any config setting. var = getenv("RESIDUALVM_PORT"); if (var) { warning("AlsaMusicPlugin: RESIDUALVM_PORT environment variable overrides config settings"); if (parse_addr(var, &seq_client, &seq_port) >= 0) { found = true; } else { warning("AlsaMusicPlugin: Invalid port %s, using config settings instead", var); } } // Try to match the setting to an available ALSA device. if (!found && dev) { AlsaDevices alsaDevices = getAlsaDevices(); for (AlsaDevices::iterator d = alsaDevices.begin(); d != alsaDevices.end(); ++d) { MusicDevice device(this, d->getName(), d->getType()); if (device.getCompleteId().equals(MidiDriver::getDeviceString(dev, MidiDriver::kDeviceId))) { found = true; seq_client = d->getClient(); seq_port = -1; break; } } } // Still nothing? Try a sensible default. if (!found) { // TODO: What's a sensible default anyway? And exactly when do // we get to this case? warning("AlsaMusicPlugin: Using 17:0 as default ALSA port"); seq_client = 17; seq_port = 0; } *mididriver = new MidiDriver_ALSA(seq_client, seq_port); return Common::kNoError; }
MusicDevices AlsaMusicPlugin::getDevices() const { MusicDevices devices; AlsaDevices::iterator d; AlsaDevices alsaDevices = getAlsaDevices(); // Since the default behavior is to use the first device in the list, // try to put something sensible there. We used to have 17:0 and 65:0 // as defaults. for (d = alsaDevices.begin(); d != alsaDevices.end();) { const int client = d->getClient(); if (client == 17 || client == 65) { devices.push_back(MusicDevice(this, d->getName(), d->getType())); d = alsaDevices.erase(d); } else { ++d; } } // 128:0 is probably TiMidity, or something like that, so that's // probably a good second choice. for (d = alsaDevices.begin(); d != alsaDevices.end();) { if (d->getClient() == 128) { devices.push_back(MusicDevice(this, d->getName(), d->getType())); d = alsaDevices.erase(d); } else { ++d; } } // Add the remaining devices in the order they were found. for (d = alsaDevices.begin(); d != alsaDevices.end(); ++d) devices.push_back(MusicDevice(this, d->getName(), d->getType())); return devices; }