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/usb_midi_input_stream.h"
11 #include "base/logging.h"
12 #include "media/midi/usb_midi_device.h"
13 #include "media/midi/usb_midi_jack.h"
17 UsbMidiInputStream::JackUniqueKey::JackUniqueKey(UsbMidiDevice
* device
,
21 endpoint_number(endpoint_number
),
22 cable_number(cable_number
) {}
24 bool UsbMidiInputStream::JackUniqueKey::operator==(
25 const JackUniqueKey
& that
) const {
26 return device
== that
.device
&&
27 endpoint_number
== that
.endpoint_number
&&
28 cable_number
== that
.cable_number
;
31 bool UsbMidiInputStream::JackUniqueKey::operator<(
32 const JackUniqueKey
& that
) const {
33 if (device
!= that
.device
)
34 return device
< that
.device
;
35 if (endpoint_number
!= that
.endpoint_number
)
36 return endpoint_number
< that
.endpoint_number
;
37 return cable_number
< that
.cable_number
;
40 UsbMidiInputStream::UsbMidiInputStream(const std::vector
<UsbMidiJack
>& jacks
,
42 : delegate_(delegate
) {
43 for (size_t i
= 0; i
< jacks
.size(); ++i
) {
44 jack_dictionary_
.insert(
45 std::make_pair(JackUniqueKey(jacks
[i
].device
,
46 jacks
[i
].endpoint_number(),
47 jacks
[i
].cable_number
),
52 UsbMidiInputStream::~UsbMidiInputStream() {}
54 void UsbMidiInputStream::OnReceivedData(UsbMidiDevice
* device
,
58 base::TimeTicks time
) {
59 DCHECK_EQ(0u, size
% kPacketSize
);
61 while (current
+ kPacketSize
<= size
) {
62 ProcessOnePacket(device
, endpoint_number
, &data
[current
], time
);
63 current
+= kPacketSize
;
67 void UsbMidiInputStream::ProcessOnePacket(UsbMidiDevice
* device
,
70 base::TimeTicks time
) {
71 // The first 4 bytes of the packet is accessible here.
72 uint8 code_index
= packet
[0] & 0x0f;
73 uint8 cable_number
= packet
[0] >> 4;
74 const size_t packet_size_table
[16] = {
75 0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1,
77 size_t packet_size
= packet_size_table
[code_index
];
78 if (packet_size
== 0) {
79 // These CINs are reserved. Ignore them.
80 DVLOG(1) << "code index number (" << code_index
<< ") arrives "
81 << "but it is reserved.";
84 std::map
<JackUniqueKey
, size_t>::const_iterator it
=
85 jack_dictionary_
.find(JackUniqueKey(device
,
88 if (it
!= jack_dictionary_
.end())
89 delegate_
->OnReceivedData(it
->second
, &packet
[1], packet_size
, time
);
92 std::vector
<UsbMidiInputStream::JackUniqueKey
>
93 UsbMidiInputStream::RegisteredJackKeysForTesting() const {
94 std::vector
<JackUniqueKey
> result(jack_dictionary_
.size(),
95 JackUniqueKey(0, 0, 0));
96 for (std::map
<JackUniqueKey
, size_t>::const_iterator it
=
97 jack_dictionary_
.begin();
98 it
!= jack_dictionary_
.end(); ++it
) {
99 DCHECK_LT(it
->second
, result
.size());
100 result
[it
->second
] = it
->first
;