Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: media/midi/midi_manager_alsa.cc

Issue 1126983007: MidiManagerAlsa: Enable manufacturer again, now with hotplug (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@magical-sound-furnace
Patch Set: Fix midi_device for user clients Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/midi/midi_manager_alsa.h ('k') | media/midi/midi_manager_alsa_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <poll.h> 8 #include <poll.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <algorithm> 10 #include <algorithm>
(...skipping 19 matching lines...) Expand all
30 namespace midi { 30 namespace midi {
31 31
32 namespace { 32 namespace {
33 33
34 // Per-output buffer. This can be smaller, but then large sysex messages 34 // Per-output buffer. This can be smaller, but then large sysex messages
35 // will be (harmlessly) split across multiple seq events. This should 35 // will be (harmlessly) split across multiple seq events. This should
36 // not have any real practical effect, except perhaps to slightly reorder 36 // not have any real practical effect, except perhaps to slightly reorder
37 // realtime messages with respect to sysex. 37 // realtime messages with respect to sysex.
38 const size_t kSendBufferSize = 256; 38 const size_t kSendBufferSize = 256;
39 39
40 // Minimum client id for which we will have ALSA card devices for. When we
41 // are searching for card devices (used to get the path, id, and manufacturer),
42 // we don't want to get confused by kernel clients that do not have a card.
43 // See seq_clientmgr.c in the ALSA code for this.
44 // TODO(agoode): Add proper client -> card export from the kernel to avoid
45 // hardcoding.
46 const int kMinimumClientIdForCards = 16;
47
40 // ALSA constants. 48 // ALSA constants.
41 const char kAlsaHw[] = "hw"; 49 const char kAlsaHw[] = "hw";
42 50
43 // udev constants. 51 // udev constants.
44 const char kUdev[] = "udev"; 52 const char kUdev[] = "udev";
45 const char kUdevSubsystemSound[] = "sound"; 53 const char kUdevSubsystemSound[] = "sound";
46 const char kUdevPropertySoundInitialized[] = "SOUND_INITIALIZED"; 54 const char kUdevPropertySoundInitialized[] = "SOUND_INITIALIZED";
47 const char kUdevActionChange[] = "change"; 55 const char kUdevActionChange[] = "change";
48 const char kUdevActionRemove[] = "remove"; 56 const char kUdevActionRemove[] = "remove";
49 57
58 const char kUdevIdVendor[] = "ID_VENDOR";
59 const char kUdevIdVendorEnc[] = "ID_VENDOR_ENC";
60 const char kUdevIdVendorFromDatabase[] = "ID_VENDOR_FROM_DATABASE";
61 const char kUdevIdVendorId[] = "ID_VENDOR_ID";
62 const char kUdevIdModelId[] = "ID_MODEL_ID";
63 const char kUdevIdBus[] = "ID_BUS";
64 const char kUdevIdPath[] = "ID_PATH";
65 const char kUdevIdUsbInterfaceNum[] = "ID_USB_INTERFACE_NUM";
66 const char kUdevIdSerialShort[] = "ID_SERIAL_SHORT";
67
68 const char kSysattrVendorName[] = "vendor_name";
69 const char kSysattrVendor[] = "vendor";
70 const char kSysattrModel[] = "model";
71 const char kSysattrGuid[] = "guid";
72
73 const char kCardSyspath[] = "/card";
74
50 // Constants for the capabilities we search for in inputs and outputs. 75 // Constants for the capabilities we search for in inputs and outputs.
51 // See http://www.alsa-project.org/alsa-doc/alsa-lib/seq.html. 76 // See http://www.alsa-project.org/alsa-doc/alsa-lib/seq.html.
52 const unsigned int kRequiredInputPortCaps = 77 const unsigned int kRequiredInputPortCaps =
53 SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ; 78 SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ;
54 const unsigned int kRequiredOutputPortCaps = 79 const unsigned int kRequiredOutputPortCaps =
55 SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE; 80 SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;
56 81
57 const unsigned int kCreateOutputPortCaps = 82 const unsigned int kCreateOutputPortCaps =
58 SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_NO_EXPORT; 83 SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_NO_EXPORT;
59 const unsigned int kCreateInputPortCaps = 84 const unsigned int kCreateInputPortCaps =
60 SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_NO_EXPORT; 85 SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_NO_EXPORT;
61 const unsigned int kCreatePortType = 86 const unsigned int kCreatePortType =
62 SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION; 87 SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION;
63 88
64 int AddrToInt(int client, int port) { 89 int AddrToInt(int client, int port) {
65 return (client << 8) | port; 90 return (client << 8) | port;
66 } 91 }
67 92
93 bool IsCardKernelClient(snd_seq_client_type_t type, int client_id) {
94 return (type == SND_SEQ_KERNEL_CLIENT) &&
95 (client_id >= kMinimumClientIdForCards);
96 }
97
98 // TODO(agoode): Move this to device/udev_linux.
99 const std::string UdevDeviceGetPropertyOrSysattr(
100 struct udev_device* udev_device,
101 const char* property_key,
102 const char* sysattr_key) {
103 // First try the property.
104 std::string value =
105 device::UdevDeviceGetPropertyValue(udev_device, property_key);
106
107 // If no property, look for sysattrs and walk up the parent devices too.
108 while (value.empty() && udev_device) {
109 value = device::UdevDeviceGetSysattrValue(udev_device, sysattr_key);
110 udev_device = device::udev_device_get_parent(udev_device);
111 }
112 return value;
113 }
114
115 int GetCardNumber(udev_device* dev) {
116 const char* syspath = device::udev_device_get_syspath(dev);
117 if (!syspath)
118 return -1;
119
120 std::string syspath_str(syspath);
121 size_t i = syspath_str.rfind(kCardSyspath);
122 if (i == std::string::npos)
123 return -1;
124
125 int number;
126 if (!base::StringToInt(syspath_str.substr(i + strlen(kCardSyspath)), &number))
127 return -1;
128 return number;
129 }
130
68 void SetStringIfNonEmpty(base::DictionaryValue* value, 131 void SetStringIfNonEmpty(base::DictionaryValue* value,
69 const std::string& path, 132 const std::string& path,
70 const std::string& in_value) { 133 const std::string& in_value) {
71 if (!in_value.empty()) 134 if (!in_value.empty())
72 value->SetString(path, in_value); 135 value->SetString(path, in_value);
73 } 136 }
74 137
75 } // namespace 138 } // namespace
76 139
77 MidiManagerAlsa::MidiManagerAlsa() 140 MidiManagerAlsa::MidiManagerAlsa()
78 : in_client_(NULL), 141 : in_client_(NULL),
79 out_client_(NULL), 142 out_client_(NULL),
80 out_client_id_(-1), 143 out_client_id_(-1),
81 in_port_id_(-1), 144 in_port_id_(-1),
145 alsa_cards_deleter_(&alsa_cards_),
146 alsa_card_midi_count_(0),
82 decoder_(NULL), 147 decoder_(NULL),
83 udev_(device::udev_new()), 148 udev_(device::udev_new()),
84 send_thread_("MidiSendThread"), 149 send_thread_("MidiSendThread"),
85 event_thread_("MidiEventThread"), 150 event_thread_("MidiEventThread"),
86 event_thread_shutdown_(false) { 151 event_thread_shutdown_(false) {
87 // Initialize decoder. 152 // Initialize decoder.
88 snd_midi_event_new(0, &decoder_); 153 snd_midi_event_new(0, &decoder_);
89 snd_midi_event_no_status(decoder_, 1); 154 snd_midi_event_no_status(decoder_, 1);
90 } 155 }
91 156
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 break; 553 break;
489 case MidiPort::Type::kOutput: 554 case MidiPort::Type::kOutput:
490 web_port_index = num_output_ports_++; 555 web_port_index = num_output_ports_++;
491 break; 556 break;
492 } 557 }
493 port->set_web_port_index(web_port_index); 558 port->set_web_port_index(web_port_index);
494 ports()->push_back(port.Pass()); 559 ports()->push_back(port.Pass());
495 return web_port_index; 560 return web_port_index;
496 } 561 }
497 562
498 MidiManagerAlsa::AlsaSeqState::AlsaSeqState() : clients_deleter_(&clients_) { 563 MidiManagerAlsa::AlsaSeqState::AlsaSeqState()
564 : clients_deleter_(&clients_), kernel_client_count_(0) {
499 } 565 }
500 566
501 MidiManagerAlsa::AlsaSeqState::~AlsaSeqState() { 567 MidiManagerAlsa::AlsaSeqState::~AlsaSeqState() {
502 } 568 }
503 569
504 void MidiManagerAlsa::AlsaSeqState::ClientStart(int client_id, 570 void MidiManagerAlsa::AlsaSeqState::ClientStart(int client_id,
505 const std::string& client_name, 571 const std::string& client_name,
506 snd_seq_client_type_t type) { 572 snd_seq_client_type_t type) {
507 ClientExit(client_id); 573 ClientExit(client_id);
508 clients_[client_id] = new Client(client_name, type); 574 clients_[client_id] = new Client(client_name, type);
575 if (IsCardKernelClient(type, client_id))
576 ++kernel_client_count_;
509 } 577 }
510 578
511 bool MidiManagerAlsa::AlsaSeqState::ClientStarted(int client_id) { 579 bool MidiManagerAlsa::AlsaSeqState::ClientStarted(int client_id) {
512 return clients_.find(client_id) != clients_.end(); 580 return clients_.find(client_id) != clients_.end();
513 } 581 }
514 582
515 void MidiManagerAlsa::AlsaSeqState::ClientExit(int client_id) { 583 void MidiManagerAlsa::AlsaSeqState::ClientExit(int client_id) {
516 auto it = clients_.find(client_id); 584 auto it = clients_.find(client_id);
517 if (it != clients_.end()) { 585 if (it != clients_.end()) {
586 if (IsCardKernelClient(it->second->type(), client_id))
587 --kernel_client_count_;
518 delete it->second; 588 delete it->second;
519 clients_.erase(it); 589 clients_.erase(it);
520 } 590 }
521 } 591 }
522 592
523 void MidiManagerAlsa::AlsaSeqState::PortStart( 593 void MidiManagerAlsa::AlsaSeqState::PortStart(
524 int client_id, 594 int client_id,
525 int port_id, 595 int port_id,
526 const std::string& port_name, 596 const std::string& port_name,
527 MidiManagerAlsa::AlsaSeqState::PortDirection direction, 597 MidiManagerAlsa::AlsaSeqState::PortDirection direction,
(...skipping 12 matching lines...) Expand all
540 610
541 snd_seq_client_type_t MidiManagerAlsa::AlsaSeqState::ClientType( 611 snd_seq_client_type_t MidiManagerAlsa::AlsaSeqState::ClientType(
542 int client_id) const { 612 int client_id) const {
543 auto it = clients_.find(client_id); 613 auto it = clients_.find(client_id);
544 if (it == clients_.end()) 614 if (it == clients_.end())
545 return SND_SEQ_USER_CLIENT; 615 return SND_SEQ_USER_CLIENT;
546 return it->second->type(); 616 return it->second->type();
547 } 617 }
548 618
549 scoped_ptr<MidiManagerAlsa::TemporaryMidiPortState> 619 scoped_ptr<MidiManagerAlsa::TemporaryMidiPortState>
550 MidiManagerAlsa::AlsaSeqState::ToMidiPortState() { 620 MidiManagerAlsa::AlsaSeqState::ToMidiPortState(const AlsaCardMap& alsa_cards) {
551 scoped_ptr<MidiManagerAlsa::TemporaryMidiPortState> midi_ports( 621 scoped_ptr<MidiManagerAlsa::TemporaryMidiPortState> midi_ports(
552 new TemporaryMidiPortState); 622 new TemporaryMidiPortState);
553 // TODO(agoode): Use information from udev as well. 623 // TODO(agoode): Use more information from udev, to allow hardware matching.
624 // See http://crbug.com/486471.
625 auto card_it = alsa_cards.begin();
554 626
627 int card_midi_device = -1;
555 for (const auto& client_pair : clients_) { 628 for (const auto& client_pair : clients_) {
556 int client_id = client_pair.first; 629 int client_id = client_pair.first;
557 const auto& client = client_pair.second; 630 const auto& client = client_pair.second;
558 631
559 // Get client metadata. 632 // Get client metadata.
560 const std::string client_name = client->name(); 633 const std::string client_name = client->name();
561 std::string manufacturer; 634 std::string manufacturer;
562 std::string driver; 635 std::string driver;
563 std::string path; 636 std::string path;
564 std::string id; 637 std::string id;
565 std::string serial; 638 std::string serial;
566 std::string card_name; 639 std::string card_name;
567 std::string card_longname; 640 std::string card_longname;
568 int midi_device = -1; 641 int midi_device = -1;
569 642
643 if (IsCardKernelClient(client->type(), client_id)) {
644 auto& card = card_it->second;
645 if (card_midi_device == -1)
646 card_midi_device = 0;
647
648 manufacturer = card->manufacturer();
649 midi_device = card_midi_device;
650
651 ++card_midi_device;
652 if (card_midi_device >= card->midi_device_count()) {
653 card_midi_device = -1;
654 ++card_it;
655 }
656 }
657
570 for (const auto& port_pair : *client) { 658 for (const auto& port_pair : *client) {
571 int port_id = port_pair.first; 659 int port_id = port_pair.first;
572 const auto& port = port_pair.second; 660 const auto& port = port_pair.second;
573 661
574 if (port->midi()) { 662 if (port->midi()) {
575 std::string version; 663 std::string version;
576 if (!driver.empty()) { 664 if (!driver.empty()) {
577 version = driver + " / "; 665 version = driver + " / ";
578 } 666 }
579 version += 667 version +=
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 MidiManagerAlsa::AlsaSeqState::Client::PortMap::const_iterator 743 MidiManagerAlsa::AlsaSeqState::Client::PortMap::const_iterator
656 MidiManagerAlsa::AlsaSeqState::Client::begin() const { 744 MidiManagerAlsa::AlsaSeqState::Client::begin() const {
657 return ports_.begin(); 745 return ports_.begin();
658 } 746 }
659 747
660 MidiManagerAlsa::AlsaSeqState::Client::PortMap::const_iterator 748 MidiManagerAlsa::AlsaSeqState::Client::PortMap::const_iterator
661 MidiManagerAlsa::AlsaSeqState::Client::end() const { 749 MidiManagerAlsa::AlsaSeqState::Client::end() const {
662 return ports_.end(); 750 return ports_.end();
663 } 751 }
664 752
753 MidiManagerAlsa::AlsaCard::AlsaCard(udev_device* dev,
754 const std::string& alsa_name,
755 const std::string& alsa_longname,
756 const std::string& alsa_driver,
757 int midi_device_count)
758 : alsa_name_(alsa_name),
759 alsa_longname_(alsa_longname),
760 alsa_driver_(alsa_driver),
761 midi_device_count_(midi_device_count) {
762 // Try to get the vendor string. Sometimes it is encoded.
763 std::string vendor = device::UdevDecodeString(
764 device::UdevDeviceGetPropertyValue(dev, kUdevIdVendorEnc));
765 // Sometimes it is not encoded.
766 if (vendor.empty())
767 vendor =
768 UdevDeviceGetPropertyOrSysattr(dev, kUdevIdVendor, kSysattrVendorName);
769 // Also get the vendor string from the hardware database.
770 std::string vendor_from_database =
771 device::UdevDeviceGetPropertyValue(dev, kUdevIdVendorFromDatabase);
772
773 // Get the device path.
774 path_ = device::UdevDeviceGetPropertyValue(dev, kUdevIdPath);
775 // Get the bus.
776 bus_ = device::UdevDeviceGetPropertyValue(dev, kUdevIdBus);
777
778 // Get the "serial" number. (Often untrustable or missing.)
779 serial_ =
780 UdevDeviceGetPropertyOrSysattr(dev, kUdevIdSerialShort, kSysattrGuid);
781
782 // Get the vendor id, by either property or sysattr.
783 vendor_id_ =
784 UdevDeviceGetPropertyOrSysattr(dev, kUdevIdVendorId, kSysattrVendor);
785 // Get the model id, by either property or sysattr.
786 model_id_ =
787 UdevDeviceGetPropertyOrSysattr(dev, kUdevIdModelId, kSysattrModel);
788 // Get the usb interface number.
789 usb_interface_num_ =
790 device::UdevDeviceGetPropertyValue(dev, kUdevIdUsbInterfaceNum);
791 manufacturer_ = ExtractManufacturerString(
792 vendor, vendor_id_, vendor_from_database, alsa_name, alsa_longname);
793 }
794
795 MidiManagerAlsa::AlsaCard::~AlsaCard() {
796 }
797
665 // static 798 // static
666 std::string MidiManagerAlsa::ExtractManufacturerString( 799 std::string MidiManagerAlsa::AlsaCard::ExtractManufacturerString(
667 const std::string& udev_id_vendor, 800 const std::string& udev_id_vendor,
668 const std::string& udev_id_vendor_id, 801 const std::string& udev_id_vendor_id,
669 const std::string& udev_id_vendor_from_database, 802 const std::string& udev_id_vendor_from_database,
670 const std::string& alsa_name, 803 const std::string& alsa_name,
671 const std::string& alsa_longname) { 804 const std::string& alsa_longname) {
672 // Let's try to determine the manufacturer. Here is the ordered preference 805 // Let's try to determine the manufacturer. Here is the ordered preference
673 // in extraction: 806 // in extraction:
674 // 1. Vendor name from the hardware device string, from udev properties 807 // 1. Vendor name from the hardware device string, from udev properties
675 // or sysattrs. 808 // or sysattrs.
676 // 2. Vendor name from the udev database (property ID_VENDOR_FROM_DATABASE). 809 // 2. Vendor name from the udev database (property ID_VENDOR_FROM_DATABASE).
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 kUdevPropertySoundInitialized)) 1049 kUdevPropertySoundInitialized))
917 return; 1050 return;
918 1051
919 // Get the action. If no action, then we are doing first time enumeration 1052 // Get the action. If no action, then we are doing first time enumeration
920 // and the device is treated as new. 1053 // and the device is treated as new.
921 const char* action = device::udev_device_get_action(dev); 1054 const char* action = device::udev_device_get_action(dev);
922 if (!action) 1055 if (!action)
923 action = kUdevActionChange; 1056 action = kUdevActionChange;
924 1057
925 if (strcmp(action, kUdevActionChange) == 0) { 1058 if (strcmp(action, kUdevActionChange) == 0) {
926 // TODO(agoode): add 1059 AddCard(dev);
1060 // Generate Web MIDI events.
1061 UpdatePortStateAndGenerateEvents();
927 } else if (strcmp(action, kUdevActionRemove) == 0) { 1062 } else if (strcmp(action, kUdevActionRemove) == 0) {
928 // TODO(agoode): remove 1063 RemoveCard(GetCardNumber(dev));
1064 // Generate Web MIDI events.
1065 UpdatePortStateAndGenerateEvents();
929 } 1066 }
930 } 1067 }
931 1068
1069 void MidiManagerAlsa::AddCard(udev_device* dev) {
1070 int number = GetCardNumber(dev);
1071 if (number == -1)
1072 return;
1073
1074 RemoveCard(number);
1075
1076 snd_ctl_card_info_t* card;
1077 snd_hwdep_info_t* hwdep;
1078 snd_ctl_card_info_alloca(&card);
1079 snd_hwdep_info_alloca(&hwdep);
1080 const std::string id = base::StringPrintf("hw:CARD=%i", number);
1081 snd_ctl_t* handle;
1082 int err = snd_ctl_open(&handle, id.c_str(), 0);
1083 if (err != 0) {
1084 VLOG(1) << "snd_ctl_open fails: " << snd_strerror(err);
1085 return;
1086 }
1087 err = snd_ctl_card_info(handle, card);
1088 if (err != 0) {
1089 VLOG(1) << "snd_ctl_card_info fails: " << snd_strerror(err);
1090 snd_ctl_close(handle);
1091 return;
1092 }
1093 std::string name = snd_ctl_card_info_get_name(card);
1094 std::string longname = snd_ctl_card_info_get_longname(card);
1095 std::string driver = snd_ctl_card_info_get_driver(card);
1096
1097 // Count rawmidi devices (not subdevices).
1098 int midi_count = 0;
1099 for (int device = -1;
1100 !snd_ctl_rawmidi_next_device(handle, &device) && device >= 0;)
1101 ++midi_count;
1102
1103 // Count any hwdep synths that become MIDI devices outside of rawmidi.
1104 //
1105 // Explanation:
1106 // Any kernel driver can create an ALSA client (visible to us).
1107 // With modern hardware, only rawmidi devices do this. Kernel
1108 // drivers create rawmidi devices and the rawmidi subsystem makes
1109 // the seq clients. But the OPL3 driver is special, it does not
1110 // make a rawmidi device but a seq client directly. (This is the
1111 // only one to worry about in the kernel code, as of 2015-03-23.)
1112 //
1113 // OPL3 is very old (but still possible to get in new
1114 // hardware). It is unlikely that new drivers would not use
1115 // rawmidi and defeat our heuristic.
1116 //
1117 // Longer term, support should be added in the kernel to expose a
1118 // direct link from card->client (or client->card) so that all
1119 // these heuristics will be obsolete. Once that is there, we can
1120 // assume our old heuristics will work on old kernels and the new
1121 // robust code will be used on new. Then we will not need to worry
1122 // about changes to kernel internals breaking our code.
1123 // See the TODO above at kMinimumClientIdForCards.
1124 for (int device = -1;
1125 !snd_ctl_hwdep_next_device(handle, &device) && device >= 0;) {
1126 err = snd_ctl_hwdep_info(handle, hwdep);
1127 if (err != 0) {
1128 VLOG(1) << "snd_ctl_hwdep_info fails: " << snd_strerror(err);
1129 continue;
1130 }
1131 snd_hwdep_iface_t iface = snd_hwdep_info_get_iface(hwdep);
1132 if (iface == SND_HWDEP_IFACE_OPL2 || iface == SND_HWDEP_IFACE_OPL3 ||
1133 iface == SND_HWDEP_IFACE_OPL4)
1134 ++midi_count;
1135 }
1136 snd_ctl_close(handle);
1137
1138 if (midi_count > 0)
1139 alsa_cards_[number] = new AlsaCard(dev, name, longname, driver, midi_count);
1140 alsa_card_midi_count_ += midi_count;
1141 }
1142
1143 void MidiManagerAlsa::RemoveCard(int number) {
1144 auto it = alsa_cards_.find(number);
1145 if (it == alsa_cards_.end())
1146 return;
1147
1148 alsa_card_midi_count_ -= it->second->midi_device_count();
1149 delete it->second;
1150 alsa_cards_.erase(it);
1151 }
1152
932 void MidiManagerAlsa::UpdatePortStateAndGenerateEvents() { 1153 void MidiManagerAlsa::UpdatePortStateAndGenerateEvents() {
1154 if (alsa_card_midi_count_ != alsa_seq_state_.kernel_client_count())
Takashi Toyoshima 2015/05/11 12:32:04 Can you add some comments to know what this check
Adam Goode 2015/05/11 15:17:25 Yes. I also renamed the variables to be more clear
1155 return;
1156
933 // Generate new port state. 1157 // Generate new port state.
934 auto new_port_state = alsa_seq_state_.ToMidiPortState(); 1158 auto new_port_state = alsa_seq_state_.ToMidiPortState(alsa_cards_);
935 1159
936 // Disconnect any connected old ports that are now missing. 1160 // Disconnect any connected old ports that are now missing.
937 for (auto* old_port : port_state_) { 1161 for (auto* old_port : port_state_) {
938 if (old_port->connected() && 1162 if (old_port->connected() &&
939 (new_port_state->FindConnected(*old_port) == new_port_state->end())) { 1163 (new_port_state->FindConnected(*old_port) == new_port_state->end())) {
940 old_port->set_connected(false); 1164 old_port->set_connected(false);
941 uint32 web_port_index = old_port->web_port_index(); 1165 uint32 web_port_index = old_port->web_port_index();
942 switch (old_port->type()) { 1166 switch (old_port->type()) {
943 case MidiPort::Type::kInput: 1167 case MidiPort::Type::kInput:
944 source_map_.erase( 1168 source_map_.erase(
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 source_map_[AddrToInt(client_id, port_id)] = port_index; 1356 source_map_[AddrToInt(client_id, port_id)] = port_index;
1133 return true; 1357 return true;
1134 } 1358 }
1135 1359
1136 MidiManager* MidiManager::Create() { 1360 MidiManager* MidiManager::Create() {
1137 return new MidiManagerAlsa(); 1361 return new MidiManagerAlsa();
1138 } 1362 }
1139 1363
1140 } // namespace midi 1364 } // namespace midi
1141 } // namespace media 1365 } // namespace media
OLDNEW
« no previous file with comments | « media/midi/midi_manager_alsa.h ('k') | media/midi/midi_manager_alsa_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698