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

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

Issue 151343002: Web MIDI: make naming convention be consistent (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review boliu #2 Created 6 years, 10 months 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 | Annotate | Revision Log
« no previous file with comments | « media/midi/midi_manager_mac.h ('k') | media/midi/midi_manager_usb.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/debug/trace_event.h" 9 #include "base/debug/trace_event.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 MIDIManager* MIDIManager::Create() { 26 MidiManager* MidiManager::Create() {
27 return new MIDIManagerMac(); 27 return new MidiManagerMac();
28 } 28 }
29 29
30 MIDIManagerMac::MIDIManagerMac() 30 MidiManagerMac::MidiManagerMac()
31 : midi_client_(0), 31 : midi_client_(0),
32 coremidi_input_(0), 32 coremidi_input_(0),
33 coremidi_output_(0), 33 coremidi_output_(0),
34 packet_list_(NULL), 34 packet_list_(NULL),
35 midi_packet_(NULL), 35 midi_packet_(NULL),
36 send_thread_("MIDISendThread") { 36 send_thread_("MidiSendThread") {
37 } 37 }
38 38
39 bool MIDIManagerMac::Initialize() { 39 bool MidiManagerMac::Initialize() {
40 TRACE_EVENT0("midi", "MIDIManagerMac::Initialize"); 40 TRACE_EVENT0("midi", "MidiManagerMac::Initialize");
41 41
42 // CoreMIDI registration. 42 // CoreMIDI registration.
43 midi_client_ = 0; 43 midi_client_ = 0;
44 OSStatus result = MIDIClientCreate( 44 OSStatus result = MIDIClientCreate(
45 CFSTR("Google Chrome"), 45 CFSTR("Google Chrome"),
46 NULL, 46 NULL,
47 NULL, 47 NULL,
48 &midi_client_); 48 &midi_client_);
49 49
50 if (result != noErr) 50 if (result != noErr)
51 return false; 51 return false;
52 52
53 coremidi_input_ = 0; 53 coremidi_input_ = 0;
54 54
55 // Create input and output port. 55 // Create input and output port.
56 result = MIDIInputPortCreate( 56 result = MIDIInputPortCreate(
57 midi_client_, 57 midi_client_,
58 CFSTR("MIDI Input"), 58 CFSTR("MIDI Input"),
59 ReadMIDIDispatch, 59 ReadMidiDispatch,
60 this, 60 this,
61 &coremidi_input_); 61 &coremidi_input_);
62 if (result != noErr) 62 if (result != noErr)
63 return false; 63 return false;
64 64
65 result = MIDIOutputPortCreate( 65 result = MIDIOutputPortCreate(
66 midi_client_, 66 midi_client_,
67 CFSTR("MIDI Output"), 67 CFSTR("MIDI Output"),
68 &coremidi_output_); 68 &coremidi_output_);
69 if (result != noErr) 69 if (result != noErr)
70 return false; 70 return false;
71 71
72 uint32 destination_count = MIDIGetNumberOfDestinations(); 72 uint32 destination_count = MIDIGetNumberOfDestinations();
73 destinations_.resize(destination_count); 73 destinations_.resize(destination_count);
74 74
75 for (uint32 i = 0; i < destination_count ; i++) { 75 for (uint32 i = 0; i < destination_count ; i++) {
76 MIDIEndpointRef destination = MIDIGetDestination(i); 76 MIDIEndpointRef destination = MIDIGetDestination(i);
77 77
78 // Keep track of all destinations (known as outputs by the Web MIDI API). 78 // Keep track of all destinations (known as outputs by the Web MIDI API).
79 // Cache to avoid any possible overhead in calling MIDIGetDestination(). 79 // Cache to avoid any possible overhead in calling MIDIGetDestination().
80 destinations_[i] = destination; 80 destinations_[i] = destination;
81 81
82 MIDIPortInfo info = GetPortInfoFromEndpoint(destination); 82 MidiPortInfo info = GetPortInfoFromEndpoint(destination);
83 AddOutputPort(info); 83 AddOutputPort(info);
84 } 84 }
85 85
86 // Open connections from all sources. 86 // Open connections from all sources.
87 uint32 source_count = MIDIGetNumberOfSources(); 87 uint32 source_count = MIDIGetNumberOfSources();
88 88
89 for (uint32 i = 0; i < source_count; ++i) { 89 for (uint32 i = 0; i < source_count; ++i) {
90 // Receive from all sources. 90 // Receive from all sources.
91 MIDIEndpointRef src = MIDIGetSource(i); 91 MIDIEndpointRef src = MIDIGetSource(i);
92 MIDIPortConnectSource(coremidi_input_, src, reinterpret_cast<void*>(src)); 92 MIDIPortConnectSource(coremidi_input_, src, reinterpret_cast<void*>(src));
93 93
94 // Keep track of all sources (known as inputs in Web MIDI API terminology). 94 // Keep track of all sources (known as inputs in Web MIDI API terminology).
95 source_map_[src] = i; 95 source_map_[src] = i;
96 96
97 MIDIPortInfo info = GetPortInfoFromEndpoint(src); 97 MidiPortInfo info = GetPortInfoFromEndpoint(src);
98 AddInputPort(info); 98 AddInputPort(info);
99 } 99 }
100 100
101 // TODO(crogers): Fix the memory management here! 101 // TODO(toyoshim): Fix the memory management here!
102 packet_list_ = reinterpret_cast<MIDIPacketList*>(midi_buffer_); 102 packet_list_ = reinterpret_cast<MIDIPacketList*>(midi_buffer_);
103 midi_packet_ = MIDIPacketListInit(packet_list_); 103 midi_packet_ = MIDIPacketListInit(packet_list_);
104 104
105 return true; 105 return true;
106 } 106 }
107 107
108 void MIDIManagerMac::DispatchSendMIDIData(MIDIManagerClient* client, 108 void MidiManagerMac::DispatchSendMidiData(MidiManagerClient* client,
109 uint32 port_index, 109 uint32 port_index,
110 const std::vector<uint8>& data, 110 const std::vector<uint8>& data,
111 double timestamp) { 111 double timestamp) {
112 if (!send_thread_.IsRunning()) 112 if (!send_thread_.IsRunning())
113 send_thread_.Start(); 113 send_thread_.Start();
114 114
115 // OK to use base::Unretained(this) since we join to thread in dtor(). 115 // OK to use base::Unretained(this) since we join to thread in dtor().
116 send_thread_.message_loop()->PostTask( 116 send_thread_.message_loop()->PostTask(
117 FROM_HERE, 117 FROM_HERE,
118 base::Bind(&MIDIManagerMac::SendMIDIData, base::Unretained(this), 118 base::Bind(&MidiManagerMac::SendMidiData, base::Unretained(this),
119 client, port_index, data, timestamp)); 119 client, port_index, data, timestamp));
120 } 120 }
121 121
122 MIDIManagerMac::~MIDIManagerMac() { 122 MidiManagerMac::~MidiManagerMac() {
123 // Wait for the termination of |send_thread_| before disposing MIDI ports. 123 // Wait for the termination of |send_thread_| before disposing MIDI ports.
124 send_thread_.Stop(); 124 send_thread_.Stop();
125 125
126 if (coremidi_input_) 126 if (coremidi_input_)
127 MIDIPortDispose(coremidi_input_); 127 MIDIPortDispose(coremidi_input_);
128 if (coremidi_output_) 128 if (coremidi_output_)
129 MIDIPortDispose(coremidi_output_); 129 MIDIPortDispose(coremidi_output_);
130 } 130 }
131 131
132 // static 132 // static
133 void MIDIManagerMac::ReadMIDIDispatch(const MIDIPacketList* packet_list, 133 void MidiManagerMac::ReadMidiDispatch(const MIDIPacketList* packet_list,
134 void* read_proc_refcon, 134 void* read_proc_refcon,
135 void* src_conn_refcon) { 135 void* src_conn_refcon) {
136 MIDIManagerMac* manager = static_cast<MIDIManagerMac*>(read_proc_refcon); 136 MidiManagerMac* manager = static_cast<MidiManagerMac*>(read_proc_refcon);
137 #if __LP64__ 137 #if __LP64__
138 MIDIEndpointRef source = reinterpret_cast<uintptr_t>(src_conn_refcon); 138 MIDIEndpointRef source = reinterpret_cast<uintptr_t>(src_conn_refcon);
139 #else 139 #else
140 MIDIEndpointRef source = static_cast<MIDIEndpointRef>(src_conn_refcon); 140 MIDIEndpointRef source = static_cast<MIDIEndpointRef>(src_conn_refcon);
141 #endif 141 #endif
142 142
143 // Dispatch to class method. 143 // Dispatch to class method.
144 manager->ReadMIDI(source, packet_list); 144 manager->ReadMidi(source, packet_list);
145 } 145 }
146 146
147 void MIDIManagerMac::ReadMIDI(MIDIEndpointRef source, 147 void MidiManagerMac::ReadMidi(MIDIEndpointRef source,
148 const MIDIPacketList* packet_list) { 148 const MIDIPacketList* packet_list) {
149 // Lookup the port index based on the source. 149 // Lookup the port index based on the source.
150 SourceMap::iterator j = source_map_.find(source); 150 SourceMap::iterator j = source_map_.find(source);
151 if (j == source_map_.end()) 151 if (j == source_map_.end())
152 return; 152 return;
153 uint32 port_index = source_map_[source]; 153 uint32 port_index = source_map_[source];
154 154
155 // Go through each packet and process separately. 155 // Go through each packet and process separately.
156 for (size_t i = 0; i < packet_list->numPackets; i++) { 156 for (size_t i = 0; i < packet_list->numPackets; i++) {
157 // Each packet contains MIDI data for one or more messages (like note-on). 157 // Each packet contains MIDI data for one or more messages (like note-on).
158 const MIDIPacket &packet = packet_list->packet[i]; 158 const MIDIPacket &packet = packet_list->packet[i];
159 double timestamp_seconds = MIDITimeStampToSeconds(packet.timeStamp); 159 double timestamp_seconds = MIDITimeStampToSeconds(packet.timeStamp);
160 160
161 ReceiveMIDIData( 161 ReceiveMidiData(
162 port_index, 162 port_index,
163 packet.data, 163 packet.data,
164 packet.length, 164 packet.length,
165 timestamp_seconds); 165 timestamp_seconds);
166 } 166 }
167 } 167 }
168 168
169 void MIDIManagerMac::SendMIDIData(MIDIManagerClient* client, 169 void MidiManagerMac::SendMidiData(MidiManagerClient* client,
170 uint32 port_index, 170 uint32 port_index,
171 const std::vector<uint8>& data, 171 const std::vector<uint8>& data,
172 double timestamp) { 172 double timestamp) {
173 DCHECK(send_thread_.message_loop_proxy()->BelongsToCurrentThread()); 173 DCHECK(send_thread_.message_loop_proxy()->BelongsToCurrentThread());
174 174
175 // System Exclusive has already been filtered. 175 // System Exclusive has already been filtered.
176 MIDITimeStamp coremidi_timestamp = SecondsToMIDITimeStamp(timestamp); 176 MIDITimeStamp coremidi_timestamp = SecondsToMIDITimeStamp(timestamp);
177 177
178 midi_packet_ = MIDIPacketListAdd( 178 midi_packet_ = MIDIPacketListAdd(
179 packet_list_, 179 packet_list_,
180 kMaxPacketListSize, 180 kMaxPacketListSize,
181 midi_packet_, 181 midi_packet_,
182 coremidi_timestamp, 182 coremidi_timestamp,
183 data.size(), 183 data.size(),
184 &data[0]); 184 &data[0]);
185 185
186 // Lookup the destination based on the port index. 186 // Lookup the destination based on the port index.
187 if (static_cast<size_t>(port_index) >= destinations_.size()) 187 if (static_cast<size_t>(port_index) >= destinations_.size())
188 return; 188 return;
189 189
190 MIDIEndpointRef destination = destinations_[port_index]; 190 MIDIEndpointRef destination = destinations_[port_index];
191 191
192 MIDISend(coremidi_output_, destination, packet_list_); 192 MIDISend(coremidi_output_, destination, packet_list_);
193 193
194 // Re-initialize for next time. 194 // Re-initialize for next time.
195 midi_packet_ = MIDIPacketListInit(packet_list_); 195 midi_packet_ = MIDIPacketListInit(packet_list_);
196 196
197 client->AccumulateMIDIBytesSent(data.size()); 197 client->AccumulateMidiBytesSent(data.size());
198 } 198 }
199 199
200 // static 200 // static
201 MIDIPortInfo MIDIManagerMac::GetPortInfoFromEndpoint( 201 MidiPortInfo MidiManagerMac::GetPortInfoFromEndpoint(
202 MIDIEndpointRef endpoint) { 202 MIDIEndpointRef endpoint) {
203 SInt32 id_number = 0; 203 SInt32 id_number = 0;
204 MIDIObjectGetIntegerProperty(endpoint, kMIDIPropertyUniqueID, &id_number); 204 MIDIObjectGetIntegerProperty(endpoint, kMIDIPropertyUniqueID, &id_number);
205 string id = IntToString(id_number); 205 string id = IntToString(id_number);
206 206
207 string manufacturer; 207 string manufacturer;
208 CFStringRef manufacturer_ref = NULL; 208 CFStringRef manufacturer_ref = NULL;
209 OSStatus result = MIDIObjectGetStringProperty( 209 OSStatus result = MIDIObjectGetStringProperty(
210 endpoint, kMIDIPropertyManufacturer, &manufacturer_ref); 210 endpoint, kMIDIPropertyManufacturer, &manufacturer_ref);
211 if (result == noErr) { 211 if (result == noErr) {
(...skipping 19 matching lines...) Expand all
231 endpoint, kMIDIPropertyDriverVersion, &version_number); 231 endpoint, kMIDIPropertyDriverVersion, &version_number);
232 if (result == noErr) { 232 if (result == noErr) {
233 version = IntToString(version_number); 233 version = IntToString(version_number);
234 } else { 234 } else {
235 // kMIDIPropertyDriverVersion is not supported in IAC driver providing 235 // kMIDIPropertyDriverVersion is not supported in IAC driver providing
236 // endpoints, and the result will be kMIDIUnknownProperty (-10835). 236 // endpoints, and the result will be kMIDIUnknownProperty (-10835).
237 DLOG(WARNING) << "Failed to get kMIDIPropertyDriverVersion with status " 237 DLOG(WARNING) << "Failed to get kMIDIPropertyDriverVersion with status "
238 << result; 238 << result;
239 } 239 }
240 240
241 return MIDIPortInfo(id, manufacturer, name, version); 241 return MidiPortInfo(id, manufacturer, name, version);
242 } 242 }
243 243
244 // static 244 // static
245 double MIDIManagerMac::MIDITimeStampToSeconds(MIDITimeStamp timestamp) { 245 double MidiManagerMac::MIDITimeStampToSeconds(MIDITimeStamp timestamp) {
246 UInt64 nanoseconds = AudioConvertHostTimeToNanos(timestamp); 246 UInt64 nanoseconds = AudioConvertHostTimeToNanos(timestamp);
247 return static_cast<double>(nanoseconds) / 1.0e9; 247 return static_cast<double>(nanoseconds) / 1.0e9;
248 } 248 }
249 249
250 // static 250 // static
251 MIDITimeStamp MIDIManagerMac::SecondsToMIDITimeStamp(double seconds) { 251 MIDITimeStamp MidiManagerMac::SecondsToMIDITimeStamp(double seconds) {
252 UInt64 nanos = UInt64(seconds * 1.0e9); 252 UInt64 nanos = UInt64(seconds * 1.0e9);
253 return AudioConvertNanosToHostTime(nanos); 253 return AudioConvertNanosToHostTime(nanos);
254 } 254 }
255 255
256 } // namespace media 256 } // namespace media
OLDNEW
« no previous file with comments | « media/midi/midi_manager_mac.h ('k') | media/midi/midi_manager_usb.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698