| 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 <algorithm> | 7 #include <algorithm> |
| 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" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 client_thread_.Stop(); | 128 client_thread_.Stop(); |
| 129 | 129 |
| 130 if (coremidi_input_) | 130 if (coremidi_input_) |
| 131 MIDIPortDispose(coremidi_input_); | 131 MIDIPortDispose(coremidi_input_); |
| 132 if (coremidi_output_) | 132 if (coremidi_output_) |
| 133 MIDIPortDispose(coremidi_output_); | 133 MIDIPortDispose(coremidi_output_); |
| 134 if (midi_client_) | 134 if (midi_client_) |
| 135 MIDIClientDispose(midi_client_); | 135 MIDIClientDispose(midi_client_); |
| 136 } | 136 } |
| 137 | 137 |
| 138 | |
| 139 void MidiManagerMac::DispatchSendMidiData(MidiManagerClient* client, | 138 void MidiManagerMac::DispatchSendMidiData(MidiManagerClient* client, |
| 140 uint32 port_index, | 139 uint32_t port_index, |
| 141 const std::vector<uint8>& data, | 140 const std::vector<uint8_t>& data, |
| 142 double timestamp) { | 141 double timestamp) { |
| 143 RunOnClientThread( | 142 RunOnClientThread( |
| 144 base::Bind(&MidiManagerMac::SendMidiData, | 143 base::Bind(&MidiManagerMac::SendMidiData, |
| 145 base::Unretained(this), client, port_index, data, timestamp)); | 144 base::Unretained(this), client, port_index, data, timestamp)); |
| 146 } | 145 } |
| 147 | 146 |
| 148 void MidiManagerMac::RunOnClientThread(const base::Closure& closure) { | 147 void MidiManagerMac::RunOnClientThread(const base::Closure& closure) { |
| 149 if (shutdown_) | 148 if (shutdown_) |
| 150 return; | 149 return; |
| 151 | 150 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 180 DCHECK_EQ(0u, coremidi_output_); | 179 DCHECK_EQ(0u, coremidi_output_); |
| 181 result = MIDIOutputPortCreate( | 180 result = MIDIOutputPortCreate( |
| 182 midi_client_, | 181 midi_client_, |
| 183 CFSTR("MIDI Output"), | 182 CFSTR("MIDI Output"), |
| 184 &coremidi_output_); | 183 &coremidi_output_); |
| 185 if (result != noErr || coremidi_output_ == 0) | 184 if (result != noErr || coremidi_output_ == 0) |
| 186 return CompleteInitialization(Result::INITIALIZATION_ERROR); | 185 return CompleteInitialization(Result::INITIALIZATION_ERROR); |
| 187 | 186 |
| 188 // Following loop may miss some newly attached devices, but such device will | 187 // Following loop may miss some newly attached devices, but such device will |
| 189 // be captured by ReceiveMidiNotifyDispatch callback. | 188 // be captured by ReceiveMidiNotifyDispatch callback. |
| 190 uint32 destination_count = MIDIGetNumberOfDestinations(); | 189 uint32_t destination_count = MIDIGetNumberOfDestinations(); |
| 191 destinations_.resize(destination_count); | 190 destinations_.resize(destination_count); |
| 192 for (uint32 i = 0; i < destination_count ; i++) { | 191 for (uint32_t i = 0; i < destination_count; i++) { |
| 193 MIDIEndpointRef destination = MIDIGetDestination(i); | 192 MIDIEndpointRef destination = MIDIGetDestination(i); |
| 194 if (destination == 0) { | 193 if (destination == 0) { |
| 195 // One ore more devices may be detached. | 194 // One ore more devices may be detached. |
| 196 destinations_.resize(i); | 195 destinations_.resize(i); |
| 197 break; | 196 break; |
| 198 } | 197 } |
| 199 | 198 |
| 200 // Keep track of all destinations (known as outputs by the Web MIDI API). | 199 // Keep track of all destinations (known as outputs by the Web MIDI API). |
| 201 // Cache to avoid any possible overhead in calling MIDIGetDestination(). | 200 // Cache to avoid any possible overhead in calling MIDIGetDestination(). |
| 202 destinations_[i] = destination; | 201 destinations_[i] = destination; |
| 203 | 202 |
| 204 MidiPortInfo info = GetPortInfoFromEndpoint(destination); | 203 MidiPortInfo info = GetPortInfoFromEndpoint(destination); |
| 205 AddOutputPort(info); | 204 AddOutputPort(info); |
| 206 } | 205 } |
| 207 | 206 |
| 208 // Open connections from all sources. This loop also may miss new devices. | 207 // Open connections from all sources. This loop also may miss new devices. |
| 209 uint32 source_count = MIDIGetNumberOfSources(); | 208 uint32_t source_count = MIDIGetNumberOfSources(); |
| 210 for (uint32 i = 0; i < source_count; ++i) { | 209 for (uint32_t i = 0; i < source_count; ++i) { |
| 211 // Receive from all sources. | 210 // Receive from all sources. |
| 212 MIDIEndpointRef source = MIDIGetSource(i); | 211 MIDIEndpointRef source = MIDIGetSource(i); |
| 213 if (source == 0) | 212 if (source == 0) |
| 214 break; | 213 break; |
| 215 | 214 |
| 216 // Start listening. | 215 // Start listening. |
| 217 MIDIPortConnectSource( | 216 MIDIPortConnectSource( |
| 218 coremidi_input_, source, reinterpret_cast<void*>(source)); | 217 coremidi_input_, source, reinterpret_cast<void*>(source)); |
| 219 | 218 |
| 220 // Keep track of all sources (known as inputs in Web MIDI API terminology). | 219 // Keep track of all sources (known as inputs in Web MIDI API terminology). |
| (...skipping 29 matching lines...) Expand all Loading... |
| 250 if (notification->childType == kMIDIObjectType_Source) { | 249 if (notification->childType == kMIDIObjectType_Source) { |
| 251 // Attaching device is an input device. | 250 // Attaching device is an input device. |
| 252 auto it = source_map_.find(endpoint); | 251 auto it = source_map_.find(endpoint); |
| 253 if (it == source_map_.end()) { | 252 if (it == source_map_.end()) { |
| 254 MidiPortInfo info = GetPortInfoFromEndpoint(endpoint); | 253 MidiPortInfo info = GetPortInfoFromEndpoint(endpoint); |
| 255 // If the device disappears before finishing queries, MidiPortInfo | 254 // If the device disappears before finishing queries, MidiPortInfo |
| 256 // becomes incomplete. Skip and do not cache such information here. | 255 // becomes incomplete. Skip and do not cache such information here. |
| 257 // On kMIDIMsgObjectRemoved, the entry will be ignored because it | 256 // On kMIDIMsgObjectRemoved, the entry will be ignored because it |
| 258 // will not be found in the pool. | 257 // will not be found in the pool. |
| 259 if (!info.id.empty()) { | 258 if (!info.id.empty()) { |
| 260 uint32 index = source_map_.size(); | 259 uint32_t index = source_map_.size(); |
| 261 source_map_[endpoint] = index; | 260 source_map_[endpoint] = index; |
| 262 AddInputPort(info); | 261 AddInputPort(info); |
| 263 MIDIPortConnectSource( | 262 MIDIPortConnectSource( |
| 264 coremidi_input_, endpoint, reinterpret_cast<void*>(endpoint)); | 263 coremidi_input_, endpoint, reinterpret_cast<void*>(endpoint)); |
| 265 } | 264 } |
| 266 } else { | 265 } else { |
| 267 SetInputPortState(it->second, MIDI_PORT_OPENED); | 266 SetInputPortState(it->second, MIDI_PORT_OPENED); |
| 268 } | 267 } |
| 269 } else if (notification->childType == kMIDIObjectType_Destination) { | 268 } else if (notification->childType == kMIDIObjectType_Destination) { |
| 270 // Attaching device is an output device. | 269 // Attaching device is an output device. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 const MIDIPacketList* packet_list) { | 320 const MIDIPacketList* packet_list) { |
| 322 // This method is called from ReadMidiDispatch() and runs on a separate | 321 // This method is called from ReadMidiDispatch() and runs on a separate |
| 323 // high-priority thread owned by CoreMIDI. | 322 // high-priority thread owned by CoreMIDI. |
| 324 | 323 |
| 325 // Lookup the port index based on the source. | 324 // Lookup the port index based on the source. |
| 326 auto it = source_map_.find(source); | 325 auto it = source_map_.find(source); |
| 327 if (it == source_map_.end()) | 326 if (it == source_map_.end()) |
| 328 return; | 327 return; |
| 329 // This is safe since MidiManagerMac does not remove any existing | 328 // This is safe since MidiManagerMac does not remove any existing |
| 330 // MIDIEndpointRef, and the order is saved. | 329 // MIDIEndpointRef, and the order is saved. |
| 331 uint32 port_index = it->second; | 330 uint32_t port_index = it->second; |
| 332 | 331 |
| 333 // Go through each packet and process separately. | 332 // Go through each packet and process separately. |
| 334 const MIDIPacket* packet = &packet_list->packet[0]; | 333 const MIDIPacket* packet = &packet_list->packet[0]; |
| 335 for (size_t i = 0; i < packet_list->numPackets; i++) { | 334 for (size_t i = 0; i < packet_list->numPackets; i++) { |
| 336 // Each packet contains MIDI data for one or more messages (like note-on). | 335 // Each packet contains MIDI data for one or more messages (like note-on). |
| 337 double timestamp_seconds = MIDITimeStampToSeconds(packet->timeStamp); | 336 double timestamp_seconds = MIDITimeStampToSeconds(packet->timeStamp); |
| 338 | 337 |
| 339 ReceiveMidiData( | 338 ReceiveMidiData( |
| 340 port_index, | 339 port_index, |
| 341 packet->data, | 340 packet->data, |
| 342 packet->length, | 341 packet->length, |
| 343 timestamp_seconds); | 342 timestamp_seconds); |
| 344 | 343 |
| 345 packet = MIDIPacketNext(packet); | 344 packet = MIDIPacketNext(packet); |
| 346 } | 345 } |
| 347 } | 346 } |
| 348 | 347 |
| 349 void MidiManagerMac::SendMidiData(MidiManagerClient* client, | 348 void MidiManagerMac::SendMidiData(MidiManagerClient* client, |
| 350 uint32 port_index, | 349 uint32_t port_index, |
| 351 const std::vector<uint8>& data, | 350 const std::vector<uint8_t>& data, |
| 352 double timestamp) { | 351 double timestamp) { |
| 353 DCHECK(client_thread_.task_runner()->BelongsToCurrentThread()); | 352 DCHECK(client_thread_.task_runner()->BelongsToCurrentThread()); |
| 354 | 353 |
| 355 // Lookup the destination based on the port index. | 354 // Lookup the destination based on the port index. |
| 356 if (static_cast<size_t>(port_index) >= destinations_.size()) | 355 if (static_cast<size_t>(port_index) >= destinations_.size()) |
| 357 return; | 356 return; |
| 358 | 357 |
| 359 MIDITimeStamp coremidi_timestamp = SecondsToMIDITimeStamp(timestamp); | 358 MIDITimeStamp coremidi_timestamp = SecondsToMIDITimeStamp(timestamp); |
| 360 MIDIEndpointRef destination = destinations_[port_index]; | 359 MIDIEndpointRef destination = destinations_[port_index]; |
| 361 | 360 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 380 DCHECK(midi_packet); | 379 DCHECK(midi_packet); |
| 381 | 380 |
| 382 MIDISend(coremidi_output_, destination, packet_list); | 381 MIDISend(coremidi_output_, destination, packet_list); |
| 383 } | 382 } |
| 384 | 383 |
| 385 AccumulateMidiBytesSent(client, data.size()); | 384 AccumulateMidiBytesSent(client, data.size()); |
| 386 } | 385 } |
| 387 | 386 |
| 388 } // namespace midi | 387 } // namespace midi |
| 389 } // namespace media | 388 } // namespace media |
| OLD | NEW |