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 <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "base/strings/sys_string_conversions.h" | 12 #include "base/strings/sys_string_conversions.h" |
13 | 13 |
14 #include <CoreAudio/HostTime.h> | 14 #include <CoreAudio/HostTime.h> |
15 | 15 |
16 using base::IntToString; | 16 using base::IntToString; |
17 using base::SysCFStringRefToUTF8; | 17 using base::SysCFStringRefToUTF8; |
18 using std::string; | 18 using std::string; |
19 | 19 |
20 // NB: System MIDI types are pointer types in 32-bit and integer types in | 20 // NB: System MIDI types are pointer types in 32-bit and integer types in |
21 // 64-bit. Therefore, the initialization is the simplest one that satisfies both | 21 // 64-bit. Therefore, the initialization is the simplest one that satisfies both |
22 // (if possible). | 22 // (if possible). |
23 | 23 |
24 namespace media { | 24 namespace media { |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 MidiPortInfo GetPortInfoFromEndpoint( | 28 MidiPortInfo GetPortInfoFromEndpoint(const MIDIEndpointRef endpoint) { |
yhirano
2014/10/24 03:30:08
What does this const mean?
Takashi Toyoshima
2015/02/17 17:10:38
reverted
| |
29 MIDIEndpointRef endpoint) { | |
30 SInt32 id_number = 0; | 29 SInt32 id_number = 0; |
31 MIDIObjectGetIntegerProperty(endpoint, kMIDIPropertyUniqueID, &id_number); | 30 MIDIObjectGetIntegerProperty(endpoint, kMIDIPropertyUniqueID, &id_number); |
32 string id = IntToString(id_number); | 31 string id = IntToString(id_number); |
33 | 32 |
34 string manufacturer; | 33 string manufacturer; |
35 CFStringRef manufacturer_ref = NULL; | 34 CFStringRef manufacturer_ref = NULL; |
36 OSStatus result = MIDIObjectGetStringProperty( | 35 OSStatus result = MIDIObjectGetStringProperty( |
37 endpoint, kMIDIPropertyManufacturer, &manufacturer_ref); | 36 endpoint, kMIDIPropertyManufacturer, &manufacturer_ref); |
38 if (result == noErr) { | 37 if (result == noErr) { |
39 manufacturer = SysCFStringRefToUTF8(manufacturer_ref); | 38 manufacturer = SysCFStringRefToUTF8(manufacturer_ref); |
(...skipping 18 matching lines...) Expand all Loading... | |
58 endpoint, kMIDIPropertyDriverVersion, &version_number); | 57 endpoint, kMIDIPropertyDriverVersion, &version_number); |
59 if (result == noErr) { | 58 if (result == noErr) { |
60 version = IntToString(version_number); | 59 version = IntToString(version_number); |
61 } else { | 60 } else { |
62 // kMIDIPropertyDriverVersion is not supported in IAC driver providing | 61 // kMIDIPropertyDriverVersion is not supported in IAC driver providing |
63 // endpoints, and the result will be kMIDIUnknownProperty (-10835). | 62 // endpoints, and the result will be kMIDIUnknownProperty (-10835). |
64 DLOG(WARNING) << "Failed to get kMIDIPropertyDriverVersion with status " | 63 DLOG(WARNING) << "Failed to get kMIDIPropertyDriverVersion with status " |
65 << result; | 64 << result; |
66 } | 65 } |
67 | 66 |
68 return MidiPortInfo(id, manufacturer, name, version); | 67 const bool connected = true; |
68 return MidiPortInfo(id, manufacturer, name, version, connected); | |
69 } | 69 } |
70 | 70 |
71 double MIDITimeStampToSeconds(MIDITimeStamp timestamp) { | 71 double MIDITimeStampToSeconds(MIDITimeStamp timestamp) { |
72 UInt64 nanoseconds = AudioConvertHostTimeToNanos(timestamp); | 72 UInt64 nanoseconds = AudioConvertHostTimeToNanos(timestamp); |
73 return static_cast<double>(nanoseconds) / 1.0e9; | 73 return static_cast<double>(nanoseconds) / 1.0e9; |
74 } | 74 } |
75 | 75 |
76 MIDITimeStamp SecondsToMIDITimeStamp(double seconds) { | 76 MIDITimeStamp SecondsToMIDITimeStamp(double seconds) { |
77 UInt64 nanos = UInt64(seconds * 1.0e9); | 77 UInt64 nanos = UInt64(seconds * 1.0e9); |
78 return AudioConvertNanosToHostTime(nanos); | 78 return AudioConvertNanosToHostTime(nanos); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 client_thread_.message_loop()->PostTask(FROM_HERE, closure); | 133 client_thread_.message_loop()->PostTask(FROM_HERE, closure); |
134 } | 134 } |
135 | 135 |
136 void MidiManagerMac::InitializeCoreMIDI() { | 136 void MidiManagerMac::InitializeCoreMIDI() { |
137 DCHECK(client_thread_.message_loop_proxy()->BelongsToCurrentThread()); | 137 DCHECK(client_thread_.message_loop_proxy()->BelongsToCurrentThread()); |
138 | 138 |
139 // CoreMIDI registration. | 139 // CoreMIDI registration. |
140 // TODO(toyoshim): Set MIDINotifyProc to receive CoreMIDI event notifications. | 140 // TODO(toyoshim): Set MIDINotifyProc to receive CoreMIDI event notifications. |
141 midi_client_ = 0; | 141 midi_client_ = 0; |
142 OSStatus result = | 142 OSStatus result = |
143 MIDIClientCreate(CFSTR("Chrome"), NULL, NULL, &midi_client_); | 143 MIDIClientCreate(CFSTR("Chrome"), ReceiveMidiNotifyDispatch, this, |
144 &midi_client_); | |
144 | 145 |
145 if (result != noErr) | 146 if (result != noErr) |
146 return CompleteInitialization(MIDI_INITIALIZATION_ERROR); | 147 return CompleteInitialization(MIDI_INITIALIZATION_ERROR); |
147 | 148 |
148 coremidi_input_ = 0; | 149 coremidi_input_ = 0; |
149 | 150 |
150 // Create input and output port. | 151 // Create input and output port. |
151 result = MIDIInputPortCreate( | 152 result = MIDIInputPortCreate( |
152 midi_client_, | 153 midi_client_, |
153 CFSTR("MIDI Input"), | 154 CFSTR("MIDI Input"), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
193 AddInputPort(info); | 194 AddInputPort(info); |
194 } | 195 } |
195 | 196 |
196 packet_list_ = reinterpret_cast<MIDIPacketList*>(midi_buffer_); | 197 packet_list_ = reinterpret_cast<MIDIPacketList*>(midi_buffer_); |
197 midi_packet_ = MIDIPacketListInit(packet_list_); | 198 midi_packet_ = MIDIPacketListInit(packet_list_); |
198 | 199 |
199 CompleteInitialization(MIDI_OK); | 200 CompleteInitialization(MIDI_OK); |
200 } | 201 } |
201 | 202 |
202 // static | 203 // static |
204 void MidiManagerMac::ReceiveMidiNotifyDispatch(const MIDINotification* message, | |
205 void* refcon) { | |
206 MidiManagerMac* manager = static_cast<MidiManagerMac*>(refcon); | |
207 manager->ReceiveMidiNotify(message); | |
208 } | |
209 | |
210 void MidiManagerMac::ReceiveMidiNotify(const MIDINotification* message) { | |
211 DCHECK(client_thread_.message_loop_proxy()->BelongsToCurrentThread()); | |
212 | |
213 if (kMIDIMsgObjectAdded == message->messageID) { | |
214 const MIDIObjectAddRemoveNotification* notification = | |
215 reinterpret_cast<const MIDIObjectAddRemoveNotification*>(message); | |
216 MIDIEndpointRef endpoint = | |
217 static_cast<MIDIEndpointRef>(notification->child); | |
218 if (notification->childType == kMIDIObjectType_Source) { | |
219 SourceMap::iterator it = source_map_.find(endpoint); | |
220 if (it == source_map_.end()) { | |
221 uint32 index = source_map_.size(); | |
222 source_map_[endpoint] = index; | |
223 MidiPortInfo info = GetPortInfoFromEndpoint(endpoint); | |
224 AddInputPort(info); | |
225 } else { | |
226 uint32 index = source_map_[endpoint]; | |
227 SetInputPortState(index, true); | |
228 } | |
229 } else if (notification->childType == kMIDIObjectType_Destination) { | |
230 bool found = false; | |
231 for (uint32 i = 0; i < destinations_.size(); ++i) { | |
yhirano
2014/10/24 03:30:08
You can use std::find.
palmer
2014/10/24 19:07:14
Yes, std::find.
Takashi Toyoshima
2015/02/17 17:10:37
But, I need to use the index i for SetOutputPortSt
yhirano
2015/02/18 03:21:25
Year, and you can use it:
auto i = std::find(...)
Takashi Toyoshima
2015/02/18 04:43:13
Oh, great. Sorry, I did't know this usage. thanks!
| |
232 if (destinations_[i] != endpoint) | |
233 continue; | |
234 found = true; | |
235 SetOutputPortState(i, true); | |
236 break; | |
237 } | |
238 if (!found) { | |
239 destinations_.push_back(endpoint); | |
240 MidiPortInfo info = GetPortInfoFromEndpoint(endpoint); | |
241 AddOutputPort(info); | |
242 } | |
243 } | |
244 } else if (kMIDIMsgObjectRemoved == message->messageID) { | |
245 const MIDIObjectAddRemoveNotification* notification = | |
246 reinterpret_cast<const MIDIObjectAddRemoveNotification*>(message); | |
247 MIDIEndpointRef endpoint = | |
248 static_cast<MIDIEndpointRef>(notification->child); | |
249 if (notification->childType == kMIDIObjectType_Source) { | |
250 SourceMap::iterator it = source_map_.find(endpoint); | |
251 if (it != source_map_.end()) { | |
252 uint32 index = source_map_[endpoint]; | |
253 SetInputPortState(index, false); | |
254 } | |
255 } else if (notification->childType == kMIDIObjectType_Destination) { | |
256 for (uint32 i = 0; i < destinations_.size(); ++i) { | |
yhirano
2014/10/24 03:30:08
ditto
Takashi Toyoshima
2015/02/17 17:10:38
same reason
| |
257 if (destinations_[i] != endpoint) | |
258 continue; | |
259 SetOutputPortState(i, false); | |
260 break; | |
261 } | |
262 } | |
263 } | |
264 } | |
265 | |
266 // static | |
203 void MidiManagerMac::ReadMidiDispatch(const MIDIPacketList* packet_list, | 267 void MidiManagerMac::ReadMidiDispatch(const MIDIPacketList* packet_list, |
204 void* read_proc_refcon, | 268 void* read_proc_refcon, |
205 void* src_conn_refcon) { | 269 void* src_conn_refcon) { |
206 // This method is called on a separate high-priority thread owned by CoreMIDI. | 270 // This method is called on a separate high-priority thread owned by CoreMIDI. |
207 | 271 |
208 MidiManagerMac* manager = static_cast<MidiManagerMac*>(read_proc_refcon); | 272 MidiManagerMac* manager = static_cast<MidiManagerMac*>(read_proc_refcon); |
209 #if __LP64__ | 273 #if __LP64__ |
210 MIDIEndpointRef source = reinterpret_cast<uintptr_t>(src_conn_refcon); | 274 MIDIEndpointRef source = reinterpret_cast<uintptr_t>(src_conn_refcon); |
211 #else | 275 #else |
212 MIDIEndpointRef source = static_cast<MIDIEndpointRef>(src_conn_refcon); | 276 MIDIEndpointRef source = static_cast<MIDIEndpointRef>(src_conn_refcon); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 | 332 |
269 MIDISend(coremidi_output_, destination, packet_list_); | 333 MIDISend(coremidi_output_, destination, packet_list_); |
270 | 334 |
271 // Re-initialize for next time. | 335 // Re-initialize for next time. |
272 midi_packet_ = MIDIPacketListInit(packet_list_); | 336 midi_packet_ = MIDIPacketListInit(packet_list_); |
273 | 337 |
274 client->AccumulateMidiBytesSent(data.size()); | 338 client->AccumulateMidiBytesSent(data.size()); |
275 } | 339 } |
276 | 340 |
277 } // namespace media | 341 } // namespace media |
OLD | NEW |