Plugin Host and VSTs on Mac


#1

I am trying to get the demo plugin and the Plugin Host in Juce 1.50 to work nicely together. I am doing this on Mac OS 10.6.2.

What I have done:

  • A few minor project changes to get the Plugin Host to build
  • Changes to the JuceDemoPlugin project so that it only builds VST, the Info.plist has correct information etc.

What is happening:

  • JuceDemoPlugin appears to be working reasonably - it loads in Reaper (third-party host!), doesn’t crash, UI displays, doesn’t crash on quit (all good results!)
  • PluginHost has some trouble with JuceDemoPlugin. It loads, and I got the UI to display once, but it always crashes on quit and often crashes when the window is first displayed.

Is this working correctly for others out there? It seems that the demo projects in the source distribution might need some settings tweaked…

The reason I am looking into this is that I am working on another project - Jost, http://code.google.com/p/juced/ - and getting it working nicely on mac. There are various issues with the Jost’s VST support on Mac at present (though it is somewhat functional), and I plan to use the Plugin Host code as a reference when fixing the Mac-specific VST hosting problems in Jost.

So if I can get Juce Demo Plugin and Plugin Host working together reliably I’d be off to a good start!

thanks!


#2

You’re probably running into problems with symbol clashes being linked incorrectly. When you’ve got a debug plugin build and a debug host build that share a load of similiarly-names symbols, all of which are public, the linker can get pretty confused, and all the statics end up calling into the wrong module…

There isn’t an easy fix - though I guess you could use a different namespace for juce in the host… hmm, might give that a try.


#3

Aha! I will try a release build of both - that sounds like it should work…

… looks like I am seeing a similar crash - first time I loaded the plugin, worked fine, quit fine. Relaunched and added a plugin instance again, didn’t connect anything, double-clicked to show UI, crash:

Thread 0 Crashed: Dispatch queue: com.apple.main-thread 0 ...terialsoftware.PRODUCT_NAME 0x15002ac9 juce::Component::isShowing() const + 9 (juce_amalgamated.cpp:37737) 1 ...terialsoftware.PRODUCT_NAME 0x15092f9d juce::Component::grabFocusInternal(juce::Component::FocusChangeType, bool) + 45 (juce_amalgamated.cpp:40743) 2 ...terialsoftware.PRODUCT_NAME 0x15093878 juce::Component::grabKeyboardFocus() + 74 (juce_amalgamated.cpp:40791) 3 PluginHost 0x0002440a -[JuceNSWindow_1_50_3 constrainFrameRect:toScreen:] + 70 (juce_amalgamated.cpp:257170) 4 com.apple.AppKit 0x90424445 -[NSWindow _setFrameAfterMove:] + 94 5 com.apple.AppKit 0x904240ab -[NSWindow _windowMovedToRect:] + 139 6 com.apple.AppKit 0x90424005 -[NSWindow _windowMoved:] + 147 7 com.apple.AppKit 0x903bafe0 -[NSWindow sendEvent:] + 5757 8 com.apple.AppKit 0x902d3b2f -[NSApplication sendEvent:] + 6431 9 com.apple.AppKit 0x902674ff -[NSApplication run] + 917 10 PluginHost 0x00035e99 juce::MessageManager::runDispatchLoop() + 121 (juce_amalgamated.cpp:260906) 11 PluginHost 0x000b0666 juce::JUCEApplication::main(juce::String&, juce::JUCEApplication*) + 608 (juce_amalgamated.cpp:16143) 12 PluginHost 0x000b07f5 juce::JUCEApplication::main(int, char**, juce::JUCEApplication*) + 147 (juce_amalgamated.cpp:16221) 13 PluginHost 0x0000cbdc main + 96 (HostStartup.cpp:117) 14 PluginHost 0x00004da7 _start + 209 15 PluginHost 0x00004cd5 start + 41

So the namespace / juce link error may not be the (only) problem here?

I am very interested in getting the Xcode projects for these parts of Juce working out of the box. Note also I may have broken the build of the host or the plugin by my changes to the projects. In any case I’m sure there’s a way of setting up these projects so that out of the box they compile and run. And I’m keen to help reach this goal.

(I realise the plugin host is a tech demo / work in progress, but I believe it’s possible to get it more stable!?)


#4

I already checked in a better version myself earlier today - have a go with that.


#5

PluginHost compile fails with #error "Building for OSX 10.3 is no longer supported!" in juce_amalgamated.h line 152, when compiling FilterGraph.cpp (and then a whole lot of other files).

I am not attempting to build for 10.3! And this is with a completely clean checkout. I fixed this problem in a hacky way when I was trying to compile tip before - but I’d like to find out how this is compiling for you, so the clean checkout works for everyone …


#6

Like I said, I checked in a new version and that’s one of the things I cleaned up!


#7

Right you are - release build of a new checkout (I must not know my git from my elbow, I thought I had updated my checkout yesterday…) of PluginHost and DemoPlugin works, and no runtime issues when loading the built plugin (as a VST).

I will look into namespacing juce to work around the debug issue - it does still crash when debugging, hopefully the namespace will fix this, as the Jost project depends on multiple plugins and the host all built from the same juce, and debugging is useful!


#8

By the way the plugin project has two minor problems out of the box - it links to libPluginLibrary, which I don’t have, and the xcconfig files referenced don’t exist either. No biggie but worth tidying up next time you look at the project I guess. If the lib etc are needed for other plugin formats, and rely on other SDKs, maybe they could be put in a separate project (or at least a separate target).


#9

Great news - the namespace trick works, I am now able to debug the plugin host and the demo plugin.

I changed the juce namespace by adding a preprocessor definition JUCE_NAMESPACE=juce_DemoPluginNamespace to the plugin project.

