OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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_mac.h" | 5 #include "media/midi/midi_manager_mac.h" |
6 | 6 |
7 #include <iostream> | 7 #include <iostream> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 | 47 |
48 if (result != noErr) | 48 if (result != noErr) |
49 return false; | 49 return false; |
50 | 50 |
51 coremidi_input_ = 0; | 51 coremidi_input_ = 0; |
52 | 52 |
53 // Create input and output port. | 53 // Create input and output port. |
54 result = MIDIInputPortCreate( | 54 result = MIDIInputPortCreate( |
55 midi_client_, | 55 midi_client_, |
56 CFSTR("MIDI Input"), | 56 CFSTR("MIDI Input"), |
57 ReadMidiDispatch, | 57 ReadMIDIDispatch, |
58 this, | 58 this, |
59 &coremidi_input_); | 59 &coremidi_input_); |
60 if (result != noErr) | 60 if (result != noErr) |
61 return false; | 61 return false; |
62 | 62 |
63 result = MIDIOutputPortCreate( | 63 result = MIDIOutputPortCreate( |
64 midi_client_, | 64 midi_client_, |
65 CFSTR("MIDI Output"), | 65 CFSTR("MIDI Output"), |
66 &coremidi_output_); | 66 &coremidi_output_); |
67 if (result != noErr) | 67 if (result != noErr) |
68 return false; | 68 return false; |
69 | 69 |
70 int destination_count = MIDIGetNumberOfDestinations(); | 70 uint32 destination_count = MIDIGetNumberOfDestinations(); |
71 destinations_.resize(destination_count); | 71 destinations_.resize(destination_count); |
72 | 72 |
73 for (int i = 0; i < destination_count ; i++) { | 73 for (uint32 i = 0; i < destination_count ; i++) { |
74 MIDIEndpointRef destination = MIDIGetDestination(i); | 74 MIDIEndpointRef destination = MIDIGetDestination(i); |
75 | 75 |
76 // Keep track of all destinations (known as outputs by the Web MIDI API). | 76 // Keep track of all destinations (known as outputs by the Web MIDI API). |
77 // Cache to avoid any possible overhead in calling MIDIGetDestination(). | 77 // Cache to avoid any possible overhead in calling MIDIGetDestination(). |
78 destinations_[i] = destination; | 78 destinations_[i] = destination; |
79 | 79 |
80 MIDIPortInfo info = GetPortInfoFromEndpoint(destination); | 80 MIDIPortInfo info = GetPortInfoFromEndpoint(destination); |
81 AddOutputPort(info); | 81 AddOutputPort(info); |
82 } | 82 } |
83 | 83 |
84 // Open connections from all sources. | 84 // Open connections from all sources. |
85 int source_count = MIDIGetNumberOfSources(); | 85 uint32 source_count = MIDIGetNumberOfSources(); |
86 | 86 |
87 for (int i = 0; i < source_count; ++i) { | 87 for (uint32 i = 0; i < source_count; ++i) { |
88 // Receive from all sources. | 88 // Receive from all sources. |
89 MIDIEndpointRef src = MIDIGetSource(i); | 89 MIDIEndpointRef src = MIDIGetSource(i); |
90 MIDIPortConnectSource(coremidi_input_, src, reinterpret_cast<void*>(src)); | 90 MIDIPortConnectSource(coremidi_input_, src, reinterpret_cast<void*>(src)); |
91 | 91 |
92 // Keep track of all sources (known as inputs in Web MIDI API terminology). | 92 // Keep track of all sources (known as inputs in Web MIDI API terminology). |
93 source_map_[src] = i; | 93 source_map_[src] = i; |
94 | 94 |
95 MIDIPortInfo info = GetPortInfoFromEndpoint(src); | 95 MIDIPortInfo info = GetPortInfoFromEndpoint(src); |
96 AddInputPort(info); | 96 AddInputPort(info); |
97 } | 97 } |
98 | 98 |
99 // TODO(crogers): Fix the memory management here! | 99 // TODO(crogers): Fix the memory management here! |
100 packet_list_ = reinterpret_cast<MIDIPacketList*>(midi_buffer_); | 100 packet_list_ = reinterpret_cast<MIDIPacketList*>(midi_buffer_); |
101 midi_packet_ = MIDIPacketListInit(packet_list_); | 101 midi_packet_ = MIDIPacketListInit(packet_list_); |
102 | 102 |
103 return true; | 103 return true; |
104 } | 104 } |
105 | 105 |
106 MIDIManagerMac::~MIDIManagerMac() { | 106 MIDIManagerMac::~MIDIManagerMac() { |
107 if (coremidi_input_) | 107 if (coremidi_input_) |
108 MIDIPortDispose(coremidi_input_); | 108 MIDIPortDispose(coremidi_input_); |
109 if (coremidi_output_) | 109 if (coremidi_output_) |
110 MIDIPortDispose(coremidi_output_); | 110 MIDIPortDispose(coremidi_output_); |
111 } | 111 } |
112 | 112 |
113 void MIDIManagerMac::ReadMidiDispatch(const MIDIPacketList* packet_list, | 113 void MIDIManagerMac::ReadMIDIDispatch(const MIDIPacketList* packet_list, |
114 void* read_proc_refcon, | 114 void* read_proc_refcon, |
115 void* src_conn_refcon) { | 115 void* src_conn_refcon) { |
116 MIDIManagerMac* manager = static_cast<MIDIManagerMac*>(read_proc_refcon); | 116 MIDIManagerMac* manager = static_cast<MIDIManagerMac*>(read_proc_refcon); |
117 #if __LP64__ | 117 #if __LP64__ |
118 MIDIEndpointRef source = reinterpret_cast<uintptr_t>(src_conn_refcon); | 118 MIDIEndpointRef source = reinterpret_cast<uintptr_t>(src_conn_refcon); |
119 #else | 119 #else |
120 MIDIEndpointRef source = static_cast<MIDIEndpointRef>(src_conn_refcon); | 120 MIDIEndpointRef source = static_cast<MIDIEndpointRef>(src_conn_refcon); |
121 #endif | 121 #endif |
122 | 122 |
123 // Dispatch to class method. | 123 // Dispatch to class method. |
124 manager->ReadMidi(source, packet_list); | 124 manager->ReadMIDI(source, packet_list); |
125 } | 125 } |
126 | 126 |
127 void MIDIManagerMac::ReadMidi(MIDIEndpointRef source, | 127 void MIDIManagerMac::ReadMIDI(MIDIEndpointRef source, |
128 const MIDIPacketList* packet_list) { | 128 const MIDIPacketList* packet_list) { |
129 // Lookup the port index based on the source. | 129 // Lookup the port index based on the source. |
130 SourceMap::iterator j = source_map_.find(source); | 130 SourceMap::iterator j = source_map_.find(source); |
131 if (j == source_map_.end()) | 131 if (j == source_map_.end()) |
132 return; | 132 return; |
133 int port_index = source_map_[source]; | 133 uint32 port_index = source_map_[source]; |
134 | 134 |
135 // Go through each packet and process separately. | 135 // Go through each packet and process separately. |
136 for(size_t i = 0; i < packet_list->numPackets; i++) { | 136 for(size_t i = 0; i < packet_list->numPackets; i++) { |
137 // Each packet contains MIDI data for one or more messages (like note-on). | 137 // Each packet contains MIDI data for one or more messages (like note-on). |
138 const MIDIPacket &packet = packet_list->packet[i]; | 138 const MIDIPacket &packet = packet_list->packet[i]; |
139 double timestamp_seconds = MIDITimeStampToSeconds(packet.timeStamp); | 139 double timestamp_seconds = MIDITimeStampToSeconds(packet.timeStamp); |
140 | 140 |
141 ReceiveMIDIData( | 141 ReceiveMIDIData( |
142 port_index, | 142 port_index, |
143 packet.data, | 143 packet.data, |
144 packet.length, | 144 packet.length, |
145 timestamp_seconds); | 145 timestamp_seconds); |
146 } | 146 } |
147 } | 147 } |
148 | 148 |
149 void MIDIManagerMac::SendMIDIData(MIDIManagerClient* client, | 149 void MIDIManagerMac::SendMIDIData(MIDIManagerClient* client, |
150 int port_index, | 150 uint32 port_index, |
151 const uint8* data, | 151 const std::vector<uint8>& data, |
152 size_t length, | |
153 double timestamp) { | 152 double timestamp) { |
| 153 DCHECK(CurrentlyOnMIDISendThread()); |
| 154 |
154 // System Exclusive has already been filtered. | 155 // System Exclusive has already been filtered. |
155 MIDITimeStamp coremidi_timestamp = SecondsToMIDITimeStamp(timestamp); | 156 MIDITimeStamp coremidi_timestamp = SecondsToMIDITimeStamp(timestamp); |
156 | 157 |
157 midi_packet_ = MIDIPacketListAdd( | 158 midi_packet_ = MIDIPacketListAdd( |
158 packet_list_, | 159 packet_list_, |
159 kMaxPacketListSize, | 160 kMaxPacketListSize, |
160 midi_packet_, | 161 midi_packet_, |
161 coremidi_timestamp, | 162 coremidi_timestamp, |
162 length, | 163 data.size(), |
163 data); | 164 &data[0]); |
164 | 165 |
165 // Lookup the destination based on the port index. | 166 // Lookup the destination based on the port index. |
166 // TODO(crogers): re-factor |port_index| to use unsigned | 167 if (static_cast<size_t>(port_index) >= destinations_.size()) |
167 // to avoid the need for this check. | |
168 if (port_index < 0 || | |
169 static_cast<size_t>(port_index) >= destinations_.size()) | |
170 return; | 168 return; |
171 | 169 |
172 MIDIEndpointRef destination = destinations_[port_index]; | 170 MIDIEndpointRef destination = destinations_[port_index]; |
173 | 171 |
174 MIDISend(coremidi_output_, destination, packet_list_); | 172 MIDISend(coremidi_output_, destination, packet_list_); |
175 | 173 |
176 // Re-initialize for next time. | 174 // Re-initialize for next time. |
177 midi_packet_ = MIDIPacketListInit(packet_list_); | 175 midi_packet_ = MIDIPacketListInit(packet_list_); |
178 | 176 |
179 client->AccumulateMIDIBytesSent(length); | 177 client->AccumulateMIDIBytesSent(data.size()); |
180 } | 178 } |
181 | 179 |
182 MIDIPortInfo MIDIManagerMac::GetPortInfoFromEndpoint( | 180 MIDIPortInfo MIDIManagerMac::GetPortInfoFromEndpoint( |
183 MIDIEndpointRef endpoint) { | 181 MIDIEndpointRef endpoint) { |
184 SInt32 id_number = 0; | 182 SInt32 id_number = 0; |
185 MIDIObjectGetIntegerProperty(endpoint, kMIDIPropertyUniqueID, &id_number); | 183 MIDIObjectGetIntegerProperty(endpoint, kMIDIPropertyUniqueID, &id_number); |
186 string id = IntToString(id_number); | 184 string id = IntToString(id_number); |
187 | 185 |
188 CFStringRef manufacturer_ref = NULL; | 186 CFStringRef manufacturer_ref = NULL; |
189 MIDIObjectGetStringProperty( | 187 MIDIObjectGetStringProperty( |
(...skipping 16 matching lines...) Expand all Loading... |
206 UInt64 nanoseconds = AudioConvertHostTimeToNanos(timestamp); | 204 UInt64 nanoseconds = AudioConvertHostTimeToNanos(timestamp); |
207 return static_cast<double>(nanoseconds) / 1.0e9; | 205 return static_cast<double>(nanoseconds) / 1.0e9; |
208 } | 206 } |
209 | 207 |
210 MIDITimeStamp MIDIManagerMac::SecondsToMIDITimeStamp(double seconds) { | 208 MIDITimeStamp MIDIManagerMac::SecondsToMIDITimeStamp(double seconds) { |
211 UInt64 nanos = UInt64(seconds * 1.0e9); | 209 UInt64 nanos = UInt64(seconds * 1.0e9); |
212 return AudioConvertNanosToHostTime(nanos); | 210 return AudioConvertNanosToHostTime(nanos); |
213 } | 211 } |
214 | 212 |
215 } // namespace media | 213 } // namespace media |
OLD | NEW |