Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Side by Side Diff: media/midi/midi_manager_mac.cc

Issue 662233002: Web MIDI: make MidiManagerMac notify device connections (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase + cleanup Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698