| 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 |