diff --git a/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj b/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj
index fe3e98184..f41a5ccee 100644
--- a/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj
+++ b/Plugins/HighlyComplete/HighlyComplete.xcodeproj/project.pbxproj
@@ -21,6 +21,7 @@
 		8360EF6E17F92E86005208A4 /* HighlyExperimental.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8360EF4417F92C92005208A4 /* HighlyExperimental.framework */; };
 		8384904A180764B500E7332D /* SSEQPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83848FEC1807624000E7332D /* SSEQPlayer.framework */; };
 		8384904B180764C200E7332D /* SSEQPlayer.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83848FEC1807624000E7332D /* SSEQPlayer.framework */; };
+		83D4481E18ACA5C8000F443A /* lazyusf in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83D4481B18ACA5AD000F443A /* lazyusf */; };
 		83DE0CBC180B02CC00269051 /* vio2sf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83DE0C3A180A9BD500269051 /* vio2sf.framework */; };
 		83DE0CBD180B02D800269051 /* vio2sf.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83DE0C3A180A9BD500269051 /* vio2sf.framework */; };
 		83DE0CC0180B27C200269051 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83DE0CBF180B27C200269051 /* libz.dylib */; };
@@ -129,6 +130,16 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
+		83D4481A18ACA591000F443A /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "";
+			dstSubfolderSpec = 6;
+			files = (
+				83D4481E18ACA5C8000F443A /* lazyusf in CopyFiles */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		83F18C3717F9300400471B6C /* CopyFiles */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 2147483647;
@@ -167,6 +178,7 @@
 		8360EEF317F92AC8005208A4 /* HighlyComplete-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "HighlyComplete-Prefix.pch"; sourceTree = "<group>"; };
 		8360EF3E17F92C91005208A4 /* HighlyExperimental.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HighlyExperimental.xcodeproj; path = ../../Frameworks/HighlyExperimental/HighlyExperimental.xcodeproj; sourceTree = "<group>"; };
 		83848FE61807623F00E7332D /* SSEQPlayer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SSEQPlayer.xcodeproj; path = ../../Frameworks/SSEQPlayer/SSEQPlayer.xcodeproj; sourceTree = "<group>"; };
+		83D4481B18ACA5AD000F443A /* lazyusf */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; name = lazyusf; path = ../../ThirdParty/lazyusf/lazyusf; sourceTree = "<group>"; };
 		83DE0C34180A9BD400269051 /* vio2sf.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = vio2sf.xcodeproj; path = ../../Frameworks/vio2sf/vio2sf.xcodeproj; sourceTree = "<group>"; };
 		83DE0CBF180B27C200269051 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
 /* End PBXFileReference section */