Is this one of the reasons why the library is recommended to be used as a monolithic source file? Until now (with Juced, on Mac) I had been compiling Juce into a static library and linking to it, but this won’t work if each binary needs a different JUCE_NAMESPACE. The reason I don’t like the monolithic file is it is painful for debugging - if I need to step through some juce code, Xcode grinds to a halt with the amalgamated source file…

Anyway thanks for your help, I have plenty to be going on with now…


#10

Yes, it does make life easier for that. Have a look inside the juce_LibrarySource.cpp file for tips on debugging it.


#11

I’m in the process of porting my VST host to the Mac. Currently it asserts when trying to load a plug-in’s editor when checking if the component is valid during ComponentDeletionWatcher::hasBeenDeleted. The assertion occurs because the MessageManager instance does not include the component being checked among its listeners (MessageListener::isValidListener()). Depending on the plugin, it occurs when the plugin is scanned or, if I’m likely and it scans, when it’s added to the AudioProcessorGraph. I’ve also been to trigger the assertion in the Demo Plugin Host, though it takes more effort than in my host. Both hosts work when running outside the debugger so maybe this is not a problem (though I’ve not done any real testing at this point).

I’m running the tip as of today (Jan 2, 2010) with a few mods in AudioProcessorPlayer to do MidiOut. My Mac is running OSX 10.5. Any hints as to what’s going on are appreciated.


#12

Does this happen with 3rd party VSTs or just your own juce-built ones? If it’s your own plugins, then it might just be that they’re getting dynamically linked incorrectly because of symbol naming clashes between the host and plugin.


#13

It occurs on both 3rd party and the demo plugin. It also crashes if I try to load one of the built in audio units. Exceptions occur running outside the debugger, they’re just caught later. Note that the assertion failures are all checks for a valid message listener.

Do you think upgrading to OSX 10.6 or reverting to an earlier Juce would help? I did follow the instructions in the read me required to build the project.


#14

Nope.

I just tried the hosting demo here and it all runs perfectly, so it must be something you’re doing on your system that’s breaking it… Can’t think of any suggestions though…


#15

I tried with a clean copy of the amalgamated files, rebuilt everything, and duplicated my original results with the demo host: crash in debugger, runs ok outside of it. This time crash occurred in the AudioDeviceManager’s scanning for devices. In the device manager UI, the midi ports of the Tascam are listed, but not the audio. When I disconnect my Tascam US-144 interface, the demo host runs fine in the debugger although I was able to crash it trying to open AUMatrixReverb’s UI.

The same symptom, Tascam ports not recognized by device manager, was present in my earlier attempts with the demo host, but I thought it was a separate problem.


#16

When you say “crash in debugger, runs ok outside it”, presumably you actually mean “assertion failure”? If so, actually telling me what the assertion was might be helpful!


#17

Actually it’ll eventually crash running outside the debugger, just takes a few seconds longer. I downloaded the latest tip (1/20/2010) and reproduced the problem right off running in the debugger. The signal and call stack are reproduced below. First though, I had to patch lines 30330-30331 of juce_amalgamated.cpp to get it to compile:

numIns = jmax ((SInt16)numIns, supportedChannels[i].inChannels); numOuts = jmax ((SInt16)numOuts, supportedChannels[i].outChannels);
Casting the second arg to int instead of the first to Sint16 led to the same results. Now for the crash: When AUMatrixReverb is loaded into the demo Plugin Host, GDB breaks because it receives an EXC_BAD_ACCESS signal. Here’s the call stack:

#0	0x70074075 in AUMultibandCompressorEntry
#1	0x7007d8f0 in AUMultibandCompressorEntry
#2	0x7002f31c in AUMatrixReverbEntry
#3	0x70006662 in dyld_stub_vsnprintf
#4	0x7003ffd1 in SystemOutputAUEntry
#5	0x7002df3e in AUMatrixReverbEntry
#6	0x952089c9 in CallComponentDispatch
#7	0x91ad4af3 in AudioUnitRender
#8	0x000ec1f8 in JuceDemoHost::AudioUnitPluginInstance::processBlock at juce_amalgamated.cpp:30670
#9	0x0023e265 in JuceDemoHost::GraphRenderingOps::ProcessBufferOp::perform at juce_amalgamated.cpp:35323
#10	0x001274ee in JuceDemoHost::AudioProcessorGraph::processBlock at juce_amalgamated.cpp:35891
#11	0x0012705d in JuceDemoHost::AudioProcessorPlayer::audioDeviceIOCallback at juce_amalgamated.cpp:36243
#12	0x00125cef in JuceDemoHost::AudioDeviceManager::audioDeviceIOCallbackInt at juce_amalgamated.cpp:24696
#13	0x00126059 in JuceDemoHost::AudioDeviceManager::CallbackHandler::audioDeviceIOCallback at juce_amalgamated.cpp:24926
#14	0x002353e3 in JuceDemoHost::CoreAudioInternal::audioCallback at juce_amalgamated.cpp:250309
#15	0x00235665 in JuceDemoHost::CoreAudioInternal::audioIOProc at juce_amalgamated.cpp:250466
#16	0x93491177 in HP_IOProc::Call
#17	0x93490e68 in IOA_Device::CallIOProcs
#18	0x93490d44 in HP_IOThread::PerformIO
#19	0x9348f11f in HP_IOThread::WorkLoop
#20	0x9348ec43 in HP_IOThread::ThreadEntry
#21	0x9347f480 in CAPThread::Entry
#22	0x9142a155 in _pthread_start
#23	0x9142a012 in thread_start

#18

That’s crashing inside Apple’s code though… Hard to know what it’s unhappy about…


#19