Index: lib/cmetrics/lindriver.cpp
===================================================================
--- lib/cmetrics/lindriver.cpp	(revision 2449)
+++ lib/cmetrics/lindriver.cpp	(working copy)
@@ -26,8 +26,10 @@
  **********************************************************************/
 
 #ifndef LINUX
+#ifndef OSX
 #error "Invalid Arch"
 #endif
+#endif
 
 #include "globaldefs.h"
 #include "protocol/protocol.h"
Index: lib/cmetrics/SConscript
===================================================================
--- lib/cmetrics/SConscript	(revision 2449)
+++ lib/cmetrics/SConscript	(working copy)
@@ -32,7 +32,7 @@
 
 
 #Set Flags
-if platform == 'linux':
+if platform == 'linux' or platform == 'osx':
     #libname = libname + "." + versionMajor + "." + versionMinor
     env.Append(CCFLAGS = '-DLINUX')
     env.Append(CXXFLAGS = '-DLINUX')
Index: lib/cmetrics/meminfo/meminfo.c
===================================================================
--- lib/cmetrics/meminfo/meminfo.c	(revision 2449)
+++ lib/cmetrics/meminfo/meminfo.c	(working copy)
@@ -29,6 +29,9 @@
 #include <sys/sysinfo.h>
 #elif WIN32
 #include <windows.h>
+#elif OSX
+#include <sys/types.h>
+#include <sys/sysctl.h>
 #endif
 
 int meminfoGetType()
@@ -65,6 +68,8 @@
         free(pmemInfo);
         return -1;
     }
+#elif OSX
+    sysctlbyname( ) //TODO: Look at the man page for this puppy - Albert Feb 6/08
 #elif WIN32
 	/* Detect Windows Version */
 	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
Index: lib/cmetrics/osinfo/SConscript
===================================================================
--- lib/cmetrics/osinfo/SConscript	(revision 2449)
+++ lib/cmetrics/osinfo/SConscript	(working copy)
@@ -8,6 +8,8 @@
 	source = Split("""win32.c""")
 elif platform == 'linux':
 	source = Split("""linux.c""")
+elif platform == 'osx':
+    source = Split("""osx.c""")
 
 obj = []
 if flags_unittest == '1':
Index: src/midiobjectcoremidi.h
===================================================================
--- src/midiobjectcoremidi.h	(revision 2449)
+++ src/midiobjectcoremidi.h	(working copy)
@@ -43,16 +43,22 @@
     void handleMidi(const MIDIPacketList *packets, QString device);
     void makeDeviceList();
     MIDIEndpointRef getEndpoint(QString device);
+    void sendSysexMsg(unsigned char data[], unsigned int length);
+    void sendShortMsg(unsigned int word);
 protected:
     void run();
     void stop();
 
     char            *buffer;
     MIDIClientRef   midiClient;
-    MIDIPortRef     midiPort;
-    MIDIEndpointRef currentMidiEndpoint;
+    MIDIPortRef     midiInPort;
+    MIDIPortRef     midiOutPort;
+    MIDIEndpointRef currentMidiInEndpoint;
+    MIDIEndpointRef midiOutEndpoint;
     QList<MIDIEndpointRef> currentMidiEndpoints;
     QList<QString *> persistentDeviceNames;
+    CFStringRef m_persistentString;
+    CFStringRef m_outputPortName; /** Output port name. Must not go out of scope, so I've made it a member variable. */
 };
 
 static void midi_read_proc(const MIDIPacketList *packets, void *refCon, void *connRefCon);
