diff --git a/src/au/aulayer.cpp b/src/au/aulayer.cpp index 4b8fb39b848..623bc13606b 100644 --- a/src/au/aulayer.cpp +++ b/src/au/aulayer.cpp @@ -7,7 +7,9 @@ typedef SurgeSynthesizer sub3_synth; +#ifdef GENERATE_AU_LOG FILE* AULOG::lf = NULL; +#endif //---------------------------------------------------------------------------------------------------- @@ -716,79 +718,4 @@ OSStatus aulayer::HandleMidiEvent(UInt8 status, UInt8 channel, UInt8 data1, UInt return noErr; } -#if MAC_CARBON - -SHAZBOT - -#include "AUCarbonViewBase.h" -#include "plugguieditor.h" - -class VSTGUIAUView : public AUCarbonViewBase -{ -public: - VSTGUIAUView (AudioUnitCarbonView auv) - : AUCarbonViewBase (auv) - , editor (0) - , xOffset (0) - , yOffset (0) - { - } - - virtual ~VSTGUIAUView () - { - if (editor) - { - editor->close (); - delete editor; - } - } - - void RespondToEventTimer (EventLoopTimerRef inTimer) - { - if (editor) - editor->doIdleStuff (); - } - - virtual OSStatus CreateUI(Float32 xoffset, Float32 yoffset) - { - AudioUnit unit = GetEditAudioUnit (); - if (unit) - { - void* pluginAddr=0; - UInt32 dataSize = sizeof(pluginAddr); - ComponentResult err = AudioUnitGetProperty(mEditAudioUnit,kVmbAAudioUnitProperty_GetPluginCPPInstance, kAudioUnitScope_Global, 0, &pluginAddr, &dataSize); - - editor = new sub3_editor (pluginAddr); - WindowRef window = GetCarbonWindow (); - editor->open (window); - HIViewRef platformControl = (HIViewRef)editor->getFrame()->getPlatformControl(); -// HIViewMoveBy ((HIViewRef)editor->getFrame ()->getPlatformControl (), xoffset, yoffset); - EmbedControl (platformControl); - CRect fsize = editor->getFrame ()->getViewSize (fsize); - SizeControl (mCarbonPane, fsize.width (), fsize.height ()); - // CreateEventLoopTimer verkar sno focus och göra så den tappar mouseup-events - CreateEventLoopTimer (kEventDurationSecond, kEventDurationSecond / 30); - HIViewSetVisible (platformControl, true); - HIViewSetNeedsDisplay (platformControl, true); - //SetMouseCoalescingEnabled(false,NULL); - } - return noErr; - } - - Float32 xOffset, yOffset; -protected: - sub3_editor* editor; -}; - -COMPONENT_ENTRY(VSTGUIAUView); - -#elif MAC_COCOA - -// #error Implement the UI here, probably cribbing off of that AudioKit again -// TODO AU - - - -#endif - AUDIOCOMPONENT_ENTRY(AUMusicDeviceFactory, aulayer); diff --git a/src/au/aulayer.h b/src/au/aulayer.h index 9a8635f9ab6..bd69d68576d 100644 --- a/src/au/aulayer.h +++ b/src/au/aulayer.h @@ -14,29 +14,31 @@ typedef SurgeSynthesizer plugin; struct AULOG { - static FILE* lf; - - static void log( const char* format, ... ) - { - fprintf( stderr, "ENTERING WITH LF=%d\n", lf ); - if( lf == NULL ) - { - lf = fopen( "/Users/paul/Library/Logs/Surge.log", "a" ); - fprintf( stderr, "LOG FILE IS %d\n", lf ); - } - va_list args; - va_start( args, format ); - vfprintf( stderr, format, args ); - va_end( args ); - if( lf != NULL ) - { +#ifdef GENERATE_AU_LOG + static FILE* lf; + + static void log( const char* format, ... ) + { + if( lf == NULL ) + { + lf = fopen( "/Users/paul/Library/Logs/Surge.log", "a" ); + } + va_list args; va_start( args, format ); - vfprintf( lf, format, args ); + vfprintf( stderr, format, args ); va_end( args ); - fflush( lf ); - } - - } + if( lf != NULL ) + { + va_start( args, format ); + vfprintf( lf, format, args ); + va_end( args ); + fflush( lf ); + } + + } +#else + static void log( const char* format, ... ) { } +#endif }; //------------------------------------------------------------------------------------------------------- diff --git a/src/au/aulayer_cocoaui.mm b/src/au/aulayer_cocoaui.mm index 04d8674fec3..2be418d65a9 100644 --- a/src/au/aulayer_cocoaui.mm +++ b/src/au/aulayer_cocoaui.mm @@ -4,6 +4,29 @@ // // Created by Paul Walker on 12/10/18. // +/* + OK so how do cocoa uis work in AU2? There's two things + + 1: You return a valid AudioUnitViewInfo which contains basically a bundle URL and class name. You implement this in GetProperty in + response to kAudioUnitPropert_CocoaUI + + 2: You make that class that you return match the AUCococUIBase protocol which requires it to be able to create a frame + + Now the question is how does that frame get a reference to your audio unit? Well there's trick three, which is the uiForAudioUnit has to + use the property mechanism to get a reference to an editor. In this case I do that by sending the kVmBAudioUnitPropert_GetEditPointer + which I basically just made up. That returns (in this case) a pointer to a SurgeGUIEditor which uses a subset of the VST api + (only the public API) to give you a drawable element. + + The other trick to make this all work is that Surge itself works by having parameter changes which imapct other parameter changes + (like when you change patch number it changes patch name) just update parameters and not redraw. This makes sense for all + the obvious reasons (thread locality; bunched drawing; etc...). You can see the refresh_param_quuee and refresh_control_queue + implementation which just keep getting stacked up. But to unstack them you need to call a redraw, basically, and that's what the + editor ::idle method does. So the final thing to make it all work is to spin up a CFRunLoopTimer (not an NSTImer, note; I tried and + that's not the way to go) to call ::idle every 50ms. + + And that's what this code does. + + */ #include #import @@ -12,6 +35,8 @@ #include "aulayer_cocoaui.h" #include + + @interface SurgeNSView : NSView { SurgeGUIEditor *editController; @@ -37,8 +62,7 @@ - (NSView *) uiViewForAudioUnit: (AudioUnit) inAudioUnit { // Remember we end up being called here because that's what AUCocoaUIView does in the initiation collaboration with hosts AULOG::log( "uiViewForAudioUnit %s on %s\n", __TIME__, __DATE__ ); - AULOG::log( "My thread is %d\n", pthread_self( ) ); - + SurgeGUIEditor* editController = 0; UInt32 size = sizeof (SurgeGUIEditor *); if (AudioUnitGetProperty (inAudioUnit, kVmbAAudioUnitProperty_GetEditPointer, kAudioUnitScope_Global, 0, &editController, &size) != noErr) @@ -49,7 +73,6 @@ - (NSView *) uiViewForAudioUnit: (AudioUnit) inAudioUnit } - (unsigned int)interfaceVersion { - AULOG::log( "interfaceVersion\n" ); return 0; } @@ -73,7 +96,7 @@ - (id) initWithSurge: (SurgeGUIEditor *) cont preferredSize: (NSSize) size editController = cont; if (self) { - AULOG::log( "About to poen with %d\n", cont ); + AULOG::log( "Opening new editor view\n" ); cont->open( self ); ERect *vr; @@ -83,8 +106,6 @@ - (id) initWithSurge: (SurgeGUIEditor *) cont preferredSize: (NSSize) size [self setFrame:newSize]; } - AULOG::log( "Done resizing\n" ); - CFTimeInterval TIMER_INTERVAL = .05; // In SurgeGUISynthesizer.h it uses 50 ms CFRunLoopTimerContext TimerContext = {0, self, NULL, NULL, NULL}; CFAbsoluteTime FireTime = CFAbsoluteTimeGetCurrent() + TIMER_INTERVAL; @@ -96,7 +117,6 @@ - (id) initWithSurge: (SurgeGUIEditor *) cont preferredSize: (NSSize) size &TimerContext); if (idleTimer) CFRunLoopAddTimer (CFRunLoopGetMain (), idleTimer, kCFRunLoopCommonModes); - AULOG::log( "Added timer on %d\n", self ); } return self; @@ -109,11 +129,9 @@ - (void) doIdle - (void) dealloc { - AULOG::log( "Shutting down SurgeNSView in dealloc\n" ); editController->close(); if( idleTimer ) { - AULOG::log( "Invadliated Timer\n" ); CFRunLoopTimerInvalidate( idleTimer ); } @@ -183,7 +201,6 @@ static CFBundleRef GetBundleFromExecutable (const char* filepath) } case kVmbAAudioUnitProperty_GetEditPointer: { - AULOG::log( "Asking for the edit pointer on %d\n", pthread_self() ); if( editor_instance == NULL ) { editor_instance = new SurgeGUIEditor( this, plugin_instance );