| 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 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 FROM_HERE, base::Bind(&MidiManagerAlsa::SendMidiData, | 236 FROM_HERE, base::Bind(&MidiManagerAlsa::SendMidiData, |
| 237 base::Unretained(this), port_index, data), | 237 base::Unretained(this), port_index, data), |
| 238 delay); | 238 delay); |
| 239 | 239 |
| 240 // Acknowledge send. | 240 // Acknowledge send. |
| 241 send_thread_.message_loop()->PostTask( | 241 send_thread_.message_loop()->PostTask( |
| 242 FROM_HERE, base::Bind(&MidiManagerClient::AccumulateMidiBytesSent, | 242 FROM_HERE, base::Bind(&MidiManagerClient::AccumulateMidiBytesSent, |
| 243 base::Unretained(client), data.size())); | 243 base::Unretained(client), data.size())); |
| 244 } | 244 } |
| 245 | 245 |
| 246 MidiManagerAlsa::AlsaRawmidi::AlsaRawmidi(const MidiManagerAlsa* outer, | 246 MidiManagerAlsa::AlsaCard::AlsaCard(const MidiManagerAlsa* outer, |
| 247 const std::string& alsa_name, | 247 const std::string& alsa_name, |
| 248 const std::string& alsa_longname, | 248 const std::string& alsa_longname, |
| 249 const std::string& alsa_driver, | 249 const std::string& alsa_driver, |
| 250 int card_index) | 250 int card_index, |
| 251 int midi_count) |
| 251 : alsa_name_(alsa_name), | 252 : alsa_name_(alsa_name), |
| 252 alsa_longname_(alsa_longname), | 253 alsa_longname_(alsa_longname), |
| 253 alsa_driver_(alsa_driver) { | 254 alsa_driver_(alsa_driver), |
| 255 midi_count_(midi_count) { |
| 254 // Get udev properties if available. | 256 // Get udev properties if available. |
| 255 std::string vendor; | 257 std::string vendor; |
| 256 std::string vendor_from_database; | 258 std::string vendor_from_database; |
| 257 | 259 |
| 258 #if defined(USE_UDEV) | 260 #if defined(USE_UDEV) |
| 259 const std::string sysname = base::StringPrintf("card%i", card_index); | 261 const std::string sysname = base::StringPrintf("card%i", card_index); |
| 260 device::ScopedUdevDevicePtr udev_device( | 262 device::ScopedUdevDevicePtr udev_device( |
| 261 device::udev_device_new_from_subsystem_sysname( | 263 device::udev_device_new_from_subsystem_sysname( |
| 262 outer->udev_.get(), kSoundClass, sysname.c_str())); | 264 outer->udev_.get(), kSoundClass, sysname.c_str())); |
| 263 | 265 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 290 | 292 |
| 291 // Get the usb interface number. | 293 // Get the usb interface number. |
| 292 usb_interface_num_ = | 294 usb_interface_num_ = |
| 293 device::UdevDeviceGetPropertyValue(udev_device.get(), kUsbInterfaceNum); | 295 device::UdevDeviceGetPropertyValue(udev_device.get(), kUsbInterfaceNum); |
| 294 #endif // defined(USE_UDEV) | 296 #endif // defined(USE_UDEV) |
| 295 | 297 |
| 296 manufacturer_ = ExtractManufacturerString( | 298 manufacturer_ = ExtractManufacturerString( |
| 297 vendor, vendor_id_, vendor_from_database, alsa_name, alsa_longname); | 299 vendor, vendor_id_, vendor_from_database, alsa_name, alsa_longname); |
| 298 } | 300 } |
| 299 | 301 |
| 300 MidiManagerAlsa::AlsaRawmidi::~AlsaRawmidi() { | 302 MidiManagerAlsa::AlsaCard::~AlsaCard() { |
| 301 } | 303 } |
| 302 | 304 |
| 303 const std::string MidiManagerAlsa::AlsaRawmidi::alsa_name() const { | 305 const std::string MidiManagerAlsa::AlsaCard::alsa_name() const { |
| 304 return alsa_name_; | 306 return alsa_name_; |
| 305 } | 307 } |
| 306 | 308 |
| 307 const std::string MidiManagerAlsa::AlsaRawmidi::alsa_longname() const { | 309 const std::string MidiManagerAlsa::AlsaCard::alsa_longname() const { |
| 308 return alsa_longname_; | 310 return alsa_longname_; |
| 309 } | 311 } |
| 310 | 312 |
| 311 const std::string MidiManagerAlsa::AlsaRawmidi::manufacturer() const { | 313 const std::string MidiManagerAlsa::AlsaCard::manufacturer() const { |
| 312 return manufacturer_; | 314 return manufacturer_; |
| 313 } | 315 } |
| 314 | 316 |
| 315 const std::string MidiManagerAlsa::AlsaRawmidi::alsa_driver() const { | 317 const std::string MidiManagerAlsa::AlsaCard::alsa_driver() const { |
| 316 return alsa_driver_; | 318 return alsa_driver_; |
| 317 } | 319 } |
| 318 | 320 |
| 319 const std::string MidiManagerAlsa::AlsaRawmidi::path() const { | 321 const std::string MidiManagerAlsa::AlsaCard::path() const { |
| 320 return path_; | 322 return path_; |
| 321 } | 323 } |
| 322 | 324 |
| 323 const std::string MidiManagerAlsa::AlsaRawmidi::bus() const { | 325 const std::string MidiManagerAlsa::AlsaCard::bus() const { |
| 324 return bus_; | 326 return bus_; |
| 325 } | 327 } |
| 326 | 328 |
| 327 const std::string MidiManagerAlsa::AlsaRawmidi::vendor_id() const { | 329 const std::string MidiManagerAlsa::AlsaCard::vendor_id() const { |
| 328 return vendor_id_; | 330 return vendor_id_; |
| 329 } | 331 } |
| 330 | 332 |
| 331 const std::string MidiManagerAlsa::AlsaRawmidi::id() const { | 333 const std::string MidiManagerAlsa::AlsaCard::id() const { |
| 332 std::string id = vendor_id_; | 334 std::string id = vendor_id_; |
| 333 if (!model_id_.empty()) | 335 if (!model_id_.empty()) |
| 334 id += ":" + model_id_; | 336 id += ":" + model_id_; |
| 335 if (!usb_interface_num_.empty()) | 337 if (!usb_interface_num_.empty()) |
| 336 id += ":" + usb_interface_num_; | 338 id += ":" + usb_interface_num_; |
| 337 return id; | 339 return id; |
| 338 } | 340 } |
| 339 | 341 |
| 342 const int MidiManagerAlsa::AlsaCard::midi_count() const { |
| 343 return midi_count_; |
| 344 } |
| 345 |
| 340 // static | 346 // static |
| 341 std::string MidiManagerAlsa::AlsaRawmidi::ExtractManufacturerString( | 347 std::string MidiManagerAlsa::AlsaCard::ExtractManufacturerString( |
| 342 const std::string& udev_id_vendor, | 348 const std::string& udev_id_vendor, |
| 343 const std::string& udev_id_vendor_id, | 349 const std::string& udev_id_vendor_id, |
| 344 const std::string& udev_id_vendor_from_database, | 350 const std::string& udev_id_vendor_from_database, |
| 345 const std::string& alsa_name, | 351 const std::string& alsa_name, |
| 346 const std::string& alsa_longname) { | 352 const std::string& alsa_longname) { |
| 347 // Let's try to determine the manufacturer. Here is the ordered preference | 353 // Let's try to determine the manufacturer. Here is the ordered preference |
| 348 // in extraction: | 354 // in extraction: |
| 349 // 1. Vendor name from the hardware device string, from udev properties | 355 // 1. Vendor name from the hardware device string, from udev properties |
| 350 // or sysattrs. | 356 // or sysattrs. |
| 351 // 2. Vendor name from the udev database (property ID_VENDOR_FROM_DATABASE). | 357 // 2. Vendor name from the udev database (property ID_VENDOR_FROM_DATABASE). |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 // mapping and just use a UUID or other random string. | 444 // mapping and just use a UUID or other random string. |
| 439 // http://crbug.com/465320 | 445 // http://crbug.com/465320 |
| 440 std::string MidiManagerAlsa::AlsaPortMetadata::OpaqueKey() const { | 446 std::string MidiManagerAlsa::AlsaPortMetadata::OpaqueKey() const { |
| 441 uint8 hash[crypto::kSHA256Length]; | 447 uint8 hash[crypto::kSHA256Length]; |
| 442 crypto::SHA256HashString(JSONValue(), &hash, sizeof(hash)); | 448 crypto::SHA256HashString(JSONValue(), &hash, sizeof(hash)); |
| 443 return base::HexEncode(&hash, sizeof(hash)); | 449 return base::HexEncode(&hash, sizeof(hash)); |
| 444 } | 450 } |
| 445 | 451 |
| 446 // TODO(agoode): Add a client->card/rawmidi mapping to the kernel to avoid | 452 // TODO(agoode): Add a client->card/rawmidi mapping to the kernel to avoid |
| 447 // needing to probe in this way. | 453 // needing to probe in this way. |
| 448 ScopedVector<MidiManagerAlsa::AlsaRawmidi> MidiManagerAlsa::AllAlsaRawmidis() { | 454 ScopedVector<MidiManagerAlsa::AlsaCard> MidiManagerAlsa::AllMidiCards() { |
| 449 ScopedVector<AlsaRawmidi> devices; | 455 ScopedVector<AlsaCard> devices; |
| 450 snd_ctl_card_info_t* card; | 456 snd_ctl_card_info_t* card; |
| 451 snd_hwdep_info_t* hwdep; | 457 snd_hwdep_info_t* hwdep; |
| 452 snd_ctl_card_info_alloca(&card); | 458 snd_ctl_card_info_alloca(&card); |
| 453 snd_hwdep_info_alloca(&hwdep); | 459 snd_hwdep_info_alloca(&hwdep); |
| 454 for (int card_index = -1; !snd_card_next(&card_index) && card_index >= 0;) { | 460 for (int card_index = -1; !snd_card_next(&card_index) && card_index >= 0;) { |
| 461 int midi_count = 0; |
| 455 const std::string id = base::StringPrintf("hw:CARD=%i", card_index); | 462 const std::string id = base::StringPrintf("hw:CARD=%i", card_index); |
| 456 snd_ctl_t* handle; | 463 snd_ctl_t* handle; |
| 457 int err = snd_ctl_open(&handle, id.c_str(), 0); | 464 int err = snd_ctl_open(&handle, id.c_str(), 0); |
| 458 if (err != 0) { | 465 if (err != 0) { |
| 459 VLOG(1) << "snd_ctl_open fails: " << snd_strerror(err); | 466 VLOG(1) << "snd_ctl_open fails: " << snd_strerror(err); |
| 460 continue; | 467 continue; |
| 461 } | 468 } |
| 462 err = snd_ctl_card_info(handle, card); | 469 err = snd_ctl_card_info(handle, card); |
| 463 if (err != 0) { | 470 if (err != 0) { |
| 464 VLOG(1) << "snd_ctl_card_info fails: " << snd_strerror(err); | 471 VLOG(1) << "snd_ctl_card_info fails: " << snd_strerror(err); |
| 465 snd_ctl_close(handle); | 472 snd_ctl_close(handle); |
| 466 continue; | 473 continue; |
| 467 } | 474 } |
| 468 std::string name = snd_ctl_card_info_get_name(card); | 475 std::string name = snd_ctl_card_info_get_name(card); |
| 469 std::string longname = snd_ctl_card_info_get_longname(card); | 476 std::string longname = snd_ctl_card_info_get_longname(card); |
| 470 std::string driver = snd_ctl_card_info_get_driver(card); | 477 std::string driver = snd_ctl_card_info_get_driver(card); |
| 471 | 478 |
| 472 // Count rawmidi devices (not subdevices). | 479 // Count rawmidi devices (not subdevices). |
| 473 for (int device = -1; | 480 for (int device = -1; |
| 474 !snd_ctl_rawmidi_next_device(handle, &device) && device >= 0;) { | 481 !snd_ctl_rawmidi_next_device(handle, &device) && device >= 0;) |
| 475 devices.push_back( | 482 ++midi_count; |
| 476 new AlsaRawmidi(this, name, longname, driver, card_index)); | |
| 477 } | |
| 478 | 483 |
| 479 // Count any hwdep synths that become MIDI devices. | 484 // Count any hwdep synths that become MIDI devices outside of rawmidi. |
| 480 // | 485 // |
| 481 // Explanation: | 486 // Explanation: |
| 482 // Any kernel driver can create an ALSA client (visible to us). | 487 // Any kernel driver can create an ALSA client (visible to us). |
| 483 // With modern hardware, only rawmidi devices do this. Kernel | 488 // With modern hardware, only rawmidi devices do this. Kernel |
| 484 // drivers create rawmidi devices and the rawmidi subsystem makes | 489 // drivers create rawmidi devices and the rawmidi subsystem makes |
| 485 // the seq clients. But the OPL3 driver is special, it does not | 490 // the seq clients. But the OPL3 driver is special, it does not |
| 486 // make a rawmidi device but a seq client directly. (This is the | 491 // make a rawmidi device but a seq client directly. (This is the |
| 487 // only one to worry about in the kernel code, as of 2015-03-23.) | 492 // only one to worry about in the kernel code, as of 2015-03-23.) |
| 488 // | 493 // |
| 489 // OPL3 is very old (but still possible to get in new | 494 // OPL3 is very old (but still possible to get in new |
| 490 // hardware). It is unlikely that new drivers would not use | 495 // hardware). It is unlikely that new drivers would not use |
| 491 // rawmidi and defeat our heuristic. | 496 // rawmidi and defeat our heuristic. |
| 492 // | 497 // |
| 493 // Longer term, support should be added in the kernel to expose a | 498 // Longer term, support should be added in the kernel to expose a |
| 494 // direct link from card->client (or client->card) so that all | 499 // direct link from card->client (or client->card) so that all |
| 495 // these heuristics will be obsolete. Once that is there, we can | 500 // these heuristics will be obsolete. Once that is there, we can |
| 496 // assume our old heuristics will work on old kernels and the new | 501 // assume our old heuristics will work on old kernels and the new |
| 497 // robust code will be used on new. Then we will not need to worry | 502 // robust code will be used on new. Then we will not need to worry |
| 498 // about changes to kernel internals breaking our code. | 503 // about changes to kernel internals breaking our code. |
| 499 // See the TODO above at kMinimumClientIdForCards. | 504 // See the TODO above at kMinimumClientIdForCards. |
| 500 for (int device = -1; | 505 for (int device = -1; |
| 501 !snd_ctl_hwdep_next_device(handle, &device) && device >= 0;) { | 506 !snd_ctl_hwdep_next_device(handle, &device) && device >= 0;) { |
| 502 snd_ctl_hwdep_info(handle, hwdep); | 507 snd_ctl_hwdep_info(handle, hwdep); |
| 503 snd_hwdep_iface_t iface = snd_hwdep_info_get_iface(hwdep); | 508 snd_hwdep_iface_t iface = snd_hwdep_info_get_iface(hwdep); |
| 504 if (iface == SND_HWDEP_IFACE_OPL2 || iface == SND_HWDEP_IFACE_OPL3 || | 509 if (iface == SND_HWDEP_IFACE_OPL2 || iface == SND_HWDEP_IFACE_OPL3 || |
| 505 iface == SND_HWDEP_IFACE_OPL4) | 510 iface == SND_HWDEP_IFACE_OPL4) |
| 506 devices.push_back( | 511 ++midi_count; |
| 507 new AlsaRawmidi(this, name, longname, driver, card_index)); | |
| 508 } | 512 } |
| 513 |
| 514 if (midi_count > 0) |
| 515 devices.push_back( |
| 516 new AlsaCard(this, name, longname, driver, card_index, midi_count)); |
| 509 snd_ctl_close(handle); | 517 snd_ctl_close(handle); |
| 510 } | 518 } |
| 511 | 519 |
| 512 return devices.Pass(); | 520 return devices.Pass(); |
| 513 } | 521 } |
| 514 | 522 |
| 515 void MidiManagerAlsa::EnumeratePorts() { | 523 void MidiManagerAlsa::EnumeratePorts() { |
| 516 ScopedVector<AlsaRawmidi> devices = AllAlsaRawmidis(); | 524 ScopedVector<AlsaCard> cards = AllMidiCards(); |
| 525 std::vector<const AlsaCard*> devices; |
| 526 for (const auto* card : cards) { |
| 527 // Insert 1 AlsaCard per number of MIDI devices. |
| 528 for (int n = 0; n < card->midi_count(); ++n) |
| 529 devices.push_back(card); |
| 530 } |
| 517 | 531 |
| 518 snd_seq_port_subscribe_t* subs; | 532 snd_seq_port_subscribe_t* subs; |
| 519 snd_seq_port_subscribe_alloca(&subs); | 533 snd_seq_port_subscribe_alloca(&subs); |
| 520 | 534 |
| 521 int in_client_id = snd_seq_client_id(in_client_); | 535 int in_client_id = snd_seq_client_id(in_client_); |
| 522 | 536 |
| 523 // Enumerate all clients. | 537 // Enumerate all clients. |
| 524 snd_seq_client_info_t* client_info; | 538 snd_seq_client_info_t* client_info; |
| 525 snd_seq_client_info_alloca(&client_info); | 539 snd_seq_client_info_alloca(&client_info); |
| 526 snd_seq_port_info_t* port_info; | 540 snd_seq_port_info_t* port_info; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 544 | 558 |
| 545 std::string manufacturer; | 559 std::string manufacturer; |
| 546 std::string driver; | 560 std::string driver; |
| 547 std::string path; | 561 std::string path; |
| 548 std::string bus; | 562 std::string bus; |
| 549 std::string vendor_id; | 563 std::string vendor_id; |
| 550 std::string id; | 564 std::string id; |
| 551 std::string card_name; | 565 std::string card_name; |
| 552 std::string card_longname; | 566 std::string card_longname; |
| 553 | 567 |
| 554 // Join kernel clients against the list of AlsaRawmidis. | 568 // Join kernel clients against the list of AlsaCards. |
| 555 // In the current ALSA kernel implementation, kernel clients match the | 569 // In the current ALSA kernel implementation, kernel clients match the |
| 556 // kernel devices in the same order, for devices with client_id over | 570 // kernel devices in the same order, for clients with client_id over |
| 557 // kMinimumClientIdForCards. | 571 // kMinimumClientIdForCards. |
| 558 if ((snd_seq_client_info_get_type(client_info) == SND_SEQ_KERNEL_CLIENT) && | 572 if ((snd_seq_client_info_get_type(client_info) == SND_SEQ_KERNEL_CLIENT) && |
| 559 (current_device < devices.size()) && | 573 (current_device < devices.size()) && |
| 560 (client_id >= kMinimumClientIdForCards)) { | 574 (client_id >= kMinimumClientIdForCards)) { |
| 561 const AlsaRawmidi* device = devices[current_device]; | 575 const AlsaCard* device = devices[current_device]; |
| 562 manufacturer = device->manufacturer(); | 576 manufacturer = device->manufacturer(); |
| 563 driver = device->alsa_driver(); | 577 driver = device->alsa_driver(); |
| 564 path = device->path(); | 578 path = device->path(); |
| 565 bus = device->bus(); | 579 bus = device->bus(); |
| 566 vendor_id = device->vendor_id(); | 580 vendor_id = device->vendor_id(); |
| 567 id = device->id(); | 581 id = device->id(); |
| 568 card_name = device->alsa_name(); | 582 card_name = device->alsa_name(); |
| 569 card_longname = device->alsa_longname(); | 583 card_longname = device->alsa_longname(); |
| 570 current_device++; | 584 current_device++; |
| 571 } | 585 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 } | 707 } |
| 694 | 708 |
| 695 // Handle announce events. | 709 // Handle announce events. |
| 696 if (event->source.client == SND_SEQ_CLIENT_SYSTEM && | 710 if (event->source.client == SND_SEQ_CLIENT_SYSTEM && |
| 697 event->source.port == SND_SEQ_PORT_SYSTEM_ANNOUNCE) { | 711 event->source.port == SND_SEQ_PORT_SYSTEM_ANNOUNCE) { |
| 698 switch (event->type) { | 712 switch (event->type) { |
| 699 case SND_SEQ_EVENT_CLIENT_START: | 713 case SND_SEQ_EVENT_CLIENT_START: |
| 700 // TODO(agoode): rescan hardware devices. | 714 // TODO(agoode): rescan hardware devices. |
| 701 break; | 715 break; |
| 702 | 716 |
| 717 case SND_SEQ_EVENT_PORT_START: |
| 718 // TODO(agoode): add port. |
| 719 break; |
| 720 |
| 703 case SND_SEQ_EVENT_CLIENT_EXIT: | 721 case SND_SEQ_EVENT_CLIENT_EXIT: |
| 704 // Check for disconnection of our "out" client. This means "shut down". | 722 // Check for disconnection of our "out" client. This means "shut down". |
| 705 if (event->data.addr.client == out_client_id_) | 723 if (event->data.addr.client == out_client_id_) |
| 706 return; | 724 return; |
| 707 | 725 |
| 708 // TODO(agoode): remove all ports for a client. | 726 // TODO(agoode): remove all ports for a client. |
| 709 break; | 727 break; |
| 710 | 728 |
| 711 case SND_SEQ_EVENT_PORT_START: | |
| 712 // TODO(agoode): add port. | |
| 713 break; | |
| 714 | |
| 715 case SND_SEQ_EVENT_PORT_EXIT: | 729 case SND_SEQ_EVENT_PORT_EXIT: |
| 716 // TODO(agoode): remove port. | 730 // TODO(agoode): remove port. |
| 717 break; | 731 break; |
| 718 } | 732 } |
| 733 } else { |
| 734 ProcessSingleEvent(event, timestamp); |
| 719 } | 735 } |
| 720 | 736 |
| 721 ProcessSingleEvent(event, timestamp); | |
| 722 | |
| 723 // Do again. | 737 // Do again. |
| 724 ScheduleEventLoop(); | 738 ScheduleEventLoop(); |
| 725 } | 739 } |
| 726 | 740 |
| 727 void MidiManagerAlsa::ProcessSingleEvent(snd_seq_event_t* event, | 741 void MidiManagerAlsa::ProcessSingleEvent(snd_seq_event_t* event, |
| 728 double timestamp) { | 742 double timestamp) { |
| 729 std::map<int, uint32>::iterator source_it = | 743 auto source_it = source_map_.find(AddrToInt(&event->source)); |
| 730 source_map_.find(AddrToInt(&event->source)); | |
| 731 if (source_it != source_map_.end()) { | 744 if (source_it != source_map_.end()) { |
| 732 uint32 source = source_it->second; | 745 uint32 source = source_it->second; |
| 733 if (event->type == SND_SEQ_EVENT_SYSEX) { | 746 if (event->type == SND_SEQ_EVENT_SYSEX) { |
| 734 // Special! Variable-length sysex. | 747 // Special! Variable-length sysex. |
| 735 ReceiveMidiData(source, static_cast<const uint8*>(event->data.ext.ptr), | 748 ReceiveMidiData(source, static_cast<const uint8*>(event->data.ext.ptr), |
| 736 event->data.ext.len, timestamp); | 749 event->data.ext.len, timestamp); |
| 737 } else { | 750 } else { |
| 738 // Otherwise, decode this and send that on. | 751 // Otherwise, decode this and send that on. |
| 739 unsigned char buf[12]; | 752 unsigned char buf[12]; |
| 740 long count = snd_midi_event_decode(decoder_, buf, sizeof(buf), event); | 753 long count = snd_midi_event_decode(decoder_, buf, sizeof(buf), event); |
| 741 if (count <= 0) { | 754 if (count <= 0) { |
| 742 if (count != -ENOENT) { | 755 if (count != -ENOENT) { |
| 743 // ENOENT means that it's not a MIDI message, which is not an | 756 // ENOENT means that it's not a MIDI message, which is not an |
| 744 // error, but other negative values are errors for us. | 757 // error, but other negative values are errors for us. |
| 745 VLOG(1) << "snd_midi_event_decoder fails " << snd_strerror(count); | 758 VLOG(1) << "snd_midi_event_decoder fails " << snd_strerror(count); |
| 746 // TODO(agoode): Record this failure. | 759 // TODO(agoode): Record this failure. |
| 747 } | 760 } |
| 748 } else { | 761 } else { |
| 749 ReceiveMidiData(source, buf, count, timestamp); | 762 ReceiveMidiData(source, buf, count, timestamp); |
| 750 } | 763 } |
| 751 } | 764 } |
| 752 } | 765 } |
| 753 } | 766 } |
| 754 | 767 |
| 755 MidiManager* MidiManager::Create() { | 768 MidiManager* MidiManager::Create() { |
| 756 return new MidiManagerAlsa(); | 769 return new MidiManagerAlsa(); |
| 757 } | 770 } |
| 758 | 771 |
| 759 } // namespace media | 772 } // namespace media |
| OLD | NEW |