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
3 // found in the LICENSE file.
5 #include "media/midi/midi_manager_usb.h"
7 #include "base/callback.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "media/midi/usb_midi_descriptor_parser.h"
12 #include "media/midi/usb_midi_device.h"
13 #include "media/midi/usb_midi_input_stream.h"
14 #include "media/midi/usb_midi_jack.h"
15 #include "media/midi/usb_midi_output_stream.h"
21 // Noop callback for (sync) Initialize.
22 // TODO(yhirano): This function should go away when
23 // MidiManager::Initialize() becomes asynchronous. See http://crbug.com/339746.
24 void Noop(bool result
) {
29 MidiManagerUsb::MidiManagerUsb(scoped_ptr
<UsbMidiDevice::Factory
> factory
)
30 : device_factory_(factory
.Pass()) {
33 MidiManagerUsb::~MidiManagerUsb() {
36 bool MidiManagerUsb::Initialize() {
37 Initialize(base::Bind(Noop
));
41 void MidiManagerUsb::Initialize(base::Callback
<void(bool result
)> callback
) {
42 initialize_callback_
= callback
;
43 // This is safe because EnumerateDevices cancels the operation on destruction.
44 device_factory_
->EnumerateDevices(
46 base::Bind(&MidiManagerUsb::OnEnumerateDevicesDone
,
47 base::Unretained(this)));
50 void MidiManagerUsb::DispatchSendMidiData(MidiManagerClient
* client
,
52 const std::vector
<uint8
>& data
,
54 DCHECK_LT(port_index
, output_streams_
.size());
55 output_streams_
[port_index
]->Send(data
);
56 client
->AccumulateMidiBytesSent(data
.size());
59 void MidiManagerUsb::ReceiveUsbMidiData(UsbMidiDevice
* device
,
66 input_stream_
->OnReceivedData(device
,
73 void MidiManagerUsb::OnReceivedData(size_t jack_index
,
77 ReceiveMidiData(jack_index
, data
, size
, timestamp
);
81 void MidiManagerUsb::OnEnumerateDevicesDone(bool result
,
82 UsbMidiDevice::Devices
* devices
) {
84 initialize_callback_
.Run(false);
87 devices
->swap(devices_
);
88 for (size_t i
= 0; i
< devices_
.size(); ++i
) {
89 UsbMidiDescriptorParser parser
;
90 std::vector
<uint8
> descriptor
= devices_
[i
]->GetDescriptor();
91 const uint8
* data
= descriptor
.size() > 0 ? &descriptor
[0] : NULL
;
92 std::vector
<UsbMidiJack
> jacks
;
93 bool parse_result
= parser
.Parse(devices_
[i
],
98 initialize_callback_
.Run(false);
101 std::vector
<UsbMidiJack
> input_jacks
;
102 for (size_t j
= 0; j
< jacks
.size(); ++j
) {
103 if (jacks
[j
].direction() == UsbMidiJack::DIRECTION_OUT
) {
104 output_streams_
.push_back(new UsbMidiOutputStream(jacks
[j
]));
105 // TODO(yhirano): Set appropriate properties.
106 AddOutputPort(MidiPortInfo());
108 DCHECK_EQ(jacks
[j
].direction(), UsbMidiJack::DIRECTION_IN
);
109 input_jacks
.push_back(jacks
[j
]);
110 // TODO(yhirano): Set appropriate properties.
111 AddInputPort(MidiPortInfo());
114 input_stream_
.reset(new UsbMidiInputStream(input_jacks
, this));
116 initialize_callback_
.Run(true);