Index: src/midiobjectcoremidi.cpp
===================================================================
--- src/midiobjectcoremidi.cpp	(revision 2449)
+++ src/midiobjectcoremidi.cpp	(working copy)
@@ -22,11 +22,11 @@
 {
     // Initialize CoreMidi
     MIDIClientCreate(CFSTR("Mixxx"), 0, 0, &midiClient);
-    MIDIInputPortCreate(midiClient, CFSTR("Input port"), midi_read_proc, (void *)this, &midiPort);
+    MIDIInputPortCreate(midiClient, CFSTR("Input port"), midi_read_proc, (void *)this, &midiInPort);
 
     // No default device opening
     //currentMidiEndpoint = MIDIGetSource(0);
-    //MIDIPortConnectSource(midiPort, currentMidiEndpoint, 0);
+    //MIDIPortConnectSource(midiInPort, currentMidiEndpoint, 0);
 
     // Allocate buffer
     buffer = new char[4096];
@@ -65,35 +65,50 @@
 void MidiObjectCoreMidi::devOpen(QString device)
 {
     // Select device
-	MIDIEndpointRef ref = getEndpoint(device);
-	if (!ref) return;
+    MIDIEndpointRef ref = getEndpoint(device);
+    if (!ref) return;
 
-	// Add to list of active endpoints
-	currentMidiEndpoints.push_back(ref);
+    // Add to list of active endpoints
+    currentMidiEndpoints.push_back(ref);
 
-	// We need a pointer that will be available
-	QString * persistentString = new QString(device);
-	// Keep track of the pointer for deletion later
-	persistentDeviceNames.append(persistentString);
+    // We need a pointer that will be available
 
-    MIDIPortConnectSource(midiPort, ref, persistentString);
+    // Keep track of the pointer for deletion later
+    persistentDeviceNames.append(&device);
 
+    QByteArray qbaDevice = device.toUtf8();
+    m_persistentString = CFStringCreateWithBytes(NULL,
+                                                 (const UInt8*)qbaDevice.constData(),
+                                                 qbaDevice.count(),
+                                                 kCFStringEncodingUTF8,
+                                                 false);
+
+    //Connect input port to some MIDI device.
+    MIDIPortConnectSource(midiInPort, ref, &m_persistentString);
+       
+    qDebug() << "Creating output port for MIDI";
+    
+    //Create output port
+    m_outputPortName = CFSTR("Mixxx");
+    MIDISourceCreate(midiClient, m_outputPortName, &midiOutEndpoint);
+    MIDIOutputPortCreate(midiClient, m_outputPortName, &midiOutPort);
+
     // Should follow selected device !!!!
     openDevices.append(device);
 }
 
 void MidiObjectCoreMidi::devClose(MIDIEndpointRef ref) {
-	if (!ref) return;
+    if (!ref) return;
 
-	MIDIPortDisconnectSource(midiPort, ref);
+    MIDIPortDisconnectSource(midiInPort, ref);
 }
 
 void MidiObjectCoreMidi::devClose(QString device)
 {
-	// Find the endpoint associated with the device
-	MIDIEndpointRef ref = getEndpoint(device);
-	devClose(ref);
-	openDevices.remove(device);
+    // Find the endpoint associated with the device
+    MIDIEndpointRef ref = getEndpoint(device);
+    devClose(ref);
+    openDevices.remove(device);
 }
 
 void MidiObjectCoreMidi::stop()
@@ -158,8 +173,8 @@
 
 // Get an endpoint given a device name
 MIDIEndpointRef MidiObjectCoreMidi::getEndpoint(QString device) {
-	unsigned int i; // Unsigned because of comparison
-	for (i = 0; i < MIDIGetNumberOfSources(); i++)
+    unsigned int i; // Unsigned because of comparison
+    for (i = 0; i < MIDIGetNumberOfSources(); i++)
     {
         MIDIEndpointRef endpoint = MIDIGetSource(i);
         CFStringRef name = EndpointName(endpoint, true);
@@ -170,7 +185,7 @@
     }
 
     qDebug() << "CoreMIDI: Error finding device endpoint for \"" << device
-			<< "\"";
+            << "\"";
     return 0;
 }
 
@@ -188,61 +203,96 @@
 // The result should be released by the caller.
 static CFStringRef EndpointName(MIDIEndpointRef endpoint, bool isExternal)
 {
-	CFMutableStringRef result = CFStringCreateMutable(NULL, 0);
-	CFStringRef str;
+    CFMutableStringRef result = CFStringCreateMutable(NULL, 0);
+    CFStringRef str;
 
-	// begin with the endpoint's name
-	str = NULL;
-	MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &str);
-	if (str != NULL) {
-		CFStringAppend(result, str);
-		CFRelease(str);
-	}
+    // begin with the endpoint's name
+    str = NULL;
+    MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &str);
+    if (str != NULL) {
+        CFStringAppend(result, str);
+        CFRelease(str);
+    }
 
-	MIDIEntityRef entity = NULL;
-	MIDIEndpointGetEntity(endpoint, &entity);
-	if (entity == NULL)
-		// probably virtual
-		return result;
+    MIDIEntityRef entity = NULL;
+    MIDIEndpointGetEntity(endpoint, &entity);
+    if (entity == NULL)
+        // probably virtual
+        return result;
 
