| Index: media/midi/midi_manager_alsa.cc
|
| diff --git a/media/midi/midi_manager_alsa.cc b/media/midi/midi_manager_alsa.cc
|
| index 9015be9913033bb54d4b78b2b7e2640c567c8920..5474455dc27637b144194c4fcc4c552fe3aab04e 100644
|
| --- a/media/midi/midi_manager_alsa.cc
|
| +++ b/media/midi/midi_manager_alsa.cc
|
| @@ -261,8 +261,8 @@ MidiManagerAlsa::AlsaRawmidi::AlsaRawmidi(const MidiManagerAlsa* outer,
|
| device::UdevDeviceGetPropertyValue(udev_device.get(), kIdVendorEnc));
|
| // Sometimes it is not encoded.
|
| if (vendor.empty())
|
| - UdevDeviceGetPropertyOrSysattr(udev_device.get(), kIdVendor,
|
| - kSysattrVendorName);
|
| + vendor = UdevDeviceGetPropertyOrSysattr(udev_device.get(), kIdVendor,
|
| + kSysattrVendorName);
|
| // Also get the vendor string from the hardware database.
|
| vendor_from_database = device::UdevDeviceGetPropertyValue(
|
| udev_device.get(), kIdVendorFromDatabase);
|
| @@ -344,8 +344,8 @@ std::string MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString(
|
| // 2. Vendor name from the udev database (property ID_VENDOR_FROM_DATABASE).
|
| // 3. Heuristic from ALSA.
|
|
|
| - // Is the vendor string not just the vendor hex id?
|
| - if (udev_id_vendor != udev_id_vendor_id) {
|
| + // Is the vendor string present and not just the vendor hex id?
|
| + if (!udev_id_vendor.empty() && (udev_id_vendor != udev_id_vendor_id)) {
|
| return udev_id_vendor;
|
| }
|
|
|
| @@ -441,11 +441,9 @@ std::string MidiManagerAlsa::AlsaPortMetadata::OpaqueKey() const {
|
| ScopedVector<MidiManagerAlsa::AlsaRawmidi> MidiManagerAlsa::AllAlsaRawmidis() {
|
| ScopedVector<AlsaRawmidi> devices;
|
| snd_ctl_card_info_t* card;
|
| - snd_rawmidi_info_t* midi_out;
|
| - snd_rawmidi_info_t* midi_in;
|
| + snd_hwdep_info_t* hwdep;
|
| snd_ctl_card_info_alloca(&card);
|
| - snd_rawmidi_info_alloca(&midi_out);
|
| - snd_rawmidi_info_alloca(&midi_in);
|
| + snd_hwdep_info_alloca(&hwdep);
|
| for (int card_index = -1; !snd_card_next(&card_index) && card_index >= 0;) {
|
| const std::string id = base::StringPrintf("hw:CARD=%i", card_index);
|
| snd_ctl_t* handle;
|
| @@ -460,28 +458,46 @@ ScopedVector<MidiManagerAlsa::AlsaRawmidi> MidiManagerAlsa::AllAlsaRawmidis() {
|
| snd_ctl_close(handle);
|
| continue;
|
| }
|
| - // Enumerate any rawmidi devices (not subdevices) and extract AlsaRawmidi.
|
| + std::string name = snd_ctl_card_info_get_name(card);
|
| + std::string longname = snd_ctl_card_info_get_longname(card);
|
| + std::string driver = snd_ctl_card_info_get_driver(card);
|
| +
|
| + // Count rawmidi devices (not subdevices).
|
| for (int device = -1;
|
| !snd_ctl_rawmidi_next_device(handle, &device) && device >= 0;) {
|
| - bool output;
|
| - bool input;
|
| - snd_rawmidi_info_set_device(midi_out, device);
|
| - snd_rawmidi_info_set_subdevice(midi_out, 0);
|
| - snd_rawmidi_info_set_stream(midi_out, SND_RAWMIDI_STREAM_OUTPUT);
|
| - output = snd_ctl_rawmidi_info(handle, midi_out) == 0;
|
| - snd_rawmidi_info_set_device(midi_in, device);
|
| - snd_rawmidi_info_set_subdevice(midi_in, 0);
|
| - snd_rawmidi_info_set_stream(midi_in, SND_RAWMIDI_STREAM_INPUT);
|
| - input = snd_ctl_rawmidi_info(handle, midi_in) == 0;
|
| - if (!output && !input)
|
| - continue;
|
| -
|
| - // Compute and save ALSA and udev properties.
|
| - snd_rawmidi_info_t* midi = midi_out ? midi_out : midi_in;
|
| - devices.push_back(new AlsaRawmidi(this, snd_rawmidi_info_get_name(midi),
|
| - snd_ctl_card_info_get_longname(card),
|
| - snd_ctl_card_info_get_driver(card),
|
| - card_index));
|
| + devices.push_back(
|
| + new AlsaRawmidi(this, name, longname, driver, card_index));
|
| + }
|
| +
|
| + // Count any hwdep synths that become MIDI devices.
|
| + //
|
| + // Explanation:
|
| + // Any kernel driver can create an ALSA client (visible to us).
|
| + // With modern hardware, only rawmidi devices do this. Kernel
|
| + // drivers create rawmidi devices and the rawmidi subsystem makes
|
| + // the seq clients. But the OPL3 driver is special, it does not
|
| + // make a rawmidi device but a seq client directly. (This is the
|
| + // only one to worry about in the kernel code, as of 2015-03-23.)
|
| + //
|
| + // OPL3 is very old (but still possible to get in new
|
| + // hardware). It is unlikely that new drivers would not use
|
| + // rawmidi and defeat our heuristic.
|
| + //
|
| + // Longer term, support should be added in the kernel to expose a
|
| + // direct link from card->client (or client->card) so that all
|
| + // these heuristics will be obsolete. Once that is there, we can
|
| + // assume our old heuristics will work on old kernels and the new
|
| + // robust code will be used on new. Then we will not need to worry
|
| + // about changes to kernel internals breaking our code.
|
| + // See the TODO above at kMinimumClientIdForCards.
|
| + for (int device = -1;
|
| + !snd_ctl_hwdep_next_device(handle, &device) && device >= 0;) {
|
| + snd_ctl_hwdep_info(handle, hwdep);
|
| + snd_hwdep_iface_t iface = snd_hwdep_info_get_iface(hwdep);
|
| + if (iface == SND_HWDEP_IFACE_OPL2 || iface == SND_HWDEP_IFACE_OPL3 ||
|
| + iface == SND_HWDEP_IFACE_OPL4)
|
| + devices.push_back(
|
| + new AlsaRawmidi(this, name, longname, driver, card_index));
|
| }
|
| snd_ctl_close(handle);
|
| }
|
|
|