Chromium Code Reviews| 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 |