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

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

Issue 23379002: Web MIDI: fix multi-threading problem around message buffer handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review #12 (for submmit) Created 7 years, 3 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') | no next file » | 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 <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
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
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
OLDNEW
« no previous file with comments | « media/midi/midi_manager_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698