Index: media/midi/midi_manager_mac.cc |
diff --git a/media/midi/midi_manager_mac.cc b/media/midi/midi_manager_mac.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c2285dd52e45ca9d601c5701f1cbeaaa2db72d88 |
--- /dev/null |
+++ b/media/midi/midi_manager_mac.cc |
@@ -0,0 +1,160 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "media/midi/midi_manager_mac.h" |
+ |
+#include "base/time.h" |
+#include <CoreAudio/HostTime.h> |
+ |
+namespace media { |
+ |
+MIDIManager* MIDIManager::Create() { |
+ return new MIDIManagerMac(); |
+} |
+ |
+MIDIManagerMac::MIDIManagerMac() { |
scherkus (not reviewing)
2013/06/03 22:44:59
FYI this will be executed on the main UI thread wh
|
+ OSStatus result = noErr; |
+ |
+ // Create client and ports. |
+ midi_client_ = NULL; |
+ result = MIDIClientCreate(CFSTR("Google Chrome"), NULL, NULL, &midi_client_); |
+ |
+ input_port_ = NULL; |
+ |
+ result = MIDIInputPortCreate(midi_client_, |
+ CFSTR("MIDI Input"), |
+ ReadMidiDispatch, |
+ this, |
+ &input_port_); |
+ |
+ result = MIDIOutputPortCreate(midi_client_, |
+ CFSTR("MIDI Output"), |
+ &output_port_); |
+ |
+ int m = MIDIGetNumberOfDestinations(); |
+ |
+ for (int i = 0; i < m ; i++) { |
+ MIDIEndpointRef destination = MIDIGetDestination(i); |
+ CFStringRef deviceName = GetDeviceNameFromEndpoint(destination); |
+ |
+ printf("%d: ", i); |
+ CFShow(deviceName); |
+ } |
+ |
+ // Use first destination as default. |
+ destination_ = MIDIGetDestination(0); |
+ |
+ // Open connections from all sources |
+ int n = MIDIGetNumberOfSources(); |
+ |
+ for (int i = 0; i < n; ++i) { |
+ // Receive from all sources |
+ MIDIEndpointRef src = MIDIGetSource(i); |
+ MIDIPortConnectSource(input_port_, src, src); |
+ |
+ // Keep track of all sources (known as inputs in Web MIDI API terminology). |
+ source_map_[src] = i; |
+ |
+ // CFStringRef deviceName = GetDeviceNameFromEndpoint(src); |
+ |
+ CFStringRef midiSourceNameRef; |
+ MIDIObjectGetStringProperty(src, kMIDIPropertyName, &midiSourceNameRef); |
+ |
+ CFShow(midiSourceNameRef); |
+ } |
+ |
+ // init MIDIPacketList |
+ packet_list_ = reinterpret_cast<MIDIPacketList*>(mMIDIBuffer); |
+ midi_packet_ = MIDIPacketListInit(packet_list_); |
+} |
+ |
+MIDIManagerMac::~MIDIManagerMac() { |
+ MIDIPortDispose(input_port_); |
+ MIDIPortDispose(output_port_); |
+} |
+ |
+void MIDIManagerMac::ReadMidiDispatch(const MIDIPacketList* packet_list, |
+ void* read_proc_refcon, |
+ void* src_conn_refcon) { |
+ MIDIManagerMac* manager = static_cast<MIDIManagerMac*>(read_proc_refcon); |
+ MIDIEndpointRef source = static_cast<MIDIEndpointRef>(src_conn_refcon); |
+ |
+ // Dispatch to class method. |
+ manager->ReadMidi(source, packet_list); |
+} |
+ |
+void MIDIManagerMac::ReadMidi(MIDIEndpointRef source, |
+ const MIDIPacketList* packet_list) { |
+ // Lookup the port index based on the source. |
+ SourceMap::iterator j = source_map_.find(source); |
+ if (j == source_map_.end()) |
+ return; |
+ int port_index = source_map_[source]; |
+ // printf("port_index = %d\n", port_index); |
+ |
+ // Go through each packet and process separately. |
+ for(size_t i = 0; i < packet_list->numPackets; i++) { |
+ // Each packet contains MIDI data for one or more messages (like note-on). |
+ const MIDIPacket &packet = packet_list->packet[i]; |
+ double timestamp_seconds = MIDITimeStampToSeconds(packet.timeStamp); |
+ |
+ // TODO(crogers): handle port index properly at Blink layer. |
+ // Right now it only allows a value of 0. |
+ port_index = 0; |
+ |
+ ReceiveMIDIData( |
+ port_index, |
+ packet.data, |
+ packet.length, |
+ timestamp_seconds); |
+ } |
+} |
+ |
+void MIDIManagerMac::SendMIDI(UInt8 *midi_data, |
+ UInt32 length, |
+ MIDITimeStamp timestamp) { |
+ midi_packet_ = MIDIPacketListAdd( |
+ packet_list_, |
+ kMaxPacketListSize, |
+ midi_packet_, |
+ timestamp, |
+ length, |
+ midi_data); |
+ |
+ MIDISend(output_port_, destination_, packet_list_); |
+ |
+ // Re-initialize for next time. |
+ midi_packet_ = MIDIPacketListInit(packet_list_); |
+} |
+ |
+double MIDIManagerMac::MIDITimeStampToSeconds(MIDITimeStamp timestamp) |
+{ |
+ UInt64 nanos = AudioConvertHostTimeToNanos(timestamp ); |
+ |
+ double seconds = double(nanos) / 1.0e9; |
+ return seconds; |
+} |
+ |
+MIDITimeStamp MIDIManagerMac::SecondsToMIDITimeStamp(double seconds) { |
+ UInt64 nanos = UInt64(seconds * 1.0e9); |
+ MIDITimeStamp timeStamp = AudioConvertNanosToHostTime(nanos); |
+ return timeStamp; |
+} |
+ |
+CFStringRef MIDIManagerMac::GetDeviceNameFromEndpoint( |
+ MIDIEndpointRef endpoint) { |
+ MIDIEntityRef entity; |
+ MIDIEndpointGetEntity(endpoint, &entity); |
+ |
+ MIDIDeviceRef device; |
+ MIDIEntityGetDevice(entity, &device); |
+ |
+ CFStringRef device_name_ref; |
+ MIDIObjectGetStringProperty(device, kMIDIPropertyName, &device_name_ref); |
+ |
+ return device_name_ref; |
+} |
+ |
+} // namespace media |
+ |