@@ -226,6 +238,7 @@
 		8360EEDB17F92AC8005208A4 = {
 			isa = PBXGroup;
 			children = (
+				83D4481D18ACA5B1000F443A /* External */,
 				8360EEED17F92AC8005208A4 /* HighlyComplete */,
 				8360EEE617F92AC8005208A4 /* Frameworks */,
 				8360EEE517F92AC8005208A4 /* Products */,
@@ -306,6 +319,14 @@
 			name = Products;
 			sourceTree = "<group>";
 		};
+		83D4481D18ACA5B1000F443A /* External */ = {
+			isa = PBXGroup;
+			children = (
+				83D4481B18ACA5AD000F443A /* lazyusf */,
+			);
+			name = External;
+			sourceTree = "<group>";
+		};
 		83DE0C35180A9BD400269051 /* Products */ = {
 			isa = PBXGroup;
 			children = (
@@ -325,6 +346,7 @@
 				8360EEE117F92AC8005208A4 /* Frameworks */,
 				8360EEE217F92AC8005208A4 /* Resources */,
 				83F18C3717F9300400471B6C /* CopyFiles */,
+				83D4481A18ACA591000F443A /* CopyFiles */,
 			);
 			buildRules = (
 			);
diff --git a/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm b/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm
index e4a3274f6..d997ad90c 100644
--- a/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm
+++ b/Plugins/HighlyComplete/HighlyComplete/HCDecoder.mm
@@ -32,6 +32,10 @@
 
 #include <zlib.h>
 
+#include <dlfcn.h>
+
+// #define USF_LOG
+
 @interface psf_file_container : NSObject {
     NSLock * lock;
     NSMutableDictionary * list;
@@ -879,11 +883,16 @@ static int twosf_info(void * context, const char * name, const char * value)
 	return 0;
 }
 
-#if 0
 struct usf_loader_state
 {
+#ifdef USF_LOG
     FILE * log;
-    FILE * fLazyusf;
+#endif
+    NSTask * task;
+    NSPipe * pipe_stdin;
+    NSPipe * pipe_stdout;
+    NSFileHandle * file_stdin;
+    NSFileHandle * file_stdout;
     bool donewriting;
     uint32_t enablecompare;
     uint32_t enablefifofull;
@@ -891,7 +900,11 @@ struct usf_loader_state
     uint32_t pairsleft;
     
     usf_loader_state()
-    : log(NULL), fLazyusf(NULL),
+    :
+#ifdef USF_LOG
+    log(NULL),
+#endif
+    task(nil), pipe_stdin(nil), pipe_stdout(nil),
     enablecompare(0), enablefifofull(0),
     samplerate(0), pairsleft(0) { }
     
@@ -900,64 +913,88 @@ struct usf_loader_state
         close();
     }
     
-    void fwrite( const void * buf, ssize_t size, ssize_t count, FILE * f )
+    void fwrite( const void * buf, ssize_t size, ssize_t count )
     {
-        ::fwrite( buf, size, count, f );
+        [file_stdin writeData:[NSData dataWithBytes:buf length:size * count]];
+#ifdef USF_LOG
         if ( log )
+        {
             ::fwrite( buf, size, count, log );
+            fflush( log );
+        }
+#endif
+    }
+    
+    ssize_t fread( void * buf, ssize_t size, ssize_t count )
+    {
+        NSData * data = [file_stdout readDataOfLength:size * count];
+        if ( data && [data length] )
+        {
+            memcpy( buf, [data bytes], [data length] );
+            return [data length] / size;
+        }
+        return 0;
     }
     
     void open()
     {
         close();
-        
+
+#ifdef USF_LOG
         log = fopen("/tmp/lazyusf_transaction", "w");
-        fLazyusf = popen( "/usr/local/bin/lazyusf", "r+" );
-        fwrite( &enablecompare, sizeof(enablecompare), 1, fLazyusf );
-        fwrite( &enablefifofull, sizeof(enablefifofull), 1, fLazyusf );
+#endif
+        Dl_info info;
+        dladdr( (void*) &twosf_info, &info );
+        
+        NSString * base_path = [[NSString stringWithUTF8String:info.dli_fname] stringByDeletingLastPathComponent];
+
+        task = [[NSTask alloc] init];
+        [task setLaunchPath:[base_path stringByAppendingPathComponent:@"lazyusf"]];
+        
+        pipe_stdin = [[NSPipe alloc] init];
+        pipe_stdout = [[NSPipe alloc] init];
+        
+        [task setStandardInput:pipe_stdin];
+        [task setStandardOutput:pipe_stdout];
+        
+        file_stdin = [pipe_stdin fileHandleForWriting];
+        file_stdout = [pipe_stdout fileHandleForReading];
+        
+        [task launch];
+        
+        fwrite( &enablecompare, sizeof(enablecompare), 1 );
+        fwrite( &enablefifofull, sizeof(enablefifofull), 1 );
         donewriting = false;
     }
     
     void close()
     {
-        if (fLazyusf)
+        if (task != nil)
         {
             uint32_t zero = 0;
-            fwrite( &zero, sizeof(uint32_t), 1, fLazyusf );
-            pclose( fLazyusf );
+            fwrite( &zero, sizeof(uint32_t), 1 );
+            [task release];
+            task = nil;
+            [pipe_stdin release];
+            pipe_stdin = nil;
+            [pipe_stdout release];
+            pipe_stdout = nil;
         }
-        fLazyusf = NULL;
+#ifdef USF_LOG
         if (log) fclose(log);
         log = NULL;
+#endif
     }
     
     bool opened()
     {
-        return fLazyusf != NULL;
+        return task != nil;
     }
     
     void write_reserved( const uint8_t * reserved, uint32_t reserved_size )
     {
-        fwrite( &reserved_size, sizeof(reserved_size), 1, fLazyusf );
-        if ( reserved_size ) fwrite( reserved, 1, reserved_size, fLazyusf );
-    }
-    
-    ssize_t fread( void * buf, ssize_t size, ssize_t count, FILE * f )
-    {
-        int d = fileno( f );
-        for (;;)
-        {
-            ssize_t r = read( d, buf, size * count );
-            if ( r == -1 && errno == EAGAIN )
-            {
-                usleep( 1000 );
-                continue;
-            }
-            else if ( r > 0 )
-                return r / size;
-            else
-                return -1;
-        }
+        fwrite( &reserved_size, sizeof(reserved_size), 1 );
+        if ( reserved_size ) fwrite( reserved, 1, reserved_size );
     }
     
     BOOL read_samples( int16_t * out, uint32_t out_pairs )
@@ -965,37 +1002,35 @@ struct usf_loader_state
         if ( !donewriting )
         {
             write_reserved( NULL, 0 );
-            fflush( fLazyusf );
+#ifdef USF_LOG
             fclose( log ); log = NULL;
-            int d = fileno(fLazyusf);
-            fcntl(d, F_SETFL, fcntl(d, F_GETFL, 0) | O_NONBLOCK);
+#endif
             donewriting = true;
         }
         while ( out_pairs )
         {
             if ( !pairsleft )
             {
-                if (fread( &samplerate, sizeof(samplerate), 1, fLazyusf ) < 0) return NO;
-                if (fread( &pairsleft, sizeof(pairsleft), 1, fLazyusf ) < 0) return NO;
+                if (fread( &samplerate, sizeof(samplerate), 1 ) < 1) return NO;
+                if (fread( &pairsleft, sizeof(pairsleft), 1 ) < 1) return NO;
                 pairsleft >>= 1;
             }
             if ( pairsleft )
             {
-                if ( pairsleft >= out_pairs )
+                if ( pairsleft > out_pairs )
                 {
-                    if (fread( out, sizeof(int16_t) * 2, out_pairs, fLazyusf ) < 0) return NO;
+                    if (fread( out, sizeof(int16_t) * 2, out_pairs ) < out_pairs) return NO;
                     pairsleft -= out_pairs;
                     return YES;
                 }
             
-                if (fread( out, sizeof(int16_t) * 2, pairsleft, fLazyusf ) < 0) return NO;
+                if (fread( out, sizeof(int16_t) * 2, pairsleft ) < pairsleft) return NO;
                 out += pairsleft * 2;
                 out_pairs -= pairsleft;
                 pairsleft = 0;
                 
                 uint32_t one = 1;
-                fwrite( &one, sizeof(one), 1, fLazyusf );
-                fflush( fLazyusf );
+                fwrite( &one, sizeof(one), 1 );
             }
         }
         return YES;
@@ -1029,7 +1064,6 @@ static int usf_info(void * context, const char * name, const char * value)
 
     return 0;
 }
-#endif
 
 - (BOOL)initializeDecoder
 {
@@ -1098,7 +1132,6 @@ static int usf_info(void * context, const char * name, const char * value)
         
         free( state.data );
     }
-#if 0
     else if ( type == 0x21 )
     {
         struct usf_loader_state * uUsf = new usf_loader_state;
@@ -1108,7 +1141,6 @@ static int usf_info(void * context, const char * name, const char * value)
         if ( psf_load( [currentUrl UTF8String], &source_callbacks, 0x21, usf_loader, uUsf, usf_info, uUsf ) <= 0 )
             return NO;
     }
-#endif
     else if ( type == 0x22 )
     {
         struct gsf_loader_state state;
@@ -1383,7 +1415,6 @@ static int usf_info(void * context, const char * name, const char * value)
         sega_execute( emulatorCore, 0x7fffffff, ( int16_t * ) buf, &howmany );
         frames = howmany;
     }
-#if 0
     else if ( type == 0x21 )
     {
         struct usf_loader_state * uUsf = ( struct usf_loader_state * ) emulatorCore;
@@ -1393,7 +1424,6 @@ static int usf_info(void * context, const char * name, const char * value)
 
         sampleRate = uUsf->samplerate;
     }
-#endif
     else if ( type == 0x22 )
     {
         GBASystem * system = ( GBASystem * ) emulatorCore;
@@ -1507,13 +1537,10 @@ static int usf_info(void * context, const char * name, const char * value)
 - (void)closeDecoder
 {
     if ( emulatorCore ) {
-#if 0
         if ( type == 0x21 ) {
             struct usf_loader_state * uUsf = ( struct usf_loader_state * ) emulatorCore;
             delete uUsf;
-        } else
-#endif
-            if ( type == 0x22 ) {
+        } else if ( type == 0x22 ) {
             GBASystem * system = ( GBASystem * ) emulatorCore;
             CPUCleanUp( system );
             soundShutdown( system );
@@ -1604,7 +1631,6 @@ static int usf_info(void * context, const char * name, const char * value)
         }
         while (framesRead < frame);
     }
-#if 0
     else if ( type == 0x21 )
     {
         struct usf_loader_state * uUsf = ( struct usf_loader_state * ) emulatorCore;
@@ -1617,7 +1643,6 @@ static int usf_info(void * context, const char * name, const char * value)
             framesRead += howmany;
         } while (framesRead < frame);
     }
-#endif
     else if ( type == 0x22 )
     {
         GBASystem * system = ( GBASystem * ) emulatorCore;
@@ -1739,11 +1764,7 @@ static int usf_info(void * context, const char * name, const char * value)
 
 + (NSArray *)fileTypes
 {
-	return [NSArray arrayWithObjects:@"psf",@"minipsf",@"psf2", @"minipsf2", @"ssf", @"minissf", @"dsf", @"minidsf", @"qsf", @"miniqsf", @"gsf", @"minigsf", @"ncsf", @"minincsf", @"2sf", @"mini2sf",
-#if 0
-            @"usf", @"miniusf",
-#endif
-            nil];
+	return [NSArray arrayWithObjects:@"psf",@"minipsf",@"psf2", @"minipsf2", @"ssf", @"minissf", @"dsf", @"minidsf", @"qsf", @"miniqsf", @"gsf", @"minigsf", @"ncsf", @"minincsf", @"2sf", @"mini2sf", @"usf", @"miniusf", nil];
 }
 
 + (NSArray *)mimeTypes
diff --git a/ThirdParty/lazyusf/lazyusf b/ThirdParty/lazyusf/lazyusf
new file mode 100755
index 000000000..dbd8827ff
Binary files /dev/null and b/ThirdParty/lazyusf/lazyusf differ