OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/midi/midi_manager_alsa.h" | 5 #include "media/midi/midi_manager_alsa.h" |
6 | 6 |
7 #include <alsa/asoundlib.h> | 7 #include <alsa/asoundlib.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <string> | 10 #include <string> |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 device::udev_device_new_from_subsystem_sysname( | 254 device::udev_device_new_from_subsystem_sysname( |
255 outer->udev_.get(), kSoundClass, sysname.c_str())); | 255 outer->udev_.get(), kSoundClass, sysname.c_str())); |
256 | 256 |
257 // TODO(agoode): Move this to a new utility class in device/udev_linux? | 257 // TODO(agoode): Move this to a new utility class in device/udev_linux? |
258 | 258 |
259 // Try to get the vendor string. Sometimes it is encoded. | 259 // Try to get the vendor string. Sometimes it is encoded. |
260 vendor = device::UdevDecodeString( | 260 vendor = device::UdevDecodeString( |
261 device::UdevDeviceGetPropertyValue(udev_device.get(), kIdVendorEnc)); | 261 device::UdevDeviceGetPropertyValue(udev_device.get(), kIdVendorEnc)); |
262 // Sometimes it is not encoded. | 262 // Sometimes it is not encoded. |
263 if (vendor.empty()) | 263 if (vendor.empty()) |
264 UdevDeviceGetPropertyOrSysattr(udev_device.get(), kIdVendor, | 264 vendor = UdevDeviceGetPropertyOrSysattr(udev_device.get(), kIdVendor, |
265 kSysattrVendorName); | 265 kSysattrVendorName); |
266 // Also get the vendor string from the hardware database. | 266 // Also get the vendor string from the hardware database. |
267 vendor_from_database = device::UdevDeviceGetPropertyValue( | 267 vendor_from_database = device::UdevDeviceGetPropertyValue( |
268 udev_device.get(), kIdVendorFromDatabase); | 268 udev_device.get(), kIdVendorFromDatabase); |
269 | 269 |
270 // Get the device path. | 270 // Get the device path. |
271 path_ = device::UdevDeviceGetPropertyValue(udev_device.get(), kIdPath); | 271 path_ = device::UdevDeviceGetPropertyValue(udev_device.get(), kIdPath); |
272 | 272 |
273 // Get the bus. | 273 // Get the bus. |
274 bus_ = device::UdevDeviceGetPropertyValue(udev_device.get(), kIdBus); | 274 bus_ = device::UdevDeviceGetPropertyValue(udev_device.get(), kIdBus); |
275 | 275 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 const std::string& udev_id_vendor_from_database, | 337 const std::string& udev_id_vendor_from_database, |
338 const std::string& alsa_name, | 338 const std::string& alsa_name, |
339 const std::string& alsa_longname) { | 339 const std::string& alsa_longname) { |
340 // Let's try to determine the manufacturer. Here is the ordered preference | 340 // Let's try to determine the manufacturer. Here is the ordered preference |
341 // in extraction: | 341 // in extraction: |
342 // 1. Vendor name from the hardware device string, from udev properties | 342 // 1. Vendor name from the hardware device string, from udev properties |
343 // or sysattrs. | 343 // or sysattrs. |
344 // 2. Vendor name from the udev database (property ID_VENDOR_FROM_DATABASE). | 344 // 2. Vendor name from the udev database (property ID_VENDOR_FROM_DATABASE). |
345 // 3. Heuristic from ALSA. | 345 // 3. Heuristic from ALSA. |
346 | 346 |
347 // Is the vendor string not just the vendor hex id? | 347 // Is the vendor string present and not just the vendor hex id? |
348 if (udev_id_vendor != udev_id_vendor_id) { | 348 if (!udev_id_vendor.empty() && (udev_id_vendor != udev_id_vendor_id)) { |
349 return udev_id_vendor; | 349 return udev_id_vendor; |
350 } | 350 } |
351 | 351 |
352 // Is there a vendor string in the hardware database? | 352 // Is there a vendor string in the hardware database? |
353 if (!udev_id_vendor_from_database.empty()) { | 353 if (!udev_id_vendor_from_database.empty()) { |
354 return udev_id_vendor_from_database; | 354 return udev_id_vendor_from_database; |
355 } | 355 } |
356 | 356 |
357 // Ok, udev gave us nothing useful, or was unavailable. So try a heuristic. | 357 // Ok, udev gave us nothing useful, or was unavailable. So try a heuristic. |
358 // We assume that card longname is in the format of | 358 // We assume that card longname is in the format of |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
434 uint8 hash[crypto::kSHA256Length]; | 434 uint8 hash[crypto::kSHA256Length]; |
435 crypto::SHA256HashString(JSONValue(), &hash, sizeof(hash)); | 435 crypto::SHA256HashString(JSONValue(), &hash, sizeof(hash)); |
436 return base::HexEncode(&hash, sizeof(hash)); | 436 return base::HexEncode(&hash, sizeof(hash)); |
437 } | 437 } |
438 | 438 |
439 // TODO(agoode): Add a client->card/rawmidi mapping to the kernel to avoid | 439 // TODO(agoode): Add a client->card/rawmidi mapping to the kernel to avoid |
440 // needing to probe in this way. | 440 // needing to probe in this way. |
441 ScopedVector<MidiManagerAlsa::AlsaRawmidi> MidiManagerAlsa::AllAlsaRawmidis() { | 441 ScopedVector<MidiManagerAlsa::AlsaRawmidi> MidiManagerAlsa::AllAlsaRawmidis() { |
442 ScopedVector<AlsaRawmidi> devices; | 442 ScopedVector<AlsaRawmidi> devices; |
443 snd_ctl_card_info_t* card; | 443 snd_ctl_card_info_t* card; |
444 snd_rawmidi_info_t* midi_out; | 444 snd_hwdep_info_t* hwdep; |
445 snd_rawmidi_info_t* midi_in; | |
446 snd_ctl_card_info_alloca(&card); | 445 snd_ctl_card_info_alloca(&card); |
447 snd_rawmidi_info_alloca(&midi_out); | 446 snd_hwdep_info_alloca(&hwdep); |
448 snd_rawmidi_info_alloca(&midi_in); | |
449 for (int card_index = -1; !snd_card_next(&card_index) && card_index >= 0;) { | 447 for (int card_index = -1; !snd_card_next(&card_index) && card_index >= 0;) { |
450 const std::string id = base::StringPrintf("hw:CARD=%i", card_index); | 448 const std::string id = base::StringPrintf("hw:CARD=%i", card_index); |
451 snd_ctl_t* handle; | 449 snd_ctl_t* handle; |
452 int err = snd_ctl_open(&handle, id.c_str(), 0); | 450 int err = snd_ctl_open(&handle, id.c_str(), 0); |
453 if (err != 0) { | 451 if (err != 0) { |
454 VLOG(1) << "snd_ctl_open fails: " << snd_strerror(err); | 452 VLOG(1) << "snd_ctl_open fails: " << snd_strerror(err); |
455 continue; | 453 continue; |
456 } | 454 } |
457 err = snd_ctl_card_info(handle, card); | 455 err = snd_ctl_card_info(handle, card); |
458 if (err != 0) { | 456 if (err != 0) { |
459 VLOG(1) << "snd_ctl_card_info fails: " << snd_strerror(err); | 457 VLOG(1) << "snd_ctl_card_info fails: " << snd_strerror(err); |
460 snd_ctl_close(handle); | 458 snd_ctl_close(handle); |
461 continue; | 459 continue; |
462 } | 460 } |
463 // Enumerate any rawmidi devices (not subdevices) and extract AlsaRawmidi. | 461 std::string name = snd_ctl_card_info_get_name(card); |
462 std::string longname = snd_ctl_card_info_get_longname(card); | |
463 std::string driver = snd_ctl_card_info_get_driver(card); | |
464 | |
465 // Count rawmidi devices (not subdevices). | |
464 for (int device = -1; | 466 for (int device = -1; |
465 !snd_ctl_rawmidi_next_device(handle, &device) && device >= 0;) { | 467 !snd_ctl_rawmidi_next_device(handle, &device) && device >= 0;) { |
466 bool output; | 468 devices.push_back(new AlsaRawmidi(this, name, |
Takashi Toyoshima
2015/03/23 06:45:38
this indent style isn't bad, but how about using t
Adam Goode
2015/03/24 01:39:34
Done.
| |
467 bool input; | 469 longname, driver, card_index)); |
468 snd_rawmidi_info_set_device(midi_out, device); | 470 } |
469 snd_rawmidi_info_set_subdevice(midi_out, 0); | |
470 snd_rawmidi_info_set_stream(midi_out, SND_RAWMIDI_STREAM_OUTPUT); | |
471 output = snd_ctl_rawmidi_info(handle, midi_out) == 0; | |
472 snd_rawmidi_info_set_device(midi_in, device); | |
473 snd_rawmidi_info_set_subdevice(midi_in, 0); | |
474 snd_rawmidi_info_set_stream(midi_in, SND_RAWMIDI_STREAM_INPUT); | |
475 input = snd_ctl_rawmidi_info(handle, midi_in) == 0; | |
476 if (!output && !input) | |
477 continue; | |
478 | 471 |
479 // Compute and save ALSA and udev properties. | 472 // Count any hwdep synths that become MIDI devices. |
480 snd_rawmidi_info_t* midi = midi_out ? midi_out : midi_in; | 473 for (int device = -1; |
481 devices.push_back(new AlsaRawmidi(this, snd_rawmidi_info_get_name(midi), | 474 !snd_ctl_hwdep_next_device(handle, &device) && device >= 0;) { |
482 snd_ctl_card_info_get_longname(card), | 475 snd_ctl_hwdep_info(handle, hwdep); |
483 snd_ctl_card_info_get_driver(card), | 476 snd_hwdep_iface_t iface = snd_hwdep_info_get_iface(hwdep); |
484 card_index)); | 477 if (iface == SND_HWDEP_IFACE_OPL2 || iface == SND_HWDEP_IFACE_OPL3 || |
Takashi Toyoshima
2015/03/23 06:45:38
Hum... I'm not sure this is the right check to fin
Adam Goode
2015/03/24 01:39:34
Yes, explanation is needed. I've put a comment exp
| |
478 iface == SND_HWDEP_IFACE_OPL4) | |
479 devices.push_back( | |
480 new AlsaRawmidi(this, name, longname, driver, card_index)); | |
485 } | 481 } |
486 snd_ctl_close(handle); | 482 snd_ctl_close(handle); |
487 } | 483 } |
488 | 484 |
489 return devices.Pass(); | 485 return devices.Pass(); |
490 } | 486 } |
491 | 487 |
492 void MidiManagerAlsa::EnumeratePorts() { | 488 void MidiManagerAlsa::EnumeratePorts() { |
493 ScopedVector<AlsaRawmidi> devices = AllAlsaRawmidis(); | 489 ScopedVector<AlsaRawmidi> devices = AllAlsaRawmidis(); |
494 | 490 |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
727 } | 723 } |
728 } | 724 } |
729 } | 725 } |
730 } | 726 } |
731 | 727 |
732 MidiManager* MidiManager::Create() { | 728 MidiManager* MidiManager::Create() { |
733 return new MidiManagerAlsa(); | 729 return new MidiManagerAlsa(); |
734 } | 730 } |
735 | 731 |
736 } // namespace media | 732 } // namespace media |
OLD | NEW |