Skip to content

Commit

Permalink
Some hackery around the NI components conflicting
Browse files Browse the repository at this point in the history
  • Loading branch information
tillt committed Feb 4, 2023
1 parent 4c60e19 commit 6752f08
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 9 deletions.
66 changes: 65 additions & 1 deletion KompleteSynthesia/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,66 @@ @interface AppDelegate ()

@end

@implementation AppDelegate
enum {
kAlienHardwareAgent = 0,
kAlienHostIntegration,
kAlienDaemon,
kAlienItemCount
};

@implementation AppDelegate {
BOOL restartAlien[kAlienItemCount];
}

+ (BOOL)terminateApp:(NSString*)name
{
NSArray* apps = [[NSWorkspace sharedWorkspace] runningApplications];
for (NSRunningApplication* app in apps) {
if ([app.localizedName compare:name] == NSOrderedSame) {
NSLog(@"found and trying to kill...");
return [app forceTerminate];
}
}
return NO;
}

NSString* kHardwareAgentName = @"NIHardwareAgent.app";
NSString* kHardwareAgentPath = @"/Library/Application Support/Native Instruments/Hardware/NIHardwareAgent.app";

NSString* kHostIntegrationAgentName = @"NIHostIntegrationAgent.app";
NSString* kHostIntegrationAgentPath = @"/Library/Application Support/Native Instruments/Hardware/NIHostIntegrationAgent.app";

NSString* kDaemonName = @"NIHardwareAgent.app";
NSString* kDaemonPath = @"/Library/Application Support/Native Instruments/Hardware/NIHardwareAgent.app";

- (void)killNativeInstrumentsComponentsIfNeeded
{
NSString* fmtAssert = @"asserting %@ not active";
NSString* fmtStopped = @"stopped %@";
NSArray<NSString*>* items = @[ kHardwareAgentName, kHostIntegrationAgentName, kDaemonName ];

assert(items.count == kAlienItemCount);

for (int i = 0; i < kAlienItemCount; i++) {
[_logViewController logLine:[NSString stringWithFormat:fmtAssert, items[i]]];

restartAlien[i] = [AppDelegate terminateApp:items[i]];

if (restartAlien[i]) {
[_logViewController logLine:[NSString stringWithFormat:fmtStopped, items[i]]];
}
}
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSError* error = nil;

_logViewController = [[LogViewController alloc] initWithNibName:@"LogViewController" bundle:NULL];

[self killNativeInstrumentsComponentsIfNeeded];

[NSThread sleepForTimeInterval:0.5f];

_synthesia = [[SynthesiaController alloc] initWithLogViewController:_logViewController
delegate:self
Expand Down Expand Up @@ -90,6 +143,7 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
self.statusMenu = menu;

if ([SynthesiaController synthesiaRunning] == NO) {
[_logViewController logLine:@"Synthesia not running, starting it now"];
[_midi2hidController boostrapSynthesia];
}
}
Expand Down Expand Up @@ -154,6 +208,16 @@ - (void)applicationWillTerminate:(NSNotification *)aNotification
{
[_videoController stopMirroringAndWait:YES];
[_midi2hidController teardown];

NSArray<NSString*>* items = @[ kHardwareAgentPath, kHostIntegrationAgentPath, kDaemonPath ];

assert(items.count == kAlienItemCount);

for (int i = 0; i < kAlienItemCount; i++) {
if (restartAlien[i]) {
system([NSString stringWithFormat:@"open '%@'", items[i]].cString);
}
}
}

- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app
Expand Down
9 changes: 8 additions & 1 deletion KompleteSynthesia/KompleteSynthesia.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<false/>
<key>com.apple.security.device.usb</key>
<true/>
<key>com.apple.security.get-task-allow</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.temporary-exception.apple-events</key>
<array>
<string>com.native-instruments.NIHostIntegrationAgent</string>
<string>com.native-instruments.NIHardwareService</string>
</array>
</dict>
</plist>
3 changes: 2 additions & 1 deletion KompleteSynthesia/SynthesiaController.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN

@property (nonatomic, weak) id<SynthesiaControllerDelegate> delegate;

+ (BOOL)applicationIsRunning:(NSString*)name;
+ (BOOL)synthesiaRunning;
+ (BOOL)synthesiaHasFocus;
+ (BOOL)activateSynthesia;
Expand All @@ -33,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN

- (id)initWithLogViewController:(LogViewController*)logViewController delegate:(id)delegate error:(NSError**)error;
- (BOOL)assertMultiDeviceConfig:(NSError**)error message:(NSString*_Nullable *_Nullable)message;
//- (void)adjustVolumeByDelta:(int)delta;

@end

NS_ASSUME_NONNULL_END
9 changes: 7 additions & 2 deletions KompleteSynthesia/SynthesiaController.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,22 @@ + (int)synthesiaWindowNumber
return 0;
}

+ (BOOL)synthesiaRunning
+ (BOOL)applicationIsRunning:(NSString*)name
{
NSArray* apps = [[NSWorkspace sharedWorkspace] runningApplications];
for (NSRunningApplication* app in apps) {
if ([app.localizedName compare:kSynthesiaApplicationName] == NSOrderedSame) {
if ([app.localizedName compare:name] == NSOrderedSame) {
return YES;
}
}
return NO;
}

+ (BOOL)synthesiaRunning
{
return [SynthesiaController applicationIsRunning:kSynthesiaApplicationName];
}

+ (void)runSynthesiaWithCompletion:(void(^)(void))completion
{
NSWorkspaceOpenConfiguration* configuration = [NSWorkspaceOpenConfiguration new];
Expand Down
9 changes: 6 additions & 3 deletions KompleteSynthesia/VideoController.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,14 @@ - (id)initWithLogViewController:(LogViewController*)lc error:(NSError**)error
screenBuffer[1] = NULL;
atomic_fetch_and(&stopMirroring, 0);
atomic_fetch_and(&mirrorActive, 0);

log = lc;

usb = [[USBController alloc] initWithError:error];
if (usb == nil) {
return nil;
}
[log logLine:[NSString stringWithFormat:@"detected %@ USB device", usb.deviceName]];

if (usb.mk2Controller == YES) {
_screenCount = 2;
Expand Down Expand Up @@ -93,11 +96,11 @@ - (BOOL)startMirroring

int windowNumber = [SynthesiaController synthesiaWindowNumber];
if (windowNumber == 0) {
NSLog(@"Synthesia window not found");
NSLog(@"synthesia window not found");
return NO;
}

[log logLine:@"Starting window mirroring"];
[log logLine:@"starting window mirroring"];

dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
atomic_fetch_or(&mirrorActive, 1);
Expand Down Expand Up @@ -125,7 +128,7 @@ - (BOOL)startMirroring
- (BOOL)reset:(NSError**)error
{
if ([SynthesiaController synthesiaRunning] == NO) {
[log logLine:@"We need synthesia running for grabbing its video"];
[log logLine:@"we need synthesia running for grabbing its video"];

if (error != nil) {
NSDictionary *userInfo = @{
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Native Instruments Komplete Kontrol Light Guide and Screen Mirroring Support for

## Features

Routes Synthesia lighting information to your Native Instruments keyboard controller USB device.
Routes Synthesia lighting information to your Native Instruments keyboard controller USB device. Mirrors the Synthesia application window onto your Komplete Kontrol MK2 displays.

Auto-detects a Native Instruments S-series keyboard controller USB device. Listens on the 'LoopBe' MIDI input interface port. Notes received are forwarded to the keyboard controller USB device as key lighting requests adhering to the Synthesia protocol.

Expand Down

0 comments on commit 6752f08

Please sign in to comment.