MIDI: Add unstable configuration for AU players
Some checks are pending
Check if Cog buildable / Build Universal Cog.app (push) Waiting to run
Some checks are pending
Check if Cog buildable / Build Universal Cog.app (push) Waiting to run
It's regarded as unstable as some plugins randomly decide to overflow the main thread queue and crash the player on the main thread check, but only sometimes, and not always. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
f770e90caa
commit
c97c6735df
12 changed files with 475 additions and 16 deletions
|
@ -28,6 +28,7 @@ class AUPlayer : public MIDIPlayer {
|
|||
static void enumComponents(callback cbEnum);
|
||||
|
||||
void setComponent(OSType uSubType, OSType uManufacturer);
|
||||
void setPreset(NSDictionary *preset);
|
||||
|
||||
protected:
|
||||
virtual unsigned int send_event_needs_time();
|
||||
|
@ -61,6 +62,8 @@ class AUPlayer : public MIDIPlayer {
|
|||
OSType componentSubType, componentManufacturer;
|
||||
|
||||
BOOL needsInput;
|
||||
|
||||
NSDictionary *preset;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -208,6 +208,10 @@ void AUPlayer::setSoundFont(const char *in) {
|
|||
}
|
||||
}
|
||||
|
||||
void AUPlayer::setPreset(NSDictionary *preset) {
|
||||
this->preset = preset;
|
||||
}
|
||||
|
||||
/*void AUPlayer::setFileSoundFont( const char * in )
|
||||
{
|
||||
sFileSoundFontName = in;
|
||||
|
@ -334,6 +338,11 @@ bool AUPlayer::startup() {
|
|||
value = 1;
|
||||
AudioUnitSetProperty(samplerUnit[i], kMusicDeviceProperty_StreamFromDisk, kAudioUnitScope_Global, 0, &value, size);
|
||||
|
||||
if(preset) {
|
||||
CFDictionaryRef cdict = (__bridge CFDictionaryRef)preset;
|
||||
AudioUnitSetProperty(samplerUnit[i], kAudioUnitProperty_ClassInfo, kAudioUnitScope_Global, 0, &cdict, sizeof(cdict));
|
||||
}
|
||||
|
||||
error = AudioUnitInitialize(samplerUnit[i]);
|
||||
|
||||
if(error != noErr)
|
||||
|
|
|
@ -270,6 +270,14 @@ static OSType getOSType(const char *in_) {
|
|||
soundFontsAssigned = YES;
|
||||
}
|
||||
|
||||
NSDictionary *midiPluginSettings = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"midiPluginSettings"];
|
||||
if(midiPluginSettings) {
|
||||
NSDictionary *theSettings = [midiPluginSettings objectForKey:plugin];
|
||||
if(theSettings) {
|
||||
auplayer->setPreset(theSettings);
|
||||
}
|
||||
}
|
||||
|
||||
player = auplayer;
|
||||
}
|
||||
}
|
||||
|
|
57
Preferences/Preferences/AUPlayerView.h
Normal file
57
Preferences/Preferences/AUPlayerView.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// AUPlayerView.h
|
||||
// MIDI
|
||||
//
|
||||
// Created by Christopher Snowhill on 1/29/16.
|
||||
// Copyright © 2016-2022 Christopher Snowhill. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __AUPlayerView_h__
|
||||
#define __AUPlayerView_h__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <AppKit/AppKit.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioUnit/AudioUnitCarbonView.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
@class NSWindowDeleter;
|
||||
|
||||
class AUPluginUI {
|
||||
public:
|
||||
AUPluginUI(NSString *name, AudioUnit& sampler);
|
||||
~AUPluginUI();
|
||||
|
||||
bool window_opened() const;
|
||||
|
||||
private:
|
||||
AudioUnit& au;
|
||||
NSString* name;
|
||||
int prefheight;
|
||||
int prefwidth;
|
||||
|
||||
bool opened;
|
||||
bool mapped;
|
||||
bool resizable;
|
||||
int min_width;
|
||||
int min_height;
|
||||
int req_width;
|
||||
int req_height;
|
||||
int alo_width;
|
||||
int alo_height;
|
||||
|
||||
/* Cocoa */
|
||||
|
||||
NSWindowDeleter* cocoa_window;
|
||||
NSView* au_view;
|
||||
NSRect last_au_frame;
|
||||
|
||||
bool test_cocoa_view_support();
|
||||
int create_cocoa_view();
|
||||
|
||||
bool plugin_class_valid(Class pluginClass);
|
||||
};
|
||||
|
||||
#endif
|
222
Preferences/Preferences/AUPlayerView.mm
Normal file
222
Preferences/Preferences/AUPlayerView.mm
Normal file
|
@ -0,0 +1,222 @@
|
|||
//
|
||||
// AUPlayerView.mm
|
||||
// MIDI
|
||||
//
|
||||
// Created by Christopher Snowhill on 1/29/16.
|
||||
// Copyright © 2016-2022 Christopher Snowhill. All rights reserved.
|
||||
//
|
||||
|
||||
#import <AudioUnit/AUCocoaUIView.h>
|
||||
#import <CoreAudioKit/AUGenericView.h>
|
||||
|
||||
#import "AUPlayerView.h"
|
||||
|
||||
@interface NSWindowDeleter : NSWindow {
|
||||
AUPluginUI *parent;
|
||||
}
|
||||
|
||||
- (void)setParentObject:(AUPluginUI *)object;
|
||||
- (void)dealloc;
|
||||
@end
|
||||
|
||||
@implementation NSWindowDeleter
|
||||
|
||||
- (void)setParentObject:(AUPluginUI *)object {
|
||||
parent = object;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
delete parent;
|
||||
}
|
||||
@end
|
||||
|
||||
AUPluginUI::AUPluginUI(NSString *_name, AudioUnit &_au)
|
||||
: name(_name), au(_au), mapped(false), resizable(false), min_width(0), min_height(0), req_width(0), req_height(0), alo_width(0), alo_height(0) {
|
||||
opened = false;
|
||||
cocoa_window = nil;
|
||||
au_view = nil;
|
||||
|
||||
if(test_cocoa_view_support()) {
|
||||
create_cocoa_view();
|
||||
}
|
||||
|
||||
if(au_view) {
|
||||
cocoa_window = [[NSWindowDeleter alloc] initWithContentRect:NSMakeRect(0, 0, req_width, req_height)
|
||||
styleMask:(NSWindowStyleMaskTitled |
|
||||
NSWindowStyleMaskClosable)
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
|
||||
[cocoa_window setParentObject:this];
|
||||
|
||||
[cocoa_window setAutodisplay:YES];
|
||||
[cocoa_window setTitle:@"AU Plug-in"];
|
||||
[cocoa_window setOneShot:YES];
|
||||
|
||||
[cocoa_window setContentView:au_view];
|
||||
|
||||
NSDictionary *midiPluginSettings = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"midiPluginSettings"];
|
||||
if(midiPluginSettings) {
|
||||
NSDictionary *theSettings = [midiPluginSettings objectForKey:name];
|
||||
if(theSettings) {
|
||||
CFDictionaryRef cdict = (__bridge CFDictionaryRef)theSettings;
|
||||
AudioUnitSetProperty(au,
|
||||
kAudioUnitProperty_ClassInfo,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&cdict,
|
||||
sizeof(cdict));
|
||||
}
|
||||
}
|
||||
|
||||
[cocoa_window orderFront:cocoa_window];
|
||||
|
||||
opened = true;
|
||||
}
|
||||
}
|
||||
|
||||
AUPluginUI::~AUPluginUI() {
|
||||
if(opened) {
|
||||
NSMutableDictionary *midiPluginSettings = [[[[NSUserDefaultsController sharedUserDefaultsController] defaults] objectForKey:@"midiPluginSettings"] mutableCopy];
|
||||
if(!midiPluginSettings) {
|
||||
midiPluginSettings = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
CFDictionaryRef outClassInfo = nil;
|
||||
UInt32 objectSize = sizeof(outClassInfo);
|
||||
OSErr err = AudioUnitGetProperty(au,
|
||||
kAudioUnitProperty_ClassInfo,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&outClassInfo,
|
||||
&objectSize);
|
||||
if(err == noErr) {
|
||||
NSDictionary *dict = (__bridge NSDictionary *)outClassInfo;
|
||||
[midiPluginSettings setObject:dict forKey:name];
|
||||
[[[NSUserDefaultsController sharedUserDefaultsController] defaults] setObject:midiPluginSettings forKey:@"midiPluginSettings"];
|
||||
dict = nil;
|
||||
CFRelease(outClassInfo);
|
||||
}
|
||||
}
|
||||
|
||||
AudioUnitUninitialize(au);
|
||||
AudioComponentInstanceDispose(au);
|
||||
au = NULL;
|
||||
}
|
||||
|
||||
bool AUPluginUI::test_cocoa_view_support() {
|
||||
UInt32 dataSize = 0;
|
||||
Boolean isWritable = 0;
|
||||
OSStatus err = AudioUnitGetPropertyInfo(au,
|
||||
kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global,
|
||||
0, &dataSize, &isWritable);
|
||||
|
||||
return dataSize > 0 && err == noErr;
|
||||
}
|
||||
|
||||
bool AUPluginUI::plugin_class_valid(Class pluginClass) {
|
||||
if([pluginClass conformsToProtocol:@protocol(AUCocoaUIBase)]) {
|
||||
if([pluginClass instancesRespondToSelector:@selector(interfaceVersion)] &&
|
||||
[pluginClass instancesRespondToSelector:@selector(uiViewForAudioUnit:withSize:)]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int AUPluginUI::create_cocoa_view() {
|
||||
bool wasAbleToLoadCustomView = false;
|
||||
AudioUnitCocoaViewInfo *cocoaViewInfo = NULL;
|
||||
UInt32 numberOfClasses = 0;
|
||||
UInt32 dataSize;
|
||||
Boolean isWritable;
|
||||
NSString *factoryClassName = 0;
|
||||
NSURL *CocoaViewBundlePath = NULL;
|
||||
|
||||
OSStatus result = AudioUnitGetPropertyInfo(au,
|
||||
kAudioUnitProperty_CocoaUI,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&dataSize,
|
||||
&isWritable);
|
||||
|
||||
numberOfClasses = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef);
|
||||
|
||||
// Does view have custom Cocoa UI?
|
||||
|
||||
if((result == noErr) && (numberOfClasses > 0)) {
|
||||
cocoaViewInfo = (AudioUnitCocoaViewInfo *)malloc(dataSize);
|
||||
|
||||
if(AudioUnitGetProperty(au,
|
||||
kAudioUnitProperty_CocoaUI,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
cocoaViewInfo,
|
||||
&dataSize) == noErr) {
|
||||
CocoaViewBundlePath = (__bridge NSURL *)cocoaViewInfo->mCocoaAUViewBundleLocation;
|
||||
|
||||
// we only take the first view in this example.
|
||||
factoryClassName = (__bridge NSString *)cocoaViewInfo->mCocoaAUViewClass[0];
|
||||
} else {
|
||||
if(cocoaViewInfo != NULL) {
|
||||
free(cocoaViewInfo);
|
||||
cocoaViewInfo = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [A] Show custom UI if view has it
|
||||
|
||||
if(CocoaViewBundlePath && factoryClassName) {
|
||||
NSBundle *viewBundle = [NSBundle bundleWithPath:[CocoaViewBundlePath path]];
|
||||
|
||||
if(viewBundle == NULL) {
|
||||
return -1;
|
||||
} else {
|
||||
Class factoryClass = [viewBundle classNamed:factoryClassName];
|
||||
if(!factoryClass) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// make sure 'factoryClass' implements the AUCocoaUIBase protocol
|
||||
if(!plugin_class_valid(factoryClass)) {
|
||||
return -1;
|
||||
}
|
||||
// make a factory
|
||||
id factory = [[factoryClass alloc] init];
|
||||
if(factory == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// make a view
|
||||
au_view = [factory uiViewForAudioUnit:au withSize:NSZeroSize];
|
||||
|
||||
// cleanup
|
||||
if(cocoaViewInfo) {
|
||||
UInt32 i;
|
||||
for(i = 0; i < numberOfClasses; i++)
|
||||
CFRelease(cocoaViewInfo->mCocoaAUViewClass[i]);
|
||||
|
||||
free(cocoaViewInfo);
|
||||
}
|
||||
wasAbleToLoadCustomView = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!wasAbleToLoadCustomView) {
|
||||
// load generic Cocoa view
|
||||
au_view = [[AUGenericView alloc] initWithAudioUnit:au];
|
||||
[(AUGenericView *)au_view setShowsExpertParameters:1];
|
||||
}
|
||||
|
||||
// Get the initial size of the new AU View's frame
|
||||
NSRect frame = [au_view frame];
|
||||
min_width = req_width = CGRectGetWidth(NSRectToCGRect(frame));
|
||||
min_height = req_height = CGRectGetHeight(NSRectToCGRect(frame));
|
||||
resizable = [au_view autoresizingMask];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AUPluginUI::window_opened() const {
|
||||
return opened;
|
||||
}
|
|
@ -449,6 +449,9 @@
|
|||
<customObject id="i5B-ga-Atm" userLabel="MIDIPane" customClass="MIDIPane">
|
||||
<connections>
|
||||
<outlet property="midiFlavorControl" destination="1Yw-25-Gbs" id="6In-S0-YE2"/>
|
||||
<outlet property="midiPluginBehaviorArrayController" destination="czk-eG-6QG" id="6FE-WD-VwB"/>
|
||||
<outlet property="midiPluginControl" destination="8Nj-G4-5ag" id="1k1-lQ-sQi"/>
|
||||
<outlet property="midiPluginSetupButton" destination="49M-Dx-QSC" id="AVl-il-IYO"/>
|
||||
<outlet property="view" destination="JXu-ar-J3Y" id="uI3-0O-h4x"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
|
@ -879,7 +882,7 @@
|
|||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8Nj-G4-5ag" userLabel="MIDI Plugin">
|
||||
<rect key="frame" x="295" y="176" width="329" height="26"/>
|
||||
<rect key="frame" x="295" y="176" width="263" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Item 1" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="vaQ-pZ-jXy" id="xcv-1b-kTI">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -893,12 +896,24 @@
|
|||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="setMidiPlugin:" target="i5B-ga-Atm" id="hN2-mi-z23"/>
|
||||
<binding destination="czk-eG-6QG" name="content" keyPath="arrangedObjects" id="Mzg-yr-6mv"/>
|
||||
<binding destination="czk-eG-6QG" name="contentValues" keyPath="arrangedObjects.name" previousBinding="NFp-di-hMf" id="6JE-ba-47Z"/>
|
||||
<binding destination="czk-eG-6QG" name="contentObjects" keyPath="arrangedObjects.preference" previousBinding="Mzg-yr-6mv" id="NFp-di-hMf"/>
|
||||
<binding destination="52" name="selectedObject" keyPath="values.midiPlugin" previousBinding="6JE-ba-47Z" id="ePY-TV-ngD"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="49M-Dx-QSC" userLabel="Setup">
|
||||
<rect key="frame" x="555" y="174" width="70" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Setup" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Tdt-2E-FVm" userLabel="Setup">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="setupPlugin:" target="i5B-ga-Atm" id="NNs-KH-p3S"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="G86-18-hiK">
|
||||
<rect key="frame" x="18" y="151" width="274" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
|
|
|
@ -10,9 +10,14 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface MIDIPane : GeneralPreferencePane {
|
||||
IBOutlet NSArrayController *midiPluginBehaviorArrayController;
|
||||
IBOutlet NSButton *midiPluginSetupButton;
|
||||
IBOutlet NSPopUpButton *midiPluginControl;
|
||||
IBOutlet NSPopUpButton *midiFlavorControl;
|
||||
}
|
||||
|
||||
- (IBAction)setupPlugin:(id)sender;
|
||||
|
||||
- (IBAction)setSoundFont:(id)sender;
|
||||
|
||||
@end
|
||||
|
|
128
Preferences/Preferences/MIDIPane.mm
Normal file
128
Preferences/Preferences/MIDIPane.mm
Normal file
|
@ -0,0 +1,128 @@
|
|||
//
|
||||
// MIDIPane.m
|
||||
// General
|
||||
//
|
||||
// Created by Christopher Snowhill on 10/15/13.
|
||||
//
|
||||
//
|
||||
|
||||
#import "MIDIPane.h"
|
||||
|
||||
#import "SandboxBroker.h"
|
||||
|
||||
#import "AppController.h"
|
||||
|
||||
#import "AUPlayerView.h"
|
||||
|
||||
@implementation MIDIPane {
|
||||
NSTimer *startupTimer;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib {
|
||||
__block MIDIPane *_self = self;
|
||||
startupTimer = [NSTimer timerWithTimeInterval:0.2 repeats:YES block:^(NSTimer * _Nonnull timer) {
|
||||
NSUInteger selectedItem = [_self->midiPluginControl indexOfSelectedItem];
|
||||
NSArray *arrangedObjects = [_self->midiPluginBehaviorArrayController arrangedObjects];
|
||||
if([arrangedObjects count] > selectedItem) {
|
||||
NSDictionary *selectedInfo = arrangedObjects[selectedItem];
|
||||
[_self->midiPluginSetupButton setEnabled:[[selectedInfo objectForKey:@"configurable"] boolValue]];
|
||||
[timer invalidate];
|
||||
}
|
||||
}];
|
||||
[[NSRunLoop mainRunLoop] addTimer:startupTimer forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[startupTimer invalidate];
|
||||
startupTimer = nil;
|
||||
}
|
||||
|
||||
- (NSString *)title {
|
||||
return NSLocalizedPrefString(@"Synthesis");
|
||||
}
|
||||
|
||||
- (NSImage *)icon {
|
||||
if(@available(macOS 11.0, *))
|
||||
return [NSImage imageWithSystemSymbolName:@"pianokeys" accessibilityDescription:nil];
|
||||
return [[NSImage alloc] initWithContentsOfFile:[[NSBundle bundleForClass:[self class]] pathForImageResource:@"midi"]];
|
||||
}
|
||||
|
||||
- (IBAction)setSoundFont:(id)sender {
|
||||
NSArray *fileTypes = @[@"sf2", @"sf2pack", @"sflist", @"sf3"];
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setCanChooseDirectories:NO];
|
||||
[panel setCanChooseFiles:YES];
|
||||
[panel setFloatingPanel:YES];
|
||||
[panel setAllowedFileTypes:fileTypes];
|
||||
NSString *oldPath = [[NSUserDefaults standardUserDefaults] stringForKey:@"soundFontPath"];
|
||||
if(oldPath != nil)
|
||||
[panel setDirectoryURL:[NSURL fileURLWithPath:oldPath]];
|
||||
NSInteger result = [panel runModal];
|
||||
if(result == NSModalResponseOK) {
|
||||
[[NSUserDefaults standardUserDefaults] setValue:[[panel URL] path] forKey:@"soundFontPath"];
|
||||
|
||||
id sandboxBrokerClass = NSClassFromString(@"SandboxBroker");
|
||||
NSURL *pathUrl = [panel URL];
|
||||
if(![[sandboxBrokerClass sharedSandboxBroker] areAllPathsSafe:@[pathUrl]]) {
|
||||
id appControllerClass = NSClassFromString(@"AppController");
|
||||
[appControllerClass globalShowPathSuggester];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)setMidiPlugin:(id)sender {
|
||||
NSUInteger selectedItem = [midiPluginControl indexOfSelectedItem];
|
||||
NSDictionary *selectedInfo = [midiPluginBehaviorArrayController arrangedObjects][selectedItem];
|
||||
[midiPluginSetupButton setEnabled:[[selectedInfo objectForKey:@"configurable"] boolValue]];
|
||||
}
|
||||
|
||||
static OSType getOSType(const char *in_) {
|
||||
const unsigned char *in = (const unsigned char *)in_;
|
||||
OSType v = (in[0] << 24) + (in[1] << 16) + (in[2] << 8) + in[3];
|
||||
return v;
|
||||
}
|
||||
|
||||
- (IBAction)setupPlugin:(id)sender {
|
||||
NSUInteger selectedItem = [midiPluginControl indexOfSelectedItem];
|
||||
NSDictionary *selectedInfo = [midiPluginBehaviorArrayController arrangedObjects][selectedItem];
|
||||
if(![[selectedInfo objectForKey:@"configurable"] boolValue])
|
||||
return;
|
||||
|
||||
NSString *plugin = [selectedInfo objectForKey:@"preference"];
|
||||
const char *cplugin = [plugin UTF8String];
|
||||
|
||||
AudioComponentDescription cd = { 0 };
|
||||
|
||||
cd.componentType = kAudioUnitType_MusicDevice;
|
||||
cd.componentSubType = getOSType(cplugin);
|
||||
cd.componentManufacturer = getOSType(cplugin + 4);
|
||||
|
||||
AudioComponent comp = NULL;
|
||||
|
||||
comp = AudioComponentFindNext(comp, &cd);
|
||||
|
||||
if(!comp)
|
||||
return;
|
||||
|
||||
AudioUnit au = NULL;
|
||||
|
||||
OSStatus error;
|
||||
|
||||
error = AudioComponentInstanceNew(comp, &au);
|
||||
|
||||
if(error != noErr)
|
||||
return;
|
||||
|
||||
/*error = AudioUnitInitialize(au);
|
||||
if(error != noErr)
|
||||
return;*/
|
||||
|
||||
AUPluginUI * pluginUI = new AUPluginUI(plugin, au);
|
||||
|
||||
if(!pluginUI->window_opened()) {
|
||||
delete pluginUI;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
|
@ -60,25 +60,25 @@ static void enumCallback(void *context, OSType uSubType, OSType uManufacturer, c
|
|||
pref[8] = '\0';
|
||||
|
||||
[pself addObject:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSString stringWithUTF8String:name], @"name",
|
||||
[NSString stringWithUTF8String:pref], @"preference", nil]];
|
||||
@{@"name": [NSString stringWithUTF8String:name],
|
||||
@"preference": [NSString stringWithUTF8String:pref],
|
||||
@"configurable": @YES}];
|
||||
}
|
||||
|
||||
@implementation MIDIPluginBehaviorArrayController
|
||||
- (void)awakeFromNib {
|
||||
[self removeObjects:[self arrangedObjects]];
|
||||
|
||||
[self addObject:@{@"name": @"BASSMIDI", @"preference": @"BASSMIDI"}];
|
||||
[self addObject:@{@"name": @"BASSMIDI", @"preference": @"BASSMIDI", @"configurable": @NO}];
|
||||
|
||||
[self addObject:@{@"name": @"DMX Generic", @"preference": @"DOOM0000"}];
|
||||
[self addObject:@{@"name": @"DMX Doom 1", @"preference": @"DOOM0001"}];
|
||||
[self addObject:@{@"name": @"DMX Doom 2", @"preference": @"DOOM0002"}];
|
||||
[self addObject:@{@"name": @"DMX Raptor", @"preference": @"DOOM0003"}];
|
||||
[self addObject:@{@"name": @"DMX Strife", @"preference": @"DOOM0004"}];
|
||||
[self addObject:@{@"name": @"DMXOPL", @"preference": @"DOOM0005"}];
|
||||
[self addObject:@{@"name": @"DMX Generic", @"preference": @"DOOM0000", @"configurable": @NO}];
|
||||
[self addObject:@{@"name": @"DMX Doom 1", @"preference": @"DOOM0001", @"configurable": @NO}];
|
||||
[self addObject:@{@"name": @"DMX Doom 2", @"preference": @"DOOM0002", @"configurable": @NO}];
|
||||
[self addObject:@{@"name": @"DMX Raptor", @"preference": @"DOOM0003", @"configurable": @NO}];
|
||||
[self addObject:@{@"name": @"DMX Strife", @"preference": @"DOOM0004", @"configurable": @NO}];
|
||||
[self addObject:@{@"name": @"DMXOPL", @"preference": @"DOOM0005", @"configurable": @NO}];
|
||||
|
||||
[self addObject:@{@"name": @"OPL3Windows", @"preference": @"OPL3W000"}];
|
||||
[self addObject:@{@"name": @"OPL3Windows", @"preference": @"OPL3W000", @"configurable": @NO}];
|
||||
|
||||
enumComponents(enumCallback, (__bridge void *)(self));
|
||||
}
|
||||
|
|
|
@ -32,10 +32,11 @@
|
|||
8391EA06286F9D3200A37593 /* PathSuggester.xib in Resources */ = {isa = PBXBuildFile; fileRef = 83DAD9F0286EDBCD000FAA9A /* PathSuggester.xib */; };
|
||||
83A3B72C283AE04800CC6593 /* ColorToValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A3B72B283AE04800CC6593 /* ColorToValueTransformer.m */; };
|
||||
83AC573A2861A54D009D6F50 /* PathSuggester.m in Sources */ = {isa = PBXBuildFile; fileRef = 83AC57382861A54D009D6F50 /* PathSuggester.m */; };
|
||||
83B06729180D85B8008E3612 /* MIDIPane.m in Sources */ = {isa = PBXBuildFile; fileRef = 83B06728180D85B8008E3612 /* MIDIPane.m */; };
|
||||
83B06729180D85B8008E3612 /* MIDIPane.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83B06728180D85B8008E3612 /* MIDIPane.mm */; };
|
||||
83B0672B180D8B39008E3612 /* midi.png in Resources */ = {isa = PBXBuildFile; fileRef = 83B0672A180D8B39008E3612 /* midi.png */; };
|
||||
83B8FE242D59CDA7005854C1 /* rubberband.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 83B8FE232D59CDA7005854C1 /* rubberband.pdf */; };
|
||||
83B8FE292D59D059005854C1 /* RubberbandPane.m in Sources */ = {isa = PBXBuildFile; fileRef = 83B8FE282D59D059005854C1 /* RubberbandPane.m */; };
|
||||
83E83F7E2D96780E0054365C /* AUPlayerView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83E83F7D2D96780E0054365C /* AUPlayerView.mm */; };
|
||||
83EF495F17FBC96A00642E3C /* VolumeBehaviorArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83EF495E17FBC96A00642E3C /* VolumeBehaviorArrayController.m */; };
|
||||
83F27E6B1810DD3A00CEF538 /* appearance@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 83F27E651810DD3A00CEF538 /* appearance@2x.png */; };
|
||||
83F27E6E1810DD3A00CEF538 /* midi@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 83F27E681810DD3A00CEF538 /* midi@2x.png */; };
|
||||
|
@ -136,7 +137,7 @@
|
|||
83AC57382861A54D009D6F50 /* PathSuggester.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PathSuggester.m; sourceTree = "<group>"; };
|
||||
83AC573E2861B77E009D6F50 /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../../Utils/SandboxBroker.h; sourceTree = "<group>"; };
|
||||
83B06727180D85B8008E3612 /* MIDIPane.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIDIPane.h; sourceTree = "<group>"; };
|
||||
83B06728180D85B8008E3612 /* MIDIPane.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIDIPane.m; sourceTree = "<group>"; };
|
||||
83B06728180D85B8008E3612 /* MIDIPane.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MIDIPane.mm; sourceTree = "<group>"; };
|
||||
83B0672A180D8B39008E3612 /* midi.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = midi.png; path = Icons/midi.png; sourceTree = "<group>"; };
|
||||
83B8FE232D59CDA7005854C1 /* rubberband.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = rubberband.pdf; path = Icons/rubberband.pdf; sourceTree = "<group>"; };
|
||||
83B8FE272D59D03F005854C1 /* RubberbandPane.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RubberbandPane.h; sourceTree = "<group>"; };
|
||||
|
@ -145,6 +146,8 @@
|
|||
83DAD9F1286EDBCD000FAA9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PathSuggester.xib; sourceTree = "<group>"; };
|
||||
83DAD9F3286EDBD2000FAA9A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/PathSuggester.strings; sourceTree = "<group>"; };
|
||||
83DAD9F5286EDBD6000FAA9A /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/PathSuggester.strings; sourceTree = "<group>"; };
|
||||
83E83F7C2D96780E0054365C /* AUPlayerView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUPlayerView.h; sourceTree = "<group>"; };
|
||||
83E83F7D2D96780E0054365C /* AUPlayerView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AUPlayerView.mm; sourceTree = "<group>"; };
|
||||
83EF495D17FBC96A00642E3C /* VolumeBehaviorArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VolumeBehaviorArrayController.h; sourceTree = "<group>"; };
|
||||
83EF495E17FBC96A00642E3C /* VolumeBehaviorArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VolumeBehaviorArrayController.m; sourceTree = "<group>"; };
|
||||
83F0E6AF287CAB4100D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/PathSuggester.strings; sourceTree = "<group>"; };
|
||||
|
@ -269,7 +272,7 @@
|
|||
17C6433D0B8A783F00C53518 /* OutputPane.h */,
|
||||
17C6433E0B8A783F00C53518 /* OutputPane.m */,
|
||||
83B06727180D85B8008E3612 /* MIDIPane.h */,
|
||||
83B06728180D85B8008E3612 /* MIDIPane.m */,
|
||||
83B06728180D85B8008E3612 /* MIDIPane.mm */,
|
||||
8307D309286057B5000FF8EB /* GeneralPane.h */,
|
||||
8307D30A286057B5000FF8EB /* GeneralPane.m */,
|
||||
83B8FE272D59D03F005854C1 /* RubberbandPane.h */,
|
||||
|
@ -281,6 +284,8 @@
|
|||
17D503410ABDB1660022D1E8 /* Custom */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83E83F7C2D96780E0054365C /* AUPlayerView.h */,
|
||||
83E83F7D2D96780E0054365C /* AUPlayerView.mm */,
|
||||
83651DA427322C8700A2C097 /* MIDIFlavorBehaviorArrayController.h */,
|
||||
83651DA327322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m */,
|
||||
837C0D3E1C50954000CAE18F /* MIDIPluginBehaviorArrayController.h */,
|
||||
|
@ -502,8 +507,9 @@
|
|||
83AC573A2861A54D009D6F50 /* PathSuggester.m in Sources */,
|
||||
83B8FE292D59D059005854C1 /* RubberbandPane.m in Sources */,
|
||||
83726F022CF41B3200F15FBF /* AppearancePane.m in Sources */,
|
||||
83E83F7E2D96780E0054365C /* AUPlayerView.mm in Sources */,
|
||||
83651DA527322C8700A2C097 /* MIDIFlavorBehaviorArrayController.m in Sources */,
|
||||
83B06729180D85B8008E3612 /* MIDIPane.m in Sources */,
|
||||
83B06729180D85B8008E3612 /* MIDIPane.mm in Sources */,
|
||||
8E07AA880AAC8EA200A4B32F /* HotKeyPane.m in Sources */,
|
||||
83F27E741810E45D00CEF538 /* PathToFileTransformer.m in Sources */,
|
||||
8E07AA890AAC8EA200A4B32F /* GeneralPreferencePane.m in Sources */,
|
||||
|
|
|
@ -292,3 +292,6 @@
|
|||
|
||||
/* Class = "NSTextFieldCell"; title = "Channels:"; ObjectID = "LpA-ak-Aj5"; */
|
||||
"LpA-ak-Aj5.title" = "Channels:";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Setup"; ObjectID = "Tdt-2E-FVm"; */
|
||||
"Tdt-2E-FVm.title" = "Setup";
|
||||
|
|
|
@ -291,3 +291,6 @@
|
|||
|
||||
/* Class = "NSTextFieldCell"; title = "Channels:"; ObjectID = "LpA-ak-Aj5"; */
|
||||
"LpA-ak-Aj5.title" = "Canales:";
|
||||
|
||||
/* Class = "NSButtonCell"; title = "Setup"; ObjectID = "Tdt-2E-FVm"; */
|
||||
"Tdt-2E-FVm.title" = "Config.";
|
||||
|
|
Loading…
Reference in a new issue