-	if (CFStringGetLength(result) == 0) {
-		// endpoint name has zero length -- try the entity
-		str = NULL;
-		MIDIObjectGetStringProperty(entity, kMIDIPropertyName, &str);
-		if (str != NULL) {
-			CFStringAppend(result, str);
-			CFRelease(str);
-		}
-	}
-	// now consider the device's name
-	MIDIDeviceRef device = NULL;
-	MIDIEntityGetDevice(entity, &device);
-	if (device == NULL)
-		return result;
+    if (CFStringGetLength(result) == 0) {
+        // endpoint name has zero length -- try the entity
+        str = NULL;
+        MIDIObjectGetStringProperty(entity, kMIDIPropertyName, &str);
+        if (str != NULL) {
+            CFStringAppend(result, str);
+            CFRelease(str);
+        }
+    }
+    // now consider the device's name
+    MIDIDeviceRef device = NULL;
+    MIDIEntityGetDevice(entity, &device);
+    if (device == NULL)
+        return result;
 
-	str = NULL;
-	MIDIObjectGetStringProperty(device, kMIDIPropertyName, &str);
-	if (str != NULL) {
-		// if an external device has only one entity, throw away the endpoint name and just use the device name
-		if (isExternal && MIDIDeviceGetNumberOfEntities(device) < 2) {
-			CFRelease(result);
-			return str;
-		} else {
-			// does the entity name already start with the device name? (some drivers do this though they shouldn't)
-			// if so, do not prepend
-			if (CFStringCompareWithOptions(str /* device name */, result /* endpoint name */, CFRangeMake(0, CFStringGetLength(str)), 0) != kCFCompareEqualTo) {
-				// prepend the device name to the entity name
-				if (CFStringGetLength(result) > 0)
-					CFStringInsert(result, 0, CFSTR(" "));
-				CFStringInsert(result, 0, str);
-			}
-			CFRelease(str);
-		}
-	}
-	return result;
+    str = NULL;
+    MIDIObjectGetStringProperty(device, kMIDIPropertyName, &str);
+    if (str != NULL) {
+        // if an external device has only one entity, throw away the endpoint name and just use the device name
+        if (isExternal && MIDIDeviceGetNumberOfEntities(device) < 2) {
+            CFRelease(result);
+            return str;
+        } else {
+            // does the entity name already start with the device name? (some drivers do this though they shouldn't)
+            // if so, do not prepend
+            if (CFStringCompareWithOptions(str /* device name */, result /* endpoint name */, CFRangeMake(0, CFStringGetLength(str)), 0) != kCFCompareEqualTo) {
+                // prepend the device name to the entity name
+                if (CFStringGetLength(result) > 0)
+                    CFStringInsert(result, 0, CFSTR(" "));
+                CFStringInsert(result, 0, str);
+            }
+            CFRelease(str);
+        }
+    }
+    return result;
 }
 
 /* TODO:
  * - Figure out a way of storing the endpoint, or even just the device name
  * - Retrieve the endpoint on a midi event..
  */
+ 
+void MidiObjectCoreMidi::sendShortMsg(unsigned int word) {
+    int byte1, byte2, byte3;
+
+    // Safely retrieve the message sequence from the input
+    byte1 = word & 0xff;
+    byte2 = (word>>8) & 0xff;
+    byte3 = (word>>16) & 0xff;
+    // qDebug() << "MIDI message send via alsa seq -- byte1:" << byte1 << "byte2:" << byte2 << "byte3:" << byte3;
+
+    MIDIPacketList pktlist;
+    MIDIPacket* packet = MIDIPacketListInit(&pktlist);
+    packet->timeStamp = 0;
+    packet->length = 3;
+    packet->data[0] = byte1;
+    packet->data[1] = byte2;
+    packet->data[2] = byte3;
+
+    MIDISend(midiOutPort, midiOutEndpoint, &pktlist);
+
+}
+
+// The sysex data must already contain the start byte 0xf0 and the end byte 0xf7.
+void MidiObjectCoreMidi::sendSysexMsg(unsigned char data[], unsigned int length) {
+    MIDISysexSendRequest request;
+    memset(&request, 0, sizeof(request));
+    request.destination = midiOutEndpoint;
+    request.data = (Byte*)data;
+    request.bytesToSend = (UInt32)length;
+    request.complete = false;
+    request.completionProc = NULL;
+    request.completionRefCon = NULL;
+    
+    MIDISendSysex(&request);
+}
