OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_win.h" | 5 #include "media/midi/midi_manager_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <ks.h> | 8 #include <ks.h> |
9 #include <ksmedia.h> | 9 #include <ksmedia.h> |
10 #include <mmreg.h> | 10 #include <mmreg.h> |
(...skipping 12 matching lines...) Loading... |
23 | 23 |
24 #include <algorithm> | 24 #include <algorithm> |
25 #include <functional> | 25 #include <functional> |
26 #include <queue> | 26 #include <queue> |
27 #include <string> | 27 #include <string> |
28 | 28 |
29 #include "base/bind.h" | 29 #include "base/bind.h" |
30 #include "base/containers/hash_tables.h" | 30 #include "base/containers/hash_tables.h" |
31 #include "base/macros.h" | 31 #include "base/macros.h" |
32 #include "base/message_loop/message_loop.h" | 32 #include "base/message_loop/message_loop.h" |
| 33 #include "base/single_thread_task_runner.h" |
33 #include "base/strings/string16.h" | 34 #include "base/strings/string16.h" |
34 #include "base/strings/string_number_conversions.h" | 35 #include "base/strings/string_number_conversions.h" |
35 #include "base/strings/string_piece.h" | 36 #include "base/strings/string_piece.h" |
36 #include "base/strings/stringprintf.h" | 37 #include "base/strings/stringprintf.h" |
37 #include "base/strings/utf_string_conversions.h" | 38 #include "base/strings/utf_string_conversions.h" |
38 #include "base/system_monitor/system_monitor.h" | 39 #include "base/system_monitor/system_monitor.h" |
39 #include "base/threading/thread_checker.h" | 40 #include "base/threading/thread_checker.h" |
40 #include "base/timer/timer.h" | 41 #include "base/timer/timer.h" |
41 #include "base/win/message_window.h" | 42 #include "base/win/message_window.h" |
42 #include "device/usb/usb_ids.h" | 43 #include "device/usb/usb_ids.h" |
(...skipping 451 matching lines...) Loading... |
494 sender_thread_.Start(); | 495 sender_thread_.Start(); |
495 task_thread_.Start(); | 496 task_thread_.Start(); |
496 | 497 |
497 // Start monitoring device changes. This should start before the | 498 // Start monitoring device changes. This should start before the |
498 // following UpdateDeviceList() call not to miss the event happening | 499 // following UpdateDeviceList() call not to miss the event happening |
499 // between the call and the observer registration. | 500 // between the call and the observer registration. |
500 base::SystemMonitor::Get()->AddDevicesChangedObserver(this); | 501 base::SystemMonitor::Get()->AddDevicesChangedObserver(this); |
501 | 502 |
502 UpdateDeviceList(); | 503 UpdateDeviceList(); |
503 | 504 |
504 task_thread_.message_loop()->PostTask( | 505 task_thread_.task_runner()->PostTask( |
505 FROM_HERE, | 506 FROM_HERE, |
506 base::Bind(&MidiServiceWinImpl::CompleteInitializationOnTaskThread, | 507 base::Bind(&MidiServiceWinImpl::CompleteInitializationOnTaskThread, |
507 base::Unretained(this), Result::OK)); | 508 base::Unretained(this), Result::OK)); |
508 } | 509 } |
509 | 510 |
510 void SendMidiDataAsync(uint32_t port_number, | 511 void SendMidiDataAsync(uint32_t port_number, |
511 const std::vector<uint8_t>& data, | 512 const std::vector<uint8_t>& data, |
512 base::TimeTicks time) final { | 513 base::TimeTicks time) final { |
513 if (destructor_started) { | 514 if (destructor_started) { |
514 LOG(ERROR) << "ThreadSafeSendData failed because MidiServiceWinImpl is " | 515 LOG(ERROR) << "ThreadSafeSendData failed because MidiServiceWinImpl is " |
515 "being destructed. port: " << port_number; | 516 "being destructed. port: " << port_number; |
516 return; | 517 return; |
517 } | 518 } |
518 auto state = GetOutputDeviceFromPort(port_number); | 519 auto state = GetOutputDeviceFromPort(port_number); |
519 if (!state) { | 520 if (!state) { |
520 LOG(ERROR) << "ThreadSafeSendData failed due to an invalid port number. " | 521 LOG(ERROR) << "ThreadSafeSendData failed due to an invalid port number. " |
521 << "port: " << port_number; | 522 << "port: " << port_number; |
522 return; | 523 return; |
523 } | 524 } |
524 if (state->closed) { | 525 if (state->closed) { |
525 LOG(ERROR) | 526 LOG(ERROR) |
526 << "ThreadSafeSendData failed because target port is already closed." | 527 << "ThreadSafeSendData failed because target port is already closed." |
527 << "port: " << port_number; | 528 << "port: " << port_number; |
528 return; | 529 return; |
529 } | 530 } |
530 const auto now = base::TimeTicks::Now(); | 531 const auto now = base::TimeTicks::Now(); |
531 if (now < time) { | 532 if (now < time) { |
532 sender_thread_.message_loop()->PostDelayedTask( | 533 sender_thread_.task_runner()->PostDelayedTask( |
533 FROM_HERE, base::Bind(&MidiServiceWinImpl::SendOnSenderThread, | 534 FROM_HERE, base::Bind(&MidiServiceWinImpl::SendOnSenderThread, |
534 base::Unretained(this), port_number, | 535 base::Unretained(this), port_number, |
535 state->port_age, data, time), | 536 state->port_age, data, time), |
536 time - now); | 537 time - now); |
537 } else { | 538 } else { |
538 sender_thread_.message_loop()->PostTask( | 539 sender_thread_.task_runner()->PostTask( |
539 FROM_HERE, base::Bind(&MidiServiceWinImpl::SendOnSenderThread, | 540 FROM_HERE, base::Bind(&MidiServiceWinImpl::SendOnSenderThread, |
540 base::Unretained(this), port_number, | 541 base::Unretained(this), port_number, |
541 state->port_age, data, time)); | 542 state->port_age, data, time)); |
542 } | 543 } |
543 } | 544 } |
544 | 545 |
545 // base::SystemMonitor::DevicesChangedObserver overrides: | 546 // base::SystemMonitor::DevicesChangedObserver overrides: |
546 void OnDevicesChanged(base::SystemMonitor::DeviceType device_type) final { | 547 void OnDevicesChanged(base::SystemMonitor::DeviceType device_type) final { |
547 DCHECK(thread_checker_.CalledOnValidThread()); | 548 DCHECK(thread_checker_.CalledOnValidThread()); |
548 if (destructor_started) | 549 if (destructor_started) |
(...skipping 29 matching lines...) Loading... |
578 | 579 |
579 scoped_refptr<MidiOutputDeviceState> GetOutputDeviceFromPort( | 580 scoped_refptr<MidiOutputDeviceState> GetOutputDeviceFromPort( |
580 uint32_t port_number) { | 581 uint32_t port_number) { |
581 base::AutoLock auto_lock(output_ports_lock_); | 582 base::AutoLock auto_lock(output_ports_lock_); |
582 if (output_ports_.size() <= port_number) | 583 if (output_ports_.size() <= port_number) |
583 return nullptr; | 584 return nullptr; |
584 return output_ports_[port_number]; | 585 return output_ports_[port_number]; |
585 } | 586 } |
586 | 587 |
587 void UpdateDeviceList() { | 588 void UpdateDeviceList() { |
588 task_thread_.message_loop()->PostTask( | 589 task_thread_.task_runner()->PostTask( |
589 FROM_HERE, base::Bind(&MidiServiceWinImpl::UpdateDeviceListOnTaskThread, | 590 FROM_HERE, base::Bind(&MidiServiceWinImpl::UpdateDeviceListOnTaskThread, |
590 base::Unretained(this))); | 591 base::Unretained(this))); |
591 } | 592 } |
592 | 593 |
593 ///////////////////////////////////////////////////////////////////////////// | 594 ///////////////////////////////////////////////////////////////////////////// |
594 // Callbacks on the OS multimedia thread. | 595 // Callbacks on the OS multimedia thread. |
595 ///////////////////////////////////////////////////////////////////////////// | 596 ///////////////////////////////////////////////////////////////////////////// |
596 | 597 |
597 static void CALLBACK | 598 static void CALLBACK |
598 OnMidiInEventOnMainlyMultimediaThread(HMIDIIN midi_in_handle, | 599 OnMidiInEventOnMainlyMultimediaThread(HMIDIIN midi_in_handle, |
(...skipping 59 matching lines...) Loading... |
658 } | 659 } |
659 input_ports_[port_number] = state; | 660 input_ports_[port_number] = state; |
660 | 661 |
661 input_ports_ages_[port_number] += 1; | 662 input_ports_ages_[port_number] += 1; |
662 input_device_map_[input_ports_[port_number]->midi_handle] = | 663 input_device_map_[input_ports_[port_number]->midi_handle] = |
663 input_ports_[port_number]; | 664 input_ports_[port_number]; |
664 input_ports_[port_number]->port_index = port_number; | 665 input_ports_[port_number]->port_index = port_number; |
665 input_ports_[port_number]->port_age = input_ports_ages_[port_number]; | 666 input_ports_[port_number]->port_age = input_ports_ages_[port_number]; |
666 } | 667 } |
667 // Several initial startup tasks cannot be done in MIM_OPEN handler. | 668 // Several initial startup tasks cannot be done in MIM_OPEN handler. |
668 task_thread_.message_loop()->PostTask( | 669 task_thread_.task_runner()->PostTask( |
669 FROM_HERE, base::Bind(&MidiServiceWinImpl::StartInputDeviceOnTaskThread, | 670 FROM_HERE, base::Bind(&MidiServiceWinImpl::StartInputDeviceOnTaskThread, |
670 base::Unretained(this), midi_in_handle)); | 671 base::Unretained(this), midi_in_handle)); |
671 if (add_new_port) { | 672 if (add_new_port) { |
672 const MidiPortInfo port_info( | 673 const MidiPortInfo port_info( |
673 // TODO(toyoshim): Use a hash ID insted crbug.com/467448 | 674 // TODO(toyoshim): Use a hash ID insted crbug.com/467448 |
674 base::IntToString(static_cast<int>(port_number)), | 675 base::IntToString(static_cast<int>(port_number)), |
675 GetManufacturerName(state_device_info), | 676 GetManufacturerName(state_device_info), |
676 base::WideToUTF8(state_device_info.product_name), | 677 base::WideToUTF8(state_device_info.product_name), |
677 MmversionToString(state_device_info.driver_version), | 678 MmversionToString(state_device_info.driver_version), |
678 MIDI_PORT_OPENED); | 679 MIDI_PORT_OPENED); |
679 task_thread_.message_loop()->PostTask( | 680 task_thread_.task_runner()->PostTask( |
680 FROM_HERE, base::Bind(&MidiServiceWinImpl::AddInputPortOnTaskThread, | 681 FROM_HERE, base::Bind(&MidiServiceWinImpl::AddInputPortOnTaskThread, |
681 base::Unretained(this), port_info)); | 682 base::Unretained(this), port_info)); |
682 } else { | 683 } else { |
683 task_thread_.message_loop()->PostTask( | 684 task_thread_.task_runner()->PostTask( |
684 FROM_HERE, | 685 FROM_HERE, |
685 base::Bind(&MidiServiceWinImpl::SetInputPortStateOnTaskThread, | 686 base::Bind(&MidiServiceWinImpl::SetInputPortStateOnTaskThread, |
686 base::Unretained(this), port_number, | 687 base::Unretained(this), port_number, |
687 MidiPortState::MIDI_PORT_CONNECTED)); | 688 MidiPortState::MIDI_PORT_CONNECTED)); |
688 } | 689 } |
689 } | 690 } |
690 | 691 |
691 void OnMidiInDataOnMultimediaThread(HMIDIIN midi_in_handle, | 692 void OnMidiInDataOnMultimediaThread(HMIDIIN midi_in_handle, |
692 DWORD_PTR param1, | 693 DWORD_PTR param1, |
693 DWORD_PTR param2) { | 694 DWORD_PTR param2) { |
694 auto state = GetInputDeviceFromHandle(midi_in_handle); | 695 auto state = GetInputDeviceFromHandle(midi_in_handle); |
695 if (!state) | 696 if (!state) |
696 return; | 697 return; |
697 const uint8_t status_byte = static_cast<uint8_t>(param1 & 0xff); | 698 const uint8_t status_byte = static_cast<uint8_t>(param1 & 0xff); |
698 const uint8_t first_data_byte = static_cast<uint8_t>((param1 >> 8) & 0xff); | 699 const uint8_t first_data_byte = static_cast<uint8_t>((param1 >> 8) & 0xff); |
699 const uint8_t second_data_byte = | 700 const uint8_t second_data_byte = |
700 static_cast<uint8_t>((param1 >> 16) & 0xff); | 701 static_cast<uint8_t>((param1 >> 16) & 0xff); |
701 const DWORD elapsed_ms = param2; | 702 const DWORD elapsed_ms = param2; |
702 const size_t len = GetMidiMessageLength(status_byte); | 703 const size_t len = GetMidiMessageLength(status_byte); |
703 const uint8_t kData[] = {status_byte, first_data_byte, second_data_byte}; | 704 const uint8_t kData[] = {status_byte, first_data_byte, second_data_byte}; |
704 std::vector<uint8_t> data; | 705 std::vector<uint8_t> data; |
705 data.assign(kData, kData + len); | 706 data.assign(kData, kData + len); |
706 DCHECK_LE(len, arraysize(kData)); | 707 DCHECK_LE(len, arraysize(kData)); |
707 // MIM_DATA/MIM_LONGDATA message treats the time when midiInStart() is | 708 // MIM_DATA/MIM_LONGDATA message treats the time when midiInStart() is |
708 // called as the origin of |elapsed_ms|. | 709 // called as the origin of |elapsed_ms|. |
709 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd757284.aspx | 710 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd757284.aspx |
710 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd757286.aspx | 711 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd757286.aspx |
711 const base::TimeTicks event_time = | 712 const base::TimeTicks event_time = |
712 state->start_time + base::TimeDelta::FromMilliseconds(elapsed_ms); | 713 state->start_time + base::TimeDelta::FromMilliseconds(elapsed_ms); |
713 task_thread_.message_loop()->PostTask( | 714 task_thread_.task_runner()->PostTask( |
714 FROM_HERE, base::Bind(&MidiServiceWinImpl::ReceiveMidiDataOnTaskThread, | 715 FROM_HERE, base::Bind(&MidiServiceWinImpl::ReceiveMidiDataOnTaskThread, |
715 base::Unretained(this), state->port_index, data, | 716 base::Unretained(this), state->port_index, data, |
716 event_time)); | 717 event_time)); |
717 } | 718 } |
718 | 719 |
719 void OnMidiInLongDataOnMultimediaThread(HMIDIIN midi_in_handle, | 720 void OnMidiInLongDataOnMultimediaThread(HMIDIIN midi_in_handle, |
720 DWORD_PTR param1, | 721 DWORD_PTR param1, |
721 DWORD_PTR param2) { | 722 DWORD_PTR param2) { |
722 auto state = GetInputDeviceFromHandle(midi_in_handle); | 723 auto state = GetInputDeviceFromHandle(midi_in_handle); |
723 if (!state) | 724 if (!state) |
(...skipping 16 matching lines...) Loading... |
740 if (header->dwBytesRecorded > 0) { | 741 if (header->dwBytesRecorded > 0) { |
741 const uint8_t* src = reinterpret_cast<const uint8_t*>(header->lpData); | 742 const uint8_t* src = reinterpret_cast<const uint8_t*>(header->lpData); |
742 std::vector<uint8_t> data; | 743 std::vector<uint8_t> data; |
743 data.assign(src, src + header->dwBytesRecorded); | 744 data.assign(src, src + header->dwBytesRecorded); |
744 // MIM_DATA/MIM_LONGDATA message treats the time when midiInStart() is | 745 // MIM_DATA/MIM_LONGDATA message treats the time when midiInStart() is |
745 // called as the origin of |elapsed_ms|. | 746 // called as the origin of |elapsed_ms|. |
746 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd757284.aspx | 747 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd757284.aspx |
747 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd757286.aspx | 748 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd757286.aspx |
748 const base::TimeTicks event_time = | 749 const base::TimeTicks event_time = |
749 state->start_time + base::TimeDelta::FromMilliseconds(elapsed_ms); | 750 state->start_time + base::TimeDelta::FromMilliseconds(elapsed_ms); |
750 task_thread_.message_loop()->PostTask( | 751 task_thread_.task_runner()->PostTask( |
751 FROM_HERE, | 752 FROM_HERE, |
752 base::Bind(&MidiServiceWinImpl::ReceiveMidiDataOnTaskThread, | 753 base::Bind(&MidiServiceWinImpl::ReceiveMidiDataOnTaskThread, |
753 base::Unretained(this), state->port_index, data, | 754 base::Unretained(this), state->port_index, data, |
754 event_time)); | 755 event_time)); |
755 } | 756 } |
756 result = midiInAddBuffer(state->midi_handle, header, sizeof(*header)); | 757 result = midiInAddBuffer(state->midi_handle, header, sizeof(*header)); |
757 DLOG_IF(ERROR, result != MMSYSERR_NOERROR) | 758 DLOG_IF(ERROR, result != MMSYSERR_NOERROR) |
758 << "Failed to attach input buffer: " << GetInErrorMessage(result) | 759 << "Failed to attach input buffer: " << GetInErrorMessage(result) |
759 << "port number:" << state->port_index; | 760 << "port number:" << state->port_index; |
760 } | 761 } |
761 | 762 |
762 void OnMidiInCloseOnMultimediaThread(HMIDIIN midi_in_handle) { | 763 void OnMidiInCloseOnMultimediaThread(HMIDIIN midi_in_handle) { |
763 auto state = GetInputDeviceFromHandle(midi_in_handle); | 764 auto state = GetInputDeviceFromHandle(midi_in_handle); |
764 if (!state) | 765 if (!state) |
765 return; | 766 return; |
766 const uint32_t port_number = state->port_index; | 767 const uint32_t port_number = state->port_index; |
767 const auto device_info(state->device_info); | 768 const auto device_info(state->device_info); |
768 { | 769 { |
769 base::AutoLock auto_lock(input_ports_lock_); | 770 base::AutoLock auto_lock(input_ports_lock_); |
770 input_device_map_.erase(state->midi_handle); | 771 input_device_map_.erase(state->midi_handle); |
771 input_ports_[port_number] = nullptr; | 772 input_ports_[port_number] = nullptr; |
772 input_ports_ages_[port_number] += 1; | 773 input_ports_ages_[port_number] += 1; |
773 unused_input_ports_[device_info].push(port_number); | 774 unused_input_ports_[device_info].push(port_number); |
774 } | 775 } |
775 task_thread_.message_loop()->PostTask( | 776 task_thread_.task_runner()->PostTask( |
776 FROM_HERE, | 777 FROM_HERE, |
777 base::Bind(&MidiServiceWinImpl::SetInputPortStateOnTaskThread, | 778 base::Bind(&MidiServiceWinImpl::SetInputPortStateOnTaskThread, |
778 base::Unretained(this), port_number, | 779 base::Unretained(this), port_number, |
779 MIDI_PORT_DISCONNECTED)); | 780 MIDI_PORT_DISCONNECTED)); |
780 } | 781 } |
781 | 782 |
782 static void CALLBACK | 783 static void CALLBACK |
783 OnMidiOutEventOnMainlyMultimediaThread(HMIDIOUT midi_out_handle, | 784 OnMidiOutEventOnMainlyMultimediaThread(HMIDIOUT midi_out_handle, |
784 UINT message, | 785 UINT message, |
785 DWORD_PTR instance, | 786 DWORD_PTR instance, |
(...skipping 61 matching lines...) Loading... |
847 output_ports_[port_number]->port_age = output_ports_ages_[port_number]; | 848 output_ports_[port_number]->port_age = output_ports_ages_[port_number]; |
848 } | 849 } |
849 if (add_new_port) { | 850 if (add_new_port) { |
850 const MidiPortInfo port_info( | 851 const MidiPortInfo port_info( |
851 // TODO(toyoshim): Use a hash ID insted. crbug.com/467448 | 852 // TODO(toyoshim): Use a hash ID insted. crbug.com/467448 |
852 base::IntToString(static_cast<int>(port_number)), | 853 base::IntToString(static_cast<int>(port_number)), |
853 GetManufacturerName(state_device_info), | 854 GetManufacturerName(state_device_info), |
854 base::WideToUTF8(state_device_info.product_name), | 855 base::WideToUTF8(state_device_info.product_name), |
855 MmversionToString(state_device_info.driver_version), | 856 MmversionToString(state_device_info.driver_version), |
856 MIDI_PORT_OPENED); | 857 MIDI_PORT_OPENED); |
857 task_thread_.message_loop()->PostTask( | 858 task_thread_.task_runner()->PostTask( |
858 FROM_HERE, base::Bind(&MidiServiceWinImpl::AddOutputPortOnTaskThread, | 859 FROM_HERE, base::Bind(&MidiServiceWinImpl::AddOutputPortOnTaskThread, |
859 base::Unretained(this), port_info)); | 860 base::Unretained(this), port_info)); |
860 } else { | 861 } else { |
861 task_thread_.message_loop()->PostTask( | 862 task_thread_.task_runner()->PostTask( |
862 FROM_HERE, | 863 FROM_HERE, |
863 base::Bind(&MidiServiceWinImpl::SetOutputPortStateOnTaskThread, | 864 base::Bind(&MidiServiceWinImpl::SetOutputPortStateOnTaskThread, |
864 base::Unretained(this), port_number, MIDI_PORT_CONNECTED)); | 865 base::Unretained(this), port_number, MIDI_PORT_CONNECTED)); |
865 } | 866 } |
866 } | 867 } |
867 | 868 |
868 void OnMidiOutDoneOnMultimediaThread(HMIDIOUT midi_out_handle, | 869 void OnMidiOutDoneOnMultimediaThread(HMIDIOUT midi_out_handle, |
869 DWORD_PTR param1) { | 870 DWORD_PTR param1) { |
870 auto state = GetOutputDeviceFromHandle(midi_out_handle); | 871 auto state = GetOutputDeviceFromHandle(midi_out_handle); |
871 if (!state) | 872 if (!state) |
(...skipping 16 matching lines...) Loading... |
888 const uint32_t port_number = state->port_index; | 889 const uint32_t port_number = state->port_index; |
889 const auto device_info(state->device_info); | 890 const auto device_info(state->device_info); |
890 { | 891 { |
891 base::AutoLock auto_lock(output_ports_lock_); | 892 base::AutoLock auto_lock(output_ports_lock_); |
892 output_device_map_.erase(state->midi_handle); | 893 output_device_map_.erase(state->midi_handle); |
893 output_ports_[port_number] = nullptr; | 894 output_ports_[port_number] = nullptr; |
894 output_ports_ages_[port_number] += 1; | 895 output_ports_ages_[port_number] += 1; |
895 unused_output_ports_[device_info].push(port_number); | 896 unused_output_ports_[device_info].push(port_number); |
896 state->closed = true; | 897 state->closed = true; |
897 } | 898 } |
898 task_thread_.message_loop()->PostTask( | 899 task_thread_.task_runner()->PostTask( |
899 FROM_HERE, | 900 FROM_HERE, |
900 base::Bind(&MidiServiceWinImpl::SetOutputPortStateOnTaskThread, | 901 base::Bind(&MidiServiceWinImpl::SetOutputPortStateOnTaskThread, |
901 base::Unretained(this), port_number, | 902 base::Unretained(this), port_number, |
902 MIDI_PORT_DISCONNECTED)); | 903 MIDI_PORT_DISCONNECTED)); |
903 } | 904 } |
904 | 905 |
905 ///////////////////////////////////////////////////////////////////////////// | 906 ///////////////////////////////////////////////////////////////////////////// |
906 // Callbacks on the sender thread. | 907 // Callbacks on the sender thread. |
907 ///////////////////////////////////////////////////////////////////////////// | 908 ///////////////////////////////////////////////////////////////////////////// |
908 | 909 |
(...skipping 277 matching lines...) Loading... |
1186 base::TimeTicks time) { | 1187 base::TimeTicks time) { |
1187 ReceiveMidiData(port_index, &data[0], data.size(), time); | 1188 ReceiveMidiData(port_index, &data[0], data.size(), time); |
1188 } | 1189 } |
1189 | 1190 |
1190 MidiManager* MidiManager::Create() { | 1191 MidiManager* MidiManager::Create() { |
1191 return new MidiManagerWin(); | 1192 return new MidiManagerWin(); |
1192 } | 1193 } |
1193 | 1194 |
1194 } // namespace midi | 1195 } // namespace midi |
1195 } // namespace media | 1196 } // namespace media |
OLD | NEW |